1 //
2 // Copyright 2019 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #include "pxr/imaging/garch/glApi.h"
25
26 #include "pxr/imaging/hgi/enums.h"
27 #include "pxr/imaging/hgiGL/conversions.h"
28
29 #include "pxr/base/tf/iterator.h"
30 #include "pxr/base/tf/staticTokens.h"
31 #include "pxr/base/tf/stringUtils.h"
32
33 PXR_NAMESPACE_OPEN_SCOPE
34
35 struct _FormatDesc {
36 GLenum format;
37 GLenum type;
38 GLenum internalFormat;
39 };
40
41 static const _FormatDesc FORMAT_DESC[] =
42 {
43 // format, type, internal format
44 {GL_RED, GL_UNSIGNED_BYTE, GL_R8 }, // UNorm8
45 {GL_RG, GL_UNSIGNED_BYTE, GL_RG8 }, // UNorm8Vec2
46 // {GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8 }, // Unsupported by HgiFormat
47 {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8 }, // UNorm8Vec4
48
49 {GL_RED, GL_BYTE, GL_R8_SNORM }, // SNorm8
50 {GL_RG, GL_BYTE, GL_RG8_SNORM }, // SNorm8Vec2
51 // {GL_RGB, GL_BYTE, GL_RGB8_SNORM }, // Unsupported by HgiFormat
52 {GL_RGBA, GL_BYTE, GL_RGBA8_SNORM }, // SNorm8Vec4
53
54 {GL_RED, GL_HALF_FLOAT, GL_R16F }, // Float16
55 {GL_RG, GL_HALF_FLOAT, GL_RG16F }, // Float16Vec2
56 {GL_RGB, GL_HALF_FLOAT, GL_RGB16F }, // Float16Vec3
57 {GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F }, // Float16Vec4
58
59 {GL_RED, GL_FLOAT, GL_R32F }, // Float32
60 {GL_RG, GL_FLOAT, GL_RG32F }, // Float32Vec2
61 {GL_RGB, GL_FLOAT, GL_RGB32F }, // Float32Vec3
62 {GL_RGBA, GL_FLOAT, GL_RGBA32F }, // Float32Vec4
63
64 {GL_RED_INTEGER, GL_SHORT, GL_R16I }, // Int16
65 {GL_RG_INTEGER, GL_SHORT, GL_RG16I }, // Int16Vec2
66 {GL_RGB_INTEGER, GL_SHORT, GL_RGB16I }, // Int16Vec3
67 {GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I }, // Int16Vec4
68
69 {GL_RED_INTEGER, GL_UNSIGNED_SHORT,GL_R16UI }, // UInt16
70 {GL_RG_INTEGER, GL_UNSIGNED_SHORT,GL_RG16UI }, // UInt16Vec2
71 {GL_RGB_INTEGER, GL_UNSIGNED_SHORT,GL_RGB16UI }, // UInt16Vec3
72 {GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,GL_RGBA16UI }, // UInt16Vec4
73
74 {GL_RED_INTEGER, GL_INT, GL_R32I }, // Int32
75 {GL_RG_INTEGER, GL_INT, GL_RG32I }, // Int32Vec2
76 {GL_RGB_INTEGER, GL_INT, GL_RGB32I }, // Int32Vec3
77 {GL_RGBA_INTEGER, GL_INT, GL_RGBA32I }, // Int32Vec4
78
79 // {GL_RGB, GL_UNSIGNED_BYTE, GL_SRGB8 }, // Unsupported by HgiFormat
80 {GL_RGBA, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8}, // UNorm8Vec4sRGB,
81
82 {GL_RGB, GL_FLOAT,
83 GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT }, // BC6FloatVec3
84 {GL_RGB, GL_FLOAT,
85 GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}, // BC6UFloatVec3
86 {GL_RGBA, GL_UNSIGNED_BYTE,
87 GL_COMPRESSED_RGBA_BPTC_UNORM }, // BC7UNorm8Vec4
88 {GL_RGBA, GL_UNSIGNED_BYTE,
89 GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM }, // BC7UNorm8Vec4srgb
90 {GL_RGBA, GL_UNSIGNED_BYTE,
91 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT }, // BC1UNorm8Vec4
92 {GL_RGBA, GL_UNSIGNED_BYTE,
93 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT }, // BC3UNorm8Vec4
94
95 {GL_DEPTH_STENCIL, GL_FLOAT, GL_DEPTH32F_STENCIL8}, // Float32UInt8
96
97 };
98
99 // A few random format validations to make sure out GL table stays aligned
100 // with the HgiFormat table.
_CompileTimeValidateHgiFormatTable()101 constexpr bool _CompileTimeValidateHgiFormatTable() {
102 return (TfArraySize(FORMAT_DESC) == HgiFormatCount &&
103 HgiFormatUNorm8 == 0 &&
104 HgiFormatFloat16Vec4 == 9 &&
105 HgiFormatFloat32Vec4 == 13 &&
106 HgiFormatUInt16Vec4 == 21 &&
107 HgiFormatUNorm8Vec4srgb == 26 &&
108 HgiFormatBC3UNorm8Vec4 == 32) ? true : false;
109 }
110
111 static_assert(_CompileTimeValidateHgiFormatTable(),
112 "_FormatDesc array out of sync with HgiFormat enum");
113
114 static const uint32_t
115 _ShaderStageTable[][2] =
116 {
117 {HgiShaderStageVertex, GL_VERTEX_SHADER},
118 {HgiShaderStageFragment, GL_FRAGMENT_SHADER},
119 {HgiShaderStageCompute, GL_COMPUTE_SHADER},
120 {HgiShaderStageTessellationControl, GL_TESS_CONTROL_SHADER},
121 {HgiShaderStageTessellationEval, GL_TESS_EVALUATION_SHADER},
122 {HgiShaderStageGeometry, GL_GEOMETRY_SHADER}
123 };
124
125 static const uint32_t
126 _CullModeTable[HgiCullModeCount][2] =
127 {
128 {HgiCullModeNone, GL_NONE},
129 {HgiCullModeFront, GL_FRONT},
130 {HgiCullModeBack, GL_BACK},
131 {HgiCullModeFrontAndBack, GL_FRONT_AND_BACK}
132 };
133
134 static const uint32_t
135 _PolygonModeTable[HgiCullModeCount][2] =
136 {
137 {HgiPolygonModeFill, GL_FILL},
138 {HgiPolygonModeLine, GL_LINE},
139 {HgiPolygonModePoint, GL_POINT},
140 };
141
142 static uint32_t
143 _blendEquationTable[HgiBlendOpCount][2] =
144 {
145 {HgiBlendOpAdd, GL_FUNC_ADD},
146 {HgiBlendOpSubtract, GL_FUNC_SUBTRACT},
147 {HgiBlendOpReverseSubtract, GL_FUNC_REVERSE_SUBTRACT},
148 {HgiBlendOpMin, GL_MIN},
149 {HgiBlendOpMax, GL_MAX},
150 };
151
152 static uint32_t _blendFactorTable[HgiBlendFactorCount][2] =
153 {
154 {HgiBlendFactorZero, GL_ZERO},
155 {HgiBlendFactorOne, GL_ONE},
156 {HgiBlendFactorSrcColor, GL_SRC_COLOR},
157 {HgiBlendFactorOneMinusSrcColor, GL_ONE_MINUS_SRC_COLOR},
158 {HgiBlendFactorDstColor, GL_DST_COLOR},
159 {HgiBlendFactorOneMinusDstColor, GL_ONE_MINUS_DST_COLOR},
160 {HgiBlendFactorSrcAlpha, GL_SRC_ALPHA},
161 {HgiBlendFactorOneMinusSrcAlpha, GL_ONE_MINUS_SRC_ALPHA},
162 {HgiBlendFactorDstAlpha, GL_DST_ALPHA},
163 {HgiBlendFactorOneMinusDstAlpha, GL_ONE_MINUS_DST_ALPHA},
164 {HgiBlendFactorConstantColor, GL_CONSTANT_COLOR},
165 {HgiBlendFactorOneMinusConstantColor, GL_ONE_MINUS_CONSTANT_COLOR},
166 {HgiBlendFactorConstantAlpha, GL_CONSTANT_ALPHA},
167 {HgiBlendFactorOneMinusConstantAlpha, GL_ONE_MINUS_CONSTANT_ALPHA},
168 {HgiBlendFactorSrcAlphaSaturate, GL_SRC_ALPHA_SATURATE},
169 {HgiBlendFactorSrc1Color, GL_SRC1_COLOR},
170 {HgiBlendFactorOneMinusSrc1Color, GL_ONE_MINUS_SRC1_COLOR},
171 {HgiBlendFactorSrc1Alpha, GL_SRC1_ALPHA},
172 {HgiBlendFactorOneMinusSrc1Alpha, GL_ONE_MINUS_SRC1_COLOR},
173 };
174
175 static uint32_t
176 _compareFunctionTable[HgiCompareFunctionCount][2] =
177 {
178 {HgiCompareFunctionNever, GL_NEVER},
179 {HgiCompareFunctionLess, GL_LESS},
180 {HgiCompareFunctionEqual, GL_EQUAL},
181 {HgiCompareFunctionLEqual, GL_LEQUAL},
182 {HgiCompareFunctionGreater, GL_GREATER},
183 {HgiCompareFunctionNotEqual, GL_NOTEQUAL},
184 {HgiCompareFunctionGEqual, GL_GEQUAL},
185 {HgiCompareFunctionAlways, GL_ALWAYS},
186 };
187
188 static uint32_t
189 _textureTypeTable[HgiTextureTypeCount][2] =
190 {
191 {HgiTextureType1D, GL_TEXTURE_1D},
192 {HgiTextureType2D, GL_TEXTURE_2D},
193 {HgiTextureType3D, GL_TEXTURE_3D},
194 {HgiTextureType1DArray, GL_TEXTURE_1D_ARRAY},
195 {HgiTextureType2DArray, GL_TEXTURE_2D_ARRAY}
196 };
197
198 static uint32_t
199 _samplerAddressModeTable[HgiSamplerAddressModeCount][2] =
200 {
201 {HgiSamplerAddressModeClampToEdge, GL_CLAMP_TO_EDGE},
202 {HgiSamplerAddressModeMirrorClampToEdge, GL_MIRROR_CLAMP_TO_EDGE},
203 {HgiSamplerAddressModeRepeat, GL_REPEAT},
204 {HgiSamplerAddressModeMirrorRepeat, GL_MIRRORED_REPEAT},
205 {HgiSamplerAddressModeClampToBorderColor, GL_CLAMP_TO_BORDER}
206 };
207
208 static const uint32_t
209 _componentSwizzleTable[HgiComponentSwizzleCount][2] =
210 {
211 {HgiComponentSwizzleZero, GL_ZERO},
212 {HgiComponentSwizzleOne, GL_ONE},
213 {HgiComponentSwizzleR, GL_RED},
214 {HgiComponentSwizzleG, GL_GREEN},
215 {HgiComponentSwizzleB, GL_BLUE},
216 {HgiComponentSwizzleA, GL_ALPHA}
217 };
218
219 static const uint32_t
220 _primitiveTypeTable[HgiPrimitiveTypeCount][2] =
221 {
222 {HgiPrimitiveTypePointList, GL_POINTS},
223 {HgiPrimitiveTypeLineList, GL_LINES},
224 {HgiPrimitiveTypeLineStrip, GL_LINES_ADJACENCY},
225 {HgiPrimitiveTypeTriangleList, GL_TRIANGLES},
226 {HgiPrimitiveTypePatchList, GL_PATCHES}
227 };
228
229 void
GetFormat(HgiFormat inFormat,GLenum * outFormat,GLenum * outType,GLenum * outInternalFormat)230 HgiGLConversions::GetFormat(
231 HgiFormat inFormat,
232 GLenum *outFormat,
233 GLenum *outType,
234 GLenum *outInternalFormat)
235 {
236 if ((inFormat < 0) || (inFormat >= HgiFormatCount))
237 {
238 TF_CODING_ERROR("Unexpected %d", inFormat);
239 if (outFormat) {
240 *outFormat = GL_RGBA;
241 }
242 if (outType) {
243 *outType = GL_BYTE;
244 }
245 if (outInternalFormat) {
246 *outInternalFormat = GL_RGBA8;
247 }
248 return;
249 }
250
251 const _FormatDesc &desc = FORMAT_DESC[inFormat];
252 if (outFormat) {
253 *outFormat = desc.format;
254 }
255 if (outType) {
256 *outType = desc.type;
257 }
258 if (outInternalFormat) {
259 *outInternalFormat = desc.internalFormat;
260 }
261 }
262
263 GLenum
GetFormatType(HgiFormat inFormat)264 HgiGLConversions::GetFormatType(HgiFormat inFormat)
265 {
266 const _FormatDesc &desc = FORMAT_DESC[inFormat];
267 return desc.type;
268 }
269
270 std::vector<GLenum>
GetShaderStages(HgiShaderStage ss)271 HgiGLConversions::GetShaderStages(HgiShaderStage ss)
272 {
273 std::vector<GLenum> stages;
274 for (const auto& f : _ShaderStageTable) {
275 if (ss & f[0]) stages.push_back(f[1]);
276 }
277
278 if (stages.empty()) {
279 TF_CODING_ERROR("Missing shader stage table entry");
280 }
281 return stages;
282 }
283
284 GLenum
GetCullMode(HgiCullMode cm)285 HgiGLConversions::GetCullMode(HgiCullMode cm)
286 {
287 return _CullModeTable[cm][1];
288 }
289
290 GLenum
GetPolygonMode(HgiPolygonMode pm)291 HgiGLConversions::GetPolygonMode(HgiPolygonMode pm)
292 {
293 return _PolygonModeTable[pm][1];
294 }
295
296 GLenum
GetBlendFactor(HgiBlendFactor bf)297 HgiGLConversions::GetBlendFactor(HgiBlendFactor bf)
298 {
299 return _blendFactorTable[bf][1];
300 }
301
302 GLenum
GetBlendEquation(HgiBlendOp bo)303 HgiGLConversions::GetBlendEquation(HgiBlendOp bo)
304 {
305 return _blendEquationTable[bo][1];
306 }
307
308 GLenum
GetDepthCompareFunction(HgiCompareFunction cf)309 HgiGLConversions::GetDepthCompareFunction(HgiCompareFunction cf)
310 {
311 return _compareFunctionTable[cf][1];
312 }
313
314 GLenum
GetTextureType(HgiTextureType tt)315 HgiGLConversions::GetTextureType(HgiTextureType tt)
316 {
317 return _textureTypeTable[tt][1];
318 }
319
320 GLenum
GetSamplerAddressMode(HgiSamplerAddressMode am)321 HgiGLConversions::GetSamplerAddressMode(HgiSamplerAddressMode am)
322 {
323 return _samplerAddressModeTable[am][1];
324 }
325
326 GLenum
GetMagFilter(HgiSamplerFilter sf)327 HgiGLConversions::GetMagFilter(HgiSamplerFilter sf)
328 {
329 switch(sf) {
330 case HgiSamplerFilterNearest: return GL_NEAREST;
331 case HgiSamplerFilterLinear: return GL_LINEAR;
332 default: break;
333 }
334
335 TF_CODING_ERROR("Unsupported sampler options");
336 return GL_NONE;
337 }
338
339 GLenum
GetMinFilter(HgiSamplerFilter minFilter,HgiMipFilter mipFilter)340 HgiGLConversions::GetMinFilter(
341 HgiSamplerFilter minFilter,
342 HgiMipFilter mipFilter)
343 {
344 switch(mipFilter) {
345 // No mip-filter supplied (no mipmapping), return min-filter
346 case HgiMipFilterNotMipmapped :
347 switch(minFilter) {
348 case HgiSamplerFilterNearest: return GL_NEAREST;
349 case HgiSamplerFilterLinear: return GL_LINEAR;
350 default: TF_CODING_ERROR("Unsupported type"); break;
351 }
352
353 // Mip filter is nearest, combine min and mip filter into one enum
354 case HgiMipFilterNearest:
355 switch(minFilter) {
356 case HgiSamplerFilterNearest: return GL_NEAREST_MIPMAP_NEAREST;
357 case HgiSamplerFilterLinear: return GL_LINEAR_MIPMAP_NEAREST;
358 default: TF_CODING_ERROR("Unsupported typr"); break;
359 }
360
361 // Mip filter is linear, combine min and mip filter into one enum
362 case HgiMipFilterLinear:
363 switch(minFilter) {
364 case HgiSamplerFilterNearest: return GL_NEAREST_MIPMAP_LINEAR;
365 case HgiSamplerFilterLinear: return GL_LINEAR_MIPMAP_LINEAR;
366 default: TF_CODING_ERROR("Unsupported typr"); break;
367 }
368
369 default: break;
370 }
371
372 TF_CODING_ERROR("Unsupported sampler options");
373 return GL_NONE;
374 }
375
376 GLenum
GetComponentSwizzle(HgiComponentSwizzle componentSwizzle)377 HgiGLConversions::GetComponentSwizzle(HgiComponentSwizzle componentSwizzle)
378 {
379 return _componentSwizzleTable[componentSwizzle][1];
380 }
381
382 GLenum
GetPrimitiveType(HgiPrimitiveType pt)383 HgiGLConversions::GetPrimitiveType(HgiPrimitiveType pt)
384 {
385 return _primitiveTypeTable[pt][1];
386 }
387
388 PXR_NAMESPACE_CLOSE_SCOPE
389