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
16namespace 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