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 "RenderAPI/BsGpuProgram.h" |
7 | |
8 | #include <cstdint> |
9 | #define CAPS_CATEGORY_SIZE INT64_C(8) |
10 | #define BS_CAPS_BITSHIFT (INT64_C(64) - CAPS_CATEGORY_SIZE) |
11 | #define CAPS_CATEGORY_MASK (((INT64_C(1) << CAPS_CATEGORY_SIZE) - INT64_C(1)) << BS_CAPS_BITSHIFT) |
12 | #define BS_CAPS_VALUE(cat, val) ((cat << BS_CAPS_BITSHIFT) | (INT64_C(1) << val)) |
13 | |
14 | #define BS_MAX_BOUND_VERTEX_BUFFERS 16 |
15 | |
16 | namespace bs |
17 | { |
18 | /** @addtogroup RenderAPI-Internal |
19 | * @{ |
20 | */ |
21 | |
22 | /** Categories of render API capabilities. */ |
23 | enum CapabilitiesCategory : UINT64 |
24 | { |
25 | CAPS_CATEGORY_COMMON = 0, |
26 | CAPS_CATEGORY_GL = 1, |
27 | CAPS_CATEGORY_D3D11 = 2, |
28 | CAPS_CATEGORY_VULKAN = 3, |
29 | CAPS_CATEGORY_COUNT = 32 /**< Maximum number of categories. */ |
30 | }; |
31 | |
32 | /** Enum describing the different hardware capabilities we can check for. */ |
33 | enum Capabilities : UINT64 |
34 | { |
35 | /** Supports compressed textures in the BC formats. */ |
36 | RSC_TEXTURE_COMPRESSION_BC = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 0), |
37 | /** Supports compressed textures in the ETC2 and EAC format. */ |
38 | RSC_TEXTURE_COMPRESSION_ETC2 = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 1), |
39 | /** Supports compressed textures in the ASTC format. */ |
40 | RSC_TEXTURE_COMPRESSION_ASTC = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 2), |
41 | /** Supports GPU geometry programs. */ |
42 | RSC_GEOMETRY_PROGRAM = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 3), |
43 | /** Supports GPU tessellation programs. */ |
44 | RSC_TESSELLATION_PROGRAM = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 4), |
45 | /** Supports GPU compute programs. */ |
46 | RSC_COMPUTE_PROGRAM = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 5), |
47 | /** Supports load-store (unordered access) writes to textures/buffers in GPU programs. */ |
48 | RSC_LOAD_STORE = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 6), |
49 | /** Supports load-store (unordered access) writes to textures with multiple samples. */ |
50 | RSC_LOAD_STORE_MSAA = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 7), |
51 | /** |
52 | * Supports views that allow a sub-set of a texture to be bound to a GPU program. (i.e. specific mip level or mip |
53 | * range, and/or specific array slice or array slice range) |
54 | */ |
55 | RSC_TEXTURE_VIEWS = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 8), |
56 | /** GPU programs are allowed to cache their bytecode for faster compilation. */ |
57 | RSC_BYTECODE_CACHING = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 9), |
58 | /** Supports rendering to multiple layers of a render texture at once. */ |
59 | RSC_RENDER_TARGET_LAYERS = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 10), |
60 | /** Has native support for command buffers that can be populated from secondary threads. */ |
61 | RSC_MULTI_THREADED_CB = BS_CAPS_VALUE(CAPS_CATEGORY_COMMON, 11), |
62 | }; |
63 | |
64 | /** Conventions used for a specific render backend. */ |
65 | struct BS_CORE_EXPORT Conventions |
66 | { |
67 | enum class Axis : UINT8 |
68 | { |
69 | Up, Down |
70 | }; |
71 | |
72 | enum class MatrixOrder : UINT8 |
73 | { |
74 | ColumnMajor, RowMajor |
75 | }; |
76 | |
77 | /** Determines the direction of the Y axis in UV (texture mapping) space. */ |
78 | Axis uvYAxis = Axis::Down; |
79 | |
80 | /** Determines the direction of the Y axis in normalized device coordinate (NDC) space. */ |
81 | Axis ndcYAxis = Axis::Up; |
82 | |
83 | /** Determines the order in which matrices are laid out in GPU programs. */ |
84 | MatrixOrder matrixOrder = MatrixOrder::RowMajor; |
85 | }; |
86 | |
87 | /** Holds data about render system driver version. */ |
88 | struct BS_CORE_EXPORT DriverVersion |
89 | { |
90 | DriverVersion() = default; |
91 | |
92 | /** Returns the driver version as a single string. */ |
93 | String toString() const |
94 | { |
95 | StringStream str; |
96 | str << major << "." << minor << "." << release << "." << build; |
97 | return str.str(); |
98 | } |
99 | |
100 | /** Parses a string in the major.minor.release.build format and stores the version numbers. */ |
101 | void fromString(const String& versionString) |
102 | { |
103 | Vector<bs::String> tokens = StringUtil::split(versionString, "." ); |
104 | if(!tokens.empty()) |
105 | { |
106 | major = parseINT32(tokens[0]); |
107 | if (tokens.size() > 1) |
108 | minor = parseINT32(tokens[1]); |
109 | if (tokens.size() > 2) |
110 | release = parseINT32(tokens[2]); |
111 | if (tokens.size() > 3) |
112 | build = parseINT32(tokens[3]); |
113 | } |
114 | |
115 | } |
116 | |
117 | INT32 major = 0; |
118 | INT32 minor = 0; |
119 | INT32 release = 0; |
120 | INT32 build = 0; |
121 | }; |
122 | |
123 | /** Types of GPU vendors. */ |
124 | enum GPUVendor |
125 | { |
126 | GPU_UNKNOWN = 0, |
127 | GPU_NVIDIA = 1, |
128 | GPU_AMD = 2, |
129 | GPU_INTEL = 3, |
130 | GPU_VENDOR_COUNT = 4 |
131 | }; |
132 | |
133 | /** Information about hardware (GPU) and driver capabilities, such as supported features, limits and conventions. */ |
134 | class BS_CORE_EXPORT RenderAPICapabilities final |
135 | { |
136 | public: |
137 | /** The identifier associated with the render API. */ |
138 | StringID renderAPIName; |
139 | |
140 | /** Current version of the driver (render backend). */ |
141 | DriverVersion driverVersion; |
142 | |
143 | /** The name of the device (GPU) as reported by the render system. */ |
144 | String deviceName; |
145 | |
146 | /** Vendor of the device (GPU). */ |
147 | GPUVendor deviceVendor = GPU_UNKNOWN; |
148 | |
149 | /** The number of texture units available per stage. */ |
150 | UINT16 numTextureUnitsPerStage[GPT_COUNT] { 0 }; |
151 | |
152 | /** Total number of texture units available. */ |
153 | UINT16 numCombinedTextureUnits = 0; |
154 | |
155 | /** The number of parameter block buffers available per stage. */ |
156 | UINT16 numGpuParamBlockBuffersPerStage[GPT_COUNT] { 0 }; |
157 | |
158 | /** Total number of parameter block buffers available. */ |
159 | UINT16 numCombinedParamBlockBuffers = 0; |
160 | |
161 | /** The number of load-store texture unitss available per stage. */ |
162 | UINT16 numLoadStoreTextureUnitsPerStage[GPT_COUNT] { 0 }; |
163 | |
164 | /** Total number of load-store texture units available. */ |
165 | UINT16 numCombinedLoadStoreTextureUnits = 0; |
166 | |
167 | /** Maximum number of vertex buffers we can bind at once. */ |
168 | UINT32 maxBoundVertexBuffers = 0; |
169 | |
170 | /** The number of simultaneous render targets supported. */ |
171 | UINT16 numMultiRenderTargets = 0; |
172 | |
173 | /** The number of vertices a geometry program can emit in a single run. */ |
174 | UINT32 geometryProgramNumOutputVertices = 0; |
175 | |
176 | /** Horizontal texel offset used for mapping texels to pixels. */ |
177 | float horizontalTexelOffset = 0.0f; |
178 | |
179 | /** Vertical texel offset used for mapping texels to pixels. */ |
180 | float verticalTexelOffset = 0.0f; |
181 | |
182 | /** Minimum (closest) depth value used by this render backend */ |
183 | float minDepth = 0.0f; |
184 | |
185 | /** Maximum (farthest) depth value used by this render backend. */ |
186 | float maxDepth = 1.0f; |
187 | |
188 | /** Returns various conventions expected by the render backend. */ |
189 | Conventions conventions; |
190 | |
191 | /** Native type used for vertex colors. */ |
192 | VertexElementType vertexColorType = VET_COLOR_ABGR; |
193 | |
194 | /** Sets a capability flag indicating this capability is supported. */ |
195 | void setCapability(const Capabilities c) |
196 | { |
197 | UINT64 index = (CAPS_CATEGORY_MASK & c) >> BS_CAPS_BITSHIFT; |
198 | mCapabilities[index] |= (c & ~CAPS_CATEGORY_MASK); |
199 | } |
200 | |
201 | /** Remove a capability flag indicating this capability is not supported (default). */ |
202 | void unsetCapability(const Capabilities c) |
203 | { |
204 | UINT64 index = (CAPS_CATEGORY_MASK & c) >> BS_CAPS_BITSHIFT; |
205 | mCapabilities[index] &= (~c | CAPS_CATEGORY_MASK); |
206 | } |
207 | |
208 | /** Checks is the specified capability supported. */ |
209 | bool hasCapability(const Capabilities c) const |
210 | { |
211 | UINT64 index = (CAPS_CATEGORY_MASK & c) >> BS_CAPS_BITSHIFT; |
212 | |
213 | return (mCapabilities[index] & (c & ~CAPS_CATEGORY_MASK)) != 0; |
214 | } |
215 | |
216 | /** Adds a shader profile to the list of render-system specific supported profiles. */ |
217 | void addShaderProfile(const String& profile) |
218 | { |
219 | mSupportedShaderProfiles.insert(profile); |
220 | } |
221 | |
222 | /** Returns true if the provided profile is supported. */ |
223 | bool isShaderProfileSupported(const String& profile) const |
224 | { |
225 | return (mSupportedShaderProfiles.end() != mSupportedShaderProfiles.find(profile)); |
226 | } |
227 | |
228 | /** Returns a set of all supported shader profiles. */ |
229 | const UnorderedSet<String>& getSupportedShaderProfiles() const |
230 | { |
231 | return mSupportedShaderProfiles; |
232 | } |
233 | |
234 | /** Parses a vendor string and returns an enum with the vendor if parsed succesfully. */ |
235 | static GPUVendor vendorFromString(const String& vendorString); |
236 | |
237 | /** Converts a vendor enum to a string. */ |
238 | static String vendorToString(GPUVendor vendor); |
239 | |
240 | private: |
241 | static char const * const GPU_VENDOR_STRINGS[GPU_VENDOR_COUNT]; |
242 | |
243 | /** Stores the capabilities flags. */ |
244 | UINT32 mCapabilities[CAPS_CATEGORY_COUNT] { 0 }; |
245 | |
246 | /** The list of supported shader profiles. */ |
247 | UnorderedSet<String> mSupportedShaderProfiles; |
248 | }; |
249 | |
250 | /** @} */ |
251 | } |
252 | |