Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions pxr/imaging/hdSt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,19 @@ pxr_build_test(testHdStSubResourceRegistry
CPPFILES
testenv/testHdStSubResourceRegistry.cpp
)

pxr_build_test(testHdStGeometricShader
LIBRARIES
gf
hdSt
hd
hgi
tf
vt
CPPFILES
testenv/testHdStGeometricShader.cpp
)

endif()

if (X11_FOUND)
Expand Down Expand Up @@ -3123,6 +3136,14 @@ pxr_register_test(testHdStSubResourceRegistry
TF_DEBUG=HD_SAFE_MODE
)

pxr_register_test(testHdStGeometricShader
COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testHdStGeometricShader --offscreen"
EXPECTED_RETURN_CODE 0
TESTENV testHdStGeometricShader
ENV
TF_DEBUG=HD_SAFE_MODE
)

# Certain tests use plugins that require shared libraries.
if (TARGET shared_libs)

Expand Down
2 changes: 1 addition & 1 deletion pxr/imaging/hdSt/basisCurves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ HdStBasisCurves::_UpdateDrawItemGeometricShader(
GetId().GetText(), HdSt_PrimTypeToString(shaderKey.primType));

HdSt_GeometricShaderSharedPtr geomShader =
HdSt_GeometricShader::Create(shaderKey, resourceRegistry);
HdSt_GeometricShader::Create(shaderKey, {}, {}, resourceRegistry);

TF_VERIFY(geomShader);

Expand Down
26 changes: 19 additions & 7 deletions pxr/imaging/hdSt/commandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,21 @@ struct _SortByTexture {
HdStDrawItem const *a = aInstance->GetDrawItem();
HdStDrawItem const *b = bInstance->GetDrawItem();

size_t const textureA =
a->GetMaterialNetworkShader()->ComputeTextureSourceHash();
size_t const textureB =
b->GetMaterialNetworkShader()->ComputeTextureSourceHash();
return textureA < textureB;
size_t const geometricTextureHashA =
a->GetGeometricShader()->ComputeTextureSourceHash();
size_t const geometricTextureHashB =
b->GetGeometricShader()->ComputeTextureSourceHash();
if (geometricTextureHashA != geometricTextureHashB) {
return geometricTextureHashA < geometricTextureHashB;
}
else
{
size_t const materialTextureHashA =
a->GetMaterialNetworkShader()->ComputeTextureSourceHash();
size_t const materialTextureHashB =
b->GetMaterialNetworkShader()->ComputeTextureSourceHash();
return materialTextureHashA < materialTextureHashB;
}
}
};

Expand Down Expand Up @@ -170,9 +180,11 @@ _InsertDrawItemInstance(
// batch, we'll also combine the texture source hash into the key.
// (Note the texture source hash will be 0 for bindless textures).
if (!allowTextureResourceRebinding) {
size_t const textureHash =
size_t const geometricTextureHash =
drawItem->GetGeometricShader()->ComputeTextureSourceHash();
size_t const materialTextureHash =
drawItem->GetMaterialNetworkShader()->ComputeTextureSourceHash();
key = TfHash::Combine(key, textureHash);
key = TfHash::Combine(key, geometricTextureHash, materialTextureHash);
}

// Keep track of newly created draw batches.
Expand Down
12 changes: 8 additions & 4 deletions pxr/imaging/hdSt/drawBatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,10 @@ HdSt_DrawBatch::_CanAggregateTextures(HdStDrawItem const *drawItem0,
HdStDrawItem const *drawItem1)
{
return _allowTextureResourceRebinding ||
(drawItem0->GetMaterialNetworkShader()->ComputeTextureSourceHash() ==
drawItem1->GetMaterialNetworkShader()->ComputeTextureSourceHash());
((drawItem0->GetMaterialNetworkShader()->ComputeTextureSourceHash() ==
drawItem1->GetMaterialNetworkShader()->ComputeTextureSourceHash()) &&
(drawItem0->GetGeometricShader()->ComputeTextureSourceHash() ==
drawItem1->GetGeometricShader()->ComputeTextureSourceHash()));
}

bool
Expand Down Expand Up @@ -444,8 +446,10 @@ HdSt_DrawBatch::_DrawingProgram::CompileShader(

// also (surface, renderPass) shaders use their bindings
HdStShaderCodeSharedPtrVector shaders = GetComposedShaders();
HdStShaderCodeSharedPtrVector shadersForParameterBinding = shaders;
shadersForParameterBinding.push_back(_geometricShader);

TF_FOR_ALL(it, shaders) {
TF_FOR_ALL(it, shadersForParameterBinding) {
(*it)->AddBindings(&customBindings);
}

Expand All @@ -455,7 +459,7 @@ HdSt_DrawBatch::_DrawingProgram::CompileShader(
// let resourcebinder resolve bindings and populate metadata
// which is owned by codegen.
_resourceBinder.ResolveBindings(drawItem,
shaders,
shadersForParameterBinding,
metaData.get(),
_drawingCoordBufferBinding,
instanceDraw,
Expand Down
161 changes: 149 additions & 12 deletions pxr/imaging/hdSt/geometricShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@
#include "pxr/imaging/hdSt/binding.h"
#include "pxr/imaging/hdSt/debugCodes.h"
#include "pxr/imaging/hdSt/shaderKey.h"
#include "pxr/imaging/hdSt/textureBinder.h"
#include "pxr/imaging/hdSt/textureHandle.h"

#include "pxr/imaging/hd/tokens.h"

#include "pxr/imaging/hgi/capabilities.h"

#include "pxr/imaging/hio/glslfx.h"

#include "pxr/base/tf/hash.h"
Expand Down Expand Up @@ -47,6 +51,8 @@ HdSt_GeometricShader::HdSt_GeometricShader(std::string const &glslfxString,
, _frustumCullingPass(cullingPass)
, _fvarPatchType(fvarPatchType)
, _hash(0)
, _isValidComputedTextureSourceHash(false)
, _isValidComputedHash(false)
{
HD_TRACE_FUNCTION();
HF_MALLOC_TAG_FUNCTION();
Expand All @@ -63,15 +69,6 @@ HdSt_GeometricShader::HdSt_GeometricShader(std::string const &glslfxString,

std::stringstream ss(glslfxString);
_glslfx.reset(new HioGlslfx(ss));
_hash = TfHash::Combine(
_hash,
_glslfx->GetHash(),
cullingPass,
primType,
cullStyle,
useMetalTessellation,
fvarPatchType
);
//
// note: Don't include polygonMode into the hash.
// It is independent from the GLSL program.
Expand Down Expand Up @@ -151,28 +148,67 @@ HdSt_GeometricShader::ResolveCullMode(
HdStShaderCode::ID
HdSt_GeometricShader::ComputeHash() const
{
// All mutator methods that might affect the hash must reset this (fragile).
if (!_isValidComputedHash) {
_hash = _ComputeHash();
_isValidComputedHash = true;
}
return _hash;
}

HdStShaderCode::ID
HdSt_GeometricShader::_ComputeHash() const
{
size_t hash = HdSt_MaterialParam::ComputeHash(_params);

hash = TfHash::Combine(
hash,
_glslfx->GetHash(),
_frustumCullingPass,
_primType,
_cullStyle,
_useMetalTessellation,
_fvarPatchType
);

return hash;
}

/* virtual */
std::string
HdSt_GeometricShader::GetSource(TfToken const &shaderStageKey) const
{
return _glslfx->GetSource(shaderStageKey);
}

/*virtual*/
HdSt_MaterialParamVector const&
HdSt_GeometricShader::GetParams() const
{
return _params;
}

/*virtual*/
HdStShaderCode::NamedTextureHandleVector const&
HdSt_GeometricShader::GetNamedTextureHandles() const
{
return _namedTextureHandles;
}

/*virtual*/
void
HdSt_GeometricShader::BindResources(const int program,
HdSt_ResourceBinder const &binder)
{
// no-op
HdSt_TextureBinder::BindResources(binder, _namedTextureHandles);
}

/*virtual*/
void
HdSt_GeometricShader::UnbindResources(const int program,
HdSt_ResourceBinder const &binder)
{
// no-op
HdSt_TextureBinder::UnbindResources(binder, _namedTextureHandles);
}

/*virtual*/
Expand Down Expand Up @@ -336,15 +372,112 @@ HdSt_GeometricShader::GetHgiPrimitiveType() const
return primitiveType;
}

/*virtual*/
HdStShaderCode::ID
HdSt_GeometricShader::ComputeTextureSourceHash() const
{
if (!_isValidComputedTextureSourceHash) {
_computedTextureSourceHash = _ComputeTextureSourceHash();
_isValidComputedTextureSourceHash = true;
}
return _computedTextureSourceHash;
}

HdStShaderCode::ID
HdSt_GeometricShader::_ComputeTextureSourceHash() const
{
TRACE_FUNCTION();

// To avoid excessive plumbing and checking of HgiCapabilities in order to
// determine if bindless textures are enabled, we make things a little
// easier for ourselves by having this function check and return 0 if
// using bindless textures.
const bool useBindlessHandles = _namedTextureHandles.empty() ? false :
_namedTextureHandles[0].handles[0]->UseBindlessHandles();

if (useBindlessHandles) {
return 0;
}

size_t hash = 0;

for (const HdStShaderCode::NamedTextureHandle& namedHandle :
_namedTextureHandles) {

// Use name, texture object and sampling parameters.
hash = TfHash::Combine(hash, namedHandle.name, namedHandle.hash);
}

return hash;
}

void
HdSt_GeometricShader::_SetNamedTextureHandles(
const NamedTextureHandleVector& namedTextureHandles)
{
_namedTextureHandles = namedTextureHandles;
_isValidComputedTextureSourceHash = false;
}

void
HdSt_GeometricShader::_SetParams(const HdSt_MaterialParamVector& params)
{
_params = params;
_isValidComputedHash = false;
}

/*virtual*/
void
HdSt_GeometricShader::AddResourcesFromTextures(ResourceContext& ctx) const
{
const bool doublesSupported = ctx.GetResourceRegistry()->GetHgi()->
GetCapabilities()->IsSet(
HgiDeviceCapabilitiesBitsShaderDoublePrecision);

// Add buffer sources for bindless texture handles (and
// other texture metadata such as the sampling transform for
// a field texture).
HdBufferSourceSharedPtrVector result;
HdSt_TextureBinder::ComputeBufferSources(
GetNamedTextureHandles(), &result, doublesSupported);

if (!result.empty()) {
ctx.AddSources(GetShaderData(), std::move(result));
}
}

namespace {
size_t
_GetGeometricShaderHash(
HdSt_ShaderKey const& shaderKey,
HdStShaderCode::NamedTextureHandleVector const& namedTextureHandles,
HdSt_MaterialParamVector const& params)
{
size_t hash = shaderKey.ComputeHash();
for (const HdStShaderCode::NamedTextureHandle& namedHandle :
namedTextureHandles) {

// Use name, texture object and sampling parameters.
hash = TfHash::Combine(hash, namedHandle.name, namedHandle.hash);
}
if (!params.empty())
hash = TfHash::Combine(hash, HdSt_MaterialParam::ComputeHash(params));

return hash;
}
}
/*static*/
HdSt_GeometricShaderSharedPtr
HdSt_GeometricShader::Create(
HdSt_ShaderKey const &shaderKey,
NamedTextureHandleVector const& namedTextureHandles,
HdSt_MaterialParamVector const& params,
HdStResourceRegistrySharedPtr const &resourceRegistry)
{
// Use the shaderKey hash to deduplicate geometric shaders.
HdInstance<HdSt_GeometricShaderSharedPtr> geometricShaderInstance =
resourceRegistry->RegisterGeometricShader(shaderKey.ComputeHash());
resourceRegistry->RegisterGeometricShader(
_GetGeometricShaderHash(shaderKey, namedTextureHandles, params));

if (geometricShaderInstance.IsFirstInstance()) {
geometricShaderInstance.SetValue(
Expand All @@ -361,6 +494,10 @@ HdSt_GeometricShader::GetHgiPrimitiveType() const
shaderKey.GetFvarPatchType(),
/*debugId=*/SdfPath(),
shaderKey.GetLineWidth()));
if(!namedTextureHandles.empty())
geometricShaderInstance.GetValue()->_SetNamedTextureHandles(namedTextureHandles);
if (!params.empty())
geometricShaderInstance.GetValue()->_SetParams(params);
}
return geometricShaderInstance.GetValue();
}
Expand Down
Loading
Loading