Handle array textures and multiview properly in overlays. Closes #1895

This commit is contained in:
baldurk
2020-05-27 22:37:31 +01:00
parent b0cd8584fb
commit abb959e1fd
21 changed files with 732 additions and 235 deletions
+4 -2
View File
@@ -591,8 +591,8 @@ struct Attachment
bool operator==(const Attachment &o) const
{
return resourceId == o.resourceId && slice == o.slice && mipLevel == o.mipLevel &&
swizzle == o.swizzle;
return resourceId == o.resourceId && slice == o.slice && numSlices == o.numSlices &&
mipLevel == o.mipLevel && swizzle == o.swizzle;
}
bool operator<(const Attachment &o) const
{
@@ -610,6 +610,8 @@ struct Attachment
ResourceId resourceId;
DOCUMENT("The slice of the texture that's used in the attachment.");
uint32_t slice = 0;
DOCUMENT("The number of slices of the texture that are used in the attachment.");
uint32_t numSlices = 1;
DOCUMENT("The mip of the texture that's used in the attachment.");
uint32_t mipLevel = 0;
DOCUMENT("A :class:`TextureSwizzle4` indicating the swizzle applied to this texture.");
+2 -3
View File
@@ -249,9 +249,8 @@ public:
RDCEraseEl(ret);
return ret;
}
ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents)
ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents)
{
return ResourceId();
}
+6 -11
View File
@@ -1055,8 +1055,7 @@ MeshFormat ReplayProxy::GetPostVSBuffers(uint32_t eventId, uint32_t instID, uint
template <typename ParamSerialiser, typename ReturnSerialiser>
ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser &paramser, ReturnSerialiser &retser,
ResourceId texid, const Subresource &sub,
CompType typeCast, FloatVector clearCol,
ResourceId texid, FloatVector clearCol,
DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents)
{
@@ -1067,8 +1066,6 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser &paramser, ReturnS
{
BEGIN_PARAMS();
SERIALISE_ELEMENT(texid);
SERIALISE_ELEMENT(sub);
SERIALISE_ELEMENT(typeCast);
SERIALISE_ELEMENT(overlay);
SERIALISE_ELEMENT(clearCol);
SERIALISE_ELEMENT(eventId);
@@ -1079,7 +1076,7 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser &paramser, ReturnS
{
REMOTE_EXECUTION();
if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored)
ret = m_Remote->RenderOverlay(texid, sub, typeCast, clearCol, overlay, eventId, passEvents);
ret = m_Remote->RenderOverlay(texid, clearCol, overlay, eventId, passEvents);
}
SERIALISE_RETURN(ret);
@@ -1087,11 +1084,10 @@ ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser &paramser, ReturnS
return ret;
}
ResourceId ReplayProxy::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents)
ResourceId ReplayProxy::RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents)
{
PROXY_FUNCTION(RenderOverlay, texid, sub, typeCast, clearCol, overlay, eventId, passEvents);
PROXY_FUNCTION(RenderOverlay, texid, clearCol, overlay, eventId, passEvents);
}
template <typename ParamSerialiser, typename ReturnSerialiser>
@@ -2832,8 +2828,7 @@ bool ReplayProxy::Tick(int type)
case eReplayProxy_ContinueDebug: ContinueDebug(NULL); break;
case eReplayProxy_FreeDebugger: FreeDebugger(NULL); break;
case eReplayProxy_RenderOverlay:
RenderOverlay(ResourceId(), Subresource(), CompType::Typeless, FloatVector(),
DebugOverlay::NoOverlay, 0, rdcarray<uint32_t>());
RenderOverlay(ResourceId(), FloatVector(), DebugOverlay::NoOverlay, 0, rdcarray<uint32_t>());
break;
case eReplayProxy_PixelHistory:
PixelHistory(rdcarray<EventUsage>(), ResourceId(), 0, 0, Subresource(), CompType::Typeless);
+3 -3
View File
@@ -506,9 +506,9 @@ public:
IMPLEMENT_FUNCTION_PROXIED(MeshFormat, GetPostVSBuffers, uint32_t eventId, uint32_t instID,
uint32_t viewID, MeshDataStage stage);
IMPLEMENT_FUNCTION_PROXIED(ResourceId, RenderOverlay, ResourceId texid, const Subresource &sub,
CompType typeCast, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents);
IMPLEMENT_FUNCTION_PROXIED(ResourceId, RenderOverlay, ResourceId texid, FloatVector clearCol,
DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents);
IMPLEMENT_FUNCTION_PROXIED(rdcarray<ShaderEntryPoint>, GetShaderEntryPoints, ResourceId shader);
IMPLEMENT_FUNCTION_PROXIED(ShaderReflection *, GetShader, ResourceId pipeline, ResourceId,
+82 -15
View File
@@ -38,11 +38,66 @@
#include "data/hlsl/hlsl_cbuffers.h"
ResourceId D3D11Replay::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents)
static void SetRTVDesc(D3D11_RENDER_TARGET_VIEW_DESC &rtDesc, const D3D11_TEXTURE2D_DESC &texDesc,
const RenderOutputSubresource &sub)
{
TextureShaderDetails details = GetDebugManager()->GetShaderDetails(texid, typeCast, false);
if(texDesc.ArraySize > 1)
{
if(texDesc.SampleDesc.Count > 1)
{
rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
rtDesc.Texture2DMSArray.FirstArraySlice = sub.slice;
rtDesc.Texture2DMSArray.ArraySize = sub.numSlices;
}
else
{
rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
rtDesc.Texture2DArray.FirstArraySlice = sub.slice;
rtDesc.Texture2DArray.ArraySize = sub.numSlices;
rtDesc.Texture2DArray.MipSlice = sub.mip;
}
}
else
{
rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtDesc.Texture2D.MipSlice = sub.mip;
if(texDesc.SampleDesc.Count > 1)
rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
}
}
RenderOutputSubresource D3D11Replay::GetRenderOutputSubresource(ResourceId id)
{
id = m_pDevice->GetResourceManager()->GetOriginalID(id);
for(size_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{
const D3D11Pipe::View &rt = m_CurPipelineState.outputMerger.renderTargets[i];
if(rt.viewResourceId == id || rt.resourceResourceId == id)
return RenderOutputSubresource(rt.firstMip, rt.firstSlice, rt.numSlices);
}
const D3D11Pipe::View &dsv = m_CurPipelineState.outputMerger.depthTarget;
if(dsv.viewResourceId == id || dsv.resourceResourceId == id)
return RenderOutputSubresource(dsv.firstMip, dsv.firstSlice, dsv.numSlices);
return RenderOutputSubresource(~0U, ~0U, 0);
}
ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents)
{
TextureShaderDetails details = GetDebugManager()->GetShaderDetails(texid, CompType::Float, false);
RenderOutputSubresource sub = GetRenderOutputSubresource(texid);
if(sub.slice == ~0U)
{
RDCERR("Rendering overlay for %s couldn't find output to get subresource.", ToStr(texid).c_str());
sub = RenderOutputSubresource(0, 0, 1);
}
D3D11MarkerRegion renderoverlay(StringFormat::Fmt("RenderOverlay %d", overlay));
@@ -52,7 +107,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, const Subresource &sub,
realTexDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
realTexDesc.Usage = D3D11_USAGE_DEFAULT;
realTexDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
realTexDesc.ArraySize = 1;
realTexDesc.ArraySize = details.texArraySize;
realTexDesc.MipLevels = details.texMips;
realTexDesc.CPUAccessFlags = 0;
realTexDesc.MiscFlags = 0;
@@ -80,6 +135,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, const Subresource &sub,
// need to recreate backing custom render tex
if(realTexDesc.Width != customTexDesc.Width || realTexDesc.Height != customTexDesc.Height ||
realTexDesc.Format != customTexDesc.Format || realTexDesc.MipLevels != customTexDesc.MipLevels ||
realTexDesc.ArraySize != customTexDesc.ArraySize ||
realTexDesc.SampleDesc.Count != customTexDesc.SampleDesc.Count ||
realTexDesc.SampleDesc.Quality != customTexDesc.SampleDesc.Quality)
{
@@ -144,17 +200,31 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, const Subresource &sub,
SAFE_RELEASE(realDepth);
}
D3D11_RENDER_TARGET_VIEW_DESC rtDesc;
rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
ID3D11RenderTargetView *rtv = NULL;
D3D11_RENDER_TARGET_VIEW_DESC rtDesc = {};
rtDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
rtDesc.Texture2D.MipSlice = sub.mip;
if(realTexDesc.SampleDesc.Count > 1 || realTexDesc.SampleDesc.Quality > 0)
// clear all mips and all slices first
for(UINT mip = 0; mip < realTexDesc.MipLevels; mip++)
{
rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
SetRTVDesc(rtDesc, realTexDesc, RenderOutputSubresource(mip, 0, realTexDesc.ArraySize));
HRESULT hr = m_pDevice->CreateRenderTargetView(wrappedCustomRenderTex, &rtDesc, &rtv);
if(FAILED(hr))
{
RDCERR("Failed to create custom render tex for mip %u RTV HRESULT: %s", mip, ToStr(hr).c_str());
}
else
{
FLOAT black[] = {0.0f, 0.0f, 0.0f, 0.0f};
m_pImmediateContext->ClearRenderTargetView(rtv, black);
}
SAFE_RELEASE(rtv);
}
ID3D11RenderTargetView *rtv = NULL;
SetRTVDesc(rtDesc, realTexDesc, sub);
HRESULT hr = m_pDevice->CreateRenderTargetView(wrappedCustomRenderTex, &rtDesc, &rtv);
if(FAILED(hr))
{
@@ -162,9 +232,6 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, const Subresource &sub,
return m_Overlay.resourceId;
}
FLOAT black[] = {0.0f, 0.0f, 0.0f, 0.0f};
m_pImmediateContext->ClearRenderTargetView(rtv, black);
if(renderDepth)
{
m_pImmediateContext->CopyResource(renderDepth, preDrawDepth);
@@ -611,7 +678,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, const Subresource &sub,
m_pImmediateContext->ClearRenderTargetView(state.OM.RenderTargets[i], &clearCol.x);
// Try to clear depth as well, to help debug shadow rendering
if(state.OM.DepthView && IsDepthFormat(details.srvFormat))
if(state.OM.DepthView && IsDepthFormat(details.texFmt))
{
if(state.OM.DepthStencilState)
{
+20 -23
View File
@@ -871,31 +871,41 @@ void D3D11Replay::SavePipelineState(uint32_t eventId)
{
view.firstMip = desc.Texture1D.MostDetailedMip;
view.numMips = desc.Texture1D.MipLevels;
view.firstSlice = 0;
view.numSlices = 1;
}
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY)
{
view.numSlices = desc.Texture1DArray.ArraySize;
view.firstSlice = desc.Texture1DArray.FirstArraySlice;
view.firstMip = desc.Texture1DArray.MostDetailedMip;
view.numMips = desc.Texture1DArray.MipLevels;
view.numSlices = desc.Texture1DArray.ArraySize;
view.firstSlice = desc.Texture1DArray.FirstArraySlice;
}
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2D)
{
view.firstMip = desc.Texture2D.MostDetailedMip;
view.numMips = desc.Texture2D.MipLevels;
view.firstSlice = 0;
view.numSlices = 1;
}
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DARRAY)
{
view.numSlices = desc.Texture2DArray.ArraySize;
view.firstSlice = desc.Texture2DArray.FirstArraySlice;
view.firstMip = desc.Texture2DArray.MostDetailedMip;
view.numMips = desc.Texture2DArray.MipLevels;
view.firstSlice = desc.Texture2DArray.FirstArraySlice;
view.numSlices = desc.Texture2DArray.ArraySize;
}
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS)
{
view.firstMip = 0;
view.numMips = 1;
view.firstSlice = 0;
view.numSlices = 1;
}
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY)
{
view.firstMip = 0;
view.numMips = 1;
view.numSlices = desc.Texture2DMSArray.ArraySize;
view.firstSlice = desc.Texture2DMSArray.FirstArraySlice;
}
@@ -903,19 +913,22 @@ void D3D11Replay::SavePipelineState(uint32_t eventId)
{
view.firstMip = desc.Texture3D.MostDetailedMip;
view.numMips = desc.Texture3D.MipLevels;
view.firstSlice = 0;
view.numSlices = 1;
}
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBE)
{
view.numSlices = 6;
view.firstMip = desc.TextureCube.MostDetailedMip;
view.numMips = desc.TextureCube.MipLevels;
view.firstSlice = 0;
view.numSlices = 6;
}
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY)
{
view.numSlices = desc.TextureCubeArray.NumCubes * 6;
view.firstSlice = desc.TextureCubeArray.First2DArrayFace;
view.firstMip = desc.TextureCubeArray.MostDetailedMip;
view.numMips = desc.TextureCubeArray.MipLevels;
view.firstSlice = desc.TextureCubeArray.First2DArrayFace;
view.numSlices = desc.TextureCubeArray.NumCubes * 6;
}
SAFE_RELEASE(res);
@@ -3369,22 +3382,6 @@ ResourceId D3D11Replay::ApplyCustomShader(ResourceId shader, ResourceId texid,
return m_CustomShaderResourceId;
}
bool D3D11Replay::IsRenderOutput(ResourceId id)
{
for(size_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{
if(m_CurPipelineState.outputMerger.renderTargets[i].viewResourceId == id ||
m_CurPipelineState.outputMerger.renderTargets[i].resourceResourceId == id)
return true;
}
if(m_CurPipelineState.outputMerger.depthTarget.viewResourceId == id ||
m_CurPipelineState.outputMerger.depthTarget.resourceResourceId == id)
return true;
return false;
}
ResourceId D3D11Replay::CreateProxyTexture(const TextureDescription &templateTex)
{
ResourceId ret;
+4 -5
View File
@@ -242,9 +242,8 @@ public:
uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg,
uint32_t x, uint32_t y);
ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents);
ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents);
void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry,
const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id,
@@ -252,8 +251,8 @@ public:
ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, const Subresource &sub,
CompType typeCast);
bool IsRenderOutput(ResourceId id);
RenderOutputSubresource GetRenderOutputSubresource(ResourceId id);
bool IsRenderOutput(ResourceId id) { return GetRenderOutputSubresource(id).mip != ~0U; }
void FileChanged() {}
private:
bool m_WARP;
+83 -18
View File
@@ -200,15 +200,75 @@ struct D3D12QuadOverdrawCallback : public D3D12DrawcallCallback
D3D12RenderState m_PrevState;
};
ResourceId D3D12Replay::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents)
static void SetRTVDesc(D3D12_RENDER_TARGET_VIEW_DESC &rtDesc, const D3D12_RESOURCE_DESC &texDesc,
const RenderOutputSubresource &sub)
{
if(texDesc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D && texDesc.DepthOrArraySize > 1)
{
if(texDesc.SampleDesc.Count > 1)
{
rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY;
rtDesc.Texture2DMSArray.FirstArraySlice = sub.slice;
rtDesc.Texture2DMSArray.ArraySize = sub.numSlices;
}
else
{
rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
rtDesc.Texture2DArray.FirstArraySlice = sub.slice;
rtDesc.Texture2DArray.ArraySize = sub.numSlices;
rtDesc.Texture2DArray.MipSlice = sub.mip;
}
}
else
{
rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rtDesc.Texture2D.MipSlice = sub.mip;
if(texDesc.SampleDesc.Count > 1)
rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
}
}
RenderOutputSubresource D3D12Replay::GetRenderOutputSubresource(ResourceId id)
{
const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState;
D3D12Pipe::View view;
for(size_t i = 0; i < rs.rts.size(); i++)
{
if(id == rs.rts[i].GetResResourceId())
{
FillResourceView(view, &rs.rts[i]);
return RenderOutputSubresource(view.firstMip, view.firstSlice, view.numSlices);
}
}
if(id == rs.dsv.GetResResourceId())
{
FillResourceView(view, &rs.dsv);
return RenderOutputSubresource(view.firstMip, view.firstSlice, view.numSlices);
}
return RenderOutputSubresource(~0U, ~0U, 0);
}
ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents)
{
ID3D12Resource *resource = m_pDevice->GetResourceList()[texid];
if(resource == NULL)
return ResourceId();
RenderOutputSubresource sub = GetRenderOutputSubresource(texid);
if(sub.slice == ~0U)
{
RDCERR("Rendering overlay for %s couldn't find output to get subresource.", ToStr(texid).c_str());
sub = RenderOutputSubresource(0, 0, 1);
}
D3D12MarkerRegion renderoverlay(m_pDevice->GetQueue(),
StringFormat::Fmt("RenderOverlay %d", overlay));
@@ -216,11 +276,13 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, const Subresource &sub,
rdcarray<D3D12_RESOURCE_BARRIER> barriers;
int resType = 0;
GetDebugManager()->PrepareTextureSampling(resource, typeCast, resType, barriers);
GetDebugManager()->PrepareTextureSampling(resource, CompType::Float, resType, barriers);
D3D12_RESOURCE_DESC overlayTexDesc;
overlayTexDesc.Alignment = 0;
overlayTexDesc.DepthOrArraySize = 1;
overlayTexDesc.DepthOrArraySize = resourceDesc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D
? resourceDesc.DepthOrArraySize
: 1;
overlayTexDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
overlayTexDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
overlayTexDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
@@ -248,6 +310,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, const Subresource &sub,
if(overlayTexDesc.Width != currentOverlayDesc.Width ||
overlayTexDesc.Height != currentOverlayDesc.Height ||
overlayTexDesc.Format != currentOverlayDesc.Format ||
overlayTexDesc.DepthOrArraySize != currentOverlayDesc.DepthOrArraySize ||
overlayTexDesc.MipLevels != currentOverlayDesc.MipLevels ||
overlayTexDesc.SampleDesc.Count != currentOverlayDesc.SampleDesc.Count ||
overlayTexDesc.SampleDesc.Quality != currentOverlayDesc.SampleDesc.Quality)
@@ -353,23 +416,25 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, const Subresource &sub,
list->Close();
}
D3D12_RENDER_TARGET_VIEW_DESC rtDesc = {};
rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
rtDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
rtDesc.Texture2D.MipSlice = sub.mip;
rtDesc.Texture2D.PlaneSlice = 0;
if(overlayTexDesc.SampleDesc.Count > 1 || overlayTexDesc.SampleDesc.Quality > 0)
rtDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
D3D12_CPU_DESCRIPTOR_HANDLE rtv = GetDebugManager()->GetCPUHandle(OVERLAY_RTV);
m_pDevice->CreateRenderTargetView(wrappedCustomRenderTex, &rtDesc, rtv);
D3D12_RENDER_TARGET_VIEW_DESC rtDesc = {};
rtDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
ID3D12GraphicsCommandList *list = m_pDevice->GetNewList();
FLOAT black[] = {0.0f, 0.0f, 0.0f, 0.0f};
list->ClearRenderTargetView(rtv, black, 0, NULL);
// clear all mips and all slices first
for(UINT mip = 0; mip < overlayTexDesc.MipLevels; mip++)
{
SetRTVDesc(rtDesc, overlayTexDesc,
RenderOutputSubresource(mip, 0, overlayTexDesc.DepthOrArraySize));
m_pDevice->CreateRenderTargetView(wrappedCustomRenderTex, &rtDesc, rtv);
FLOAT black[] = {0.0f, 0.0f, 0.0f, 0.0f};
list->ClearRenderTargetView(rtv, black, 0, NULL);
}
SetRTVDesc(rtDesc, overlayTexDesc, sub);
m_pDevice->CreateRenderTargetView(wrappedCustomRenderTex, &rtDesc, rtv);
D3D12_CPU_DESCRIPTOR_HANDLE dsv = {};
+16 -17
View File
@@ -654,28 +654,42 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE1D)
{
view.firstMip = rtv.Texture1D.MipSlice;
view.numMips = 1;
view.firstSlice = 0;
view.numSlices = 1;
}
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE1DARRAY)
{
view.firstMip = rtv.Texture1DArray.MipSlice;
view.numMips = 1;
view.numSlices = rtv.Texture1DArray.ArraySize;
view.firstSlice = rtv.Texture1DArray.FirstArraySlice;
view.firstMip = rtv.Texture1DArray.MipSlice;
}
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2D)
{
view.firstMip = rtv.Texture2D.MipSlice;
view.numMips = 1;
view.firstSlice = 0;
view.numSlices = 1;
}
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2DARRAY)
{
view.numSlices = rtv.Texture2DArray.ArraySize;
view.firstSlice = rtv.Texture2DArray.FirstArraySlice;
view.firstMip = rtv.Texture2DArray.MipSlice;
view.numMips = 1;
}
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2DMS)
{
view.firstMip = 0;
view.numMips = 1;
view.firstSlice = 0;
view.numSlices = 1;
}
else if(rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY)
{
view.firstMip = 0;
view.numMips = 1;
view.numSlices = rtv.Texture2DMSArray.ArraySize;
view.firstSlice = rtv.Texture2DArray.FirstArraySlice;
}
@@ -684,6 +698,7 @@ void D3D12Replay::FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor
view.numSlices = rtv.Texture3D.WSize;
view.firstSlice = rtv.Texture3D.FirstWSlice;
view.firstMip = rtv.Texture3D.MipSlice;
view.numMips = 1;
}
}
else if(desc->GetType() == D3D12DescriptorType::DSV)
@@ -2597,22 +2612,6 @@ bool D3D12Replay::GetHistogram(ResourceId texid, const Subresource &sub, CompTyp
return true;
}
bool D3D12Replay::IsRenderOutput(ResourceId id)
{
const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState;
id = m_pDevice->GetResourceManager()->GetLiveID(id);
for(size_t i = 0; i < rs.rts.size(); i++)
if(id == rs.rts[i].GetResResourceId())
return true;
if(id == rs.dsv.GetResResourceId())
return true;
return false;
}
rdcarray<uint32_t> D3D12Replay::GetPassEvents(uint32_t eventId)
{
rdcarray<uint32_t> passEvents;
+4 -5
View File
@@ -197,9 +197,8 @@ public:
uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg,
uint32_t x, uint32_t y);
ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents);
ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents);
void BuildCustomShader(ShaderEncoding sourceEncoding, const bytebuf &source, const rdcstr &entry,
const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId &id,
@@ -207,8 +206,8 @@ public:
ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, const Subresource &sub,
CompType typeCast);
bool IsRenderOutput(ResourceId id);
RenderOutputSubresource GetRenderOutputSubresource(ResourceId id);
bool IsRenderOutput(ResourceId id) { return GetRenderOutputSubresource(id).mip != ~0U; }
void FileChanged() {}
AMDCounters *GetAMDCounters() { return m_pAMDCounters; }
private:
+274 -65
View File
@@ -227,12 +227,91 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
return HasSPIRVShaders;
}
ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents)
RenderOutputSubresource GLReplay::GetRenderOutputSubresource(ResourceId id)
{
id = m_pDriver->GetResourceManager()->GetOriginalID(id);
for(const GLPipe::Attachment &att : m_CurPipelineState.framebuffer.drawFBO.colorAttachments)
{
if(att.resourceId == id)
return RenderOutputSubresource(att.mipLevel, att.slice, att.numSlices);
}
for(const GLPipe::Attachment &att : {m_CurPipelineState.framebuffer.drawFBO.depthAttachment,
m_CurPipelineState.framebuffer.drawFBO.stencilAttachment})
{
if(att.resourceId == id)
return RenderOutputSubresource(att.mipLevel, att.slice, att.numSlices);
}
return RenderOutputSubresource(~0U, ~0U, 0);
}
void GLReplay::BindFramebufferTexture(RenderOutputSubresource &sub, GLenum texBindingEnum,
GLint numSamples)
{
WrappedOpenGL &drv = *m_pDriver;
if(sub.numSlices > 1)
{
if(IsGLES)
{
if(HasExt[OVR_multiview])
{
if(texBindingEnum == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
{
drv.glFramebufferTextureMultisampleMultiviewOVR(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0,
DebugData.overlayTex, sub.mip, numSamples,
sub.slice, sub.numSlices);
}
else
{
drv.glFramebufferTextureMultiviewOVR(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0,
DebugData.overlayTex, sub.mip, sub.slice,
sub.numSlices);
}
}
else
{
RDCERR("Multiple slices bound without OVR_multiview");
// without OVR_multiview we can't bind the whole array, so just bind slice 0
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.overlayTex,
sub.mip, sub.slice);
}
}
else
{
drv.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.overlayTex, sub.mip);
}
}
else
{
if(texBindingEnum == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY || texBindingEnum == eGL_TEXTURE_2D_ARRAY)
{
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.overlayTex,
sub.mip, sub.slice);
}
else
{
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum,
DebugData.overlayTex, sub.mip);
}
}
}
ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents)
{
WrappedOpenGL &drv = *m_pDriver;
RenderOutputSubresource sub = GetRenderOutputSubresource(texid);
if(sub.slice == ~0U)
{
RDCERR("Rendering overlay for %s couldn't find output to get subresource.", ToStr(texid).c_str());
sub = RenderOutputSubresource(0, 0, 1);
}
MakeCurrentReplayContext(&m_ReplayCtx);
GLMarkerRegion renderoverlay(StringFormat::Fmt("RenderOverlay %d", overlay));
@@ -356,10 +435,26 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
GLenum texBindingEnum = eGL_TEXTURE_2D;
GLenum texQueryEnum = eGL_TEXTURE_BINDING_2D;
GLint texSlices = texDetails.depth;
if(TextureTarget(texDetails.curType) == eGL_TEXTURE_3D)
texSlices = 1;
if(texDetails.samples > 1)
{
texBindingEnum = eGL_TEXTURE_2D_MULTISAMPLE;
texQueryEnum = eGL_TEXTURE_BINDING_2D_MULTISAMPLE;
if(texSlices > 1)
{
texBindingEnum = eGL_TEXTURE_2D_MULTISAMPLE_ARRAY;
texQueryEnum = eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
}
}
if(texSlices > 1)
{
texBindingEnum = eGL_TEXTURE_2D_ARRAY;
texQueryEnum = eGL_TEXTURE_BINDING_2D_ARRAY;
}
GLint texMips = GetNumMips(texDetails.curType, texDetails.resource.name, texDetails.width,
@@ -368,7 +463,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
// resize (or create) the overlay texture and FBO if necessary
if(DebugData.overlayTexWidth != texDetails.width ||
DebugData.overlayTexHeight != texDetails.height ||
DebugData.overlayTexSamples != texDetails.samples || DebugData.overlayTexMips != texMips)
DebugData.overlayTexSamples != texDetails.samples || DebugData.overlayTexMips != texMips ||
DebugData.overlayTexSlices != texSlices)
{
if(DebugData.overlayFBO)
{
@@ -389,11 +485,21 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
DebugData.overlayTexHeight = texDetails.height;
DebugData.overlayTexSamples = texDetails.samples;
DebugData.overlayTexMips = texMips;
DebugData.overlayTexSlices = texSlices;
if(DebugData.overlayTexSamples > 1)
{
drv.glTextureStorage2DMultisampleEXT(DebugData.overlayTex, texBindingEnum, texDetails.samples,
eGL_RGBA16F, texDetails.width, texDetails.height, true);
if(DebugData.overlayTexSlices > 1)
{
drv.glTextureStorage3DMultisampleEXT(DebugData.overlayTex, texBindingEnum,
texDetails.samples, eGL_RGBA16F, texDetails.width,
texDetails.height, texSlices, true);
}
else
{
drv.glTextureStorage2DMultisampleEXT(DebugData.overlayTex, texBindingEnum, texDetails.samples,
eGL_RGBA16F, texDetails.width, texDetails.height, true);
}
}
else
{
@@ -407,12 +513,26 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
type = eGL_UNSIGNED_BYTE;
}
drv.glTextureImage2DEXT(DebugData.overlayTex, texBindingEnum, 0, internalFormat,
texDetails.width, texDetails.height, 0, format, type, NULL);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage2DEXT(DebugData.overlayTex, texBindingEnum, i, internalFormat,
RDCMAX(1, texDetails.width >> i), RDCMAX(1, texDetails.height >> i),
0, format, type, NULL);
if(texSlices > 1)
{
drv.glTextureImage3DEXT(DebugData.overlayTex, texBindingEnum, 0, internalFormat,
texDetails.width, texDetails.height, texSlices, 0, format, type,
NULL);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage3DEXT(DebugData.overlayTex, texBindingEnum, i, internalFormat,
RDCMAX(1, texDetails.width >> i), RDCMAX(1, texDetails.height >> i),
texSlices, 0, format, type, NULL);
}
else
{
drv.glTextureImage2DEXT(DebugData.overlayTex, texBindingEnum, 0, internalFormat,
texDetails.width, texDetails.height, 0, format, type, NULL);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage2DEXT(DebugData.overlayTex, texBindingEnum, i, internalFormat,
RDCMAX(1, texDetails.width >> i),
RDCMAX(1, texDetails.height >> i), 0, format, type, NULL);
}
drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_MAX_LEVEL, texMips - 1);
drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
drv.glTexParameteri(texBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
@@ -430,14 +550,6 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
drv.glDisable(eGL_STENCIL_TEST);
drv.glStencilMask(0);
GLfloat black[4] = {};
for(GLint i = 0; i < texMips; i++)
{
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum,
DebugData.overlayTex, i);
drv.glClearBufferfv(eGL_COLOR, 0, black);
}
drv.glBindTexture(texBindingEnum, curTex);
}
@@ -446,9 +558,34 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
drv.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.overlayFBO);
// bind the desired mip
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum,
DebugData.overlayTex, sub.mip);
// clear the overlay texture to black
{
GLfloat black[4] = {};
if(texSlices > 1)
{
for(GLint s = 0; s < texSlices; s++)
{
for(GLint m = 0; m < texMips; m++)
{
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0,
DebugData.overlayTex, m, s);
drv.glClearBufferfv(eGL_COLOR, 0, black);
}
}
}
else
{
for(GLint m = 0; m < texMips; m++)
{
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum,
DebugData.overlayTex, m);
drv.glClearBufferfv(eGL_COLOR, 0, black);
}
}
}
// bind the desired mip/slice/slices
BindFramebufferTexture(sub, texBindingEnum, texDetails.samples);
// disable several tests/allow rendering - some overlays will override
// these states but commonly we don't want to inherit these states from
@@ -731,27 +868,55 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
drv.glGenTextures(1, &depthCopy);
drv.glBindTexture(copyBindingEnum, depthCopy);
if(DebugData.overlayTexSamples > 1)
if(DebugData.overlayTexSlices > 1)
{
drv.glTextureStorage2DMultisampleEXT(depthCopy, copyBindingEnum, DebugData.overlayTexSamples,
fmt, DebugData.overlayTexWidth,
DebugData.overlayTexHeight, true);
if(DebugData.overlayTexSamples > 1)
{
drv.glTextureStorage3DMultisampleEXT(
depthCopy, copyBindingEnum, DebugData.overlayTexSamples, fmt, DebugData.overlayTexWidth,
DebugData.overlayTexHeight, DebugData.overlayTexSlices, true);
}
else
{
drv.glTextureImage3DEXT(depthCopy, copyBindingEnum, 0, fmt, DebugData.overlayTexWidth,
DebugData.overlayTexHeight, DebugData.overlayTexSlices, 0,
GetBaseFormat(fmt), GetDataType(fmt), NULL);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage3DEXT(
depthCopy, copyBindingEnum, i, fmt, RDCMAX(1, DebugData.overlayTexWidth >> i),
RDCMAX(1, DebugData.overlayTexHeight >> i), DebugData.overlayTexSlices, 0,
GetBaseFormat(fmt), GetDataType(fmt), NULL);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
}
}
else
{
drv.glTextureImage2DEXT(depthCopy, copyBindingEnum, 0, fmt, DebugData.overlayTexWidth,
DebugData.overlayTexHeight, 0, GetBaseFormat(fmt), GetDataType(fmt),
NULL);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage2DEXT(depthCopy, copyBindingEnum, i, fmt,
RDCMAX(1, DebugData.overlayTexWidth >> i),
RDCMAX(1, DebugData.overlayTexHeight >> i), 0, GetBaseFormat(fmt),
if(DebugData.overlayTexSamples > 1)
{
drv.glTextureStorage2DMultisampleEXT(
depthCopy, copyBindingEnum, DebugData.overlayTexSamples, fmt,
DebugData.overlayTexWidth, DebugData.overlayTexHeight, true);
}
else
{
drv.glTextureImage2DEXT(depthCopy, copyBindingEnum, 0, fmt, DebugData.overlayTexWidth,
DebugData.overlayTexHeight, 0, GetBaseFormat(fmt),
GetDataType(fmt), NULL);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage2DEXT(depthCopy, copyBindingEnum, i, fmt,
RDCMAX(1, DebugData.overlayTexWidth >> i),
RDCMAX(1, DebugData.overlayTexHeight >> i), 0,
GetBaseFormat(fmt), GetDataType(fmt), NULL);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
}
}
drv.glBindTexture(copyBindingEnum, curTex);
@@ -782,27 +947,56 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
drv.glGenTextures(1, &stencilCopy);
drv.glBindTexture(copyBindingEnum, stencilCopy);
if(DebugData.overlayTexSamples > 1)
if(DebugData.overlayTexSlices > 1)
{
drv.glTextureStorage2DMultisampleEXT(
stencilCopy, copyBindingEnum, DebugData.overlayTexSamples, fmt,
DebugData.overlayTexWidth, DebugData.overlayTexHeight, true);
if(DebugData.overlayTexSamples > 1)
{
drv.glTextureStorage3DMultisampleEXT(stencilCopy, copyBindingEnum,
DebugData.overlayTexSamples, fmt,
DebugData.overlayTexWidth, DebugData.overlayTexHeight,
DebugData.overlayTexSlices, true);
}
else
{
drv.glTextureImage3DEXT(stencilCopy, copyBindingEnum, 0, fmt, DebugData.overlayTexWidth,
DebugData.overlayTexHeight, DebugData.overlayTexSlices, 0,
GetBaseFormat(fmt), GetDataType(fmt), NULL);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage3DEXT(
stencilCopy, copyBindingEnum, i, fmt, RDCMAX(1, DebugData.overlayTexWidth >> i),
RDCMAX(1, DebugData.overlayTexHeight >> i), DebugData.overlayTexSlices, 0,
GetBaseFormat(fmt), GetDataType(fmt), NULL);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
}
}
else
{
drv.glTextureImage2DEXT(stencilCopy, copyBindingEnum, 0, fmt, DebugData.overlayTexWidth,
DebugData.overlayTexHeight, 0, GetBaseFormat(fmt), GetDataType(fmt),
NULL);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage2DEXT(stencilCopy, copyBindingEnum, i, fmt,
RDCMAX(1, DebugData.overlayTexWidth >> i),
RDCMAX(1, DebugData.overlayTexHeight >> i), 0, GetBaseFormat(fmt),
if(DebugData.overlayTexSamples > 1)
{
drv.glTextureStorage2DMultisampleEXT(
stencilCopy, copyBindingEnum, DebugData.overlayTexSamples, fmt,
DebugData.overlayTexWidth, DebugData.overlayTexHeight, true);
}
else
{
drv.glTextureImage2DEXT(stencilCopy, copyBindingEnum, 0, fmt, DebugData.overlayTexWidth,
DebugData.overlayTexHeight, 0, GetBaseFormat(fmt),
GetDataType(fmt), NULL);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
for(GLint i = 1; i < texMips; i++)
drv.glTextureImage2DEXT(stencilCopy, copyBindingEnum, i, fmt,
RDCMAX(1, DebugData.overlayTexWidth >> i),
RDCMAX(1, DebugData.overlayTexHeight >> i), 0,
GetBaseFormat(fmt), GetDataType(fmt), NULL);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAX_LEVEL, 0);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
drv.glTexParameteri(copyBindingEnum, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
}
}
drv.glBindTexture(copyBindingEnum, curTex);
@@ -811,17 +1005,17 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
// bind depth/stencil to overlay FBO (currently bound to DRAW_FRAMEBUFFER)
if(curDepth != 0 && curDepth == curStencil)
{
drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, eGL_TEXTURE_2D,
depthCopy, sub.mip);
drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT,
copyBindingEnum, depthCopy, sub.mip);
}
else if(curDepth != 0)
{
drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_TEXTURE_2D,
drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, copyBindingEnum,
depthCopy, sub.mip);
}
else if(curStencil != 0)
{
drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_TEXTURE_2D,
drv.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, copyBindingEnum,
stencilCopy, sub.mip);
}
@@ -1099,8 +1293,13 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
// bind our FBO
drv.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, overlayFBO);
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum,
DebugData.overlayTex, sub.mip);
if(texBindingEnum == eGL_TEXTURE_2D_ARRAY ||
texBindingEnum == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0,
DebugData.overlayTex, sub.mip, sub.slice);
else
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum,
DebugData.overlayTex, sub.mip);
// now apply the depth texture binding
if(depthObj)
@@ -1554,10 +1753,20 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, const Subresource &sub, Com
// modify our fbo to attach the overlay texture instead
drv.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo);
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum,
DebugData.overlayTex, sub.mip);
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, texBindingEnum,
0, 0);
if(texBindingEnum == eGL_TEXTURE_2D_ARRAY ||
texBindingEnum == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
{
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0,
DebugData.overlayTex, sub.mip, sub.slice);
drv.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
}
else
{
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texBindingEnum,
DebugData.overlayTex, sub.mip);
drv.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT,
texBindingEnum, 0, 0);
}
drv.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
drv.glDisable(eGL_BLEND);
+89 -16
View File
@@ -373,21 +373,6 @@ void GLReplay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, byt
drv.glBindBuffer(eGL_COPY_READ_BUFFER, oldbuf);
}
bool GLReplay::IsRenderOutput(ResourceId id)
{
for(const GLPipe::Attachment &att : m_CurPipelineState.framebuffer.drawFBO.colorAttachments)
{
if(att.resourceId == id)
return true;
}
if(m_CurPipelineState.framebuffer.drawFBO.depthAttachment.resourceId == id ||
m_CurPipelineState.framebuffer.drawFBO.stencilAttachment.resourceId == id)
return true;
return false;
}
void GLReplay::CacheTexture(ResourceId id)
{
if(m_CachedTextures.find(id) != m_CachedTextures.end())
@@ -1755,11 +1740,50 @@ void GLReplay::SavePipelineState(uint32_t eventId)
pipe.framebuffer.drawFBO.colorAttachments[i].resourceId = rm->GetOriginalID(id);
GLenum attachment = GLenum(eGL_COLOR_ATTACHMENT0 + i);
if(pipe.framebuffer.drawFBO.colorAttachments[i].resourceId != ResourceId() && !rbCol[i])
GetFramebufferMipAndLayer(curDrawFBO, GLenum(eGL_COLOR_ATTACHMENT0 + i),
GetFramebufferMipAndLayer(curDrawFBO, attachment,
(GLint *)&pipe.framebuffer.drawFBO.colorAttachments[i].mipLevel,
(GLint *)&pipe.framebuffer.drawFBO.colorAttachments[i].slice);
pipe.framebuffer.drawFBO.colorAttachments[i].numSlices = 1;
if(!rbCol[i] && id != ResourceId())
{
// desktop GL allows layered attachments which attach all slices from 0 to N
if(!IsGLES)
{
GLint layered = 0;
GL.glGetNamedFramebufferAttachmentParameterivEXT(
curDrawFBO, attachment, eGL_FRAMEBUFFER_ATTACHMENT_LAYERED, &layered);
if(layered)
{
pipe.framebuffer.drawFBO.colorAttachments[i].numSlices = m_pDriver->m_Textures[id].depth;
}
}
else
{
// on GLES there's an OVR extension that allows attaching multiple layers
if(HasExt[OVR_multiview])
{
GLint numViews = 0, startView = 0;
GL.glGetNamedFramebufferAttachmentParameterivEXT(
curDrawFBO, attachment, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR, &numViews);
GL.glGetNamedFramebufferAttachmentParameterivEXT(
curDrawFBO, attachment, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR,
&startView);
if(numViews > 1)
{
pipe.framebuffer.drawFBO.colorAttachments[i].numSlices = numViews;
pipe.framebuffer.drawFBO.colorAttachments[i].slice = startView;
}
}
}
}
GLenum swizzles[4] = {eGL_RED, eGL_GREEN, eGL_BLUE, eGL_ALPHA};
if(!rbCol[i] && id != ResourceId() &&
(HasExt[ARB_texture_swizzle] || HasExt[EXT_texture_swizzle]))
@@ -1789,6 +1813,55 @@ void GLReplay::SavePipelineState(uint32_t eventId)
(GLint *)&pipe.framebuffer.drawFBO.stencilAttachment.mipLevel,
(GLint *)&pipe.framebuffer.drawFBO.stencilAttachment.slice);
pipe.framebuffer.drawFBO.depthAttachment.numSlices = 1;
pipe.framebuffer.drawFBO.stencilAttachment.numSlices = 1;
ResourceId id = pipe.framebuffer.drawFBO.depthAttachment.resourceId;
if(!rbDepth && id != ResourceId())
{
// desktop GL allows layered attachments which attach all slices from 0 to N
if(!IsGLES)
{
GLint layered = 0;
GL.glGetNamedFramebufferAttachmentParameterivEXT(
curDrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_LAYERED, &layered);
if(layered)
{
pipe.framebuffer.drawFBO.depthAttachment.numSlices = m_pDriver->m_Textures[id].depth;
}
}
else
{
// on GLES there's an OVR extension that allows attaching multiple layers
if(HasExt[OVR_multiview])
{
GLint numViews = 0, startView = 0;
GL.glGetNamedFramebufferAttachmentParameterivEXT(
curDrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR,
&numViews);
GL.glGetNamedFramebufferAttachmentParameterivEXT(
curDrawFBO, eGL_DEPTH_ATTACHMENT,
eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR, &startView);
if(numViews > 1)
{
pipe.framebuffer.drawFBO.depthAttachment.numSlices = numViews;
pipe.framebuffer.drawFBO.depthAttachment.slice = startView;
}
}
}
if(pipe.framebuffer.drawFBO.stencilAttachment.resourceId ==
pipe.framebuffer.drawFBO.depthAttachment.resourceId)
{
pipe.framebuffer.drawFBO.stencilAttachment.slice =
pipe.framebuffer.drawFBO.depthAttachment.slice;
pipe.framebuffer.drawFBO.stencilAttachment.numSlices =
pipe.framebuffer.drawFBO.depthAttachment.numSlices;
}
}
pipe.framebuffer.drawFBO.drawBuffers.resize(numCols);
for(GLint i = 0; i < numCols; i++)
{
+9 -6
View File
@@ -228,9 +228,11 @@ public:
uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg,
uint32_t x, uint32_t y);
ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents);
ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents);
void BindFramebufferTexture(RenderOutputSubresource &sub, GLenum texBindingEnum, GLint numSamples);
ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, const Subresource &sub,
CompType typeCast);
@@ -242,8 +244,8 @@ public:
ResourceId CreateProxyBuffer(const BufferDescription &templateBuf);
void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize);
bool IsRenderOutput(ResourceId id);
RenderOutputSubresource GetRenderOutputSubresource(ResourceId id);
bool IsRenderOutput(ResourceId id) { return GetRenderOutputSubresource(id).mip != ~0U; }
void FileChanged() {}
void SetReplayData(GLWindowingData data);
@@ -386,7 +388,8 @@ private:
GLuint overlayTex;
GLuint overlayFBO;
GLuint overlayProg;
GLint overlayTexWidth, overlayTexHeight, overlayTexSamples, overlayTexMips;
GLint overlayTexWidth = 0, overlayTexHeight = 0, overlayTexSamples = 0, overlayTexMips = 0,
overlayTexSlices = 0;
GLuint UBOs[3];
+94 -10
View File
@@ -454,12 +454,34 @@ void VulkanDebugManager::PatchLineStripIndexBuffer(const DrawcallDescription *dr
indexCount = (uint32_t)patchedIndices.size();
}
ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents)
RenderOutputSubresource VulkanReplay::GetRenderOutputSubresource(ResourceId id)
{
id = GetResourceManager()->GetOriginalID(id);
for(const VKPipe::Attachment &att : m_VulkanPipelineState.currentPass.framebuffer.attachments)
{
if(att.viewResourceId == id || att.imageResourceId == id)
{
return RenderOutputSubresource(att.firstMip, att.firstSlice, att.numSlices);
}
}
return RenderOutputSubresource(~0U, ~0U, 0);
}
ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents)
{
const VkDevDispatchTable *vt = ObjDisp(m_Device);
RenderOutputSubresource sub = GetRenderOutputSubresource(texid);
if(sub.slice == ~0U)
{
RDCERR("Rendering overlay for %s couldn't find output to get subresource.", ToStr(texid).c_str());
sub = RenderOutputSubresource(0, 0, 1);
}
VulkanShaderCache *shaderCache = m_pDriver->GetShaderCache();
VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid];
@@ -486,11 +508,21 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
VkMarkerRegion::Begin(StringFormat::Fmt("RenderOverlay %d", overlay), cmd);
uint32_t multiviewMask = 0;
{
const VulkanCreationInfo::RenderPass &rp =
m_pDriver->m_CreationInfo.m_RenderPass[m_pDriver->m_RenderState.renderPass];
for(uint32_t v : rp.subpasses[m_pDriver->m_RenderState.subpass].multiviews)
multiviewMask |= 1U << v;
}
// if the overlay image is the wrong size, free it
if(m_Overlay.Image != VK_NULL_HANDLE &&
(iminfo.extent.width != m_Overlay.ImageDim.width ||
iminfo.extent.height != m_Overlay.ImageDim.height || iminfo.samples != m_Overlay.Samples ||
iminfo.mipLevels != m_Overlay.MipLevels))
iminfo.mipLevels != m_Overlay.MipLevels || iminfo.arrayLayers != m_Overlay.ArrayLayers ||
multiviewMask != m_Overlay.MultiViewMask))
{
m_pDriver->vkDestroyRenderPass(m_Device, m_Overlay.NoDepthRP, NULL);
m_pDriver->vkDestroyFramebuffer(m_Device, m_Overlay.NoDepthFB, NULL);
@@ -503,10 +535,17 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
m_Overlay.NoDepthFB = VK_NULL_HANDLE;
}
VkImageSubresourceRange subRange = {VK_IMAGE_ASPECT_COLOR_BIT, sub.mip, 1, 0, 1};
VkImageSubresourceRange subRange = {VK_IMAGE_ASPECT_COLOR_BIT, sub.mip, 1, sub.slice,
sub.numSlices};
const VkFormat overlayFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
VkRenderPassMultiviewCreateInfo multiviewRP = {VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO};
multiviewRP.correlationMaskCount = 1;
multiviewRP.pCorrelationMasks = &multiviewMask;
multiviewRP.subpassCount = 1;
multiviewRP.pViewMasks = &multiviewMask;
// create the overlay image if we don't have one already
// we go through the driver's creation functions so creation info
// is saved and the resources are registered as live resources for
@@ -516,7 +555,9 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
m_Overlay.ImageDim.width = iminfo.extent.width;
m_Overlay.ImageDim.height = iminfo.extent.height;
m_Overlay.MipLevels = iminfo.mipLevels;
m_Overlay.ArrayLayers = iminfo.arrayLayers;
m_Overlay.Samples = iminfo.samples;
m_Overlay.MultiViewMask = multiviewMask;
VkImageCreateInfo imInfo = {
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -526,7 +567,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
overlayFormat,
{m_Overlay.ImageDim.width, m_Overlay.ImageDim.height, 1},
(uint32_t)iminfo.mipLevels,
1,
(uint32_t)iminfo.arrayLayers,
iminfo.samples,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
@@ -608,16 +649,22 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
NULL, // dependencies
};
if(multiviewMask > 0)
rpinfo.pNext = &multiviewRP;
vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &m_Overlay.NoDepthRP);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
}
if(m_Overlay.MipLevel != sub.mip || m_Overlay.ImageView == VK_NULL_HANDLE)
if(m_Overlay.ViewMip != sub.mip || m_Overlay.ViewSlice != sub.slice ||
m_Overlay.ViewNumSlices != sub.numSlices || m_Overlay.ImageView == VK_NULL_HANDLE)
{
m_pDriver->vkDestroyFramebuffer(m_Device, m_Overlay.NoDepthFB, NULL);
m_pDriver->vkDestroyImageView(m_Device, m_Overlay.ImageView, NULL);
m_Overlay.MipLevel = sub.mip;
m_Overlay.ViewMip = sub.mip;
m_Overlay.ViewSlice = sub.slice;
m_Overlay.ViewNumSlices = sub.numSlices;
VkImageViewCreateInfo viewInfo = {
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
@@ -644,7 +691,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
&m_Overlay.ImageView,
RDCMAX(1U, m_Overlay.ImageDim.width >> sub.mip),
RDCMAX(1U, m_Overlay.ImageDim.height >> sub.mip),
1,
sub.numSlices,
};
vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &m_Overlay.NoDepthFB);
@@ -654,6 +701,37 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
// needs to match the depth texture type wherever our draw is.
}
{
VkImageSubresourceRange fullSubRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS,
0, VK_REMAINING_ARRAY_LAYERS};
VkImageMemoryBarrier barrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
NULL,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
Unwrap(m_Overlay.Image),
fullSubRange};
DoPipelineBarrier(cmd, 1, &barrier);
float black[4] = {};
vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_Overlay.Image), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
(VkClearColorValue *)black, 1, &fullSubRange);
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask =
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
DoPipelineBarrier(cmd, 1, &barrier);
}
const DrawcallDescription *mainDraw = m_pDriver->GetDrawcall(eventId);
// Secondary commands can't have render passes
@@ -1387,6 +1465,9 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
NULL, // dependencies
};
if(multiviewMask > 0)
rpinfo.pNext = &multiviewRP;
vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &depthRP);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
@@ -2169,6 +2250,9 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
NULL, // dependencies
};
if(multiviewMask > 0)
rpinfo.pNext = &multiviewRP;
vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &RP);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
@@ -2187,7 +2271,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, const Subresource &sub,
views,
RDCMAX(1U, m_Overlay.ImageDim.width >> sub.mip),
RDCMAX(1U, m_Overlay.ImageDim.height >> sub.mip),
1,
sub.numSlices,
};
vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &FB);
-11
View File
@@ -951,17 +951,6 @@ void VulkanReplay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len,
GetDebugManager()->GetBufferData(buff, offset, len, retData);
}
bool VulkanReplay::IsRenderOutput(ResourceId id)
{
for(const VKPipe::Attachment &att : m_VulkanPipelineState.currentPass.framebuffer.attachments)
{
if(att.viewResourceId == id || att.imageResourceId == id)
return true;
}
return false;
}
void VulkanReplay::FileChanged()
{
}
+7 -7
View File
@@ -386,9 +386,8 @@ public:
uint32_t PickVertex(uint32_t eventId, int32_t width, int32_t height, const MeshDisplay &cfg,
uint32_t x, uint32_t y);
ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents);
ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents);
ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, const Subresource &sub,
CompType typeCast);
@@ -400,8 +399,8 @@ public:
ResourceId CreateProxyBuffer(const BufferDescription &templateBuf);
void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize);
bool IsRenderOutput(ResourceId id);
RenderOutputSubresource GetRenderOutputSubresource(ResourceId id);
bool IsRenderOutput(ResourceId id) { return GetRenderOutputSubresource(id).mip != ~0U; }
void FileChanged();
void InitCallstackResolver();
@@ -597,12 +596,13 @@ private:
VkDeviceSize ImageMemSize = 0;
VkImage Image = VK_NULL_HANDLE;
VkExtent2D ImageDim = {0, 0};
int32_t MipLevels = 0;
int32_t MipLevels = 0, ArrayLayers = 0;
uint32_t MultiViewMask = 0;
VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT;
VkRenderPass NoDepthRP = VK_NULL_HANDLE;
// the view and framebuffer must be recreated if the mip changes, even if the image doesn't
uint32_t MipLevel = ~0U;
uint32_t ViewMip = ~0U, ViewSlice = ~0U, ViewNumSlices = ~0U;
VkImageView ImageView = VK_NULL_HANDLE;
VkFramebuffer NoDepthFB = VK_NULL_HANDLE;
+5 -4
View File
@@ -1746,10 +1746,11 @@ void DoSerialise(SerialiserType &ser, GLPipe::Attachment &el)
{
SERIALISE_MEMBER(resourceId);
SERIALISE_MEMBER(slice);
SERIALISE_MEMBER(numSlices);
SERIALISE_MEMBER(mipLevel);
SERIALISE_MEMBER(swizzle);
SIZE_CHECK(32);
SIZE_CHECK(40);
}
template <typename SerialiserType>
@@ -1762,7 +1763,7 @@ void DoSerialise(SerialiserType &ser, GLPipe::FBO &el)
SERIALISE_MEMBER(drawBuffers);
SERIALISE_MEMBER(readBuffer);
SIZE_CHECK(128);
SIZE_CHECK(144);
}
template <typename SerialiserType>
@@ -1783,7 +1784,7 @@ void DoSerialise(SerialiserType &ser, GLPipe::FrameBuffer &el)
SERIALISE_MEMBER(readFBO);
SERIALISE_MEMBER(blendState);
SIZE_CHECK(304);
SIZE_CHECK(336);
}
template <typename SerialiserType>
@@ -1832,7 +1833,7 @@ void DoSerialise(SerialiserType &ser, GLPipe::State &el)
SERIALISE_MEMBER(hints);
SIZE_CHECK(1984);
SIZE_CHECK(2016);
}
#pragma endregion OpenGL pipeline state
+12 -3
View File
@@ -107,6 +107,16 @@ class RDCFile;
class AMDRGPControl;
struct RenderOutputSubresource
{
RenderOutputSubresource(uint32_t mip, uint32_t slice, uint32_t numSlices)
: mip(mip), slice(slice), numSlices(numSlices)
{
}
uint32_t mip, slice, numSlices;
};
// these two interfaces define what an API driver implementation must provide
// to the replay. At minimum it must implement IRemoteDriver which contains
// all of the functionality that cannot be achieved elsewhere. An IReplayDriver
@@ -198,9 +208,8 @@ public:
virtual rdcarray<ShaderDebugState> ContinueDebug(ShaderDebugger *debugger) = 0;
virtual void FreeDebugger(ShaderDebugger *debugger) = 0;
virtual ResourceId RenderOverlay(ResourceId texid, const Subresource &sub, CompType typeCast,
FloatVector clearCol, DebugOverlay overlay, uint32_t eventId,
const rdcarray<uint32_t> &passEvents) = 0;
virtual ResourceId RenderOverlay(ResourceId texid, FloatVector clearCol, DebugOverlay overlay,
uint32_t eventId, const rdcarray<uint32_t> &passEvents) = 0;
virtual bool IsRenderOutput(ResourceId id) = 0;
+8 -7
View File
@@ -266,7 +266,9 @@ void ReplayOutput::RefreshOverlay()
if(m_Type == ReplayOutputType::Texture && m_RenderData.texDisplay.overlay != DebugOverlay::NoOverlay)
{
if(draw && m_pDevice->IsRenderOutput(m_RenderData.texDisplay.resourceId))
ResourceId id = m_pDevice->GetLiveID(m_RenderData.texDisplay.resourceId);
if(draw && m_pDevice->IsRenderOutput(id))
{
FloatVector f = m_RenderData.texDisplay.backgroundColor;
@@ -274,10 +276,8 @@ void ReplayOutput::RefreshOverlay()
f.y = ConvertLinearToSRGB(f.y);
f.z = ConvertLinearToSRGB(f.z);
m_OverlayResourceId = m_pDevice->RenderOverlay(
m_pDevice->GetLiveID(m_RenderData.texDisplay.resourceId),
m_RenderData.texDisplay.subresource, m_RenderData.texDisplay.typeCast, f,
m_RenderData.texDisplay.overlay, m_EventID, passEvents);
m_OverlayResourceId =
m_pDevice->RenderOverlay(id, f, m_RenderData.texDisplay.overlay, m_EventID, passEvents);
m_OverlayDirty = false;
}
else
@@ -733,9 +733,10 @@ void ReplayOutput::DisplayTex()
m_pDevice->RenderTexture(texDisplay);
ResourceId id = m_pDevice->GetLiveID(m_RenderData.texDisplay.resourceId);
if(m_RenderData.texDisplay.overlay != DebugOverlay::NoOverlay && draw &&
m_pDevice->IsRenderOutput(m_RenderData.texDisplay.resourceId) &&
m_RenderData.texDisplay.overlay != DebugOverlay::NaN &&
m_pDevice->IsRenderOutput(id) && m_RenderData.texDisplay.overlay != DebugOverlay::NaN &&
m_RenderData.texDisplay.overlay != DebugOverlay::Clipping && m_OverlayResourceId != ResourceId())
{
texDisplay.resourceId = m_pDevice->GetLiveID(m_OverlayResourceId);
@@ -146,6 +146,7 @@ float4 main() : SV_Target0
creator.GraphicsDesc.DepthStencilState.StencilEnable = FALSE;
creator.GraphicsDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
creator.PS(whitepsblob);
creator.DSV(DXGI_FORMAT_UNKNOWN);
ID3D12PipelineStatePtr whitepipe = creator;
ResourceBarrier(vb, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
+9 -4
View File
@@ -468,7 +468,7 @@ class Overlay_Test(rdtest.TestCase):
pipe: rd.PipeState = self.controller.GetPipelineState()
col_tex = pipe.GetOutputTargets()[0].resourceId
sub = rd.Subresource(pipe.GetOutputTargets()[0].firstMip, 0, 0)
sub = rd.Subresource(pipe.GetOutputTargets()[0].firstMip, pipe.GetOutputTargets()[0].firstSlice, 0)
for overlay in rd.DebugOverlay:
if overlay == rd.DebugOverlay.NoOverlay:
@@ -497,9 +497,14 @@ class Overlay_Test(rdtest.TestCase):
shift = 1
# All values in mip 0 should be 0 for all overlays
self.check_pixel_value(overlay_id, 200, 150, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(0, 0, 0))
self.check_pixel_value(overlay_id, 197, 147, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(0, 0, 0))
self.check_pixel_value(overlay_id, 203, 153, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(0, 0, 0))
self.check_pixel_value(overlay_id, 200 >> shift, 150 >> shift, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(0, 0, 0))
self.check_pixel_value(overlay_id, 197 >> shift, 147 >> shift, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(0, 0, 0))
self.check_pixel_value(overlay_id, 203 >> shift, 153 >> shift, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(0, 0, 0))
# Also for array slice 0 on this mip
self.check_pixel_value(overlay_id, 200 >> shift, 150 >> shift, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(mip, 0, 0))
self.check_pixel_value(overlay_id, 197 >> shift, 147 >> shift, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(mip, 0, 0))
self.check_pixel_value(overlay_id, 203 >> shift, 153 >> shift, [0.0, 0.0, 0.0, 0.0], sub=rd.Subresource(mip, 0, 0))
rdtest.log.success("Other mips are empty as expected for overlay {}".format(str(overlay)))