Skip to content

Commit a0b57f8

Browse files
committed
[hdSt, hdx, hgi] OIT improvements and fixes
- Implement early fragment test directly in the shader when it is not supported by the graphics API. - Add a new test for OIT in usdImagingGL for Packed OIT and OIT - Fix recompilation of OIT shaders when garbage collection is called. - Add another pass/renderPassState to the oitRenderTask to hold the translucent pass information, this makes an appropriate use of the renderPassState and avoids recompilation of the OIT shaders due to pointer counter - Merge oitDepth and oitIndex buffer into a single interleaved buffer - Update codeGen to support handling writable and indexed interleaved buffer - Fix small bug when querying for a resource with an empty name - Updated oit shaders to use the new merged buffer - Pack the transmission, depth and color for OIT - Pack the RGBA color originally stored in a vec4 into a uvec4 - Pack the depth and transmission into a uint where the first 8 bits store the transmission(alpha) value and the rest is reserved for the depth. This results in improving the size of the OIT buffer by a factor of 4. For the old method: ``` Old hdxOitDataBuffer = 102236160 ~ 97.5MB for a resolution of 1024x780 with mssa vertex stride 16 bytesPerElement = 16 numElements = 1024 * 780 = 6389760 totalSize = 1024 * 780 * 16 = 102236160 ``` For the new method: ``` New hdxOitColorBuffer = 25559040 ~ 24.3MB for a resolution of 1024x780 with mssa vertex stride 4 bytesPerElement = 4 numElements = 1024 * 780 = 6389760 totalSize = 1024 * 780 * 4 = 25559040 ``` This is defined by the theory in: https://interplayoflight.wordpress.com/2022/06/25/order-independent-transparency-part-1/
1 parent 100f1f9 commit a0b57f8

28 files changed

+421
-124
lines changed

pxr/imaging/hdSt/codeGen.cpp

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ static void _EmitDeclaration(HioGlslfxResourceLayout::ElementVector *elements,
231231
bool isWritable=false,
232232
int arraySize=0);
233233

234+
static void _EmitDeclaration(HioGlslfxResourceLayout::ElementVector *elements,
235+
HdSt_ResourceBinder::MetaData::BindingDeclaration const &bindingDeclaration,
236+
int arraySize=0);
237+
234238
static void _EmitStructAccessor(std::stringstream &str,
235239
TfToken const &structName,
236240
TfToken const &name,
@@ -2043,12 +2047,7 @@ HdSt_CodeGen::Compile(HdStResourceRegistry*const registry)
20432047
continue;
20442048
}
20452049

2046-
_EmitDeclaration(&_resCommon,
2047-
binDecl->name,
2048-
binDecl->dataType,
2049-
binDecl->binding,
2050-
binDecl->isWritable);
2051-
2050+
_EmitDeclaration(&_resCommon, *binDecl);
20522051
_EmitAccessor(_genAccessors,
20532052
binDecl->name,
20542053
binDecl->dataType,
@@ -2066,6 +2065,7 @@ HdSt_CodeGen::Compile(HdStResourceRegistry*const registry)
20662065
HdStBinding binding = it->first;
20672066
TfToken typeName(TfStringPrintf("CustomBlockData%d", binding.GetValue()));
20682067
TfToken varName = it->second.blockName;
2068+
bool isIndexed = it->second.arraySize > 0 || (binding.GetType() != HdStBinding::UNIFORM && binding.GetType() != HdStBinding::UBO);
20692069

20702070
_genDecl << "struct " << typeName << " {\n";
20712071
// dbIt is StructEntry { name, dataType, offset, numElements }
@@ -2081,15 +2081,9 @@ HdSt_CodeGen::Compile(HdStResourceRegistry*const registry)
20812081
}
20822082
_genDecl << ";\n";
20832083

2084-
if (it->second.arraySize > 0) {
2085-
_EmitStructAccessor(_genAccessors, varName,
2086-
dbIt->name, dbIt->dataType, dbIt->arraySize,
2087-
"localIndex", dbIt->concatenateNames);
2088-
} else {
2089-
_EmitStructAccessor(_genAccessors, varName,
2090-
dbIt->name, dbIt->dataType, dbIt->arraySize,
2091-
NULL, dbIt->concatenateNames);
2092-
}
2084+
_EmitStructAccessor(_genAccessors, varName,
2085+
dbIt->name, dbIt->dataType, dbIt->arraySize,
2086+
isIndexed ? "localIndex" : NULL, dbIt->concatenateNames);
20932087

20942088
if (dbIt->name == HdShaderTokens->clipPlanes) {
20952089
_hasClipPlanes = true;
@@ -2098,7 +2092,7 @@ HdSt_CodeGen::Compile(HdStResourceRegistry*const registry)
20982092

20992093
_genDecl << "};\n";
21002094
_EmitDeclaration(&_resCommon, varName, typeName, binding,
2101-
/*isWritable=*/false, it->second.arraySize);
2095+
/*isWritable=*/it->second.isWritable, it->second.arraySize);
21022096
}
21032097

21042098
// HD_NUM_PATCH_VERTS, HD_NUM_PRIMTIIVE_VERTS
@@ -3452,7 +3446,7 @@ static void _EmitDeclaration(
34523446
static void _EmitDeclaration(
34533447
HioGlslfxResourceLayout::ElementVector *elements,
34543448
HdSt_ResourceBinder::MetaData::BindingDeclaration const &bindingDeclaration,
3455-
int arraySize=0)
3449+
int arraySize)
34563450
{
34573451
_EmitDeclaration(elements,
34583452
bindingDeclaration.name,

pxr/imaging/hdSt/glConversions.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ HdStGLConversions::GetGLSLTypename(HdType type)
262262
case HdTypeBool:
263263
return _glTypeNames->_bool;
264264

265+
case HdTypeInt16:
265266
case HdTypeInt32:
266267
return _glTypeNames->_int;
267268
case HdTypeInt32Vec2:
@@ -271,6 +272,8 @@ HdStGLConversions::GetGLSLTypename(HdType type)
271272
case HdTypeInt32Vec4:
272273
return _glTypeNames->ivec4;
273274

275+
case HdTypeUInt8:
276+
case HdTypeUInt16:
274277
case HdTypeUInt32:
275278
return _glTypeNames->_uint;
276279
case HdTypeUInt32Vec2:

pxr/imaging/hdSt/resourceBinder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@ HdSt_ResourceBinder::ResolveBindings(
930930
valueType.count,
931931
concatenateNames);
932932
}
933+
sblock.isWritable = it->isWritable();
933934
sblock.arraySize = it->GetArraySize();
934935
metaDataOut->customInterleavedBindings.insert(
935936
std::make_pair(binding, sblock));

pxr/imaging/hdSt/resourceBinder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class HdSt_ResourceBinder {
174174
TfToken blockName;
175175
std::vector<StructEntry> entries;
176176
int arraySize;
177+
bool isWritable;
177178
};
178179
using StructBlockBinding = std::map<HdStBinding, StructBlock>;
179180

pxr/imaging/hdSt/shaders/mesh.glslfx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,16 @@ vec3 ComputeScreenSpaceNeye()
14751475

14761476
void main(void)
14771477
{
1478+
#ifdef HD_HAS_depthReadback
1479+
// Sample the z-Buffer at the frag coordinate.
1480+
const float bufferVal = texelFetch(HdGetSampler_depthReadback(),
1481+
ivec2(gl_FragCoord.xy),
1482+
/* lod = */ 0).x;
1483+
// reject fragments behind opaque objects
1484+
if (gl_FragCoord.z >= bufferVal.x) {
1485+
discard;
1486+
}
1487+
#endif
14781488
ApplyDiskSampleMask();
14791489

14801490
bool isFlipped = IsFlipped();

pxr/imaging/hdSt/vboMemoryManager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ HdStBufferResourceSharedPtr
489489
HdStVBOMemoryManager::_StripedBufferArray::GetResource(TfToken const& name)
490490
{
491491
HD_TRACE_FUNCTION();
492+
if (name.IsEmpty()) return GetResource();
492493

493494
// linear search.
494495
// The number of buffer resources should be small (<10 or so).

pxr/imaging/hdx/oitBufferAccessor.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,23 @@ PXR_NAMESPACE_OPEN_SCOPE
2222
TF_DEFINE_ENV_SETTING(HDX_ENABLE_OIT, true,
2323
"Enable order independent translucency");
2424

25+
TF_DEFINE_ENV_SETTING(HDX_ENABLE_OIT_PACKED_DATA, false,
26+
"Pack color, transmission and depth into smaller buffers, trading accuracy for memory.");
27+
2528
/* static */
2629
bool
2730
HdxOitBufferAccessor::IsOitEnabled()
2831
{
2932
return TfGetEnvSetting(HDX_ENABLE_OIT);
3033
}
3134

35+
/* static */
36+
bool
37+
HdxOitBufferAccessor::IsOitPackedDepthEnabled()
38+
{
39+
return TfGetEnvSetting(HDX_ENABLE_OIT_PACKED_DATA);
40+
}
41+
3242
HdxOitBufferAccessor::HdxOitBufferAccessor(HdTaskContext *ctx)
3343
: _ctx(ctx)
3444
{
@@ -57,18 +67,23 @@ bool
5767
HdxOitBufferAccessor::AddOitBufferBindings(
5868
const HdStRenderPassShaderSharedPtr &shader)
5969
{
70+
HdBufferArrayRangeSharedPtr const & jointBar =
71+
_GetBar(HdxTokens->oitJointBufferBar);
6072
HdBufferArrayRangeSharedPtr const & counterBar =
6173
_GetBar(HdxTokens->oitCounterBufferBar);
6274
HdBufferArrayRangeSharedPtr const & dataBar =
6375
_GetBar(HdxTokens->oitDataBufferBar);
64-
HdBufferArrayRangeSharedPtr const & depthBar =
65-
_GetBar(HdxTokens->oitDepthBufferBar);
66-
HdBufferArrayRangeSharedPtr const & indexBar =
67-
_GetBar(HdxTokens->oitIndexBufferBar);
6876
HdBufferArrayRangeSharedPtr const & uniformBar =
6977
_GetBar(HdxTokens->oitUniformBar);
7078

71-
if (counterBar && dataBar && depthBar && indexBar && uniformBar) {
79+
if (counterBar && dataBar && jointBar && uniformBar) {
80+
shader->AddBufferBinding(
81+
HdStBindingRequest(HdStBinding::SSBO,
82+
HdxTokens->oitJointBufferBar,
83+
jointBar,
84+
/*interleave = */ true,
85+
/*writable = */ true));
86+
7287
shader->AddBufferBinding(
7388
HdStBindingRequest(HdStBinding::SSBO,
7489
HdxTokens->oitCounterBufferBar,
@@ -82,32 +97,17 @@ HdxOitBufferAccessor::AddOitBufferBindings(
8297
dataBar,
8398
/*interleave = */ false,
8499
/*writable = */ true));
85-
86-
shader->AddBufferBinding(
87-
HdStBindingRequest(HdStBinding::SSBO,
88-
HdxTokens->oitDepthBufferBar,
89-
depthBar,
90-
/*interleave = */ false,
91-
/*writable = */ true));
92-
93-
shader->AddBufferBinding(
94-
HdStBindingRequest(HdStBinding::SSBO,
95-
HdxTokens->oitIndexBufferBar,
96-
indexBar,
97-
/*interleave = */ false,
98-
/*writable = */ true));
99-
100+
100101
shader->AddBufferBinding(
101102
HdStBindingRequest(HdStBinding::UBO,
102103
HdxTokens->oitUniformBar,
103104
uniformBar,
104105
/*interleave = */ true));
105106
return true;
106107
} else {
108+
shader->RemoveBufferBinding(HdxTokens->oitJointBufferBar);
107109
shader->RemoveBufferBinding(HdxTokens->oitCounterBufferBar);
108110
shader->RemoveBufferBinding(HdxTokens->oitDataBufferBar);
109-
shader->RemoveBufferBinding(HdxTokens->oitDepthBufferBar);
110-
shader->RemoveBufferBinding(HdxTokens->oitIndexBufferBar);
111111
shader->RemoveBufferBinding(HdxTokens->oitUniformBar);
112112
return false;
113113
}

pxr/imaging/hdx/oitBufferAccessor.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,17 @@ using HdStRenderPassShaderSharedPtr =
2828
/// Class for OIT render tasks to access the OIT buffers.
2929
class HdxOitBufferAccessor {
3030
public:
31+
HDX_API
3132
static bool IsOitEnabled();
3233

34+
// This method helps improve the footprint of the OIT buffers by packing the color, transmission
35+
// and depth into smaller buffers. This follows the theory in
36+
// https://interplayoflight.wordpress.com/2022/06/25/order-independent-transparency-part-1/
37+
// This compression results in a 4x reduction in the memory footprint of the OIT buffers
38+
// at the cost of accuracy.
39+
HDX_API
40+
static bool IsOitPackedDepthEnabled();
41+
3342
HDX_API
3443
HdxOitBufferAccessor(HdTaskContext *ctx);
3544

0 commit comments

Comments
 (0)