Implement RenderTexture() (in a hacky way)

This commit is contained in:
baldurk
2016-07-10 18:10:00 +02:00
parent ad998a4e8b
commit 7d50aad4d7
3 changed files with 677 additions and 4 deletions
+651 -3
View File
@@ -23,9 +23,59 @@
******************************************************************************/
#include "d3d12_debug.h"
#include "common/shader_cache.h"
#include "data/resource.h"
#include "driver/dx/official/d3dcompiler.h"
#include "driver/dxgi/dxgi_common.h"
#include "maths/matrix.h"
#include "maths/vec.h"
#include "serialise/string_utils.h"
#include "d3d12_command_queue.h"
#include "d3d12_device.h"
#include "data/hlsl/debugcbuffers.h"
typedef HRESULT(WINAPI *pD3DCreateBlob)(SIZE_T Size, ID3DBlob **ppBlob);
struct D3D12BlobShaderCallbacks
{
D3D12BlobShaderCallbacks()
{
HMODULE d3dcompiler = GetD3DCompiler();
if(d3dcompiler == NULL)
RDCFATAL("Can't get handle to d3dcompiler_??.dll");
m_BlobCreate = (pD3DCreateBlob)GetProcAddress(d3dcompiler, "D3DCreateBlob");
if(m_BlobCreate == NULL)
RDCFATAL("d3dcompiler.dll doesn't contain D3DCreateBlob");
}
bool Create(uint32_t size, byte *data, ID3DBlob **ret) const
{
RDCASSERT(ret);
*ret = NULL;
HRESULT hr = m_BlobCreate((SIZE_T)size, ret);
if(FAILED(hr))
{
RDCERR("Couldn't create blob of size %u from shadercache: %08x", size, hr);
return false;
}
memcpy((*ret)->GetBufferPointer(), data, size);
return true;
}
void Destroy(ID3DBlob *blob) const { blob->Release(); }
uint32_t GetSize(ID3DBlob *blob) const { return (uint32_t)blob->GetBufferSize(); }
byte *GetData(ID3DBlob *blob) const { return (byte *)blob->GetBufferPointer(); }
pD3DCreateBlob m_BlobCreate;
} ShaderCache12Callbacks;
extern "C" __declspec(dllexport) HRESULT
__cdecl RENDERDOC_CreateWrappedDXGIFactory1(REFIID riid, void **ppFactory);
@@ -52,7 +102,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
if(FAILED(hr))
{
RDCERR("Couldn't create DXGI factory!");
RDCERR("Couldn't create DXGI factory! 0x%08x", hr);
}
D3D12_DESCRIPTOR_HEAP_DESC desc;
@@ -66,7 +116,7 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
if(FAILED(hr))
{
RDCERR("Couldn't create RTV descriptor heap!");
RDCERR("Couldn't create RTV descriptor heap! 0x%08x", hr);
}
desc.NumDescriptors = 16;
@@ -77,28 +127,385 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
if(FAILED(hr))
{
RDCERR("Couldn't create DSV descriptor heap!");
RDCERR("Couldn't create DSV descriptor heap! 0x%08x", hr);
}
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
desc.NumDescriptors = 4096;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
hr = m_WrappedDevice->CreateDescriptorHeap(&desc, __uuidof(ID3D12DescriptorHeap),
(void **)&cbvsrvHeap);
if(FAILED(hr))
{
RDCERR("Couldn't create CBV/SRV descriptor heap! 0x%08x", hr);
}
desc.NumDescriptors = 16;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
hr = m_WrappedDevice->CreateDescriptorHeap(&desc, __uuidof(ID3D12DescriptorHeap),
(void **)&samplerHeap);
if(FAILED(hr))
{
RDCERR("Couldn't create sampler descriptor heap! 0x%08x", hr);
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.2f);
// create fixed samplers, point and linear
D3D12_CPU_DESCRIPTOR_HANDLE samp;
samp = samplerHeap->GetCPUDescriptorHandleForHeapStart();
D3D12_SAMPLER_DESC sampDesc;
RDCEraseEl(sampDesc);
sampDesc.AddressU = sampDesc.AddressV = sampDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
sampDesc.MaxAnisotropy = 1;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = FLT_MAX;
sampDesc.MipLODBias = 0.0f;
sampDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
m_WrappedDevice->CreateSampler(&sampDesc, samp);
sampDesc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT;
samp.ptr += m_WrappedDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
m_WrappedDevice->CreateSampler(&sampDesc, samp);
D3D12_HEAP_PROPERTIES heapProps;
heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
heapProps.CreationNodeMask = 1;
heapProps.VisibleNodeMask = 1;
D3D12_RESOURCE_DESC cbDesc;
cbDesc.Alignment = 0;
cbDesc.DepthOrArraySize = 1;
cbDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
cbDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
cbDesc.Format = DXGI_FORMAT_UNKNOWN;
cbDesc.Height = 1;
cbDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
cbDesc.MipLevels = 1;
cbDesc.SampleDesc.Count = 1;
cbDesc.SampleDesc.Quality = 0;
cbDesc.Width = sizeof(DebugVertexCBuffer);
hr = m_WrappedDevice->CreateCommittedResource(
&heapProps, D3D12_HEAP_FLAG_NONE, &cbDesc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
__uuidof(ID3D12Resource), (void **)&m_GenericVSCbuffer);
if(FAILED(hr))
{
RDCERR("Couldn't create m_GenericVSCbuffer! 0x%08x", hr);
}
cbDesc.Width = sizeof(DebugPixelCBufferData);
hr = m_WrappedDevice->CreateCommittedResource(
&heapProps, D3D12_HEAP_FLAG_NONE, &cbDesc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
__uuidof(ID3D12Resource), (void **)&m_GenericPSCbuffer);
if(FAILED(hr))
{
RDCERR("Couldn't create m_GenericPSCbuffer! 0x%08x", hr);
}
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.4f);
bool success = LoadShaderCache("d3d12shaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion,
m_ShaderCache, ShaderCache12Callbacks);
// if we failed to load from the cache
m_ShaderCacheDirty = !success;
m_CacheShaders = true;
vector<D3D12_ROOT_PARAMETER> rootSig;
D3D12_ROOT_PARAMETER param = {};
// m_GenericVSCbuffer
param.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
param.Descriptor.ShaderRegister = 0;
rootSig.push_back(param);
// m_GenericPSCbuffer
param.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
param.Descriptor.ShaderRegister = 1;
rootSig.push_back(param);
D3D12_DESCRIPTOR_RANGE srvrange = {};
srvrange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
srvrange.BaseShaderRegister = 0;
srvrange.NumDescriptors = 32;
srvrange.OffsetInDescriptorsFromTableStart = 0;
param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
param.DescriptorTable.NumDescriptorRanges = 1;
param.DescriptorTable.pDescriptorRanges = &srvrange;
// SRV
rootSig.push_back(param);
D3D12_DESCRIPTOR_RANGE samplerrange = {};
samplerrange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
samplerrange.BaseShaderRegister = 0;
samplerrange.NumDescriptors = 2;
samplerrange.OffsetInDescriptorsFromTableStart = 0;
param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
param.DescriptorTable.NumDescriptorRanges = 1;
param.DescriptorTable.pDescriptorRanges = &samplerrange;
// samplers
rootSig.push_back(param);
ID3DBlob *root = MakeRootSig(rootSig);
RDCASSERT(root);
hr = m_WrappedDevice->CreateRootSignature(0, root->GetBufferPointer(), root->GetBufferSize(),
__uuidof(ID3D12RootSignature),
(void **)&m_TexDisplayRootSig);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.6f);
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeDesc;
RDCEraseEl(pipeDesc);
string displayhlsl = GetEmbeddedResource(debugcbuffers_h);
displayhlsl += GetEmbeddedResource(debugcommon_hlsl);
displayhlsl += GetEmbeddedResource(debugdisplay_hlsl);
ID3DBlob *GenericVS = NULL;
ID3DBlob *TexDisplayPS = NULL;
GetShaderBlob(displayhlsl.c_str(), "RENDERDOC_DebugVS", D3DCOMPILE_WARNINGS_ARE_ERRORS, "vs_5_0",
&GenericVS);
GetShaderBlob(displayhlsl.c_str(), "RENDERDOC_TexDisplayPS", D3DCOMPILE_WARNINGS_ARE_ERRORS,
"ps_5_0", &TexDisplayPS);
RDCASSERT(GenericVS);
RDCASSERT(TexDisplayPS);
pipeDesc.pRootSignature = m_TexDisplayRootSig;
pipeDesc.VS.BytecodeLength = GenericVS->GetBufferSize();
pipeDesc.VS.pShaderBytecode = GenericVS->GetBufferPointer();
pipeDesc.PS.BytecodeLength = TexDisplayPS->GetBufferSize();
pipeDesc.PS.pShaderBytecode = TexDisplayPS->GetBufferPointer();
pipeDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
pipeDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
pipeDesc.SampleMask = 0xFFFFFFFF;
pipeDesc.SampleDesc.Count = 1;
pipeDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
pipeDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
pipeDesc.NumRenderTargets = 1;
pipeDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
pipeDesc.DSVFormat = DXGI_FORMAT_UNKNOWN;
pipeDesc.BlendState.RenderTarget[0].BlendEnable = TRUE;
pipeDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
pipeDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
pipeDesc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
pipeDesc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
pipeDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
pipeDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
hr = m_WrappedDevice->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState),
(void **)&m_TexDisplayBlendPipe);
if(FAILED(hr))
{
RDCERR("Couldn't create m_TexDisplayBlendPipe! 0x%08x", hr);
}
pipeDesc.BlendState.RenderTarget[0].BlendEnable = FALSE;
hr = m_WrappedDevice->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState),
(void **)&m_TexDisplayPipe);
if(FAILED(hr))
{
RDCERR("Couldn't create m_TexDisplayPipe! 0x%08x", hr);
}
SAFE_RELEASE(GenericVS);
SAFE_RELEASE(TexDisplayPS);
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.8f);
RenderDoc::Inst().SetProgress(DebugManagerInit, 1.0f);
m_CacheShaders = false;
}
D3D12DebugManager::~D3D12DebugManager()
{
if(m_ShaderCacheDirty)
{
SaveShaderCache("d3d12shaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, m_ShaderCache,
ShaderCache12Callbacks);
}
else
{
for(auto it = m_ShaderCache.begin(); it != m_ShaderCache.end(); ++it)
ShaderCache12Callbacks.Destroy(it->second);
}
SAFE_RELEASE(m_pFactory);
SAFE_RELEASE(dsvHeap);
SAFE_RELEASE(rtvHeap);
SAFE_RELEASE(cbvsrvHeap);
SAFE_RELEASE(samplerHeap);
SAFE_RELEASE(m_GenericVSCbuffer);
SAFE_RELEASE(m_GenericPSCbuffer);
m_WrappedDevice->InternalRelease();
if(RenderDoc::Inst().GetCrashHandler())
RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this);
}
string D3D12DebugManager::GetShaderBlob(const char *source, const char *entry,
const uint32_t compileFlags, const char *profile,
ID3DBlob **srcblob)
{
uint32_t hash = strhash(source);
hash = strhash(entry, hash);
hash = strhash(profile, hash);
hash ^= compileFlags;
if(m_ShaderCache.find(hash) != m_ShaderCache.end())
{
*srcblob = m_ShaderCache[hash];
(*srcblob)->AddRef();
return "";
}
HRESULT hr = S_OK;
ID3DBlob *byteBlob = NULL;
ID3DBlob *errBlob = NULL;
HMODULE d3dcompiler = GetD3DCompiler();
if(d3dcompiler == NULL)
{
RDCFATAL("Can't get handle to d3dcompiler_??.dll");
}
pD3DCompile compileFunc = (pD3DCompile)GetProcAddress(d3dcompiler, "D3DCompile");
if(compileFunc == NULL)
{
RDCFATAL("Can't get D3DCompile from d3dcompiler_??.dll");
}
uint32_t flags = compileFlags & ~D3DCOMPILE_NO_PRESHADER;
hr = compileFunc(source, strlen(source), entry, NULL, NULL, entry, profile, flags, 0, &byteBlob,
&errBlob);
string errors = "";
if(errBlob)
{
errors = (char *)errBlob->GetBufferPointer();
string logerror = errors;
if(logerror.length() > 1024)
logerror = logerror.substr(0, 1024) + "...";
RDCWARN("Shader compile error in '%s':\n%s", entry, logerror.c_str());
SAFE_RELEASE(errBlob);
if(FAILED(hr))
{
SAFE_RELEASE(byteBlob);
return errors;
}
}
if(m_CacheShaders)
{
m_ShaderCache[hash] = byteBlob;
byteBlob->AddRef();
m_ShaderCacheDirty = true;
}
SAFE_RELEASE(errBlob);
*srcblob = byteBlob;
return errors;
}
ID3DBlob *D3D12DebugManager::MakeRootSig(const vector<D3D12_ROOT_PARAMETER> &rootSig)
{
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE serializeRootSig =
(PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(GetModuleHandleA("d3d12.dll"),
"D3D12SerializeRootSignature");
if(serializeRootSig == NULL)
{
RDCERR("Can't get D3D12SerializeRootSignature");
return NULL;
}
D3D12_ROOT_SIGNATURE_DESC desc;
desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
desc.NumStaticSamplers = 0;
desc.pStaticSamplers = NULL;
desc.NumParameters = (UINT)rootSig.size();
desc.pParameters = &rootSig[0];
ID3DBlob *ret = NULL;
ID3DBlob *errBlob = NULL;
HRESULT hr = serializeRootSig(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &ret, &errBlob);
if(FAILED(hr))
{
string errors = (char *)errBlob->GetBufferPointer();
string logerror = errors;
if(logerror.length() > 1024)
logerror = logerror.substr(0, 1024) + "...";
RDCERR("Root signature serialize error:\n%s", logerror.c_str());
SAFE_RELEASE(errBlob);
if(FAILED(hr))
{
SAFE_RELEASE(ret);
return NULL;
}
}
SAFE_RELEASE(errBlob);
return ret;
}
void D3D12DebugManager::OutputWindow::MakeRTV(bool multisampled)
{
SAFE_RELEASE(col);
D3D12_RESOURCE_DESC texDesc = bb[0]->GetDesc();
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
texDesc.SampleDesc.Count = multisampled ? 4 : 1;
texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
@@ -421,3 +828,244 @@ void D3D12DebugManager::FlipOutputWindow(uint64_t id)
outw.bbIdx++;
outw.bbIdx %= 2;
}
void D3D12DebugManager::FillCBuffer(ID3D12Resource *buf, void *data, size_t size)
{
void *ptr = NULL;
HRESULT hr = buf->Map(0, NULL, &ptr);
if(FAILED(hr))
{
RDCERR("Can't fill cbuffer %08x", hr);
}
else
{
memcpy(ptr, data, size);
buf->Unmap(0, NULL);
}
}
bool D3D12DebugManager::RenderTexture(TextureDisplay cfg, bool blendAlpha)
{
DebugVertexCBuffer vertexData;
DebugPixelCBufferData pixelData;
pixelData.AlwaysZero = 0.0f;
float x = cfg.offx;
float y = cfg.offy;
vertexData.Position.x = x * (2.0f / float(GetWidth()));
vertexData.Position.y = -y * (2.0f / float(GetHeight()));
vertexData.ScreenAspect.x =
(float(GetHeight()) / float(GetWidth())); // 0.5 = character width / character height
vertexData.ScreenAspect.y = 1.0f;
vertexData.TextureResolution.x = 1.0f / vertexData.ScreenAspect.x;
vertexData.TextureResolution.y = 1.0f;
vertexData.LineStrip = 0;
if(cfg.rangemax <= cfg.rangemin)
cfg.rangemax += 0.00001f;
pixelData.Channels.x = cfg.Red ? 1.0f : 0.0f;
pixelData.Channels.y = cfg.Green ? 1.0f : 0.0f;
pixelData.Channels.z = cfg.Blue ? 1.0f : 0.0f;
pixelData.Channels.w = cfg.Alpha ? 1.0f : 0.0f;
pixelData.RangeMinimum = cfg.rangemin;
pixelData.InverseRangeSize = 1.0f / (cfg.rangemax - cfg.rangemin);
if(_isnan(pixelData.InverseRangeSize) || !_finite(pixelData.InverseRangeSize))
{
pixelData.InverseRangeSize = FLT_MAX;
}
pixelData.WireframeColour.x = cfg.HDRMul;
pixelData.RawOutput = cfg.rawoutput ? 1 : 0;
pixelData.FlipY = cfg.FlipY ? 1 : 0;
// TODO GetShaderDetails(cfg.texid, cfg.typeHint, cfg.rawoutput ? true : false);
WrappedID3D12Resource *resource = WrappedID3D12Resource::m_List[cfg.texid];
D3D12_RESOURCE_DESC resourceDesc = resource->GetDesc();
pixelData.SampleIdx = (int)RDCCLAMP(cfg.sampleIdx, 0U, resourceDesc.SampleDesc.Count - 1);
// hacky resolve
if(cfg.sampleIdx == ~0U)
pixelData.SampleIdx = -int(resourceDesc.SampleDesc.Count);
if(resourceDesc.Format == DXGI_FORMAT_UNKNOWN)
return false;
if(resourceDesc.Format == DXGI_FORMAT_A8_UNORM && cfg.scale <= 0.0f)
{
pixelData.Channels.x = pixelData.Channels.y = pixelData.Channels.z = 0.0f;
pixelData.Channels.w = 1.0f;
}
float tex_x = float(resourceDesc.Width);
float tex_y =
float(resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D ? 100 : resourceDesc.Height);
vertexData.TextureResolution.x *= tex_x / float(GetWidth());
vertexData.TextureResolution.y *= tex_y / float(GetHeight());
pixelData.TextureResolutionPS.x = float(RDCMAX(1U, uint32_t(resourceDesc.Width >> cfg.mip)));
pixelData.TextureResolutionPS.y = float(RDCMAX(1U, uint32_t(resourceDesc.Height >> cfg.mip)));
pixelData.TextureResolutionPS.z =
float(RDCMAX(1U, uint32_t(resourceDesc.DepthOrArraySize >> cfg.mip)));
if(resourceDesc.DepthOrArraySize > 1 && resourceDesc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D)
pixelData.TextureResolutionPS.z = float(resourceDesc.DepthOrArraySize);
vertexData.Scale = cfg.scale;
pixelData.ScalePS = cfg.scale;
if(cfg.scale <= 0.0f)
{
float xscale = float(GetWidth()) / tex_x;
float yscale = float(GetHeight()) / tex_y;
vertexData.Scale = RDCMIN(xscale, yscale);
if(yscale > xscale)
{
vertexData.Position.x = 0;
vertexData.Position.y = tex_y * vertexData.Scale / float(GetHeight()) - 1.0f;
}
else
{
vertexData.Position.y = 0;
vertexData.Position.x = 1.0f - tex_x * vertexData.Scale / float(GetWidth());
}
}
vertexData.Scale *= 2.0f; // viewport is -1 -> 1
pixelData.MipLevel = (float)cfg.mip;
pixelData.OutputDisplayFormat = RESTYPE_TEX2D;
pixelData.Slice = float(RDCCLAMP(cfg.sliceFace, 0U, uint32_t(resourceDesc.DepthOrArraySize - 1)));
if(resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
{
pixelData.OutputDisplayFormat = RESTYPE_TEX3D;
pixelData.Slice = float(cfg.sliceFace) / float(resourceDesc.DepthOrArraySize);
}
else if(resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D)
{
pixelData.OutputDisplayFormat = RESTYPE_TEX1D;
}
/*
else if(details.texType == eTexType_Depth)
{
pixelData.OutputDisplayFormat = RESTYPE_DEPTH;
}
else if(details.texType == eTexType_Stencil)
{
pixelData.OutputDisplayFormat = RESTYPE_DEPTH_STENCIL;
}
else if(details.texType == eTexType_DepthMS)
{
pixelData.OutputDisplayFormat = RESTYPE_DEPTH_MS;
}
else if(details.texType == eTexType_StencilMS)
{
pixelData.OutputDisplayFormat = RESTYPE_DEPTH_STENCIL_MS;
}*/
else if(resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D &&
resourceDesc.SampleDesc.Count > 1)
{
pixelData.OutputDisplayFormat = RESTYPE_TEX2D_MS;
}
if(cfg.overlay == eTexOverlay_NaN)
{
pixelData.OutputDisplayFormat |= TEXDISPLAY_NANS;
}
if(cfg.overlay == eTexOverlay_Clipping)
{
pixelData.OutputDisplayFormat |= TEXDISPLAY_CLIPPING;
}
int srvOffset = 0;
if(IsUIntFormat(resourceDesc.Format))
{
pixelData.OutputDisplayFormat |= TEXDISPLAY_UINT_TEX;
srvOffset = 10;
}
if(IsIntFormat(resourceDesc.Format))
{
pixelData.OutputDisplayFormat |= TEXDISPLAY_SINT_TEX;
srvOffset = 20;
}
if(!IsSRGBFormat(resourceDesc.Format) && cfg.linearDisplayAsGamma)
{
pixelData.OutputDisplayFormat |= TEXDISPLAY_GAMMA_CURVE;
}
D3D12_CPU_DESCRIPTOR_HANDLE srv = cbvsrvHeap->GetCPUDescriptorHandleForHeapStart();
// hack, tex2d float is slot 2
srv.ptr +=
2 * m_WrappedDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.PlaneSlice = 0;
srvDesc.Texture2D.ResourceMinLODClamp = 0.0f;
m_WrappedDevice->CreateShaderResourceView(resource, &srvDesc, srv);
FillCBuffer(m_GenericVSCbuffer, &vertexData, sizeof(DebugVertexCBuffer));
FillCBuffer(m_GenericPSCbuffer, &pixelData, sizeof(DebugPixelCBufferData));
OutputWindow &outw = m_OutputWindows[m_CurrentOutputWindow];
// can't just clear state because we need to keep things like render targets.
{
ID3D12GraphicsCommandList *list = m_WrappedDevice->GetNewList();
list->OMSetRenderTargets(1, &outw.rtv, TRUE, NULL);
list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
if(cfg.rawoutput || !blendAlpha || cfg.CustomShader != ResourceId())
list->SetPipelineState(m_TexDisplayPipe);
else
list->SetPipelineState(m_TexDisplayBlendPipe);
list->SetGraphicsRootSignature(m_TexDisplayRootSig);
// Set the descriptor heap containing the texture srv
ID3D12DescriptorHeap *heaps[] = {cbvsrvHeap, samplerHeap};
list->SetDescriptorHeaps(2, heaps);
list->SetGraphicsRootConstantBufferView(0, m_GenericVSCbuffer->GetGPUVirtualAddress());
list->SetGraphicsRootConstantBufferView(1, m_GenericPSCbuffer->GetGPUVirtualAddress());
list->SetGraphicsRootDescriptorTable(2, cbvsrvHeap->GetGPUDescriptorHandleForHeapStart());
list->SetGraphicsRootDescriptorTable(3, samplerHeap->GetGPUDescriptorHandleForHeapStart());
float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
list->OMSetBlendFactor(factor);
list->DrawInstanced(4, 1, 0, 0);
list->Close();
m_WrappedDevice->ExecuteLists();
m_WrappedDevice->FlushLists();
}
return true;
}
+25
View File
@@ -55,6 +55,8 @@ public:
}
int GetWidth() { return m_width; }
int GetHeight() { return m_height; }
bool RenderTexture(TextureDisplay cfg, bool blendAlpha);
private:
struct OutputWindow
{
@@ -75,12 +77,35 @@ private:
int width, height;
};
void FillCBuffer(ID3D12Resource *buf, void *data, size_t size);
ID3D12DescriptorHeap *cbvsrvHeap;
ID3D12DescriptorHeap *samplerHeap;
ID3D12DescriptorHeap *rtvHeap;
ID3D12DescriptorHeap *dsvHeap;
ID3D12Resource *m_GenericVSCbuffer;
ID3D12Resource *m_GenericPSCbuffer;
ID3D12PipelineState *m_TexDisplayPipe;
ID3D12PipelineState *m_TexDisplayBlendPipe;
ID3D12RootSignature *m_TexDisplayRootSig;
static const uint32_t m_ShaderCacheMagic = 0xbaafd1d1;
static const uint32_t m_ShaderCacheVersion = 1;
bool m_ShaderCacheDirty, m_CacheShaders;
map<uint32_t, ID3DBlob *> m_ShaderCache;
string GetShaderBlob(const char *source, const char *entry, const uint32_t compileFlags,
const char *profile, ID3DBlob **srcblob);
ID3DBlob *MakeRootSig(const vector<D3D12_ROOT_PARAMETER> &rootSig);
int m_width, m_height;
uint64_t m_OutputWindowID;
uint64_t m_CurrentOutputWindow;
map<uint64_t, OutputWindow> m_OutputWindows;
WrappedID3D12Device *m_WrappedDevice;
+1 -1
View File
@@ -282,7 +282,7 @@ void D3D12Replay::BuildCustomShader(string source, string entry, const uint32_t
bool D3D12Replay::RenderTexture(TextureDisplay cfg)
{
return false;
return m_pDevice->GetDebugManager()->RenderTexture(cfg, true);
}
void D3D12Replay::RenderCheckerboard(Vec3f light, Vec3f dark)