Add texture min/max calculation for D3D12

This commit is contained in:
baldurk
2016-11-18 16:31:08 +01:00
parent 4b477e2307
commit 834148f862
3 changed files with 464 additions and 27 deletions
+439 -17
View File
@@ -142,7 +142,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
hr = m_WrappedDevice->CreateDescriptorHeap(&desc, __uuidof(ID3D12DescriptorHeap),
(void **)&cbvsrvHeap);
(void **)&cbvsrvuavHeap);
if(FAILED(hr))
{
@@ -277,9 +277,12 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
samp.ptr += m_WrappedDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
m_WrappedDevice->CreateSampler(&sampDesc, samp);
m_GenericVSCbuffer = MakeCBuffer(sizeof(DebugVertexCBuffer));
m_GenericVSCbuffer = MakeCBuffer(1024);
m_GenericPSCbuffer = MakeCBuffer(sizeof(DebugPixelCBufferData));
RDCCOMPILE_ASSERT(sizeof(DebugVertexCBuffer) < 1024, "CBuffer isn't large enough");
RDCCOMPILE_ASSERT(sizeof(HistogramCBufferData) < 1024, "CBuffer isn't large enough");
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.4f);
bool success = LoadShaderCache("d3d12shaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion,
@@ -343,6 +346,52 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
SAFE_RELEASE(root);
rootSig.clear();
// 0: CBV
param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
param.Descriptor.ShaderRegister = 0;
rootSig.push_back(param);
// 1: Texture SRVs
param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
param.DescriptorTable.NumDescriptorRanges = 1;
param.DescriptorTable.pDescriptorRanges = &srvrange;
rootSig.push_back(param);
// 2: Samplers
param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
param.DescriptorTable.NumDescriptorRanges = 1;
param.DescriptorTable.pDescriptorRanges = &samplerrange;
rootSig.push_back(param);
// 3: UAVs
D3D12_DESCRIPTOR_RANGE uavrange = {};
uavrange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
uavrange.BaseShaderRegister = 0;
uavrange.NumDescriptors = 3;
uavrange.OffsetInDescriptorsFromTableStart = 0;
param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
param.DescriptorTable.NumDescriptorRanges = 1;
param.DescriptorTable.pDescriptorRanges = &uavrange;
rootSig.push_back(param);
root = MakeRootSig(rootSig);
RDCASSERT(root);
hr = m_WrappedDevice->CreateRootSignature(0, root->GetBufferPointer(), root->GetBufferSize(),
__uuidof(ID3D12RootSignature),
(void **)&m_HistogramRootSig);
SAFE_RELEASE(root);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.6f);
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc;
@@ -431,10 +480,201 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
RDCERR("Couldn't create m_CheckerboardPipe! 0x%08x", hr);
}
string histogramhlsl = GetEmbeddedResource(debugcbuffers_h);
histogramhlsl += GetEmbeddedResource(debugcommon_hlsl);
histogramhlsl += GetEmbeddedResource(histogram_hlsl);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.7f);
D3D12_COMPUTE_PIPELINE_STATE_DESC compPipeDesc;
RDCEraseEl(compPipeDesc);
compPipeDesc.pRootSignature = m_HistogramRootSig;
RDCEraseEl(m_TileMinMaxPipe);
RDCEraseEl(m_HistogramPipe);
RDCEraseEl(m_ResultMinMaxPipe);
for(int t = RESTYPE_TEX1D; t <= RESTYPE_TEX2D_MS; t++)
{
// skip unused cube slot
if(t == 8)
continue;
// float, uint, sint
for(int i = 0; i < 3; i++)
{
ID3DBlob *tile = NULL;
ID3DBlob *result = NULL;
ID3DBlob *histogram = NULL;
string hlsl = string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n";
hlsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n";
hlsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n";
hlsl += histogramhlsl;
GetShaderBlob(hlsl.c_str(), "RENDERDOC_TileMinMaxCS", D3DCOMPILE_WARNINGS_ARE_ERRORS,
"cs_5_0", &tile);
compPipeDesc.CS.BytecodeLength = tile->GetBufferSize();
compPipeDesc.CS.pShaderBytecode = tile->GetBufferPointer();
hr = m_WrappedDevice->CreateComputePipelineState(&compPipeDesc, __uuidof(ID3D12PipelineState),
(void **)&m_TileMinMaxPipe[t][i]);
if(FAILED(hr))
{
RDCERR("Couldn't create m_TileMinMaxPipe! 0x%08x", hr);
}
GetShaderBlob(hlsl.c_str(), "RENDERDOC_HistogramCS", D3DCOMPILE_WARNINGS_ARE_ERRORS, "cs_5_0",
&histogram);
compPipeDesc.CS.BytecodeLength = histogram->GetBufferSize();
compPipeDesc.CS.pShaderBytecode = histogram->GetBufferPointer();
hr = m_WrappedDevice->CreateComputePipelineState(&compPipeDesc, __uuidof(ID3D12PipelineState),
(void **)&m_HistogramPipe[t][i]);
if(FAILED(hr))
{
RDCERR("Couldn't create m_HistogramPipe! 0x%08x", hr);
}
if(t == 1)
{
GetShaderBlob(hlsl.c_str(), "RENDERDOC_ResultMinMaxCS", D3DCOMPILE_WARNINGS_ARE_ERRORS,
"cs_5_0", &result);
compPipeDesc.CS.BytecodeLength = result->GetBufferSize();
compPipeDesc.CS.pShaderBytecode = result->GetBufferPointer();
hr = m_WrappedDevice->CreateComputePipelineState(
&compPipeDesc, __uuidof(ID3D12PipelineState), (void **)&m_ResultMinMaxPipe[i]);
if(FAILED(hr))
{
RDCERR("Couldn't create m_HistogramPipe! 0x%08x", hr);
}
}
SAFE_RELEASE(tile);
SAFE_RELEASE(histogram);
SAFE_RELEASE(result);
}
}
SAFE_RELEASE(GenericVS);
SAFE_RELEASE(TexDisplayPS);
SAFE_RELEASE(CheckerboardPS);
{
const uint64_t maxTexDim = 16384;
const uint64_t blockPixSize = HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK;
const uint64_t maxBlocksNeeded = (maxTexDim * maxTexDim) / (blockPixSize * blockPixSize);
D3D12_RESOURCE_DESC minmaxDesc = {};
minmaxDesc.Alignment = 0;
minmaxDesc.DepthOrArraySize = 1;
minmaxDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
minmaxDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
minmaxDesc.Format = DXGI_FORMAT_UNKNOWN;
minmaxDesc.Height = 1;
minmaxDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
minmaxDesc.MipLevels = 1;
minmaxDesc.SampleDesc.Count = 1;
minmaxDesc.SampleDesc.Quality = 0;
minmaxDesc.Width =
2 * sizeof(Vec4f) * HGRAM_TILES_PER_BLOCK * HGRAM_TILES_PER_BLOCK * maxBlocksNeeded;
D3D12_HEAP_PROPERTIES heapProps;
heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
heapProps.CreationNodeMask = 1;
heapProps.VisibleNodeMask = 1;
hr = m_WrappedDevice->CreateCommittedResource(
&heapProps, D3D12_HEAP_FLAG_NONE, &minmaxDesc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, NULL,
__uuidof(ID3D12Resource), (void **)&m_MinMaxTileBuffer);
if(FAILED(hr))
{
RDCERR("Failed to create tile buffer for min/max, HRESULT: 0x%08x", hr);
return;
}
D3D12_CPU_DESCRIPTOR_HANDLE uav = cbvsrvuavHeap->GetCPUDescriptorHandleForHeapStart();
uav.ptr += MINMAX_TILE_UAVS * sizeof(D3D12Descriptor);
D3D12_UNORDERED_ACCESS_VIEW_DESC tileDesc = {};
tileDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
tileDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
tileDesc.Buffer.FirstElement = 0;
tileDesc.Buffer.NumElements = UINT(minmaxDesc.Width / sizeof(Vec4f));
m_WrappedDevice->CreateUnorderedAccessView(m_MinMaxTileBuffer, NULL, &tileDesc, uav);
uav.ptr += sizeof(D3D12Descriptor);
tileDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT;
m_WrappedDevice->CreateUnorderedAccessView(m_MinMaxTileBuffer, NULL, &tileDesc, uav);
uav.ptr += sizeof(D3D12Descriptor);
tileDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT;
m_WrappedDevice->CreateUnorderedAccessView(m_MinMaxTileBuffer, NULL, &tileDesc, uav);
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
srvDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = UINT(minmaxDesc.Width / sizeof(Vec4f));
D3D12_CPU_DESCRIPTOR_HANDLE srv = cbvsrvuavHeap->GetCPUDescriptorHandleForHeapStart();
srv.ptr += MINMAX_TILE_SRVS * sizeof(D3D12Descriptor);
m_WrappedDevice->CreateShaderResourceView(m_MinMaxTileBuffer, &srvDesc, srv);
srv.ptr += sizeof(D3D12Descriptor);
srvDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT;
m_WrappedDevice->CreateShaderResourceView(m_MinMaxTileBuffer, &srvDesc, srv);
srv.ptr += sizeof(D3D12Descriptor);
srvDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT;
m_WrappedDevice->CreateShaderResourceView(m_MinMaxTileBuffer, &srvDesc, srv);
minmaxDesc.Width = 2 * sizeof(Vec4f);
hr = m_WrappedDevice->CreateCommittedResource(
&heapProps, D3D12_HEAP_FLAG_NONE, &minmaxDesc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, NULL,
__uuidof(ID3D12Resource), (void **)&m_MinMaxResultBuffer);
if(FAILED(hr))
{
RDCERR("Failed to create result buffer for min/max, HRESULT: 0x%08x", hr);
return;
}
uav = cbvsrvuavHeap->GetCPUDescriptorHandleForHeapStart();
uav.ptr += MINMAX_RESULT_UAVS * sizeof(D3D12Descriptor);
tileDesc.Buffer.NumElements = 2;
tileDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
m_WrappedDevice->CreateUnorderedAccessView(m_MinMaxResultBuffer, NULL, &tileDesc, uav);
uav.ptr += sizeof(D3D12Descriptor);
tileDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT;
m_WrappedDevice->CreateUnorderedAccessView(m_MinMaxResultBuffer, NULL, &tileDesc, uav);
uav.ptr += sizeof(D3D12Descriptor);
tileDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT;
m_WrappedDevice->CreateUnorderedAccessView(m_MinMaxResultBuffer, NULL, &tileDesc, uav);
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.8f);
// font rendering
@@ -559,13 +799,8 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
SAFE_RELEASE(uploadBuf);
D3D12_CPU_DESCRIPTOR_HANDLE srv;
srv = cbvsrvHeap->GetCPUDescriptorHandleForHeapStart();
// texture display uses the first few, move to font texture slow
srv.ptr +=
FONT_SRV *
m_WrappedDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
D3D12_CPU_DESCRIPTOR_HANDLE srv = cbvsrvuavHeap->GetCPUDescriptorHandleForHeapStart();
srv.ptr += FONT_SRV * sizeof(D3D12Descriptor);
m_WrappedDevice->CreateShaderResourceView(m_Font.Tex, NULL, srv);
@@ -728,7 +963,7 @@ D3D12DebugManager::~D3D12DebugManager()
SAFE_RELEASE(dsvHeap);
SAFE_RELEASE(rtvHeap);
SAFE_RELEASE(cbvsrvHeap);
SAFE_RELEASE(cbvsrvuavHeap);
SAFE_RELEASE(samplerHeap);
SAFE_RELEASE(m_GenericVSCbuffer);
@@ -743,6 +978,20 @@ D3D12DebugManager::~D3D12DebugManager()
SAFE_RELEASE(m_PickPixelTex);
SAFE_RELEASE(m_HistogramRootSig);
for(int t = RESTYPE_TEX1D; t <= RESTYPE_TEX2D_MS; t++)
{
for(int i = 0; i < 3; i++)
{
SAFE_RELEASE(m_TileMinMaxPipe[t][i]);
SAFE_RELEASE(m_HistogramPipe[t][i]);
if(t == RESTYPE_TEX1D)
SAFE_RELEASE(m_ResultMinMaxPipe[i]);
}
}
SAFE_RELEASE(m_MinMaxResultBuffer);
SAFE_RELEASE(m_MinMaxTileBuffer);
SAFE_RELEASE(m_TexResource);
SAFE_RELEASE(m_ReadbackBuffer);
@@ -2064,12 +2313,12 @@ void D3D12DebugManager::RenderCheckerboard(Vec3f light, Vec3f dark)
list->SetGraphicsRootSignature(m_TexDisplayRootSig);
// Set the descriptor heap containing the texture srv
ID3D12DescriptorHeap *heaps[] = {cbvsrvHeap, samplerHeap};
ID3D12DescriptorHeap *heaps[] = {cbvsrvuavHeap, samplerHeap};
list->SetDescriptorHeaps(2, heaps);
list->SetGraphicsRootConstantBufferView(0, m_GenericVSCbuffer->GetGPUVirtualAddress());
list->SetGraphicsRootConstantBufferView(1, m_GenericPSCbuffer->GetGPUVirtualAddress());
list->SetGraphicsRootDescriptorTable(2, cbvsrvHeap->GetGPUDescriptorHandleForHeapStart());
list->SetGraphicsRootDescriptorTable(2, cbvsrvuavHeap->GetGPUDescriptorHandleForHeapStart());
list->SetGraphicsRootDescriptorTable(3, samplerHeap->GetGPUDescriptorHandleForHeapStart());
float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
@@ -2178,7 +2427,7 @@ void D3D12DebugManager::RenderTextInternal(ID3D12GraphicsCommandList *list, floa
list->SetGraphicsRootSignature(m_Font.RootSig);
// Set the descriptor heap containing the texture srv
ID3D12DescriptorHeap *heaps[] = {cbvsrvHeap, samplerHeap};
ID3D12DescriptorHeap *heaps[] = {cbvsrvuavHeap, samplerHeap};
list->SetDescriptorHeaps(2, heaps);
list->SetGraphicsRootConstantBufferView(
@@ -2186,7 +2435,7 @@ void D3D12DebugManager::RenderTextInternal(ID3D12GraphicsCommandList *list, floa
list->SetGraphicsRootConstantBufferView(1, m_Font.GlyphData->GetGPUVirtualAddress());
list->SetGraphicsRootConstantBufferView(
2, m_Font.CharBuffer->GetGPUVirtualAddress() + charOffset * sizeof(Vec4f));
list->SetGraphicsRootDescriptorTable(3, cbvsrvHeap->GetGPUDescriptorHandleForHeapStart());
list->SetGraphicsRootDescriptorTable(3, cbvsrvuavHeap->GetGPUDescriptorHandleForHeapStart());
list->SetGraphicsRootDescriptorTable(4, samplerHeap->GetGPUDescriptorHandleForHeapStart());
list->DrawInstanced(4, (uint32_t)strlen(text), 0, 0);
@@ -2261,7 +2510,7 @@ void D3D12DebugManager::PrepareTextureSampling(ID3D12Resource *resource,
if(IsIntFormat(resourceDesc.Format))
srvOffset += 20;
D3D12_CPU_DESCRIPTOR_HANDLE srv = cbvsrvHeap->GetCPUDescriptorHandleForHeapStart();
D3D12_CPU_DESCRIPTOR_HANDLE srv = cbvsrvuavHeap->GetCPUDescriptorHandleForHeapStart();
srv.ptr += srvOffset * sizeof(D3D12Descriptor);
D3D12_RESOURCE_STATES realResourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
@@ -2447,6 +2696,179 @@ void D3D12DebugManager::PrepareTextureSampling(ID3D12Resource *resource,
}
}
bool D3D12DebugManager::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample,
FormatComponentType typeHint, float *minval, float *maxval)
{
ID3D12Resource *resource = WrappedID3D12Resource::GetList()[texid];
if(resource == NULL)
return false;
D3D12_RESOURCE_DESC resourceDesc = resource->GetDesc();
HistogramCBufferData cdata;
cdata.HistogramTextureResolution.x = float(RDCMAX(1U, uint32_t(resourceDesc.Width >> mip)));
cdata.HistogramTextureResolution.y = float(RDCMAX(1U, uint32_t(resourceDesc.Height >> mip)));
cdata.HistogramTextureResolution.z =
float(RDCMAX(1U, uint32_t(resourceDesc.DepthOrArraySize >> mip)));
if(resourceDesc.DepthOrArraySize > 1 && resourceDesc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D)
cdata.HistogramTextureResolution.z = float(resourceDesc.DepthOrArraySize);
cdata.HistogramSlice = float(RDCCLAMP(sliceFace, 0U, uint32_t(resourceDesc.DepthOrArraySize - 1)));
if(resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
cdata.HistogramSlice = float(sliceFace) / float(resourceDesc.DepthOrArraySize);
cdata.HistogramMip = mip;
cdata.HistogramSample = (int)RDCCLAMP(sample, 0U, resourceDesc.SampleDesc.Count - 1);
if(sample == ~0U)
cdata.HistogramSample = -int(resourceDesc.SampleDesc.Count);
cdata.HistogramMin = 0.0f;
cdata.HistogramMax = 1.0f;
cdata.HistogramChannels = 0xf;
cdata.HistogramFlags = 0;
int intIdx = 0;
DXGI_FORMAT fmt = GetTypedFormat(resourceDesc.Format, typeHint);
if(IsUIntFormat(fmt))
intIdx = 1;
else if(IsIntFormat(fmt))
intIdx = 2;
FillBuffer(m_GenericVSCbuffer, &cdata, sizeof(cdata));
int blocksX = (int)ceil(cdata.HistogramTextureResolution.x /
float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK));
int blocksY = (int)ceil(cdata.HistogramTextureResolution.y /
float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK));
vector<D3D12_RESOURCE_BARRIER> barriers;
int resType = 0;
PrepareTextureSampling(resource, typeHint, resType, barriers);
{
ID3D12GraphicsCommandList *list = m_WrappedDevice->GetNewList();
if(!barriers.empty())
list->ResourceBarrier((UINT)barriers.size(), &barriers[0]);
list->SetPipelineState(m_TileMinMaxPipe[resType][intIdx]);
list->SetComputeRootSignature(m_HistogramRootSig);
// Set the descriptor heap containing the texture srv
ID3D12DescriptorHeap *heaps[] = {cbvsrvuavHeap, samplerHeap};
list->SetDescriptorHeaps(2, heaps);
D3D12_GPU_DESCRIPTOR_HANDLE uav = cbvsrvuavHeap->GetGPUDescriptorHandleForHeapStart();
D3D12_GPU_DESCRIPTOR_HANDLE srv = cbvsrvuavHeap->GetGPUDescriptorHandleForHeapStart();
uav.ptr += MINMAX_TILE_UAVS * sizeof(D3D12Descriptor);
list->SetComputeRootConstantBufferView(0, m_GenericVSCbuffer->GetGPUVirtualAddress());
list->SetComputeRootDescriptorTable(1, srv);
list->SetComputeRootDescriptorTable(2, samplerHeap->GetGPUDescriptorHandleForHeapStart());
list->SetComputeRootDescriptorTable(3, uav);
// discard the whole resource as we will overwrite it
D3D12_DISCARD_REGION region = {};
region.NumSubresources = 1;
list->DiscardResource(m_MinMaxTileBuffer, &region);
list->Dispatch(blocksX, blocksY, 1);
D3D12_RESOURCE_BARRIER tileBarriers[2] = {};
// ensure UAV work is done. Transition to SRV
tileBarriers[0].Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
tileBarriers[0].UAV.pResource = m_MinMaxTileBuffer;
tileBarriers[1].Transition.pResource = m_MinMaxTileBuffer;
tileBarriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
tileBarriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
list->ResourceBarrier(2, tileBarriers);
// set up second dispatch
srv.ptr += MINMAX_TILE_SRVS * sizeof(D3D12Descriptor);
uav = cbvsrvuavHeap->GetGPUDescriptorHandleForHeapStart();
uav.ptr += MINMAX_RESULT_UAVS * sizeof(D3D12Descriptor);
list->SetComputeRootDescriptorTable(1, srv);
list->SetComputeRootDescriptorTable(3, uav);
list->SetPipelineState(m_ResultMinMaxPipe[intIdx]);
list->Dispatch(1, 1, 1);
// transition back to UAV for next time
std::swap(tileBarriers[1].Transition.StateBefore, tileBarriers[1].Transition.StateAfter);
list->ResourceBarrier(1, &tileBarriers[1]);
// finish the UAV work, and transition to copy.
tileBarriers[0].UAV.pResource = m_MinMaxResultBuffer;
tileBarriers[1].Transition.pResource = m_MinMaxResultBuffer;
tileBarriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
tileBarriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE;
list->ResourceBarrier(2, tileBarriers);
// copy to readback
list->CopyBufferRegion(m_ReadbackBuffer, 0, m_MinMaxResultBuffer, 0, sizeof(Vec4f) * 2);
// transition back to UAV for next time
std::swap(tileBarriers[1].Transition.StateBefore, tileBarriers[1].Transition.StateAfter);
list->ResourceBarrier(1, &tileBarriers[1]);
// transition image back to where it was
for(size_t i = 0; i < barriers.size(); i++)
std::swap(barriers[i].Transition.StateBefore, barriers[i].Transition.StateAfter);
if(!barriers.empty())
list->ResourceBarrier((UINT)barriers.size(), &barriers[0]);
list->Close();
m_WrappedDevice->ExecuteLists();
m_WrappedDevice->FlushLists();
}
D3D12_RANGE range = {0, sizeof(Vec4f) * 2};
void *data = NULL;
HRESULT hr = m_ReadbackBuffer->Map(0, &range, &data);
if(FAILED(hr))
{
RDCERR("Failed to map bufferdata buffer %08x", hr);
return false;
}
else
{
Vec4f *minmax = (Vec4f *)data;
minval[0] = minmax[0].x;
minval[1] = minmax[0].y;
minval[2] = minmax[0].z;
minval[3] = minmax[0].w;
maxval[0] = minmax[1].x;
maxval[1] = minmax[1].y;
maxval[2] = minmax[1].z;
maxval[3] = minmax[1].w;
range.End = 0;
m_ReadbackBuffer->Unmap(0, &range);
}
return true;
}
bool D3D12DebugManager::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, TextureDisplay cfg,
bool blendAlpha)
{
@@ -2609,12 +3031,12 @@ bool D3D12DebugManager::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, T
list->SetGraphicsRootSignature(m_TexDisplayRootSig);
// Set the descriptor heap containing the texture srv
ID3D12DescriptorHeap *heaps[] = {cbvsrvHeap, samplerHeap};
ID3D12DescriptorHeap *heaps[] = {cbvsrvuavHeap, samplerHeap};
list->SetDescriptorHeaps(2, heaps);
list->SetGraphicsRootConstantBufferView(0, m_GenericVSCbuffer->GetGPUVirtualAddress());
list->SetGraphicsRootConstantBufferView(1, m_GenericPSCbuffer->GetGPUVirtualAddress());
list->SetGraphicsRootDescriptorTable(2, cbvsrvHeap->GetGPUDescriptorHandleForHeapStart());
list->SetGraphicsRootDescriptorTable(2, cbvsrvuavHeap->GetGPUDescriptorHandleForHeapStart());
list->SetGraphicsRootDescriptorTable(3, samplerHeap->GetGPUDescriptorHandleForHeapStart());
float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+18 -2
View File
@@ -73,6 +73,9 @@ public:
void RenderCheckerboard(Vec3f light, Vec3f dark);
bool RenderTexture(TextureDisplay cfg, bool blendAlpha);
bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample,
FormatComponentType typeHint, float *minval, float *maxval);
void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip,
uint32_t sample, FormatComponentType typeHint, float pixel[4]);
@@ -121,8 +124,12 @@ private:
// how much character space is in the ring buffer
static const int FONT_BUFFER_CHARS = 8192;
// index in SRV heap
// baked indices in heaps
static const int FONT_SRV = 128;
static const int MINMAX_TILE_SRVS = FONT_SRV + 1;
static const int MINMAX_TILE_UAVS = MINMAX_TILE_SRVS + 3;
static const int MINMAX_RESULT_UAVS = MINMAX_TILE_UAVS + 3;
enum
{
@@ -171,7 +178,7 @@ private:
float CharSize;
} m_Font;
ID3D12DescriptorHeap *cbvsrvHeap;
ID3D12DescriptorHeap *cbvsrvuavHeap;
ID3D12DescriptorHeap *samplerHeap;
ID3D12DescriptorHeap *rtvHeap;
ID3D12DescriptorHeap *dsvHeap;
@@ -190,6 +197,15 @@ private:
ID3D12Resource *m_PickPixelTex;
D3D12_CPU_DESCRIPTOR_HANDLE m_PickPixelRTV;
ID3D12RootSignature *m_HistogramRootSig;
// one per texture type, one per int/uint/float
ID3D12PipelineState *m_TileMinMaxPipe[10][3];
ID3D12PipelineState *m_HistogramPipe[10][3];
// one per int/uint/float
ID3D12PipelineState *m_ResultMinMaxPipe[3];
ID3D12Resource *m_MinMaxResultBuffer;
ID3D12Resource *m_MinMaxTileBuffer;
ID3D12GraphicsCommandList *m_ReadbackList;
ID3D12CommandAllocator *m_ReadbackAlloc;
ID3D12Resource *m_ReadbackBuffer;
+7 -8
View File
@@ -1178,6 +1178,13 @@ bool D3D12Replay::RenderTexture(TextureDisplay cfg)
return m_pDevice->GetDebugManager()->RenderTexture(cfg, true);
}
bool D3D12Replay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample,
FormatComponentType typeHint, float *minval, float *maxval)
{
return m_pDevice->GetDebugManager()->GetMinMax(texid, sliceFace, mip, sample, typeHint, minval,
maxval);
}
bool D3D12Replay::IsTextureSupported(const ResourceFormat &format)
{
return MakeDXGIFormat(format) != DXGI_FORMAT_UNKNOWN;
@@ -1474,14 +1481,6 @@ void D3D12Replay::InitPostVSBuffers(const vector<uint32_t> &passEvents)
{
}
bool D3D12Replay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample,
FormatComponentType typeHint, float *minval, float *maxval)
{
*minval = 0.0f;
*maxval = 1.0f;
return false;
}
bool D3D12Replay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample,
FormatComponentType typeHint, float minval, float maxval,
bool channels[4], vector<uint32_t> &histogram)