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
23 changes: 22 additions & 1 deletion pxr/imaging/hdx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ pxr_build_test(testHdxLightAndShadow
CPPFILES
testenv/testHdxLightAndShadow.cpp
)
pxr_build_test(testHdxNoResourceBindings
LIBRARIES
hdx
hd
hdSt
sdf
glf
garch
arch
tf
CPPFILES
testenv/testHdxNoResourceBindings.cpp
)
endif()

if (X11_FOUND)
Expand Down Expand Up @@ -365,7 +378,15 @@ pxr_register_test(testHdxUnpickablesAsOccluders
FAIL_PERCENT 1
PERCEPTUAL
)

pxr_register_test(testHdxNoResourceBindings
COMMAND "${CMAKE_INSTALL_PREFIX}/tests/testHdxNoResourceBindings"
TESTENV testenv/testHdxNoResourceBindings
EXPECTED_RETURN_CODE 0
IMAGE_DIFF_COMPARE
color.png
FAIL 0.01
FAIL_PERCENT 0.01
)
# Certain tests use plugins that require shared libraries.
if (TARGET shared_libs)

Expand Down
5 changes: 4 additions & 1 deletion pxr/imaging/hdx/effectsShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,10 @@ HdxEffectsShader::_CreateResourceBindings()
return;
}

_resourceBindings = _hgi->CreateResourceBindings(_resourceBindingsDesc);
if (!_resourceBindingsDesc.buffers.empty() ||
!_resourceBindingsDesc.textures.empty()) {
_resourceBindings = _hgi->CreateResourceBindings(_resourceBindingsDesc);
}
}

void
Expand Down
202 changes: 202 additions & 0 deletions pxr/imaging/hdx/testenv/testHdxNoResourceBindings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
//
//
// Copyright 2025 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
#include "pxr/pxr.h"

#include "pxr/base/tf/errorMark.h"

#include "pxr/imaging/garch/glDebugWindow.h"
#include "pxr/imaging/hd/driver.h"
#include "pxr/imaging/hd/engine.h"
#include "pxr/imaging/hdSt/renderDelegate.h"
#include "pxr/imaging/hdSt/renderPassState.h"
#include "pxr/imaging/hdSt/tokens.h"
#include "pxr/imaging/hdx/fullscreenShader.h"
#include "pxr/imaging/hdx/renderSetupTask.h"
#include "pxr/imaging/hdx/renderTask.h"
#include "pxr/imaging/hdx/taskController.h"
#include "pxr/imaging/hdx/unitTestDelegate.h"
#include "pxr/imaging/hgi/hgi.h"
#include "pxr/imaging/hgi/tokens.h"

#include <iostream>

PXR_NAMESPACE_USING_DIRECTIVE

class FullScreenEffectTask : public HdxTask
{
public:
void Prepare(HdTaskContext* context, HdRenderIndex* renderIndex) override
{
_renderIndex = renderIndex;
}

void Execute(HdTaskContext* context) override
{
HdRenderPassStateSharedPtr renderPassState =
_GetRenderPassState(context);
const HdStRenderPassState* pHdStRenderPassState =
dynamic_cast<HdStRenderPassState*>(renderPassState.get());
if (!pHdStRenderPassState)
return;

HgiGraphicsCmdsDesc gfxCmdsDesc =
pHdStRenderPassState->MakeGraphicsCmdsDesc(_renderIndex);

GfVec4i viewport = pHdStRenderPassState->ComputeViewport();

HgiTextureHandle colorDst = gfxCmdsDesc.colorTextures.empty() ?
HgiTextureHandle() :
gfxCmdsDesc.colorTextures[0];
HgiTextureHandle colorResolveDst =
gfxCmdsDesc.colorResolveTextures.empty() ?
HgiTextureHandle() :
gfxCmdsDesc.colorResolveTextures[0];
HgiTextureHandle depthDst = gfxCmdsDesc.depthTexture;
HgiTextureHandle depthResolveDst = gfxCmdsDesc.depthResolveTexture;

_fullScreenShader->Draw(
colorDst, colorResolveDst, depthDst, depthResolveDst, viewport);
}

FullScreenEffectTask(HdSceneDelegate* pDelegate, SdfPath const& id)
: HdxTask(id)
{
}

private:
void _SetUpFullScreenShader()
{
HgiShaderFunctionDesc fragDesc;
fragDesc.debugName = shaderFunctionName.GetString();
fragDesc.shaderStage = HgiShaderStageFragment;

HgiShaderFunctionAddStageInput(&fragDesc, "uvOut", "vec2");
HgiShaderFunctionAddStageOutput(
&fragDesc, "hd_FragColor", "vec4", "color");

TfToken path("fullScreenEffect.glslfx");
_fullScreenShader->SetProgram(path, shaderFunctionName, fragDesc);
}

void _Sync(HdSceneDelegate* pDelegate, HdTaskContext* pCtx,
HdDirtyBits* dirtyBits) override
{
if (!_fullScreenShader) {
_fullScreenShader = std::make_unique<HdxFullscreenShader>(
_GetHgi(), shaderFunctionName.GetString());
_SetUpFullScreenShader();
}

*dirtyBits = HdChangeTracker::Clean;
}

HdRenderPassStateSharedPtr _GetRenderPassState(HdTaskContext* pCtx) const
{
HdRenderPassStateSharedPtr pRenderPassState;
_GetTaskContextData(
pCtx, HdxTokens->renderPassState, &pRenderPassState);
return pRenderPassState;
}

HdRenderIndex* _renderIndex;
std::unique_ptr<HdxFullscreenShader> _fullScreenShader;

static const TfToken shaderFunctionName;
};

const TfToken FullScreenEffectTask::shaderFunctionName{"FullScreenEffect"};

int
main(int argc, char* argv[])
{
TfErrorMark mark;

HdPerfLog& perfLog = HdPerfLog::GetInstance();
perfLog.Enable();

GarchGLDebugWindow window("Hdx Test", 256, 256);
window.Init();

// Hgi and HdDriver should be constructed before HdEngine to ensure they
// are destructed last. Hgi may be used during engine/delegate destruction.
HgiUniquePtr hgi = Hgi::CreatePlatformDefaultHgi();
HdDriver driver{HgiTokens->renderDriver, VtValue(hgi.get())};

HdStRenderDelegate renderDelegate;
const std::unique_ptr<HdRenderIndex> index(
HdRenderIndex::New(&renderDelegate, {&driver}));
const auto delegate = std::make_unique<Hdx_UnitTestDelegate>(index.get());
const auto taskController = std::make_unique<HdxTaskController>(
index.get(), SdfPath("/taskController"));

HdEngine engine;

HdTaskSharedPtrVector tasks;

// setup AOVs
const SdfPath colorAovId = SdfPath("/aov_color");
const SdfPath depthAovId = SdfPath("/aov_depth");
{
HdRenderPassAovBindingVector aovBindings;
HdRenderPassAovBinding colorAovBinding;
const HdAovDescriptor colorAovDesc =
renderDelegate.GetDefaultAovDescriptor(HdAovTokens->color);
colorAovBinding.aovName = HdAovTokens->color;
colorAovBinding.clearValue = VtValue(GfVec4f(0.1f, 0.1f, 0.1f, 1.0f));
colorAovBinding.renderBufferId = colorAovId;
colorAovBinding.aovSettings = colorAovDesc.aovSettings;
aovBindings.push_back(std::move(colorAovBinding));

HdRenderBufferDescriptor colorRbDesc;
colorRbDesc.dimensions = GfVec3i(256, 256, 1);
colorRbDesc.format = colorAovDesc.format;
colorRbDesc.multiSampled = false;
delegate->AddRenderBuffer(colorAovId, colorRbDesc);

HdRenderPassAovBinding depthAovBinding;
const HdAovDescriptor depthAovDesc =
renderDelegate.GetDefaultAovDescriptor(HdAovTokens->depth);
depthAovBinding.aovName = HdAovTokens->depth;
depthAovBinding.clearValue = VtValue(1.f);
depthAovBinding.renderBufferId = depthAovId;
depthAovBinding.aovSettings = depthAovDesc.aovSettings;
aovBindings.push_back(std::move(depthAovBinding));

HdRenderBufferDescriptor depthRbDesc;
depthRbDesc.dimensions = GfVec3i(256, 256, 1);
depthRbDesc.format = depthAovDesc.format;
depthRbDesc.multiSampled = false;
delegate->AddRenderBuffer(depthAovId, depthRbDesc);

SdfPath renderSetupTask("/renderSetupTask");
delegate->AddRenderSetupTask(renderSetupTask);
VtValue vParam =
delegate->GetTaskParam(renderSetupTask, HdTokens->params);
HdxRenderTaskParams param = vParam.Get<HdxRenderTaskParams>();
param.aovBindings = aovBindings;
delegate->SetTaskParam(
renderSetupTask, HdTokens->params, VtValue(param));
tasks.push_back(index->GetTask(renderSetupTask));
}

const SdfPath fullScreenEffectTaskId("/fullScreenEffectTask");
index->InsertTask<FullScreenEffectTask>(
delegate.get(), fullScreenEffectTaskId);
tasks.push_back(index->GetTask(fullScreenEffectTaskId));

engine.Execute(index.get(), &tasks);
delegate->WriteRenderBufferToFile(colorAovId, "color.png");

if (mark.IsClean()) {
std::cout << "OK" << std::endl;
return EXIT_SUCCESS;
} else {
std::cout << "FAILED" << std::endl;
return EXIT_FAILURE;
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- glslfx version 0.1

//
//
// Copyright 2025 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//

-- configuration
{
"techniques": {
"default": {
"FullScreenEffect": {
"source": [ "FullScreenEffect.Fragment" ]
}
}
}
}

-- glsl FullScreenEffect.Fragment

void main(void)
{
// draw something interesting
vec3 color = vec3(uvOut, uvOut.x + (1 - uvOut.y));
float intensity = pow(sin(length(60 * uvOut)) / 2 + 1, 2);
hd_FragColor = vec4(intensity * color, 1);
}
2 changes: 1 addition & 1 deletion pxr/imaging/hgi/unitTestHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,4 +463,4 @@ HgiGfxCmdBfrExecutionTestDriver::_CreateRenderTargets()
return true;
}

PXR_NAMESPACE_CLOSE_SCOPE
PXR_NAMESPACE_CLOSE_SCOPE
Loading
Loading