From eb43fb585e8aacf9383280c5b48f9dce5627b524 Mon Sep 17 00:00:00 2001 From: clach Date: Tue, 25 Jan 2022 23:46:48 -0800 Subject: [PATCH] [hdSt, hgi*] Exclude double precision transform overloads from the Storm volume shader when double precision values are not supported (e.g. using Metal). A new Hgi capability bit, HgiDeviceCapabilitiesBitsShaderDoublePrecision, is added, which codegen will use to create a shader define if needed. (Internal change: 2211644) --- pxr/imaging/hdSt/codeGen.cpp | 6 ++++++ pxr/imaging/hdSt/shaders/volume.glslfx | 4 ++++ pxr/imaging/hgi/enums.h | 19 +++++++++++-------- pxr/imaging/hgiGL/capabilities.cpp | 2 ++ pxr/imaging/hgiMetal/capabilities.mm | 2 ++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/pxr/imaging/hdSt/codeGen.cpp b/pxr/imaging/hdSt/codeGen.cpp index 4e66c29f40..83fa9dbbd5 100644 --- a/pxr/imaging/hdSt/codeGen.cpp +++ b/pxr/imaging/hdSt/codeGen.cpp @@ -533,6 +533,9 @@ HdSt_CodeGen::Compile(HdStResourceRegistry*const registry) GetCapabilities()->IsSet(HgiDeviceCapabilitiesBitsShaderDrawParameters); const bool builtinBarycentricsEnabled = registry->GetHgi()-> GetCapabilities()->IsSet(HgiDeviceCapabilitiesBitsBuiltinBarycentrics); + const bool doublePrecisionEnabled = registry->GetHgi()-> + GetCapabilities()->IsSet( + HgiDeviceCapabilitiesBitsShaderDoublePrecision); if (bindlessBufferEnabled) { _genHeader << "#extension GL_NV_shader_buffer_load : require\n" @@ -575,6 +578,9 @@ HdSt_CodeGen::Compile(HdStResourceRegistry*const registry) if (_materialTag == HdStMaterialTagTokens->masked) { _genFS << "#define HD_MATERIAL_TAG_MASKED 1\n"; } + if (doublePrecisionEnabled) { + _genFS << "#define HD_SHADER_SUPPORTS_DOUBLE_PRECISION\n"; + } // ------------------ // Custom Buffer Bindings diff --git a/pxr/imaging/hdSt/shaders/volume.glslfx b/pxr/imaging/hdSt/shaders/volume.glslfx index 9b27dbbef8..6054b80f97 100644 --- a/pxr/imaging/hdSt/shaders/volume.glslfx +++ b/pxr/imaging/hdSt/shaders/volume.glslfx @@ -98,12 +98,14 @@ transformPoint(mat4 m, vec3 point) return result.xyz / result.w; } +#ifdef HD_SHADER_SUPPORTS_DOUBLE_PRECISION vec3 transformPoint(dmat4 m, vec3 point) { const vec4 result = vec4(m * vec4(point, 1.0)); return result.xyz / result.w; } +#endif // Transform a direction by a 4x4 matrix vec3 @@ -113,12 +115,14 @@ transformDir(mat4 m, vec3 dir) return result.xyz; } +#ifdef HD_SHADER_SUPPORTS_DOUBLE_PRECISION vec3 transformDir(dmat4 m, vec3 dir) { const vec4 result = vec4(m * vec4(dir, 0.0)); return result.xyz; } +#endif // Compute time when a ray starting at pos with direction dir // exits the axis-aligned box with vertices lMin and lMax. diff --git a/pxr/imaging/hgi/enums.h b/pxr/imaging/hgi/enums.h index 0796c564fa..edf4bc9c82 100644 --- a/pxr/imaging/hgi/enums.h +++ b/pxr/imaging/hgi/enums.h @@ -55,18 +55,21 @@ using HgiBits = uint32_t; /// The device supports multiple primitive, indirect drawing ///
  • HgiDeviceCapabilitiesBitsBindlessTextures: /// The device can access GPU textures using bindless handles
  • +///
  • HgiDeviceCapabilitiesBitsShaderDoublePrecision: +/// The device supports double precision types in shaders
  • /// /// enum HgiDeviceCapabilitiesBits : HgiBits { - HgiDeviceCapabilitiesBitsPresentation = 1 << 0, - HgiDeviceCapabilitiesBitsBindlessBuffers = 1 << 1, - HgiDeviceCapabilitiesBitsConcurrentDispatch = 1 << 2, - HgiDeviceCapabilitiesBitsUnifiedMemory = 1 << 3, - HgiDeviceCapabilitiesBitsBuiltinBarycentrics = 1 << 4, - HgiDeviceCapabilitiesBitsShaderDrawParameters = 1 << 5, - HgiDeviceCapabilitiesBitsMultiDrawIndirect = 1 << 6, - HgiDeviceCapabilitiesBitsBindlessTextures = 1 << 7 + HgiDeviceCapabilitiesBitsPresentation = 1 << 0, + HgiDeviceCapabilitiesBitsBindlessBuffers = 1 << 1, + HgiDeviceCapabilitiesBitsConcurrentDispatch = 1 << 2, + HgiDeviceCapabilitiesBitsUnifiedMemory = 1 << 3, + HgiDeviceCapabilitiesBitsBuiltinBarycentrics = 1 << 4, + HgiDeviceCapabilitiesBitsShaderDrawParameters = 1 << 5, + HgiDeviceCapabilitiesBitsMultiDrawIndirect = 1 << 6, + HgiDeviceCapabilitiesBitsBindlessTextures = 1 << 7, + HgiDeviceCapabilitiesBitsShaderDoublePrecision = 1 << 8 }; using HgiDeviceCapabilities = HgiBits; diff --git a/pxr/imaging/hgiGL/capabilities.cpp b/pxr/imaging/hgiGL/capabilities.cpp index a9a8cb158a..5c413fb440 100644 --- a/pxr/imaging/hgiGL/capabilities.cpp +++ b/pxr/imaging/hgiGL/capabilities.cpp @@ -181,6 +181,8 @@ HgiGLCapabilities::_LoadCapabilities() builtinBarycentricsEnabled); _SetFlag(HgiDeviceCapabilitiesBitsShaderDrawParameters, shaderDrawParametersEnabled); + _SetFlag(HgiDeviceCapabilitiesBitsShaderDoublePrecision, + true); if (TfDebug::IsEnabled(HGI_DEBUG_DEVICE_CAPABILITIES)) { std::cout diff --git a/pxr/imaging/hgiMetal/capabilities.mm b/pxr/imaging/hgiMetal/capabilities.mm index 9dc10b10a6..b6537a6ead 100644 --- a/pxr/imaging/hgiMetal/capabilities.mm +++ b/pxr/imaging/hgiMetal/capabilities.mm @@ -51,6 +51,8 @@ _SetFlag(HgiDeviceCapabilitiesBitsBuiltinBarycentrics, true); + _SetFlag(HgiDeviceCapabilitiesBitsShaderDoublePrecision, false); + #if defined(ARCH_OS_MACOS) if (!unifiedMemory) { defaultStorageMode = MTLResourceStorageModeManaged;