mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-11 17:20:56 +00:00
Add triangle size overlay, showing heatmap of triangles < 4x4 in area
This commit is contained in:
@@ -43,7 +43,7 @@ Current Common Feature set
|
||||
* Tabbed view for locking a view of a particular resource over time.
|
||||
* Pixel value picking.
|
||||
* Save (in theory) any type of texture and format to various formats, dds as well as regular png/jpg.
|
||||
* Several debug overlays for render targets - Wireframe, Depth pass/fail, Stencil pass/fail, Clipping (below black/above white points), NaN/-ve/INF highlight, quad overdraw.
|
||||
* Several debug overlays for render targets - Wireframe, Depth pass/fail, Stencil pass/fail, Clipping (below black/above white points), NaN/-ve/INF highlight, quad overdraw, triangle size.
|
||||
|
||||
* Custom visualisation shader support - e.g. decode custom packed formats or gbuffers.
|
||||
* Hot shader editing and replacement.
|
||||
|
||||
@@ -313,6 +313,10 @@ This is a powerful tool for quickly diagnosing issues and can be very useful for
|
||||
|
||||
* ``Quad Overdraw (Draw)`` will show a similar visualisation to the above option, but limited only to the current drawcall.
|
||||
|
||||
* ``Triangle Size (Pass)`` will show a visualisation of how much pixel area triangles in the meshes are covering in the 'pass' up to the selected draw, up to 4x4 pixels (16 square px) at most. If the current API does not have the concept of a pass, it is defined as all the drawcalls with the same set of render targets.
|
||||
|
||||
* ``Triangle Size (Draw)`` will show a similar visualisation to the above option, but limited only to the current drawcall.
|
||||
|
||||
.. note::
|
||||
|
||||
These overlays are all rendered after most image controls are applied. For this reason the range control, channel controls and custom shaders do not affect the overlays.
|
||||
|
||||
@@ -230,6 +230,8 @@ set(data
|
||||
data/glsl/text.vert
|
||||
data/glsl/array2ms.comp
|
||||
data/glsl/ms2array.comp
|
||||
data/glsl/trisize.frag
|
||||
data/glsl/trisize.geom
|
||||
data/sourcecodepro.ttf
|
||||
driver/vulkan/renderdoc.json)
|
||||
|
||||
|
||||
@@ -168,6 +168,8 @@ enum TextureDisplayOverlay
|
||||
eTexOverlay_ClearBeforeDraw,
|
||||
eTexOverlay_QuadOverdrawPass,
|
||||
eTexOverlay_QuadOverdrawDraw,
|
||||
eTexOverlay_TriangleSizePass,
|
||||
eTexOverlay_TriangleSizeDraw,
|
||||
};
|
||||
|
||||
enum FileType
|
||||
|
||||
@@ -39,6 +39,8 @@ DECLARE_EMBED(glsl_fixedcol_frag);
|
||||
DECLARE_EMBED(glsl_mesh_vert);
|
||||
DECLARE_EMBED(glsl_mesh_geom);
|
||||
DECLARE_EMBED(glsl_mesh_frag);
|
||||
DECLARE_EMBED(glsl_trisize_geom);
|
||||
DECLARE_EMBED(glsl_trisize_frag);
|
||||
DECLARE_EMBED(glsl_minmaxtile_comp);
|
||||
DECLARE_EMBED(glsl_minmaxresult_comp);
|
||||
DECLARE_EMBED(glsl_histogram_comp);
|
||||
|
||||
@@ -106,6 +106,8 @@ BINDING(0) uniform MeshUBOData
|
||||
uint displayFormat;
|
||||
uint homogenousInput;
|
||||
vec2 pointSpriteSize;
|
||||
uint rawoutput;
|
||||
vec3 padding;
|
||||
}
|
||||
INST_NAME(Mesh);
|
||||
|
||||
|
||||
@@ -64,7 +64,10 @@ void main(void)
|
||||
#ifdef VULKAN
|
||||
// GL->VK conventions
|
||||
gl_Position.y = -gl_Position.y;
|
||||
gl_Position.z = (gl_Position.z + gl_Position.w) / 2.0;
|
||||
if(Mesh.rawoutput == 0)
|
||||
{
|
||||
gl_Position.z = (gl_Position.z + gl_Position.w) / 2.0;
|
||||
}
|
||||
|
||||
gl_PointSize = 4.0f;
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#define NUM_RAMP_COLOURS 128
|
||||
|
||||
layout(binding = 1) uniform OverdrawRampColors
|
||||
{
|
||||
vec4 colors[NUM_RAMP_COLOURS];
|
||||
} ramp;
|
||||
|
||||
layout (location = 0) in float pixarea;
|
||||
|
||||
layout (location = 0) out vec4 color_out;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// bucket triangle area
|
||||
float area = max(pixarea, 0.001f);
|
||||
|
||||
int bucket = 2 + int( floor(20.0f - 20.1f * (1.0f - exp(-0.4f * area) ) ) );
|
||||
|
||||
color_out = ramp.colors[bucket];
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
layout(triangles, invocations = 1) in;
|
||||
layout(triangle_strip, max_vertices = 3) out;
|
||||
|
||||
layout (location = 0) in vec4 IN_secondary[3];
|
||||
layout (location = 1) in vec4 IN_norm[3];
|
||||
|
||||
layout (location = 0) out float OUT_pixarea;
|
||||
|
||||
in gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
float gl_PointSize;
|
||||
} gl_in[];
|
||||
|
||||
out gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
float gl_PointSize;
|
||||
};
|
||||
|
||||
layout(binding = 2) uniform ViewportSizeUBO
|
||||
{
|
||||
vec4 size;
|
||||
} viewport;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 a = gl_in[0].gl_Position.xy / gl_in[0].gl_Position.w;
|
||||
vec2 b = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w;
|
||||
vec2 c = gl_in[2].gl_Position.xy / gl_in[2].gl_Position.w;
|
||||
|
||||
a = (a * 0.5f + 0.5f) * viewport.size.xy;
|
||||
b = (b * 0.5f + 0.5f) * viewport.size.xy;
|
||||
c = (c * 0.5f + 0.5f) * viewport.size.xy;
|
||||
|
||||
float ab = length(a - b);
|
||||
float bc = length(b - c);
|
||||
float ca = length(c - a);
|
||||
|
||||
float s = (ab + bc + ca) / 2.0f;
|
||||
|
||||
float area = sqrt( s * (s - ab) * (s - bc) * (s - ca) );
|
||||
|
||||
for(int i=0; i < 3; i++)
|
||||
{
|
||||
gl_Position = gl_in[i].gl_Position;
|
||||
OUT_pixarea = area;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -65,6 +65,64 @@ wireframeV2F RENDERDOC_MeshVS(meshA2V IN, uint vid : SV_VertexID)
|
||||
return OUT;
|
||||
}
|
||||
|
||||
struct triSizeV2F
|
||||
{
|
||||
float4 pos : SV_Position;
|
||||
float pixarea : PixArea;
|
||||
};
|
||||
|
||||
cbuffer viewportCBuf : register(b0)
|
||||
{
|
||||
float4 viewport;
|
||||
};
|
||||
|
||||
[maxvertexcount(3)]
|
||||
void RENDERDOC_TriangleSizeGS(triangle wireframeV2F input[3], inout TriangleStream<triSizeV2F> TriStream)
|
||||
{
|
||||
triSizeV2F output;
|
||||
|
||||
float2 a = input[0].pos.xy / input[0].pos.w;
|
||||
float2 b = input[1].pos.xy / input[1].pos.w;
|
||||
float2 c = input[2].pos.xy / input[2].pos.w;
|
||||
|
||||
a = (a * 0.5f + 0.5f) * viewport.xy;
|
||||
b = (b * 0.5f + 0.5f) * viewport.xy;
|
||||
c = (c * 0.5f + 0.5f) * viewport.xy;
|
||||
|
||||
float ab = length(a - b);
|
||||
float bc = length(b - c);
|
||||
float ca = length(c - a);
|
||||
|
||||
float s = (ab + bc + ca) / 2.0f;
|
||||
|
||||
float area = sqrt( s * (s - ab) * (s - bc) * (s - ca) );
|
||||
|
||||
for(int i=0; i<3; i++)
|
||||
{
|
||||
output.pos = input[i].pos;
|
||||
output.pixarea = area;
|
||||
TriStream.Append(output);
|
||||
}
|
||||
TriStream.RestartStrip();
|
||||
}
|
||||
|
||||
#define NUM_RAMP_COLOURS 128
|
||||
|
||||
cbuffer triangleRampCBuf : register(b0)
|
||||
{
|
||||
const float4 overdrawRampColours[NUM_RAMP_COLOURS];
|
||||
};
|
||||
|
||||
float4 RENDERDOC_TriangleSizePS(triSizeV2F IN) : SV_Target0
|
||||
{
|
||||
// bucket triangle area
|
||||
float area = max(IN.pixarea, 0.001f);
|
||||
|
||||
int bucket = 2 + int( floor(20.0f - 20.1f * (1.0f - exp(-0.4f * area) ) ) );
|
||||
|
||||
return overdrawRampColours[bucket];
|
||||
}
|
||||
|
||||
[maxvertexcount(3)]
|
||||
void RENDERDOC_MeshGS(triangle wireframeV2F input[3], inout TriangleStream<wireframeV2F> TriStream)
|
||||
{
|
||||
|
||||
@@ -133,6 +133,8 @@ RESOURCE_glsl_quadwrite_frag TYPE_EMBED "glsl/quadwrite.frag"
|
||||
RESOURCE_glsl_mesh_comp TYPE_EMBED "glsl/mesh.comp"
|
||||
RESOURCE_glsl_array2ms_comp TYPE_EMBED "glsl/array2ms.comp"
|
||||
RESOURCE_glsl_ms2array_comp TYPE_EMBED "glsl/ms2array.comp"
|
||||
RESOURCE_glsl_trisize_geom TYPE_EMBED "glsl/trisize.geom"
|
||||
RESOURCE_glsl_trisize_frag TYPE_EMBED "glsl/trisize.frag"
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#define RESOURCE_glsl_mesh_comp 421
|
||||
#define RESOURCE_glsl_array2ms_comp 422
|
||||
#define RESOURCE_glsl_ms2array_comp 423
|
||||
#define RESOURCE_glsl_trisize_geom 424
|
||||
#define RESOURCE_glsl_trisize_frag 425
|
||||
|
||||
#if !defined(STRINGIZE)
|
||||
#define STRINGIZE2(a) #a
|
||||
|
||||
@@ -3854,6 +3854,167 @@ ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, FormatComponentTyp
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(overlay == eTexOverlay_TriangleSizeDraw || overlay == eTexOverlay_TriangleSizePass)
|
||||
{
|
||||
SCOPED_TIMER("Triangle size");
|
||||
|
||||
// ensure it will be recreated on next use
|
||||
SAFE_RELEASE(m_MeshDisplayLayout);
|
||||
m_PrevMeshFmt = ResourceFormat();
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC layoutdesc[2] = {};
|
||||
|
||||
layoutdesc[0].SemanticName = "pos";
|
||||
layoutdesc[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
|
||||
// dummy for vertex shader
|
||||
layoutdesc[1].SemanticName = "sec";
|
||||
layoutdesc[1].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
layoutdesc[1].InputSlot = 1;
|
||||
layoutdesc[1].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
|
||||
|
||||
HRESULT hr = m_pDevice->CreateInputLayout(layoutdesc, 2, m_DebugRender.MeshHomogVSBytecode,
|
||||
m_DebugRender.MeshHomogVSBytelen, &m_MeshDisplayLayout);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create m_MeshDisplayLayout %08x", hr);
|
||||
m_MeshDisplayLayout = NULL;
|
||||
}
|
||||
|
||||
DebugVertexCBuffer vertexData = {};
|
||||
vertexData.LineStrip = 0;
|
||||
vertexData.ModelViewProj = Matrix4f::Identity();
|
||||
vertexData.SpriteSize = Vec2f();
|
||||
FillCBuffer(m_DebugRender.GenericVSCBuffer, &vertexData, sizeof(DebugVertexCBuffer));
|
||||
|
||||
ID3D11Buffer *psbuf = MakeCBuffer(&overdrawRamp[0].x, sizeof(overdrawRamp));
|
||||
|
||||
Vec4f viewport = Vec4f((float)details.texWidth, (float)details.texHeight);
|
||||
ID3D11Buffer *gsbuf = MakeCBuffer(&viewport.x, sizeof(viewport));
|
||||
|
||||
float overlayConsts[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
m_pImmediateContext->ClearRenderTargetView(rtv, overlayConsts);
|
||||
|
||||
vector<uint32_t> events = passEvents;
|
||||
|
||||
if(overlay == eTexOverlay_TriangleSizeDraw)
|
||||
events.clear();
|
||||
|
||||
events.push_back(eventID);
|
||||
|
||||
if(overlay == eTexOverlay_TriangleSizePass)
|
||||
m_WrappedDevice->ReplayLog(0, events[0], eReplay_WithoutDraw);
|
||||
|
||||
events.push_back(eventID);
|
||||
|
||||
for(size_t i = 0; i < events.size(); i++)
|
||||
{
|
||||
D3D11RenderState oldstate = *m_WrappedContext->GetCurrentPipelineState();
|
||||
|
||||
D3D11_DEPTH_STENCIL_DESC dsdesc = {
|
||||
/*DepthEnable =*/TRUE,
|
||||
/*DepthWriteMask =*/D3D11_DEPTH_WRITE_MASK_ALL,
|
||||
/*DepthFunc =*/D3D11_COMPARISON_LESS,
|
||||
/*StencilEnable =*/FALSE,
|
||||
/*StencilReadMask =*/D3D11_DEFAULT_STENCIL_READ_MASK,
|
||||
/*StencilWriteMask =*/D3D11_DEFAULT_STENCIL_WRITE_MASK,
|
||||
/*FrontFace =*/{D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP,
|
||||
D3D11_COMPARISON_ALWAYS},
|
||||
/*BackFace =*/{D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP,
|
||||
D3D11_COMPARISON_ALWAYS},
|
||||
};
|
||||
ID3D11DepthStencilState *ds = NULL;
|
||||
|
||||
if(oldstate.OM.DepthStencilState)
|
||||
oldstate.OM.DepthStencilState->GetDesc(&dsdesc);
|
||||
|
||||
dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||
dsdesc.StencilWriteMask = 0;
|
||||
|
||||
m_WrappedDevice->CreateDepthStencilState(&dsdesc, &ds);
|
||||
|
||||
m_WrappedContext->OMSetDepthStencilState(ds, oldstate.OM.StencRef);
|
||||
|
||||
SAFE_RELEASE(ds);
|
||||
|
||||
const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(events[i]);
|
||||
|
||||
for(uint32_t inst = 0; draw && inst < RDCMAX(1U, draw->numInstances); inst++)
|
||||
{
|
||||
MeshFormat fmt = GetPostVSBuffers(events[i], inst, eMeshDataStage_GSOut);
|
||||
if(fmt.buf == ResourceId())
|
||||
fmt = GetPostVSBuffers(events[i], inst, eMeshDataStage_VSOut);
|
||||
|
||||
if(fmt.buf != ResourceId())
|
||||
{
|
||||
D3D11_PRIMITIVE_TOPOLOGY topo = MakeD3DPrimitiveTopology(fmt.topo);
|
||||
|
||||
ID3D11Buffer *ibuf = NULL;
|
||||
DXGI_FORMAT ifmt = DXGI_FORMAT_R16_UINT;
|
||||
UINT ioffs = (UINT)fmt.idxoffs;
|
||||
|
||||
ID3D11Buffer *vbs[2] = {NULL, NULL};
|
||||
UINT str[2] = {fmt.stride, 4};
|
||||
UINT offs[2] = {(UINT)fmt.offset, 0};
|
||||
|
||||
{
|
||||
auto it = WrappedID3D11Buffer::m_BufferList.find(fmt.buf);
|
||||
|
||||
if(it != WrappedID3D11Buffer::m_BufferList.end())
|
||||
vbs[0] = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer);
|
||||
|
||||
it = WrappedID3D11Buffer::m_BufferList.find(fmt.idxbuf);
|
||||
|
||||
if(it != WrappedID3D11Buffer::m_BufferList.end())
|
||||
ibuf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer);
|
||||
|
||||
if(fmt.idxByteWidth == 4)
|
||||
ifmt = DXGI_FORMAT_R32_UINT;
|
||||
}
|
||||
|
||||
m_pImmediateContext->IASetVertexBuffers(0, 1, vbs, str, offs);
|
||||
if(ibuf)
|
||||
m_pImmediateContext->IASetIndexBuffer(ibuf, ifmt, ioffs);
|
||||
else
|
||||
m_pImmediateContext->IASetIndexBuffer(NULL, DXGI_FORMAT_UNKNOWN, NULL);
|
||||
|
||||
m_pImmediateContext->IASetPrimitiveTopology(topo);
|
||||
|
||||
m_pImmediateContext->IASetInputLayout(m_MeshDisplayLayout);
|
||||
m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer);
|
||||
m_pImmediateContext->PSSetConstantBuffers(0, 1, &psbuf);
|
||||
m_pImmediateContext->GSSetConstantBuffers(0, 1, &gsbuf);
|
||||
m_pImmediateContext->VSSetShader(m_DebugRender.WireframeHomogVS, NULL, 0);
|
||||
m_pImmediateContext->GSSetShader(m_DebugRender.TriangleSizeGS, NULL, 0);
|
||||
m_pImmediateContext->PSSetShader(m_DebugRender.TriangleSizePS, NULL, 0);
|
||||
m_pImmediateContext->HSSetShader(NULL, NULL, 0);
|
||||
m_pImmediateContext->DSSetShader(NULL, NULL, 0);
|
||||
m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff);
|
||||
m_pImmediateContext->OMSetRenderTargets(
|
||||
1, &rtv, UNWRAP(WrappedID3D11DepthStencilView, oldstate.OM.DepthView));
|
||||
|
||||
if(ibuf)
|
||||
m_pImmediateContext->DrawIndexed(fmt.numVerts, 0, fmt.baseVertex);
|
||||
else
|
||||
m_pImmediateContext->Draw(fmt.numVerts, 0);
|
||||
}
|
||||
}
|
||||
|
||||
oldstate.ApplyState(m_WrappedContext);
|
||||
|
||||
if(overlay == eTexOverlay_TriangleSizePass)
|
||||
{
|
||||
m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw);
|
||||
|
||||
if(i + 1 < events.size())
|
||||
m_WrappedDevice->ReplayLog(events[i], events[i + 1], eReplay_WithoutDraw);
|
||||
}
|
||||
}
|
||||
|
||||
if(overlay == eTexOverlay_TriangleSizePass)
|
||||
m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw);
|
||||
}
|
||||
else if(overlay == eTexOverlay_QuadOverdrawPass || overlay == eTexOverlay_QuadOverdrawDraw)
|
||||
{
|
||||
SCOPED_TIMER("Quad Overdraw");
|
||||
|
||||
@@ -669,6 +669,11 @@ bool D3D11DebugManager::InitDebugRendering()
|
||||
m_DebugRender.MeshGS = MakeGShader(meshhlsl.c_str(), "RENDERDOC_MeshGS", "gs_4_0");
|
||||
m_DebugRender.MeshPS = MakePShader(meshhlsl.c_str(), "RENDERDOC_MeshPS", "ps_4_0");
|
||||
|
||||
m_DebugRender.TriangleSizeGS =
|
||||
MakeGShader(meshhlsl.c_str(), "RENDERDOC_TriangleSizeGS", "gs_4_0");
|
||||
m_DebugRender.TriangleSizePS =
|
||||
MakePShader(meshhlsl.c_str(), "RENDERDOC_TriangleSizePS", "ps_4_0");
|
||||
|
||||
m_DebugRender.MeshVSBytecode = new byte[bytecode.size()];
|
||||
m_DebugRender.MeshVSBytelen = (uint32_t)bytecode.size();
|
||||
memcpy(m_DebugRender.MeshVSBytecode, &bytecode[0], bytecode.size());
|
||||
|
||||
@@ -447,6 +447,8 @@ private:
|
||||
SAFE_RELEASE(MeshVS);
|
||||
SAFE_RELEASE(MeshGS);
|
||||
SAFE_RELEASE(MeshPS);
|
||||
SAFE_RELEASE(TriangleSizeGS);
|
||||
SAFE_RELEASE(TriangleSizePS);
|
||||
SAFE_RELEASE(FullscreenVS);
|
||||
SAFE_RELEASE(WireframeVS);
|
||||
SAFE_RELEASE(WireframeHomogVS);
|
||||
@@ -528,8 +530,9 @@ private:
|
||||
ID3D11Buffer *GenericPSCBuffer;
|
||||
ID3D11Buffer *PublicCBuffers[20];
|
||||
ID3D11VertexShader *GenericVS, *WireframeVS, *MeshVS, *WireframeHomogVS, *FullscreenVS;
|
||||
ID3D11GeometryShader *MeshGS;
|
||||
ID3D11PixelShader *TexDisplayPS, *OverlayPS, *WireframePS, *MeshPS, *CheckerboardPS;
|
||||
ID3D11GeometryShader *MeshGS, *TriangleSizeGS;
|
||||
ID3D11PixelShader *TexDisplayPS, *OverlayPS, *WireframePS, *MeshPS, *CheckerboardPS,
|
||||
*TriangleSizePS;
|
||||
ID3D11PixelShader *OutlinePS;
|
||||
ID3D11PixelShader *CopyMSToArrayPS, *CopyArrayToMSPS;
|
||||
ID3D11PixelShader *FloatCopyMSToArrayPS, *FloatCopyArrayToMSPS;
|
||||
|
||||
@@ -319,6 +319,11 @@ void GLReplay::InitDebugData()
|
||||
DebugData.meshProg = CreateShaderProgram(vs, fs);
|
||||
DebugData.meshgsProg = CreateShaderProgram(vs, fs, gs);
|
||||
|
||||
GenerateGLSLShader(fs, eShaderGLSL, "", GetEmbeddedResource(glsl_trisize_frag), 420);
|
||||
GenerateGLSLShader(gs, eShaderGLSL, "", GetEmbeddedResource(glsl_trisize_geom), 420);
|
||||
|
||||
DebugData.trisizeProg = CreateShaderProgram(vs, fs, gs);
|
||||
|
||||
gl.glGenProgramPipelines(1, &DebugData.texDisplayPipe);
|
||||
|
||||
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.4f);
|
||||
@@ -345,10 +350,11 @@ void GLReplay::InitDebugData()
|
||||
for(size_t i = 0; i < ARRAY_COUNT(DebugData.UBOs); i++)
|
||||
{
|
||||
gl.glBindBuffer(eGL_UNIFORM_BUFFER, DebugData.UBOs[i]);
|
||||
gl.glNamedBufferDataEXT(DebugData.UBOs[i], 512, NULL, eGL_DYNAMIC_DRAW);
|
||||
RDCCOMPILE_ASSERT(sizeof(TexDisplayUBOData) < 512, "texdisplay UBO too large");
|
||||
RDCCOMPILE_ASSERT(sizeof(FontUBOData) < 512, "texdisplay UBO too large");
|
||||
RDCCOMPILE_ASSERT(sizeof(HistogramUBOData) < 512, "texdisplay UBO too large");
|
||||
gl.glNamedBufferDataEXT(DebugData.UBOs[i], 2048, NULL, eGL_DYNAMIC_DRAW);
|
||||
RDCCOMPILE_ASSERT(sizeof(TexDisplayUBOData) <= 2048, "UBO too small");
|
||||
RDCCOMPILE_ASSERT(sizeof(FontUBOData) <= 2048, "UBO too small");
|
||||
RDCCOMPILE_ASSERT(sizeof(HistogramUBOData) <= 2048, "UBO too small");
|
||||
RDCCOMPILE_ASSERT(sizeof(overdrawRamp) <= 2048, "UBO too small");
|
||||
}
|
||||
|
||||
DebugData.overlayTexWidth = DebugData.overlayTexHeight = 0;
|
||||
@@ -610,6 +616,7 @@ void GLReplay::DeleteDebugData()
|
||||
gl.glDeleteProgram(DebugData.fixedcolFSProg);
|
||||
gl.glDeleteProgram(DebugData.meshProg);
|
||||
gl.glDeleteProgram(DebugData.meshgsProg);
|
||||
gl.glDeleteProgram(DebugData.trisizeProg);
|
||||
|
||||
gl.glDeleteSamplers(1, &DebugData.linearSampler);
|
||||
gl.glDeleteSamplers(1, &DebugData.pointSampler);
|
||||
@@ -2297,6 +2304,379 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FormatComponentType typeHin
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(overlay == eTexOverlay_TriangleSizeDraw || overlay == eTexOverlay_TriangleSizePass)
|
||||
{
|
||||
SCOPED_TIMER("Triangle Size");
|
||||
|
||||
float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
gl.glClearBufferfv(eGL_COLOR, 0, black);
|
||||
|
||||
MeshUBOData uboParams = {};
|
||||
uboParams.homogenousInput = 1;
|
||||
uboParams.invProj = Matrix4f::Identity();
|
||||
uboParams.mvp = Matrix4f::Identity();
|
||||
|
||||
gl.glBindBuffer(eGL_COPY_WRITE_BUFFER, DebugData.UBOs[0]);
|
||||
|
||||
MeshUBOData *uboptr =
|
||||
(MeshUBOData *)gl.glMapBufferRange(eGL_COPY_WRITE_BUFFER, 0, sizeof(MeshUBOData),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
*uboptr = uboParams;
|
||||
gl.glUnmapBuffer(eGL_COPY_WRITE_BUFFER);
|
||||
|
||||
gl.glBindBuffer(eGL_COPY_WRITE_BUFFER, DebugData.UBOs[1]);
|
||||
Vec4f *v = (Vec4f *)gl.glMapBufferRange(eGL_COPY_WRITE_BUFFER, 0, sizeof(overdrawRamp),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
memcpy(v, overdrawRamp, sizeof(overdrawRamp));
|
||||
gl.glUnmapBuffer(eGL_COPY_WRITE_BUFFER);
|
||||
|
||||
gl.glBindBuffer(eGL_COPY_WRITE_BUFFER, DebugData.UBOs[2]);
|
||||
v = (Vec4f *)gl.glMapBufferRange(eGL_COPY_WRITE_BUFFER, 0, sizeof(Vec4f),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
*v = Vec4f((float)texDetails.width, (float)texDetails.height);
|
||||
gl.glUnmapBuffer(eGL_COPY_WRITE_BUFFER);
|
||||
|
||||
vector<uint32_t> events = passEvents;
|
||||
|
||||
if(overlay == eTexOverlay_QuadOverdrawDraw)
|
||||
events.clear();
|
||||
|
||||
events.push_back(eventID);
|
||||
|
||||
if(!events.empty())
|
||||
{
|
||||
if(overlay == eTexOverlay_TriangleSizePass)
|
||||
ReplayLog(events[0], eReplay_WithoutDraw);
|
||||
else
|
||||
rs.ApplyState(m_pDriver->GetCtx(), m_pDriver);
|
||||
|
||||
// this all happens on the replay context so we need a temp FBO/VAO
|
||||
GLuint overlayFBO = 0, tempVAO = 0;
|
||||
gl.glGenFramebuffers(1, &overlayFBO);
|
||||
gl.glGenVertexArrays(1, &tempVAO);
|
||||
|
||||
for(size_t i = 0; i < events.size(); i++)
|
||||
{
|
||||
GLboolean blending = GL_FALSE;
|
||||
GLint depthwritemask = 1;
|
||||
GLint stencilfmask = 0xff, stencilbmask = 0xff;
|
||||
GLuint drawFBO = 0, prevVAO = 0;
|
||||
struct UBO
|
||||
{
|
||||
GLuint buf;
|
||||
GLint64 offs;
|
||||
GLint64 size;
|
||||
} ubos[3];
|
||||
|
||||
// save the state we're going to mess with
|
||||
{
|
||||
gl.glGetIntegerv(eGL_DEPTH_WRITEMASK, &depthwritemask);
|
||||
gl.glGetIntegerv(eGL_STENCIL_WRITEMASK, &stencilfmask);
|
||||
gl.glGetIntegerv(eGL_STENCIL_BACK_WRITEMASK, &stencilbmask);
|
||||
|
||||
gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&drawFBO);
|
||||
gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&prevVAO);
|
||||
|
||||
blending = gl.glIsEnabled(eGL_BLEND);
|
||||
|
||||
for(uint32_t u = 0; u < 3; u++)
|
||||
{
|
||||
gl.glGetIntegeri_v(eGL_UNIFORM_BUFFER_BINDING, u, (GLint *)&ubos[u].buf);
|
||||
gl.glGetInteger64i_v(eGL_UNIFORM_BUFFER_START, u, (GLint64 *)&ubos[u].offs);
|
||||
gl.glGetInteger64i_v(eGL_UNIFORM_BUFFER_SIZE, u, (GLint64 *)&ubos[u].size);
|
||||
}
|
||||
}
|
||||
|
||||
// disable depth and stencil writes
|
||||
gl.glDepthMask(GL_FALSE);
|
||||
gl.glStencilMask(GL_FALSE);
|
||||
|
||||
// disable blending
|
||||
gl.glDisable(eGL_BLEND);
|
||||
|
||||
// bind our UBOs
|
||||
gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]);
|
||||
gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 1, DebugData.UBOs[1]);
|
||||
gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 2, DebugData.UBOs[2]);
|
||||
|
||||
const GLenum att = eGL_DEPTH_ATTACHMENT;
|
||||
GLuint depthObj = 0;
|
||||
GLint type = 0, level = 0, layered = 0, layer = 0;
|
||||
|
||||
// fetch the details of the 'real' depth attachment
|
||||
gl.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
drawFBO, att, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&depthObj);
|
||||
gl.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
drawFBO, att, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
|
||||
|
||||
if(depthObj)
|
||||
{
|
||||
gl.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
drawFBO, att, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &level);
|
||||
gl.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
drawFBO, att, eGL_FRAMEBUFFER_ATTACHMENT_LAYERED, &layered);
|
||||
|
||||
layered = (layered != 0);
|
||||
|
||||
layer = 0;
|
||||
if(layered == 0)
|
||||
gl.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
drawFBO, att, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, &layer);
|
||||
|
||||
if(type != eGL_RENDERBUFFER)
|
||||
{
|
||||
ResourceId id = m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, depthObj));
|
||||
WrappedOpenGL::TextureData &details = m_pDriver->m_Textures[id];
|
||||
|
||||
if(details.curType == eGL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
GLenum face;
|
||||
gl.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
drawFBO, att, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint *)&face);
|
||||
|
||||
layer = CubeTargetIndex(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind our FBO
|
||||
gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, overlayFBO);
|
||||
gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.overlayTex, 0);
|
||||
|
||||
// now apply the depth texture binding
|
||||
if(depthObj)
|
||||
{
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
{
|
||||
gl.glNamedFramebufferRenderbufferEXT(overlayFBO, att, eGL_RENDERBUFFER, depthObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!layered)
|
||||
{
|
||||
// we use old-style non-DSA for this because binding cubemap faces with EXT_dsa
|
||||
// is completely messed up and broken
|
||||
|
||||
// if obj is a cubemap use face-specific targets
|
||||
ResourceId id = m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, depthObj));
|
||||
WrappedOpenGL::TextureData &details = m_pDriver->m_Textures[id];
|
||||
|
||||
if(details.curType == eGL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
GLenum faces[] = {
|
||||
eGL_TEXTURE_CUBE_MAP_POSITIVE_X, eGL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
eGL_TEXTURE_CUBE_MAP_POSITIVE_Y, eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
eGL_TEXTURE_CUBE_MAP_POSITIVE_Z, eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
|
||||
};
|
||||
|
||||
if(layer < 6)
|
||||
{
|
||||
gl.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, att, faces[layer], depthObj, level);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN(
|
||||
"Invalid layer %u used to bind cubemap to framebuffer. Binding POSITIVE_X");
|
||||
gl.glFramebufferTexture2D(eGL_DRAW_FRAMEBUFFER, att, faces[0], depthObj, level);
|
||||
}
|
||||
}
|
||||
else if(details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY ||
|
||||
details.curType == eGL_TEXTURE_1D_ARRAY ||
|
||||
details.curType == eGL_TEXTURE_2D_ARRAY)
|
||||
{
|
||||
gl.glFramebufferTextureLayer(eGL_DRAW_FRAMEBUFFER, att, depthObj, level, layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCASSERT(layer == 0);
|
||||
gl.glNamedFramebufferTextureEXT(overlayFBO, att, depthObj, level);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.glNamedFramebufferTextureEXT(overlayFBO, att, depthObj, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLuint prog = 0, pipe = 0;
|
||||
gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prog);
|
||||
gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&pipe);
|
||||
|
||||
gl.glUseProgram(DebugData.trisizeProg);
|
||||
gl.glBindProgramPipeline(0);
|
||||
|
||||
const FetchDrawcall *draw = m_pDriver->GetDrawcall(events[i]);
|
||||
|
||||
for(uint32_t inst = 0; draw && inst < RDCMAX(1U, draw->numInstances); inst++)
|
||||
{
|
||||
MeshFormat fmt = GetPostVSBuffers(events[i], inst, eMeshDataStage_GSOut);
|
||||
if(fmt.buf == ResourceId())
|
||||
fmt = GetPostVSBuffers(events[i], inst, eMeshDataStage_VSOut);
|
||||
|
||||
if(fmt.buf != ResourceId())
|
||||
{
|
||||
GLenum topo = MakeGLPrimitiveTopology(fmt.topo);
|
||||
|
||||
gl.glBindVertexArray(tempVAO);
|
||||
|
||||
{
|
||||
if(fmt.specialFormat != eSpecial_Unknown)
|
||||
{
|
||||
if(fmt.specialFormat == eSpecial_R10G10B10A2)
|
||||
{
|
||||
if(fmt.compType == eCompType_UInt)
|
||||
gl.glVertexAttribIFormat(0, 4, eGL_UNSIGNED_INT_2_10_10_10_REV, 0);
|
||||
if(fmt.compType == eCompType_SInt)
|
||||
gl.glVertexAttribIFormat(0, 4, eGL_INT_2_10_10_10_REV, 0);
|
||||
}
|
||||
else if(fmt.specialFormat == eSpecial_R11G11B10)
|
||||
{
|
||||
gl.glVertexAttribFormat(0, 4, eGL_UNSIGNED_INT_10F_11F_11F_REV, GL_FALSE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("Unsupported special vertex attribute format: %x", fmt.specialFormat);
|
||||
}
|
||||
}
|
||||
else if(fmt.compType == eCompType_Float || fmt.compType == eCompType_UNorm ||
|
||||
fmt.compType == eCompType_SNorm)
|
||||
{
|
||||
GLenum fmttype = eGL_UNSIGNED_INT;
|
||||
|
||||
if(fmt.compByteWidth == 4)
|
||||
{
|
||||
if(fmt.compType == eCompType_Float)
|
||||
fmttype = eGL_FLOAT;
|
||||
else if(fmt.compType == eCompType_UNorm)
|
||||
fmttype = eGL_UNSIGNED_INT;
|
||||
else if(fmt.compType == eCompType_SNorm)
|
||||
fmttype = eGL_INT;
|
||||
}
|
||||
else if(fmt.compByteWidth == 2)
|
||||
{
|
||||
if(fmt.compType == eCompType_Float)
|
||||
fmttype = eGL_HALF_FLOAT;
|
||||
else if(fmt.compType == eCompType_UNorm)
|
||||
fmttype = eGL_UNSIGNED_SHORT;
|
||||
else if(fmt.compType == eCompType_SNorm)
|
||||
fmttype = eGL_SHORT;
|
||||
}
|
||||
else if(fmt.compByteWidth == 1)
|
||||
{
|
||||
if(fmt.compType == eCompType_UNorm)
|
||||
fmttype = eGL_UNSIGNED_BYTE;
|
||||
else if(fmt.compType == eCompType_SNorm)
|
||||
fmttype = eGL_BYTE;
|
||||
}
|
||||
|
||||
gl.glVertexAttribFormat(0, fmt.compCount, fmttype, fmt.compType != eCompType_Float,
|
||||
0);
|
||||
}
|
||||
else if(fmt.compType == eCompType_UInt || fmt.compType == eCompType_SInt)
|
||||
{
|
||||
GLenum fmttype = eGL_UNSIGNED_INT;
|
||||
|
||||
if(fmt.compByteWidth == 4)
|
||||
{
|
||||
if(fmt.compType == eCompType_UInt)
|
||||
fmttype = eGL_UNSIGNED_INT;
|
||||
else if(fmt.compType == eCompType_SInt)
|
||||
fmttype = eGL_INT;
|
||||
}
|
||||
else if(fmt.compByteWidth == 2)
|
||||
{
|
||||
if(fmt.compType == eCompType_UInt)
|
||||
fmttype = eGL_UNSIGNED_SHORT;
|
||||
else if(fmt.compType == eCompType_SInt)
|
||||
fmttype = eGL_SHORT;
|
||||
}
|
||||
else if(fmt.compByteWidth == 1)
|
||||
{
|
||||
if(fmt.compType == eCompType_UInt)
|
||||
fmttype = eGL_UNSIGNED_BYTE;
|
||||
else if(fmt.compType == eCompType_SInt)
|
||||
fmttype = eGL_BYTE;
|
||||
}
|
||||
|
||||
gl.glVertexAttribIFormat(0, fmt.compCount, fmttype, 0);
|
||||
}
|
||||
else if(fmt.compType == eCompType_Double)
|
||||
{
|
||||
gl.glVertexAttribLFormat(0, fmt.compCount, eGL_DOUBLE, 0);
|
||||
}
|
||||
|
||||
GLuint vb = m_pDriver->GetResourceManager()->GetCurrentResource(fmt.buf).name;
|
||||
gl.glBindVertexBuffer(0, vb, (GLintptr)fmt.offset, fmt.stride);
|
||||
}
|
||||
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
gl.glDisableVertexAttribArray(1);
|
||||
|
||||
if(fmt.idxbuf != ResourceId())
|
||||
{
|
||||
GLenum idxtype = eGL_UNSIGNED_BYTE;
|
||||
if(fmt.idxByteWidth == 2)
|
||||
idxtype = eGL_UNSIGNED_SHORT;
|
||||
else if(fmt.idxByteWidth == 4)
|
||||
idxtype = eGL_UNSIGNED_INT;
|
||||
|
||||
GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(fmt.idxbuf).name;
|
||||
gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib);
|
||||
gl.glDrawElementsBaseVertex(topo, fmt.numVerts, idxtype,
|
||||
(const void *)uintptr_t(fmt.idxoffs), fmt.baseVertex);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.glDrawArrays(topo, 0, fmt.numVerts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pop the state that we messed with
|
||||
{
|
||||
gl.glBindProgramPipeline(pipe);
|
||||
gl.glUseProgram(prog);
|
||||
|
||||
if(blending)
|
||||
gl.glEnable(eGL_BLEND);
|
||||
else
|
||||
gl.glDisable(eGL_BLEND);
|
||||
|
||||
// restore the previous FBO/VAO
|
||||
gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, drawFBO);
|
||||
gl.glBindVertexArray(prevVAO);
|
||||
|
||||
for(uint32_t u = 0; u < 3; u++)
|
||||
{
|
||||
if(ubos[u].buf == 0 || (ubos[u].offs == 0 && ubos[u].size == 0))
|
||||
gl.glBindBufferBase(eGL_UNIFORM_BUFFER, u, ubos[u].buf);
|
||||
else
|
||||
gl.glBindBufferRange(eGL_UNIFORM_BUFFER, u, ubos[u].buf, (GLintptr)ubos[u].offs,
|
||||
(GLsizeiptr)ubos[u].size);
|
||||
}
|
||||
|
||||
gl.glDepthMask(depthwritemask ? GL_TRUE : GL_FALSE);
|
||||
gl.glStencilMaskSeparate(eGL_FRONT, (GLuint)stencilfmask);
|
||||
gl.glStencilMaskSeparate(eGL_BACK, (GLuint)stencilbmask);
|
||||
}
|
||||
|
||||
if(overlay == eTexOverlay_TriangleSizePass)
|
||||
{
|
||||
m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw);
|
||||
|
||||
if(i + 1 < events.size())
|
||||
m_pDriver->ReplayLog(events[i], events[i + 1], eReplay_WithoutDraw);
|
||||
}
|
||||
}
|
||||
|
||||
gl.glDeleteFramebuffers(1, &overlayFBO);
|
||||
gl.glDeleteVertexArrays(1, &tempVAO);
|
||||
|
||||
if(overlay == eTexOverlay_TriangleSizePass)
|
||||
ReplayLog(eventID, eReplay_WithoutDraw);
|
||||
}
|
||||
}
|
||||
else if(overlay == eTexOverlay_QuadOverdrawDraw || overlay == eTexOverlay_QuadOverdrawPass)
|
||||
{
|
||||
if(DebugData.quadoverdraw420)
|
||||
|
||||
@@ -312,6 +312,7 @@ private:
|
||||
|
||||
GLuint meshProg;
|
||||
GLuint meshgsProg;
|
||||
GLuint trisizeProg;
|
||||
|
||||
GLuint meshVAO;
|
||||
GLuint axisVAO;
|
||||
@@ -337,7 +338,7 @@ private:
|
||||
GLuint overlayPipe;
|
||||
GLint overlayTexWidth, overlayTexHeight;
|
||||
|
||||
GLuint UBOs[2];
|
||||
GLuint UBOs[3];
|
||||
|
||||
GLuint readFBO;
|
||||
|
||||
|
||||
@@ -302,6 +302,12 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
RDCEraseEl(m_QuadResolvePipeline);
|
||||
m_QuadSPIRV = NULL;
|
||||
|
||||
m_TriSizeDescSetLayout = VK_NULL_HANDLE;
|
||||
m_TriSizeDescSet = VK_NULL_HANDLE;
|
||||
m_TriSizePipeLayout = VK_NULL_HANDLE;
|
||||
m_TriSizeGSModule = VK_NULL_HANDLE;
|
||||
m_TriSizeFSModule = VK_NULL_HANDLE;
|
||||
|
||||
m_MeshDescSetLayout = VK_NULL_HANDLE;
|
||||
m_MeshPipeLayout = VK_NULL_HANDLE;
|
||||
m_MeshDescSet = VK_NULL_HANDLE;
|
||||
@@ -405,7 +411,7 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
9 + ARRAY_COUNT(m_TexDisplayDescSet),
|
||||
10 + ARRAY_COUNT(m_TexDisplayDescSet),
|
||||
ARRAY_COUNT(replayDescPoolTypes),
|
||||
&replayDescPoolTypes[0],
|
||||
};
|
||||
@@ -666,7 +672,7 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
};
|
||||
|
||||
// declare a few more misc things that are needed on both paths
|
||||
VkDescriptorBufferInfo bufInfo[7];
|
||||
VkDescriptorBufferInfo bufInfo[8];
|
||||
RDCEraseEl(bufInfo);
|
||||
|
||||
vector<string> sources;
|
||||
@@ -1213,6 +1219,32 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
|
||||
{
|
||||
VkDescriptorSetLayoutBinding layoutBinding[] = {
|
||||
{
|
||||
0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL,
|
||||
},
|
||||
{
|
||||
1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL,
|
||||
},
|
||||
{
|
||||
2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL,
|
||||
},
|
||||
};
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = {
|
||||
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
ARRAY_COUNT(layoutBinding),
|
||||
&layoutBinding[0],
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL,
|
||||
&m_TriSizeDescSetLayout);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
|
||||
{
|
||||
VkDescriptorSetLayoutBinding layoutBinding[] = {
|
||||
{
|
||||
@@ -1295,6 +1327,11 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_QuadResolvePipeLayout);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
pipeLayoutInfo.pSetLayouts = &m_TriSizeDescSetLayout;
|
||||
|
||||
vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_TriSizePipeLayout);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
pipeLayoutInfo.pSetLayouts = &m_OutlineDescSetLayout;
|
||||
|
||||
vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_OutlinePipeLayout);
|
||||
@@ -1334,6 +1371,10 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_QuadDescSet);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
descSetAllocInfo.pSetLayouts = &m_TriSizeDescSetLayout;
|
||||
vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_TriSizeDescSet);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
descSetAllocInfo.pSetLayouts = &m_OutlineDescSetLayout;
|
||||
vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_OutlineDescSet);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
@@ -1390,12 +1431,13 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
GetEmbeddedResource(glsl_histogram_comp), GetEmbeddedResource(glsl_outline_frag),
|
||||
GetEmbeddedResource(glsl_quadresolve_frag), GetEmbeddedResource(glsl_quadwrite_frag),
|
||||
GetEmbeddedResource(glsl_mesh_comp), GetEmbeddedResource(glsl_ms2array_comp),
|
||||
GetEmbeddedResource(glsl_trisize_geom), GetEmbeddedResource(glsl_trisize_frag),
|
||||
};
|
||||
|
||||
SPIRVShaderStage shaderStages[] = {
|
||||
eSPIRVVertex, eSPIRVFragment, eSPIRVFragment, eSPIRVVertex, eSPIRVGeometry,
|
||||
eSPIRVFragment, eSPIRVCompute, eSPIRVCompute, eSPIRVCompute, eSPIRVFragment,
|
||||
eSPIRVFragment, eSPIRVFragment, eSPIRVCompute, eSPIRVCompute,
|
||||
eSPIRVVertex, eSPIRVFragment, eSPIRVFragment, eSPIRVVertex, eSPIRVGeometry, eSPIRVFragment,
|
||||
eSPIRVCompute, eSPIRVCompute, eSPIRVCompute, eSPIRVFragment, eSPIRVFragment, eSPIRVFragment,
|
||||
eSPIRVCompute, eSPIRVCompute, eSPIRVGeometry, eSPIRVFragment,
|
||||
};
|
||||
|
||||
enum shaderIdx
|
||||
@@ -1414,6 +1456,8 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
QUADWRITEFS,
|
||||
MESHCS,
|
||||
MS2ARRAYCS,
|
||||
TRISIZEGS,
|
||||
TRISIZEFS,
|
||||
NUM_SHADERS,
|
||||
};
|
||||
|
||||
@@ -1733,6 +1777,14 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
{
|
||||
m_MeshModules[2] = module[i];
|
||||
}
|
||||
else if(i == TRISIZEGS)
|
||||
{
|
||||
m_TriSizeGSModule = module[i];
|
||||
}
|
||||
else if(i == TRISIZEFS)
|
||||
{
|
||||
m_TriSizeFSModule = module[i];
|
||||
}
|
||||
else if(i == BLITVS)
|
||||
{
|
||||
m_BlitVSModule = module[i];
|
||||
@@ -1919,6 +1971,8 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
memcpy(ramp, overdrawRamp, sizeof(overdrawRamp));
|
||||
m_OverdrawRampUBO.Unmap();
|
||||
|
||||
m_TriSizeUBO.Create(driver, dev, sizeof(Vec4f), 4096, 0);
|
||||
|
||||
// pick pixel data
|
||||
{
|
||||
// create image
|
||||
@@ -2115,6 +2169,7 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
m_MeshPickUBO.FillDescriptor(bufInfo[4]);
|
||||
m_MeshPickResult.FillDescriptor(bufInfo[5]);
|
||||
m_ArrayMSUBO.FillDescriptor(bufInfo[6]);
|
||||
m_TriSizeUBO.FillDescriptor(bufInfo[7]);
|
||||
|
||||
VkWriteDescriptorSet analysisSetWrites[] = {
|
||||
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_CheckerboardDescSet), 0, 0, 1,
|
||||
@@ -2131,6 +2186,8 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev)
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &bufInfo[5], NULL},
|
||||
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 2, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, NULL, &bufInfo[6], NULL},
|
||||
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_TriSizeDescSet), 1, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, NULL, &bufInfo[3], NULL},
|
||||
};
|
||||
|
||||
ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(analysisSetWrites), analysisSetWrites,
|
||||
@@ -2173,6 +2230,9 @@ VulkanDebugManager::~VulkanDebugManager()
|
||||
for(size_t i = 0; i < ARRAY_COUNT(m_MeshModules); i++)
|
||||
m_pDriver->vkDestroyShaderModule(dev, m_MeshModules[i], NULL);
|
||||
|
||||
m_pDriver->vkDestroyShaderModule(dev, m_TriSizeGSModule, NULL);
|
||||
m_pDriver->vkDestroyShaderModule(dev, m_TriSizeFSModule, NULL);
|
||||
|
||||
m_pDriver->vkDestroyDescriptorPool(dev, m_DescriptorPool, NULL);
|
||||
|
||||
m_pDriver->vkDestroySampler(dev, m_LinearSampler, NULL);
|
||||
@@ -2294,6 +2354,9 @@ VulkanDebugManager::~VulkanDebugManager()
|
||||
m_pDriver->vkDestroyImage(dev, m_OverlayImage, NULL);
|
||||
m_pDriver->vkFreeMemory(dev, m_OverlayImageMem, NULL);
|
||||
|
||||
m_pDriver->vkDestroyDescriptorSetLayout(dev, m_TriSizeDescSetLayout, NULL);
|
||||
m_pDriver->vkDestroyPipelineLayout(dev, m_TriSizePipeLayout, NULL);
|
||||
|
||||
m_pDriver->vkDestroyDescriptorSetLayout(dev, m_QuadDescSetLayout, NULL);
|
||||
m_pDriver->vkDestroyPipelineLayout(dev, m_QuadResolvePipeLayout, NULL);
|
||||
for(size_t i = 0; i < ARRAY_COUNT(m_QuadResolvePipeline); i++)
|
||||
@@ -5365,6 +5428,433 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
else if(overlay == eTexOverlay_TriangleSizePass || overlay == eTexOverlay_TriangleSizeDraw)
|
||||
{
|
||||
VulkanRenderState prevstate = m_pDriver->m_RenderState;
|
||||
|
||||
{
|
||||
SCOPED_TIMER("Triangle Size");
|
||||
|
||||
float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(m_OverlayImage),
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
|
||||
|
||||
DoPipelineBarrier(cmd, 1, &barrier);
|
||||
|
||||
vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1,
|
||||
&subresourceRange);
|
||||
|
||||
std::swap(barrier.oldLayout, barrier.newLayout);
|
||||
std::swap(barrier.srcAccessMask, barrier.dstAccessMask);
|
||||
barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
|
||||
|
||||
DoPipelineBarrier(cmd, 1, &barrier);
|
||||
|
||||
// end this cmd buffer so the image is in the right state for the next part
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
#if defined(SINGLE_FLUSH_VALIDATE)
|
||||
m_pDriver->SubmitCmds();
|
||||
#endif
|
||||
|
||||
vector<uint32_t> events = passEvents;
|
||||
|
||||
if(overlay == eTexOverlay_TriangleSizeDraw)
|
||||
events.clear();
|
||||
|
||||
while(!events.empty())
|
||||
{
|
||||
const FetchDrawcall *draw = m_pDriver->GetDrawcall(events[0]);
|
||||
|
||||
// remove any non-drawcalls, like the pass boundary.
|
||||
if((draw->flags & eDraw_Drawcall) == 0)
|
||||
events.erase(events.begin());
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
events.push_back(eventID);
|
||||
|
||||
m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw);
|
||||
|
||||
VulkanRenderState &state = m_pDriver->GetRenderState();
|
||||
|
||||
uint32_t meshOffs = 0;
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshUBO.Map(&meshOffs);
|
||||
|
||||
data->mvp = Matrix4f::Identity();
|
||||
data->invProj = Matrix4f::Identity();
|
||||
data->color = Vec4f();
|
||||
data->homogenousInput = 1;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->displayFormat = 0;
|
||||
data->rawoutput = 1;
|
||||
data->padding = Vec3f();
|
||||
m_MeshUBO.Unmap();
|
||||
|
||||
uint32_t viewOffs = 0;
|
||||
Vec4f *ubo = (Vec4f *)m_TriSizeUBO.Map(&viewOffs);
|
||||
*ubo = Vec4f(state.views[0].width, state.views[0].height);
|
||||
m_TriSizeUBO.Unmap();
|
||||
|
||||
uint32_t offsets[2] = {meshOffs, viewOffs};
|
||||
|
||||
VkDescriptorBufferInfo bufdesc;
|
||||
m_MeshUBO.FillDescriptor(bufdesc);
|
||||
|
||||
VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
NULL,
|
||||
Unwrap(m_TriSizeDescSet),
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
|
||||
NULL,
|
||||
&bufdesc,
|
||||
NULL};
|
||||
vt->UpdateDescriptorSets(Unwrap(m_Device), 1, &write, 0, NULL);
|
||||
|
||||
m_TriSizeUBO.FillDescriptor(bufdesc);
|
||||
write.dstBinding = 2;
|
||||
vt->UpdateDescriptorSets(Unwrap(m_Device), 1, &write, 0, NULL);
|
||||
|
||||
VkRenderPass RP = m_OverlayNoDepthRP;
|
||||
VkFramebuffer FB = m_OverlayNoDepthFB;
|
||||
|
||||
VulkanCreationInfo &createinfo = m_pDriver->m_CreationInfo;
|
||||
|
||||
RDCASSERT(state.subpass < createinfo.m_RenderPass[state.renderPass].subpasses.size());
|
||||
int32_t dsIdx =
|
||||
createinfo.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment;
|
||||
|
||||
bool depthUsed = false;
|
||||
|
||||
// make a renderpass and framebuffer for rendering to overlay color and using
|
||||
// depth buffer from the orignial render
|
||||
if(dsIdx >= 0 && dsIdx < (int32_t)createinfo.m_Framebuffer[state.framebuffer].attachments.size())
|
||||
{
|
||||
depthUsed = true;
|
||||
|
||||
VkAttachmentDescription attDescs[] = {
|
||||
{0, VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
|
||||
{0, VK_FORMAT_UNDEFINED, VK_SAMPLE_COUNT_1_BIT, // will patch this just below
|
||||
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
|
||||
};
|
||||
|
||||
ResourceId depthView = createinfo.m_Framebuffer[state.framebuffer].attachments[dsIdx].view;
|
||||
ResourceId depthIm = createinfo.m_ImageView[depthView].image;
|
||||
|
||||
attDescs[1].format = createinfo.m_Image[depthIm].format;
|
||||
attDescs[0].samples = attDescs[1].samples = iminfo.samples;
|
||||
|
||||
VkAttachmentReference colRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
||||
VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
|
||||
|
||||
VkSubpassDescription sub = {
|
||||
0, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
0, NULL, // inputs
|
||||
1, &colRef, // color
|
||||
NULL, // resolve
|
||||
&dsRef, // depth-stencil
|
||||
0, NULL, // preserve
|
||||
};
|
||||
|
||||
VkRenderPassCreateInfo rpinfo = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
2,
|
||||
attDescs,
|
||||
1,
|
||||
&sub,
|
||||
0,
|
||||
NULL, // dependencies
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &RP);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkImageView views[] = {
|
||||
m_OverlayImageView, GetResourceManager()->GetCurrentHandle<VkImageView>(depthView),
|
||||
};
|
||||
|
||||
// Create framebuffer rendering just to overlay image, no depth
|
||||
VkFramebufferCreateInfo fbinfo = {
|
||||
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
RP,
|
||||
2,
|
||||
views,
|
||||
(uint32_t)m_OverlayDim.width,
|
||||
(uint32_t)m_OverlayDim.height,
|
||||
1,
|
||||
};
|
||||
|
||||
vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &FB);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipeCreateInfo;
|
||||
|
||||
MakeGraphicsPipelineInfo(pipeCreateInfo, state.graphics.pipeline);
|
||||
|
||||
VkPipelineShaderStageCreateInfo stages[3] = {
|
||||
{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
m_MeshModules[0], "main", NULL},
|
||||
{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT, m_TriSizeFSModule, "main", NULL},
|
||||
{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0,
|
||||
VK_SHADER_STAGE_GEOMETRY_BIT, m_TriSizeGSModule, "main", NULL},
|
||||
};
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo ia = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
|
||||
ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
|
||||
VkVertexInputBindingDescription binds[] = {// primary
|
||||
{0, 0, VK_VERTEX_INPUT_RATE_VERTEX},
|
||||
// secondary
|
||||
{1, 0, VK_VERTEX_INPUT_RATE_VERTEX}};
|
||||
|
||||
VkVertexInputAttributeDescription vertAttrs[] = {
|
||||
{
|
||||
0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0,
|
||||
},
|
||||
{
|
||||
1, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0,
|
||||
},
|
||||
};
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vi = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
1,
|
||||
binds,
|
||||
2,
|
||||
vertAttrs,
|
||||
};
|
||||
|
||||
VkPipelineColorBlendAttachmentState attState = {
|
||||
false,
|
||||
VK_BLEND_FACTOR_ONE,
|
||||
VK_BLEND_FACTOR_ZERO,
|
||||
VK_BLEND_OP_ADD,
|
||||
VK_BLEND_FACTOR_ONE,
|
||||
VK_BLEND_FACTOR_ZERO,
|
||||
VK_BLEND_OP_ADD,
|
||||
0xf,
|
||||
};
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo cb = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||
NULL,
|
||||
0,
|
||||
false,
|
||||
VK_LOGIC_OP_NO_OP,
|
||||
1,
|
||||
&attState,
|
||||
{1.0f, 1.0f, 1.0f, 1.0f}};
|
||||
|
||||
pipeCreateInfo.stageCount = 3;
|
||||
pipeCreateInfo.pStages = stages;
|
||||
pipeCreateInfo.pTessellationState = NULL;
|
||||
pipeCreateInfo.renderPass = RP;
|
||||
pipeCreateInfo.subpass = 0;
|
||||
pipeCreateInfo.layout = m_TriSizePipeLayout;
|
||||
pipeCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
pipeCreateInfo.basePipelineIndex = 0;
|
||||
pipeCreateInfo.pInputAssemblyState = &ia;
|
||||
pipeCreateInfo.pVertexInputState = &vi;
|
||||
pipeCreateInfo.pColorBlendState = &cb;
|
||||
|
||||
typedef std::pair<uint32_t, PrimitiveTopology> PipeKey;
|
||||
|
||||
map<PipeKey, VkPipeline> pipes;
|
||||
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
|
||||
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkClearValue clearval = {};
|
||||
VkRenderPassBeginInfo rpbegin = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
NULL,
|
||||
Unwrap(RP),
|
||||
Unwrap(FB),
|
||||
{{
|
||||
0, 0,
|
||||
},
|
||||
m_OverlayDim},
|
||||
1,
|
||||
&clearval,
|
||||
};
|
||||
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkViewport viewport = {0.0f, 0.0f, (float)m_OverlayDim.width, (float)m_OverlayDim.height,
|
||||
0.0f, 1.0f};
|
||||
vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport);
|
||||
|
||||
for(size_t i = 0; i < events.size(); i++)
|
||||
{
|
||||
const FetchDrawcall *draw = m_pDriver->GetDrawcall(events[i]);
|
||||
|
||||
for(uint32_t inst = 0; draw && inst < RDCMAX(1U, draw->numInstances); inst++)
|
||||
{
|
||||
MeshFormat fmt = GetPostVSBuffers(events[i], inst, eMeshDataStage_GSOut);
|
||||
if(fmt.buf == ResourceId())
|
||||
fmt = GetPostVSBuffers(events[i], inst, eMeshDataStage_VSOut);
|
||||
|
||||
if(fmt.buf != ResourceId())
|
||||
{
|
||||
ia.topology = MakeVkPrimitiveTopology(fmt.topo);
|
||||
|
||||
binds[0].stride = binds[1].stride = fmt.stride;
|
||||
|
||||
PipeKey key = std::make_pair(fmt.stride, fmt.topo);
|
||||
VkPipeline pipe = pipes[key];
|
||||
|
||||
if(pipe == VK_NULL_HANDLE)
|
||||
{
|
||||
vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1,
|
||||
&pipeCreateInfo, NULL, &pipe);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
|
||||
VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle<VkBuffer>(fmt.buf);
|
||||
|
||||
VkDeviceSize offs = fmt.offset;
|
||||
vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(vb), &offs);
|
||||
|
||||
pipes[key] = pipe;
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_TriSizePipeLayout), 0, 1,
|
||||
UnwrapPtr(m_TriSizeDescSet), 2, offsets);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe));
|
||||
|
||||
const VkPipelineDynamicStateCreateInfo *dyn = pipeCreateInfo.pDynamicState;
|
||||
|
||||
for(uint32_t i = 0; dyn && i < dyn->dynamicStateCount; i++)
|
||||
{
|
||||
VkDynamicState d = dyn->pDynamicStates[i];
|
||||
|
||||
if(!state.views.empty() && d == VK_DYNAMIC_STATE_VIEWPORT)
|
||||
{
|
||||
vt->CmdSetViewport(Unwrap(cmd), 0, (uint32_t)state.views.size(), &state.views[0]);
|
||||
}
|
||||
else if(!state.scissors.empty() && d == VK_DYNAMIC_STATE_SCISSOR)
|
||||
{
|
||||
vt->CmdSetScissor(Unwrap(cmd), 0, (uint32_t)state.scissors.size(),
|
||||
&state.scissors[0]);
|
||||
}
|
||||
else if(d == VK_DYNAMIC_STATE_LINE_WIDTH)
|
||||
{
|
||||
vt->CmdSetLineWidth(Unwrap(cmd), state.lineWidth);
|
||||
}
|
||||
else if(d == VK_DYNAMIC_STATE_DEPTH_BIAS)
|
||||
{
|
||||
vt->CmdSetDepthBias(Unwrap(cmd), state.bias.depth, state.bias.biasclamp,
|
||||
state.bias.slope);
|
||||
}
|
||||
else if(d == VK_DYNAMIC_STATE_BLEND_CONSTANTS)
|
||||
{
|
||||
vt->CmdSetBlendConstants(Unwrap(cmd), state.blendConst);
|
||||
}
|
||||
else if(d == VK_DYNAMIC_STATE_DEPTH_BOUNDS)
|
||||
{
|
||||
vt->CmdSetDepthBounds(Unwrap(cmd), state.mindepth, state.maxdepth);
|
||||
}
|
||||
else if(d == VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)
|
||||
{
|
||||
vt->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT,
|
||||
state.back.compare);
|
||||
vt->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT,
|
||||
state.front.compare);
|
||||
}
|
||||
else if(d == VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)
|
||||
{
|
||||
vt->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, state.back.write);
|
||||
vt->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, state.front.write);
|
||||
}
|
||||
else if(d == VK_DYNAMIC_STATE_STENCIL_REFERENCE)
|
||||
{
|
||||
vt->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, state.back.ref);
|
||||
vt->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, state.front.ref);
|
||||
}
|
||||
}
|
||||
|
||||
if(fmt.idxByteWidth)
|
||||
{
|
||||
VkIndexType idxtype = VK_INDEX_TYPE_UINT16;
|
||||
if(fmt.idxByteWidth == 4)
|
||||
idxtype = VK_INDEX_TYPE_UINT32;
|
||||
|
||||
if(fmt.idxbuf != ResourceId())
|
||||
{
|
||||
VkBuffer ib = m_pDriver->GetResourceManager()->GetCurrentHandle<VkBuffer>(fmt.idxbuf);
|
||||
|
||||
vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), fmt.idxoffs, idxtype);
|
||||
vt->CmdDrawIndexed(Unwrap(cmd), fmt.numVerts, 1, 0, fmt.baseVertex, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vt->CmdDraw(Unwrap(cmd), fmt.numVerts, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
if(depthUsed)
|
||||
{
|
||||
m_pDriver->vkDestroyFramebuffer(m_Device, FB, NULL);
|
||||
m_pDriver->vkDestroyRenderPass(m_Device, RP, NULL);
|
||||
}
|
||||
|
||||
for(auto it = pipes.begin(); it != pipes.end(); ++it)
|
||||
m_pDriver->vkDestroyPipeline(m_Device, it->second, NULL);
|
||||
}
|
||||
|
||||
// restore back to normal
|
||||
m_pDriver->ReplayLog(0, eventID, eReplay_WithoutDraw);
|
||||
|
||||
// restore state
|
||||
m_pDriver->m_RenderState = prevstate;
|
||||
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
@@ -271,6 +271,13 @@ public:
|
||||
VkPipeline m_QuadResolvePipeline[8];
|
||||
vector<uint32_t> *m_QuadSPIRV;
|
||||
|
||||
GPUBuffer m_TriSizeUBO;
|
||||
VkDescriptorSetLayout m_TriSizeDescSetLayout;
|
||||
VkDescriptorSet m_TriSizeDescSet;
|
||||
VkPipelineLayout m_TriSizePipeLayout;
|
||||
VkShaderModule m_TriSizeGSModule;
|
||||
VkShaderModule m_TriSizeFSModule;
|
||||
|
||||
VkDescriptorSetLayout m_MeshDescSetLayout;
|
||||
VkPipelineLayout m_MeshPipeLayout;
|
||||
VkDescriptorSet m_MeshDescSet;
|
||||
|
||||
@@ -1788,6 +1788,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
data->homogenousInput = cfg.position.unproject;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->displayFormat = MESHDISPLAY_SOLID;
|
||||
data->rawoutput = 0;
|
||||
|
||||
GetDebugManager()->m_MeshUBO.Unmap();
|
||||
|
||||
@@ -1918,6 +1919,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
data->homogenousInput = cfg.position.unproject;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->displayFormat = (uint32_t)solidShadeMode;
|
||||
data->rawoutput = 0;
|
||||
|
||||
if(solidShadeMode == eShade_Secondary && cfg.second.showAlpha)
|
||||
data->displayFormat = MESHDISPLAY_SECONDARY_ALPHA;
|
||||
@@ -1965,6 +1967,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
data->displayFormat = (uint32_t)eShade_Solid;
|
||||
data->homogenousInput = cfg.position.unproject;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->rawoutput = 0;
|
||||
|
||||
GetDebugManager()->m_MeshUBO.Unmap();
|
||||
|
||||
@@ -2052,6 +2055,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
data->displayFormat = (uint32_t)eShade_Solid;
|
||||
data->homogenousInput = 0;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->rawoutput = 0;
|
||||
|
||||
GetDebugManager()->m_MeshUBO.Unmap();
|
||||
|
||||
@@ -2080,6 +2084,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
data->displayFormat = (uint32_t)eShade_Solid;
|
||||
data->homogenousInput = 0;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->rawoutput = 0;
|
||||
|
||||
GetDebugManager()->m_MeshUBO.Unmap();
|
||||
|
||||
@@ -2100,6 +2105,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
data->displayFormat = (uint32_t)eShade_Solid;
|
||||
data->homogenousInput = 0;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->rawoutput = 0;
|
||||
|
||||
GetDebugManager()->m_MeshUBO.Unmap();
|
||||
|
||||
@@ -2115,6 +2121,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
data->displayFormat = (uint32_t)eShade_Solid;
|
||||
data->homogenousInput = 0;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->rawoutput = 0;
|
||||
|
||||
GetDebugManager()->m_MeshUBO.Unmap();
|
||||
|
||||
@@ -2139,6 +2146,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
data->displayFormat = (uint32_t)eShade_Solid;
|
||||
data->homogenousInput = 0;
|
||||
data->pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
data->rawoutput = 0;
|
||||
|
||||
GetDebugManager()->m_MeshUBO.Unmap();
|
||||
|
||||
@@ -2576,7 +2584,7 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &second
|
||||
else
|
||||
ModelViewProj = projMat.Mul(camMat);
|
||||
|
||||
MeshUBOData uniforms;
|
||||
MeshUBOData uniforms = {};
|
||||
uniforms.mvp = ModelViewProj;
|
||||
uniforms.color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
uniforms.displayFormat = (uint32_t)eShade_Solid;
|
||||
|
||||
@@ -407,6 +407,8 @@
|
||||
<None Include="data\glsl\texdisplay.frag" />
|
||||
<None Include="data\glsl\text.frag" />
|
||||
<None Include="data\glsl\text.vert" />
|
||||
<None Include="data\glsl\trisize.frag" />
|
||||
<None Include="data\glsl\trisize.geom" />
|
||||
<None Include="data\hlsl\debugcommon.hlsl" />
|
||||
<None Include="data\hlsl\debugdisplay.hlsl" />
|
||||
<None Include="data\hlsl\debugtext.hlsl" />
|
||||
|
||||
@@ -511,6 +511,12 @@
|
||||
<None Include="data\glsl\text.vert">
|
||||
<Filter>Resources\glsl</Filter>
|
||||
</None>
|
||||
<None Include="data\glsl\trisize.geom">
|
||||
<Filter>Resources\glsl</Filter>
|
||||
</None>
|
||||
<None Include="data\glsl\trisize.frag">
|
||||
<Filter>Resources\glsl</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="data\renderdoc.rc">
|
||||
|
||||
@@ -172,6 +172,40 @@ void ReplayOutput::RefreshOverlay()
|
||||
|
||||
passEvents = m_pDevice->GetPassEvents(m_EventID);
|
||||
|
||||
bool postVSBuffers = false;
|
||||
bool postVSWholePass = false;
|
||||
|
||||
if(m_Config.m_Type == eOutputType_MeshDisplay && m_OverlayDirty)
|
||||
{
|
||||
postVSBuffers = true;
|
||||
postVSWholePass = m_RenderData.meshDisplay.showWholePass != 0;
|
||||
}
|
||||
|
||||
if(m_Config.m_Type == eOutputType_TexDisplay)
|
||||
{
|
||||
postVSBuffers = m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizePass ||
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizeDraw;
|
||||
postVSWholePass = m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizePass;
|
||||
}
|
||||
|
||||
if(postVSBuffers)
|
||||
{
|
||||
if(m_Config.m_Type == eOutputType_MeshDisplay)
|
||||
m_OverlayDirty = false;
|
||||
|
||||
if(draw != NULL && (draw->flags & eDraw_Drawcall))
|
||||
{
|
||||
m_pDevice->InitPostVSBuffers(draw->eventID);
|
||||
|
||||
if(postVSWholePass && !passEvents.empty())
|
||||
{
|
||||
m_pDevice->InitPostVSBuffers(passEvents);
|
||||
|
||||
m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(m_Config.m_Type == eOutputType_TexDisplay && m_RenderData.texDisplay.overlay != eTexOverlay_None)
|
||||
{
|
||||
if(draw && m_pDevice->IsRenderOutput(m_RenderData.texDisplay.texid))
|
||||
@@ -181,22 +215,9 @@ void ReplayOutput::RefreshOverlay()
|
||||
m_RenderData.texDisplay.overlay, m_EventID, passEvents);
|
||||
m_OverlayDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_Config.m_Type == eOutputType_MeshDisplay && m_OverlayDirty)
|
||||
{
|
||||
m_OverlayDirty = false;
|
||||
|
||||
if(draw == NULL || (draw->flags & eDraw_Drawcall) == 0)
|
||||
return;
|
||||
|
||||
m_pDevice->InitPostVSBuffers(draw->eventID);
|
||||
|
||||
if(m_RenderData.meshDisplay.showWholePass && !passEvents.empty())
|
||||
else
|
||||
{
|
||||
m_pDevice->InitPostVSBuffers(passEvents);
|
||||
|
||||
m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw);
|
||||
m_OverlayResourceId = ResourceId();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,7 +311,9 @@ bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint
|
||||
typeHint = eCompType_None;
|
||||
}
|
||||
if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw ||
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) &&
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass ||
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizeDraw ||
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizePass) &&
|
||||
m_OverlayResourceId != ResourceId())
|
||||
{
|
||||
decodeRamp = true;
|
||||
@@ -316,6 +339,21 @@ bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// decode back into approximate pixel size area
|
||||
if(m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizePass ||
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizeDraw)
|
||||
{
|
||||
float bucket = (float)ret->value_i[0];
|
||||
|
||||
// decode bucket into approximate triangle area
|
||||
if(bucket <= 0.5f)
|
||||
ret->value_f[0] = 0.0f;
|
||||
else if(bucket < 2.0f)
|
||||
ret->value_f[0] = 16.0f;
|
||||
else
|
||||
ret->value_f[0] = -2.5f * logf(1.0f + (bucket - 22.0f) / 20.1f);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -388,7 +426,9 @@ void ReplayOutput::DisplayContext()
|
||||
disp.texid = m_CustomShaderResourceId;
|
||||
|
||||
if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw ||
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) &&
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass ||
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizeDraw ||
|
||||
m_RenderData.texDisplay.overlay == eTexOverlay_TriangleSizePass) &&
|
||||
m_OverlayResourceId != ResourceId())
|
||||
disp.texid = m_OverlayResourceId;
|
||||
|
||||
|
||||
@@ -171,6 +171,8 @@ namespace renderdoc
|
||||
ClearBeforeDraw,
|
||||
QuadOverdrawPass,
|
||||
QuadOverdrawDraw,
|
||||
TriangleSizePass,
|
||||
TriangleSizeDraw,
|
||||
};
|
||||
|
||||
public enum FileType
|
||||
|
||||
+3
-1
@@ -592,7 +592,9 @@
|
||||
"Clear Before Pass",
|
||||
"Clear Before Draw",
|
||||
"Quad Overdraw (Pass)",
|
||||
"Quad Overdraw (Draw)"});
|
||||
"Quad Overdraw (Draw)",
|
||||
"Triangle Size (Pass)",
|
||||
"Triangle Size (Draw)"});
|
||||
this.overlay.Name = "overlay";
|
||||
this.overlay.Size = new System.Drawing.Size(121, 25);
|
||||
this.overlay.SelectedIndexChanged += new System.EventHandler(this.overlay_SelectedIndexChanged);
|
||||
|
||||
Reference in New Issue
Block a user