1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Image/BsColor.h"
7#include "Reflection/BsIReflectable.h"
8#include "CoreThread/BsCoreObject.h"
9
10#include <cfloat>
11
12namespace bs
13{
14 /** @addtogroup RenderAPI
15 * @{
16 */
17
18 /**
19 * Structure used for initializing a SamplerState.
20 *
21 * @see SamplerState
22 */
23 struct BS_CORE_EXPORT SAMPLER_STATE_DESC
24 {
25 SAMPLER_STATE_DESC() { };
26
27 bool operator==(const SAMPLER_STATE_DESC& rhs) const;
28
29 /** Determines how are texture coordinates outside of [0, 1] range handled. */
30 UVWAddressingMode addressMode;
31
32 /** Filtering used when texture is displayed as smaller than its original size. */
33 FilterOptions minFilter = FO_LINEAR;
34
35 /** Filtering used when texture is displayed as larger than its original size. */
36 FilterOptions magFilter = FO_LINEAR;
37
38 /** Filtering used to blend between the different mip levels. */
39 FilterOptions mipFilter = FO_LINEAR;
40
41 /** Maximum number of samples if anisotropic filtering is enabled. Max is 16. */
42 UINT32 maxAniso = 0;
43
44 /**
45 * Mipmap bias allows you to adjust the mipmap selection calculation. Negative values force a larger mipmap to be
46 * used, and positive values smaller. Units are in values of mip levels, so -1 means use a mipmap one level higher
47 * than default.
48 */
49 float mipmapBias = 0;
50
51 /** Minimum mip-map level that is allowed to be displayed. */
52 float mipMin = -FLT_MAX;
53
54 /** Maximum mip-map level that is allowed to be displayed. Set to FLT_MAX for no limit. */
55 float mipMax = FLT_MAX;
56
57 /** Border color to use when using border addressing mode as specified by @p addressMode. */
58 Color borderColor = Color::White;
59
60 /** Function that compares sampled data with existing sampled data. */
61 CompareFunction comparisonFunc = CMPF_ALWAYS_PASS;
62 };
63
64 /** Properties of SamplerState. Shared between sim and core thread versions of SamplerState. */
65 class BS_CORE_EXPORT SamplerProperties
66 {
67 public:
68 SamplerProperties(const SAMPLER_STATE_DESC& desc);
69
70 /**
71 * Returns texture addressing mode for each possible texture coordinate. Addressing modes determine how are texture
72 * coordinates outside of [0, 1] range handled.
73 */
74 const UVWAddressingMode& getTextureAddressingMode() const { return mData.addressMode; }
75
76 /** Gets the filtering used when sampling from a texture. */
77 FilterOptions getTextureFiltering(FilterType ftpye) const;
78
79 /**
80 * Gets the anisotropy level. Higher anisotropy means better filtering for textures displayed on an angled slope
81 * relative to the viewer.
82 */
83 unsigned int getTextureAnisotropy() const { return mData.maxAniso; }
84
85 /** Gets a function that compares sampled data with existing sampled data. */
86 CompareFunction getComparisonFunction() const { return mData.comparisonFunc; }
87
88 /**
89 * Mipmap bias allows you to adjust the mipmap selection calculation. Negative values force a larger mipmap to be
90 * used, and positive values smaller. Units are in values of mip levels, so -1 means use a mipmap one level higher
91 * than default.
92 */
93 float getTextureMipmapBias() const { return mData.mipmapBias; }
94
95 /** Returns the minimum mip map level. */
96 float getMinimumMip() const { return mData.mipMin; }
97
98 /** Returns the maximum mip map level. */
99 float getMaximumMip() const { return mData.mipMax; }
100
101 /**
102 * Gets the border color that will be used when border texture addressing is used and texture address is outside of
103 * the valid range.
104 */
105 const Color& getBorderColor() const;
106
107 /** Returns the hash value generated from the sampler state properties. */
108 UINT64 getHash() const { return mHash; }
109
110 /** Returns the descriptor originally used for creating the sampler state. */
111 SAMPLER_STATE_DESC getDesc() const { return mData; }
112
113 protected:
114 friend class SamplerState;
115 friend class ct::SamplerState;
116 friend class SamplerStateRTTI;
117
118 SAMPLER_STATE_DESC mData;
119 UINT64 mHash;
120 };
121
122 /**
123 * Class representing the state of a texture sampler.
124 *
125 * @note
126 * Sampler units are used for retrieving and filtering data from textures set in a GPU program. Sampler states are
127 * immutable.
128 * @note
129 * Sim thread.
130 */
131 class BS_CORE_EXPORT SamplerState : public IReflectable, public CoreObject
132 {
133 public:
134 virtual ~SamplerState() = default;
135
136 /** Returns information about the sampler state. */
137 const SamplerProperties& getProperties() const;
138
139 /** Retrieves a core implementation of the sampler state usable only from the core thread. */
140 SPtr<ct::SamplerState> getCore() const;
141
142 /** Creates a new sampler state using the provided descriptor structure. */
143 static SPtr<SamplerState> create(const SAMPLER_STATE_DESC& desc);
144
145 /** Returns the default sampler state. */
146 static const SPtr<SamplerState>& getDefault();
147
148 /** Generates a hash value from a sampler state descriptor. */
149 static UINT64 generateHash(const SAMPLER_STATE_DESC& desc);
150
151 protected:
152 SamplerState(const SAMPLER_STATE_DESC& desc);
153
154 /** @copydoc CoreObject::createCore */
155 SPtr<ct::CoreObject> createCore() const override;
156
157 SamplerProperties mProperties;
158
159 friend class RenderStateManager;
160
161 /************************************************************************/
162 /* RTTI */
163 /************************************************************************/
164
165 public:
166 friend class SamplerStateRTTI;
167 static RTTITypeBase* getRTTIStatic();
168 RTTITypeBase* getRTTI() const override;
169 };
170
171 /** @} */
172
173 namespace ct
174 {
175 /** @addtogroup RenderAPI-Internal
176 * @{
177 */
178
179 /**
180 * Core thread version of bs::SamplerState.
181 *
182 * @note Core thread.
183 */
184 class BS_CORE_EXPORT SamplerState : public CoreObject
185 {
186 public:
187 virtual ~SamplerState();
188
189 /** Returns information about the sampler state. */
190 const SamplerProperties& getProperties() const;
191
192 /** @copydoc RenderStateManager::createSamplerState */
193 static SPtr<SamplerState> create(const SAMPLER_STATE_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
194
195 /** Returns the default sampler state. */
196 static const SPtr<SamplerState>& getDefault();
197
198 protected:
199 friend class RenderStateManager;
200
201 SamplerState(const SAMPLER_STATE_DESC& desc, GpuDeviceFlags deviceMask);
202
203 /** @copydoc CoreObject::initialize */
204 void initialize() override;
205
206 /** Creates any API-specific state objects. */
207 virtual void createInternal() { }
208
209 SamplerProperties mProperties;
210 };
211
212 /** @} */
213 }
214}
215
216/** @cond STDLIB */
217/** @addtogroup RenderAPI
218 * @{
219 */
220
221namespace std
222{
223/** Hash value generator for SAMPLER_STATE_DESC. */
224template<>
225struct hash<bs::SAMPLER_STATE_DESC>
226{
227 size_t operator()(const bs::SAMPLER_STATE_DESC& value) const
228 {
229 return (size_t)bs::SamplerState::generateHash(value);
230 }
231};
232}
233
234/** @} */
235/** @endcond */
236