Add a demos test that uses RT with ASs

This commit is contained in:
baldurk
2024-10-09 17:40:57 +01:00
parent 60d2e30f43
commit 3bd65816cf
8 changed files with 373 additions and 1 deletions
+22
View File
@@ -260,6 +260,13 @@ D3D12BufferCreator &D3D12BufferCreator::UAV()
return *this;
}
D3D12BufferCreator &D3D12BufferCreator::ASB()
{
m_InitialState = D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE;
m_BufDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
return *this;
}
D3D12BufferCreator &D3D12BufferCreator::Upload()
{
m_HeapDesc.Type = D3D12_HEAP_TYPE_UPLOAD;
@@ -442,6 +449,12 @@ D3D12ViewCreator::D3D12ViewCreator(ID3D12DevicePtr dev, ID3D12DescriptorHeap *he
desc.cbv.BufferLocation = m_Res->GetGPUVirtualAddress();
desc.cbv.SizeInBytes = 0;
}
else if(m_Type == ViewType::AS)
{
desc.srv.Format = DXGI_FORMAT_UNKNOWN;
desc.srv.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
desc.srv.RaytracingAccelerationStructure.Location = m_Res->GetGPUVirtualAddress();
}
else if(dim == D3D12_RESOURCE_DIMENSION_BUFFER)
{
SetupDescriptors(viewType, ResourceType::Buffer);
@@ -835,6 +848,8 @@ D3D12ViewCreator &D3D12ViewCreator::Offset(UINT offset)
{
if(m_Type == ViewType::CBV)
desc.cbv.BufferLocation += offset;
else if(m_Type == ViewType::AS)
desc.srv.RaytracingAccelerationStructure.Location += offset;
else
TEST_ERROR("This view & resource doesn't support SizeBytes");
return *this;
@@ -969,6 +984,13 @@ D3D12_CPU_DESCRIPTOR_HANDLE D3D12ViewCreator::CreateCPU(ID3D12DescriptorHeap *he
cpu.ptr += increment[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] * descriptor;
m_Dev->CreateConstantBufferView(&desc.cbv, cpu);
}
else if(m_Type == ViewType::AS)
{
desc.srv.Shader4ComponentMapping = Shader4ComponentMapping;
cpu.ptr += increment[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] * descriptor;
m_Dev->CreateShaderResourceView(NULL, &desc.srv, cpu);
}
else if(m_Type == ViewType::SRV)
{
if(desc.uav.ViewDimension == D3D12_SRV_DIMENSION_BUFFER)
+4
View File
@@ -80,6 +80,9 @@ COM_SMARTPTR(ID3D12InfoQueue);
COM_SMARTPTR(ID3D12CommandQueueDownlevel);
COM_SMARTPTR(ID3D12StateObject);
COM_SMARTPTR(ID3D12StateObjectProperties);
struct D3D12GraphicsTest;
class D3D12PSOCreator
@@ -130,6 +133,7 @@ public:
D3D12BufferCreator(ID3D12DevicePtr dev, D3D12GraphicsTest *test);
D3D12BufferCreator &UAV();
D3D12BufferCreator &ASB();
D3D12BufferCreator &Upload();
D3D12BufferCreator &Readback();
+329
View File
@@ -0,0 +1,329 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019-2024 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "d3d12_test.h"
RD_TEST(D3D12_RTAS_Zoo, D3D12GraphicsTest)
{
static constexpr const char *Description = "Test of different AS edge-cases and formats.";
std::string rtshaders = R"EOSHADER(
RaytracingAccelerationStructure Scene : register(t0);
RWTexture2D<float4> RenderTarget : register(u1);
struct RayPayload
{
float4 color;
};
[shader("raygeneration")]
void gen()
{
float2 lerpValues = (float2)DispatchRaysIndex() / (float2)DispatchRaysDimensions();
{
RayDesc ray;
ray.Origin = float3(0, 0, 5);
ray.Direction = float3(lerp(-1.0f, 1.0f, lerpValues.x),
lerp(-1.0f, 1.0f, lerpValues.y),
-1.0f);
ray.TMin = 0.001;
ray.TMax = 10000.0;
RayPayload payload = { float4(0, 0, 1, 1) };
TraceRay(Scene, RAY_FLAG_NONE, ~0, 0, 0, 0, ray, payload);
// Write the raytraced color to the output texture.
RenderTarget[DispatchRaysIndex().xy] = payload.color;
}
}
[shader("closesthit")]
void chit(inout RayPayload payload, in BuiltInTriangleIntersectionAttributes attrs)
{
payload.color = float4(0, 1, 0, 1);
}
[shader("miss")]
void miss(inout RayPayload payload)
{
payload.color = float4(1, 0, 0, 1);
}
)EOSHADER";
void Prepare(int argc, char **argv)
{
D3D12GraphicsTest::Prepare(argc, argv);
if(!Avail.empty())
return;
if(opts5.RaytracingTier == D3D12_RAYTRACING_TIER_NOT_SUPPORTED)
Avail = "RT is not supported";
if(!m_DXILSupport)
Avail = "DXIL can't be compiled";
}
static const uint64_t scratchSpace = 1 * 1024 * 1024;
static const uint64_t blasOffset = 0;
static const uint64_t blasSize = 1 * 1024 * 1024;
static const uint64_t tlasOffset = blasOffset + blasSize;
static const uint64_t tlasSize = 1 * 1024 * 1024;
static const uint64_t asbSize = tlasOffset + tlasSize;
int main()
{
// initialise, create window, create device, etc
if(!Init())
return 3;
ID3D12ResourcePtr asb = MakeBuffer().ASB().Size(asbSize);
asb->SetName(L"asb");
ID3D12ResourcePtr uav = MakeBuffer().UAV().Size(scratchSpace);
{
ID3D12GraphicsCommandList4Ptr cmd = GetCommandBuffer();
Reset(cmd);
D3D12_RAYTRACING_GEOMETRY_DESC geom = {};
geom.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
geom.Triangles.VertexBuffer.StartAddress = DefaultTriVB->GetGPUVirtualAddress();
geom.Triangles.VertexBuffer.StrideInBytes = sizeof(DefaultA2V);
geom.Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT;
geom.Triangles.VertexCount = 3;
geom.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE;
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC desc = {};
desc.DestAccelerationStructureData = asb->GetGPUVirtualAddress();
desc.ScratchAccelerationStructureData = uav->GetGPUVirtualAddress();
desc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
desc.Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
desc.Inputs.NumDescs = 1;
desc.Inputs.pGeometryDescs = &geom;
cmd->BuildRaytracingAccelerationStructure(&desc, 0, NULL);
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO prebuild = {};
dev5->GetRaytracingAccelerationStructurePrebuildInfo(&desc.Inputs, &prebuild);
TEST_ASSERT(prebuild.ScratchDataSizeInBytes < scratchSpace, "Insufficient scratch space");
TEST_ASSERT(prebuild.ResultDataMaxSizeInBytes < tlasOffset, "BLAS too large");
cmd->Close();
Submit({cmd});
}
D3D12_RAYTRACING_INSTANCE_DESC instances[8] = {};
for(int i = 0; i < 8; i++)
{
instances[i].AccelerationStructure = asb->GetGPUVirtualAddress();
instances[i].InstanceMask = 1;
instances[i].Transform[0][0] = 1.0f;
instances[i].Transform[1][1] = 1.0f;
instances[i].Transform[2][2] = 1.0f;
instances[i].Transform[0][3] = -4.0f + i * 1.0f;
}
ID3D12ResourcePtr instData = MakeBuffer().Size(sizeof(instances)).Upload();
byte *instUpload = Map(instData, 0);
instData->SetName(L"instData");
D3D12_GPU_VIRTUAL_ADDRESS instancesIndirect[8] = {};
for(int i = 0; i < 8; i++)
instancesIndirect[i] =
instData->GetGPUVirtualAddress() + i * sizeof(D3D12_RAYTRACING_INSTANCE_DESC);
ID3D12ResourcePtr instIndirectData = MakeBuffer().Data(instancesIndirect);
instIndirectData->SetName(L"instIndirectData");
ID3D12StateObjectPtr rtpso;
std::vector<D3D12_STATE_SUBOBJECT> subObjs;
ID3DBlobPtr lib = Compile(rtshaders, "", "lib_6_3");
D3D12_DXIL_LIBRARY_DESC libDesc = {};
libDesc.DXILLibrary.BytecodeLength = lib->GetBufferSize();
libDesc.DXILLibrary.pShaderBytecode = lib->GetBufferPointer();
ID3D12RootSignaturePtr rootsig = MakeSig({
tableParam(D3D12_SHADER_VISIBILITY_ALL, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, 0, 100, 0),
tableParam(D3D12_SHADER_VISIBILITY_ALL, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, 0, 100, 0),
});
D3D12_GLOBAL_ROOT_SIGNATURE rootSigDesc = {rootsig};
D3D12_RAYTRACING_SHADER_CONFIG shadDesc = {};
shadDesc.MaxPayloadSizeInBytes = 16;
shadDesc.MaxAttributeSizeInBytes = 8;
D3D12_RAYTRACING_PIPELINE_CONFIG pipeDesc = {};
pipeDesc.MaxTraceRecursionDepth = 1;
D3D12_HIT_GROUP_DESC hitgroupDesc = {};
hitgroupDesc.ClosestHitShaderImport = L"chit";
hitgroupDesc.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
hitgroupDesc.HitGroupExport = L"hitgroup";
subObjs.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &rootSigDesc});
subObjs.push_back({D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY, &libDesc});
subObjs.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &shadDesc});
subObjs.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &pipeDesc});
subObjs.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &hitgroupDesc});
D3D12_STATE_OBJECT_DESC stateDesc = {};
stateDesc.NumSubobjects = (UINT)subObjs.size();
stateDesc.pSubobjects = subObjs.data();
stateDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE;
dev5->CreateStateObject(&stateDesc, __uuidof(ID3D12StateObject), (void **)&rtpso);
ID3D12StateObjectPropertiesPtr rtpso_props = rtpso;
std::vector<byte> tablesData;
tablesData.resize(D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 3);
memcpy(tablesData.data(), rtpso_props->GetShaderIdentifier(L"gen"),
D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
memcpy(tablesData.data() + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT,
rtpso_props->GetShaderIdentifier(L"miss"), D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
memcpy(tablesData.data() + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 2,
rtpso_props->GetShaderIdentifier(L"hitgroup"), D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES);
ID3D12ResourcePtr tables = MakeBuffer().Data(tablesData);
ID3D12ResourcePtr uavtex = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, screenWidth, screenHeight)
.UAV()
.InitialState(D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
MakeUAV(uavtex).CreateCPU(1);
while(Running())
{
ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer();
ID3D12GraphicsCommandList4Ptr cmd4 = cmd;
Reset(cmd);
for(int i = 0; i < 8; i++)
{
instances[i].InstanceID = curFrame;
instances[i].Transform[1][3] = 2.5f * cosf(i * 0.29f + 0.05f * curFrame);
}
memcpy(instUpload, instances, sizeof(instances));
cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr());
cmd->SetComputeRootSignature(rootsig);
cmd4->SetPipelineState1(rtpso);
cmd->SetComputeRootDescriptorTable(0, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetComputeRootDescriptorTable(1, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
D3D12_DISPATCH_RAYS_DESC rayDispatch = {};
rayDispatch.Width = screenWidth;
rayDispatch.Height = screenHeight;
rayDispatch.Depth = 1;
rayDispatch.RayGenerationShaderRecord.StartAddress = tables->GetGPUVirtualAddress();
rayDispatch.RayGenerationShaderRecord.SizeInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
rayDispatch.MissShaderTable.StartAddress =
tables->GetGPUVirtualAddress() + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
rayDispatch.MissShaderTable.SizeInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
rayDispatch.MissShaderTable.StrideInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
rayDispatch.HitGroupTable.StartAddress =
tables->GetGPUVirtualAddress() + D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT * 2;
rayDispatch.HitGroupTable.StrideInBytes = 0;
rayDispatch.HitGroupTable.SizeInBytes = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
cmd4->DispatchRays(&rayDispatch);
ResourceBarrier(cmd);
cmd->Close();
Submit({cmd});
cmd = GetCommandBuffer();
cmd4 = cmd;
Reset(cmd);
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC desc = {};
desc.DestAccelerationStructureData = asb->GetGPUVirtualAddress() + tlasOffset;
desc.ScratchAccelerationStructureData = uav->GetGPUVirtualAddress();
desc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS;
desc.Inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
desc.Inputs.NumDescs = 8;
desc.Inputs.InstanceDescs = instIndirectData->GetGPUVirtualAddress();
cmd4->BuildRaytracingAccelerationStructure(&desc, 0, NULL);
MakeAS(asb).Offset(tlasOffset).CreateCPU(0);
ResourceBarrier(cmd);
cmd->Close();
Submit({cmd});
cmd = GetCommandBuffer();
cmd4 = cmd;
Reset(cmd);
cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr());
cmd->SetComputeRootSignature(rootsig);
cmd4->SetPipelineState1(rtpso);
cmd->SetComputeRootDescriptorTable(0, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetComputeRootDescriptorTable(1, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd4->DispatchRays(&rayDispatch);
ID3D12ResourcePtr bb = StartUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET);
ResourceBarrier(cmd, uavtex, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
blitToSwap(cmd, uavtex, bb);
ResourceBarrier(cmd, uavtex, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
FinishUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET);
cmd->Close();
SubmitAndPresent({cmd});
}
return 0;
}
};
REGISTER_TEST();
+7
View File
@@ -1233,6 +1233,13 @@ void D3D12GraphicsTest::ResourceBarrier(ID3D12ResourcePtr res, D3D12_RESOURCE_ST
Submit({cmd});
}
void D3D12GraphicsTest::ResourceBarrier(ID3D12GraphicsCommandListPtr cmd)
{
D3D12_RESOURCE_BARRIER barrier = {};
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
cmd->ResourceBarrier(1, &barrier);
}
void D3D12GraphicsTest::IASetVertexBuffer(ID3D12GraphicsCommandListPtr cmd, ID3D12ResourcePtr vb,
UINT stride, UINT offset)
{
+6
View File
@@ -120,6 +120,11 @@ struct D3D12GraphicsTest : public GraphicsTest
return D3D12ViewCreator(dev, m_CBVUAVSRV, NULL, ViewType::SRV, res);
}
template <typename T>
D3D12ViewCreator MakeAS(T res)
{
return D3D12ViewCreator(dev, m_CBVUAVSRV, NULL, ViewType::AS, res);
}
template <typename T>
D3D12ViewCreator MakeRTV(T res)
{
return D3D12ViewCreator(dev, m_RTV, NULL, ViewType::RTV, res);
@@ -158,6 +163,7 @@ struct D3D12GraphicsTest : public GraphicsTest
D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after);
void ResourceBarrier(ID3D12ResourcePtr res, D3D12_RESOURCE_STATES before,
D3D12_RESOURCE_STATES after);
void ResourceBarrier(ID3D12GraphicsCommandListPtr cmd);
void IASetVertexBuffer(ID3D12GraphicsCommandListPtr cmd, ID3D12ResourcePtr vb, UINT stride,
UINT offset);
+1 -1
View File
@@ -211,6 +211,7 @@
<ClCompile Include="d3d12\d3d12_render_pass.cpp" />
<ClCompile Include="d3d12\d3d12_resource_lifetimes.cpp" />
<ClCompile Include="d3d12\d3d12_resource_mapping_zoo.cpp" />
<ClCompile Include="d3d12\d3d12_rtas_zoo.cpp" />
<ClCompile Include="d3d12\d3d12_shader_debug_zoo.cpp" />
<ClCompile Include="d3d12\d3d12_shader_editing.cpp" />
<ClCompile Include="d3d12\d3d12_shader_isa.cpp" />
@@ -448,7 +449,6 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<!-- try to find the latest dxcompiler.dll, as the redist folder isn't reliably -->
<UsingTask TaskName="GetDXCDLL" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
+3
View File
@@ -691,6 +691,9 @@
<ClCompile Include="d3d12\d3d12_mesh_shader.cpp">
<Filter>D3D12\demos</Filter>
</ClCompile>
<ClCompile Include="d3d12\d3d12_rtas_zoo.cpp">
<Filter>D3D12\demos</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="D3D11">
+1
View File
@@ -75,4 +75,5 @@ enum class ViewType
DSV,
UAV,
CBV,
AS,
};