Skip to content

Commit

Permalink
Added TestDepthBuffer to Testbed.
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasBanana committed Jul 24, 2023
1 parent bc522a2 commit 3c6d140
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 2 deletions.
3 changes: 2 additions & 1 deletion include/LLGL/CommandBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ class LLGL_EXPORT CommandBuffer : public RenderSystemChild
\param[in] renderPass Specifies an optional render pass object. If this is null, the default render pass for the specified render target will be used.
This render pass object must be compatible with the render pass object the specified render target was created with.
Note that the default render pass will ignore the previous framebuffer content (see AttachmentLoadOp::Undefined), i.e. such a render pass section should fill the entire framebuffer.
\param[in] numClearValues Specifies the number of clear values that are specified in the \c clearValues parameter.
This \em should be greater than or equal to the number of render pass attachments whose load operation (i.e. AttachmentFormatDescriptor::loadOp) is set to AttachmentLoadOp::Clear.
Expand Down Expand Up @@ -752,7 +753,7 @@ class LLGL_EXPORT CommandBuffer : public RenderSystemChild
\remarks This must only be called if a graphics pipeline is currently bound.
\see EndStreamOutput
\see SetGraphicsPipeline
\see SetPipelineState
\see RenderingFeatures::hasStreamOutputs
\see RenderingLimits::maxStreamOutputs
*/
Expand Down
1 change: 1 addition & 0 deletions tests/Testbed/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Output/
131 changes: 130 additions & 1 deletion tests/Testbed/TestDepthBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,140 @@
*/

#include "Testbed.h"
#include <LLGL/Utils/Parse.h>
#include <Gauss/ProjectionMatrix4.h>
#include <Gauss/Translate.h>
#include <Gauss/Rotate.h>


DEF_TEST( DepthBuffer )
{
//todo
const Extent2D resolution{ swapChain->GetResolution() };

if (shaders[VSSolid] == nullptr || shaders[PSSolid] == nullptr)
{
Log::Errorf("Missing shaders for backend\n");
return TestResult::FailedErrors;
}

// Create texture for readback with depth-only format (D32Float)
TextureDescriptor texDesc;
{
texDesc.format = Format::D32Float;
texDesc.extent.width = resolution.width;
texDesc.extent.height = resolution.height;
texDesc.bindFlags = BindFlags::DepthStencilAttachment | BindFlags::CopySrc | BindFlags::Sampled;
texDesc.mipLevels = 1;
}
Texture* readbackTex = renderer->CreateTexture(texDesc);
readbackTex->SetName("readbackTex");

// Create depth-only render target for scene
RenderTargetDescriptor renderTargetDesc;
{
renderTargetDesc.resolution = resolution;
renderTargetDesc.depthStencilAttachment = readbackTex;
}
RenderTarget* renderTarget = renderer->CreateRenderTarget(renderTargetDesc);
renderTarget->SetName("renderTarget");

// Create PSO for rendering
PipelineLayout* psoLayout = renderer->CreatePipelineLayout(Parse("cbuffer(Scene@0):vert:frag"));

GraphicsPipelineDescriptor psoDesc;
{
psoDesc.pipelineLayout = psoLayout;
psoDesc.renderPass = renderTarget->GetRenderPass();
psoDesc.vertexShader = shaders[VSSolid];
psoDesc.depth.testEnabled = true;
psoDesc.depth.writeEnabled = true;
psoDesc.rasterizer.cullMode = CullMode::Back;
}
PipelineState* pso = renderer->CreatePipelineState(psoDesc);

// Update scene constants
sceneConstants.wMatrix.LoadIdentity();
Gs::Translate(sceneConstants.wMatrix, Gs::Vector3f{ 0, 0, 2 });
Gs::RotateFree(sceneConstants.wMatrix, Gs::Vector3f{ 0, 1, 0 }, Gs::Deg2Rad(20.0f));

Gs::Matrix4f vMatrix;
vMatrix.LoadIdentity();
Gs::Translate(vMatrix, Gs::Vector3f{ 0, 0, -3 });
vMatrix.MakeInverse();

Gs::Matrix4f vpMatrix = projection * vMatrix;
sceneConstants.wvpMatrix = vpMatrix * sceneConstants.wMatrix;

// Render scene
cmdBuffer->Begin();
{
cmdBuffer->UpdateBuffer(*sceneCbuffer, 0, &sceneConstants, sizeof(sceneConstants));
cmdBuffer->BeginRenderPass(*renderTarget);
{
// Draw scene
cmdBuffer->Clear(ClearFlags::ColorDepth);
cmdBuffer->SetPipelineState(*pso);
cmdBuffer->SetViewport(resolution);
cmdBuffer->SetVertexBuffer(*meshBuffer);
cmdBuffer->SetIndexBuffer(*meshBuffer, Format::R32UInt, models[ModelCube].indexBufferOffset);
cmdBuffer->SetResource(0, *sceneCbuffer);
cmdBuffer->DrawIndexed(models[ModelCube].numIndices, 0);
}
cmdBuffer->EndRenderPass();
}
cmdBuffer->End();

// Readback depth buffer and compare with expected result
const Offset3D readbackTexPosition
{
static_cast<std::int32_t>(resolution.width/2),
static_cast<std::int32_t>(resolution.height/2),
0,
};
const TextureRegion readbackTexRegion{ readbackTexPosition, Extent3D{ 1, 1, 1 } };

float readbackDepthValue = -1.0f;

DstImageDescriptor dstImageDesc;
{
dstImageDesc.format = ImageFormat::Depth;
dstImageDesc.data = &readbackDepthValue;
dstImageDesc.dataSize = sizeof(readbackDepthValue);
dstImageDesc.dataType = DataType::Float32;
}
renderer->ReadTexture(*readbackTex, readbackTexRegion, dstImageDesc);

const float expectedDepthValue = 0.975574434f;
const float deltaDepthValue = std::abs(readbackDepthValue - expectedDepthValue);

if (deltaDepthValue > epsilon)
{
Log::Errorf(
"Mismatch between depth buffer value at center (%f) and expected value (%f): delta = %f\n",
readbackDepthValue, expectedDepthValue, deltaDepthValue
);
//return TestResult::FailedMismatch;
}

// Match entire depth and create delta heat map
std::vector<float> readbackDepthBuffer;
readbackDepthBuffer.resize(texDesc.extent.width * texDesc.extent.height, -1.0f);
{
dstImageDesc.format = ImageFormat::Depth;
dstImageDesc.data = readbackDepthBuffer.data();
dstImageDesc.dataSize = sizeof(float) * readbackDepthBuffer.size();
dstImageDesc.dataType = DataType::Float32;
}
renderer->ReadTexture(*readbackTex, TextureRegion{ Offset3D{}, texDesc.extent }, dstImageDesc);

SaveDepthImageTGA(readbackDepthBuffer, resolution, "DepthBuffer.Result.tga", 1.0f, 10.0f);

// Clear resources
renderer->Release(*pso);
renderer->Release(*psoLayout);
renderer->Release(*renderTarget);
renderer->Release(*readbackTex);

return TestResult::Passed;
}

0 comments on commit 3c6d140

Please sign in to comment.