mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 09:00:44 +00:00
Implement mesh viewer support for task/mesh shaders
This commit is contained in:
@@ -133,6 +133,14 @@ DOCUMENT(R"(Specifies the panel to add a menu item into.
|
||||
|
||||
Adds the item to the context menu for GS/Tess output in the mesh previewing :class:`BufferViewer`.
|
||||
|
||||
.. data:: MeshPreview_TaskOutVertex
|
||||
|
||||
Adds the item to the context menu for task shader output in the mesh previewing :class:`BufferViewer`.
|
||||
|
||||
.. data:: MeshPreview_MeshOutVertex
|
||||
|
||||
Adds the item to the context menu for mesh shader output in the mesh previewing :class:`BufferViewer`.
|
||||
|
||||
.. data:: TextureViewer_Thumbnail
|
||||
|
||||
Adds the item to the context menu for all thumbnails in the :class:`TextureViewer`.
|
||||
@@ -153,6 +161,8 @@ enum class ContextMenu
|
||||
MeshPreview_VSInVertex,
|
||||
MeshPreview_VSOutVertex,
|
||||
MeshPreview_GSOutVertex,
|
||||
MeshPreview_TaskOutVertex,
|
||||
MeshPreview_MeshOutVertex,
|
||||
TextureViewer_Thumbnail,
|
||||
TextureViewer_InputThumbnail,
|
||||
TextureViewer_OutputThumbnail,
|
||||
|
||||
+1054
-490
File diff suppressed because it is too large
Load Diff
@@ -169,7 +169,7 @@ private:
|
||||
|
||||
IReplayOutput *m_Output;
|
||||
|
||||
void updateWindowTitle();
|
||||
void updateLabelsAndLayout();
|
||||
|
||||
void configureDrawRange();
|
||||
|
||||
@@ -183,12 +183,12 @@ private:
|
||||
MeshDataStage m_CurStage;
|
||||
|
||||
// cached data from PostVS data
|
||||
MeshFormat m_PostVS, m_PostGS;
|
||||
MeshFormat m_Out1Data, m_Out2Data;
|
||||
|
||||
// the configurations for 3D preview
|
||||
MeshFormat m_VSInPosition, m_VSInSecondary;
|
||||
MeshFormat m_PostVSPosition, m_PostVSSecondary;
|
||||
MeshFormat m_PostGSPosition, m_PostGSSecondary;
|
||||
MeshFormat m_InPosition, m_InSecondary;
|
||||
MeshFormat m_Out1Position, m_Out1Secondary;
|
||||
MeshFormat m_Out2Position, m_Out2Secondary;
|
||||
|
||||
QMutex m_BBoxLock;
|
||||
QMap<uint32_t, BBoxData> m_BBoxes;
|
||||
@@ -198,6 +198,8 @@ private:
|
||||
void UI_UpdateBoundingBox(const CalcBoundingBoxData &bbox);
|
||||
void UI_UpdateBoundingBoxLabels(int compCount = 0);
|
||||
|
||||
void UI_AddTaskPayloads(RDTreeWidgetItem *root, size_t baseOffset,
|
||||
const rdcarray<ShaderConstant> &consts, BufferData *buffer);
|
||||
void UI_AddFixedVariables(RDTreeWidgetItem *root, uint32_t baseOffset,
|
||||
const rdcarray<ShaderConstant> &consts,
|
||||
const rdcarray<ShaderVariable> &vars);
|
||||
@@ -242,9 +244,24 @@ private:
|
||||
|
||||
bool m_MeshView;
|
||||
|
||||
BufferItemModel *m_ModelVSIn;
|
||||
BufferItemModel *m_ModelVSOut;
|
||||
BufferItemModel *m_ModelGSOut;
|
||||
// for ease of reading, these stages are named as in, out1, and out2. Note however that this does
|
||||
// NOT correspond to which table widgets these fill out. Since it is most common to look at VS In
|
||||
// and VS Out for classic vertex pipeline draws, and Task Out and Mesh Out for mesh shader draws
|
||||
// (and because mesh shader input visualisation is not natively available) we pair up VS In and
|
||||
// Task Out on the same control, VS Out and Mesh Out on the same control, and GS/Tess Out and Mesh
|
||||
// In on the same control.
|
||||
|
||||
// the input stage
|
||||
BufferItemModel *m_ModelIn;
|
||||
// the first output stage (vertex, or task)
|
||||
BufferItemModel *m_ModelOut1;
|
||||
// the second output stage (geometry, or mesh)
|
||||
BufferItemModel *m_ModelOut2;
|
||||
|
||||
// the container widgets for each stage which are remapped depending on the draw type to one of
|
||||
// the above. This may mean 1:1 for traditional draws or [0] being out1 (task out), [1] being out2
|
||||
// (mesh out) and [2] being in
|
||||
QWidget *m_Containers[3] = {};
|
||||
|
||||
PopulateBufferData *m_Scrolls = NULL;
|
||||
|
||||
@@ -300,6 +317,7 @@ private:
|
||||
BufferItemModel *currentBufferModel() { return modelForStage(m_CurStage); }
|
||||
bool isCurrentRasterOut();
|
||||
int currentStageIndex();
|
||||
bool isMeshDraw();
|
||||
|
||||
void SetupMeshView();
|
||||
void SetupRawView();
|
||||
@@ -311,7 +329,9 @@ private:
|
||||
|
||||
void ClearModels();
|
||||
|
||||
void UI_CalculateMeshFormats();
|
||||
void UI_ConfigureFormats();
|
||||
void UI_ConfigureVertexPipeFormats();
|
||||
void UI_ConfigureMeshPipeFormats();
|
||||
|
||||
void UpdateCurrentMeshConfig();
|
||||
void EnableCameraGuessControls();
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="RDTableView" name="vsinData">
|
||||
<widget class="RDTableView" name="inTable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
@@ -78,7 +78,7 @@
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="RDTableView" name="vsoutData">
|
||||
<widget class="RDTableView" name="out1Table">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>280</x>
|
||||
@@ -130,7 +130,7 @@
|
||||
<property name="documentMode">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="vsinTab">
|
||||
<widget class="QWidget" name="inTab">
|
||||
<attribute name="title">
|
||||
<string>VS In</string>
|
||||
</attribute>
|
||||
@@ -681,7 +681,7 @@ Enter 0.0 to use automatic/guessed value derived from data.</string>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="vsoutTab">
|
||||
<widget class="QWidget" name="out1Tab">
|
||||
<attribute name="title">
|
||||
<string>VS Out</string>
|
||||
</attribute>
|
||||
@@ -703,7 +703,7 @@ Enter 0.0 to use automatic/guessed value derived from data.</string>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="gsoutTab">
|
||||
<widget class="QWidget" name="out2Tab">
|
||||
<attribute name="title">
|
||||
<string>GS/DS Out</string>
|
||||
</attribute>
|
||||
@@ -726,7 +726,7 @@ Enter 0.0 to use automatic/guessed value derived from data.</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="RDTableView" name="gsoutData">
|
||||
<widget class="RDTableView" name="out2Table">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>500</x>
|
||||
|
||||
@@ -172,10 +172,16 @@ vec3 CalcCubeCoord(vec2 uv, int face)
|
||||
|
||||
#endif
|
||||
|
||||
// first few match SolidShade enum
|
||||
#define MESHDISPLAY_SOLID 0x1
|
||||
#define MESHDISPLAY_FACELIT 0x2
|
||||
#define MESHDISPLAY_SECONDARY 0x3
|
||||
#define MESHDISPLAY_SECONDARY_ALPHA 0x4
|
||||
#define MESHDISPLAY_MESHLET 0x4
|
||||
|
||||
// extra values below
|
||||
#define MESHDISPLAY_SECONDARY_ALPHA 0x5
|
||||
|
||||
#define MAX_NUM_MESHLETS (512 * 1024)
|
||||
|
||||
#define TEXDISPLAY_TYPEMASK 0xF
|
||||
#define TEXDISPLAY_UINT_TEX 0x10
|
||||
|
||||
@@ -41,11 +41,24 @@ BINDING(0) uniform MeshUBOData
|
||||
uint rawoutput;
|
||||
uint flipY;
|
||||
vec2 padding;
|
||||
uvec4 meshletColours[12];
|
||||
}
|
||||
INST_NAME(Mesh);
|
||||
|
||||
#endif // defined(MESH_UBO) || defined(__cplusplus)
|
||||
|
||||
#if defined(MESH_UBO) && defined(VULKAN)
|
||||
|
||||
layout(binding = 1, std140) readonly buffer meshlet_data
|
||||
{
|
||||
uint meshletCount;
|
||||
uint meshletOffset;
|
||||
uvec4 data[];
|
||||
}
|
||||
meshlet;
|
||||
|
||||
#endif // defined(MESH_UBO)
|
||||
|
||||
#if defined(CHECKER_UBO) || defined(__cplusplus)
|
||||
|
||||
BINDING(0) uniform CheckerboardUBOData
|
||||
|
||||
@@ -46,7 +46,7 @@ void main(void)
|
||||
{
|
||||
int type = Mesh.displayFormat;
|
||||
|
||||
if(type == MESHDISPLAY_SECONDARY)
|
||||
if(type == MESHDISPLAY_SECONDARY || type == MESHDISPLAY_MESHLET)
|
||||
{
|
||||
color_out = vec4(SECONDARY_NAME.xyz, 1);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,69 @@ IO_LOCATION(1) in SECONDARY_TYPE vsin_secondary;
|
||||
IO_LOCATION(0) out vec4 vsout_secondary;
|
||||
IO_LOCATION(1) out vec4 vsout_norm;
|
||||
|
||||
#ifdef VULKAN
|
||||
|
||||
uint getMeshletCountAt(uint m)
|
||||
{
|
||||
uint vecIdx = m / 4;
|
||||
|
||||
if((m % 4) == 0)
|
||||
return meshlet.data[vecIdx].x;
|
||||
else if((m % 4) == 1)
|
||||
return meshlet.data[vecIdx].y;
|
||||
else if((m % 4) == 2)
|
||||
return meshlet.data[vecIdx].z;
|
||||
else if((m % 4) == 3)
|
||||
return meshlet.data[vecIdx].w;
|
||||
}
|
||||
|
||||
vec4 getMeshletColor()
|
||||
{
|
||||
uint searchIdx = VERTEX_ID;
|
||||
|
||||
// array of prefix summed counts accessible via getMeshletCountAt [x, x+y, x+y+z, ...] we do a
|
||||
// binary search to find which meshlet this index corresponds to
|
||||
|
||||
uint first = 0, last = meshlet.meshletCount - 1;
|
||||
uint count = last - first;
|
||||
|
||||
while(count > 0)
|
||||
{
|
||||
uint halfrange = count / 2;
|
||||
uint mid = first + halfrange;
|
||||
|
||||
if(searchIdx < getMeshletCountAt(mid))
|
||||
{
|
||||
count = halfrange;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = mid + 1;
|
||||
count -= halfrange + 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint meshletIndex = first;
|
||||
|
||||
if(VERTEX_ID < getMeshletCountAt(meshletIndex))
|
||||
{
|
||||
meshletIndex += meshlet.meshletOffset;
|
||||
meshletIndex %= 48;
|
||||
uvec4 meshletColor = Mesh.meshletColours[meshletIndex / 4];
|
||||
if((meshletIndex % 4) == 0)
|
||||
return unpackUnorm4x8(meshletColor.x);
|
||||
else if((meshletIndex % 4) == 1)
|
||||
return unpackUnorm4x8(meshletColor.y);
|
||||
else if((meshletIndex % 4) == 2)
|
||||
return unpackUnorm4x8(meshletColor.z);
|
||||
else if((meshletIndex % 4) == 3)
|
||||
return unpackUnorm4x8(meshletColor.w);
|
||||
}
|
||||
|
||||
return vec4(0, 0, 0, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 psprite[4] =
|
||||
@@ -65,6 +128,9 @@ void main(void)
|
||||
vsout_norm = vec4(0, 0, 1, 1);
|
||||
|
||||
#ifdef VULKAN
|
||||
if(Mesh.displayFormat == MESHDISPLAY_MESHLET)
|
||||
vsout_secondary = getMeshletColor();
|
||||
|
||||
// GL->VK conventions
|
||||
gl_Position.y = -gl_Position.y;
|
||||
if(Mesh.flipY == 1)
|
||||
|
||||
@@ -106,8 +106,15 @@ cbuffer MeshVertexCBuffer REG(b0)
|
||||
row_major float4x4 ModelViewProj;
|
||||
|
||||
float2 SpriteSize;
|
||||
|
||||
uint homogenousInput;
|
||||
uint vertMeshDisplayFormat;
|
||||
|
||||
uint meshletOffset;
|
||||
uint meshletCount;
|
||||
uint padding1;
|
||||
uint padding2;
|
||||
|
||||
uint4 meshletColours[12];
|
||||
};
|
||||
|
||||
cbuffer MeshGeometryCBuffer REG(b0)
|
||||
@@ -243,10 +250,16 @@ cbuffer DebugSampleOperation REG(b0)
|
||||
#define RESTYPE_DEPTH_STENCIL_MS 0x7
|
||||
#define RESTYPE_TEX2D_MS 0x9
|
||||
|
||||
// first few match SolidShade enum
|
||||
#define MESHDISPLAY_SOLID 0x1
|
||||
#define MESHDISPLAY_FACELIT 0x2
|
||||
#define MESHDISPLAY_SECONDARY 0x3
|
||||
#define MESHDISPLAY_SECONDARY_ALPHA 0x4
|
||||
#define MESHDISPLAY_MESHLET 0x4
|
||||
|
||||
// extra values below
|
||||
#define MESHDISPLAY_SECONDARY_ALPHA 0x5
|
||||
|
||||
#define MAX_NUM_MESHLETS (512 * 1024)
|
||||
|
||||
#define TEXDISPLAY_TYPEMASK 0xF
|
||||
#define TEXDISPLAY_NANS 0x0100
|
||||
|
||||
@@ -37,6 +37,79 @@ struct meshA2V
|
||||
float4 secondary : sec;
|
||||
};
|
||||
|
||||
StructuredBuffer<uint4> meshletSizesBuf : register(t0);
|
||||
|
||||
float4 unpackUnorm4x8(uint value)
|
||||
{
|
||||
uint4 shifted = uint4(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, value >> 24);
|
||||
return float4(shifted) / 255.0;
|
||||
}
|
||||
|
||||
uint getMeshletCountAt(uint m)
|
||||
{
|
||||
uint vecIdx = m / 4;
|
||||
|
||||
uint count = 0;
|
||||
if((m % 4) == 0)
|
||||
count = meshletSizesBuf[vecIdx].x;
|
||||
else if((m % 4) == 1)
|
||||
count = meshletSizesBuf[vecIdx].y;
|
||||
else if((m % 4) == 2)
|
||||
count = meshletSizesBuf[vecIdx].z;
|
||||
else if((m % 4) == 3)
|
||||
count = meshletSizesBuf[vecIdx].w;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
float4 getMeshletColor(uint vid)
|
||||
{
|
||||
uint searchIdx = vid;
|
||||
|
||||
// array of prefix summed counts accessible via getMeshletCountAt [x, x+y, x+y+z, ...] we do a
|
||||
// binary search to find which meshlet this index corresponds to
|
||||
|
||||
uint first = 0, last = meshletCount - 1;
|
||||
uint count = last - first;
|
||||
|
||||
while(count > 0)
|
||||
{
|
||||
uint halfrange = count / 2;
|
||||
uint mid = first + halfrange;
|
||||
|
||||
if(searchIdx < getMeshletCountAt(mid))
|
||||
{
|
||||
count = halfrange;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = mid + 1;
|
||||
count -= halfrange + 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint meshletIndex = first;
|
||||
|
||||
float4 col = float4(0, 0, 0, 1);
|
||||
|
||||
if(vid < getMeshletCountAt(meshletIndex))
|
||||
{
|
||||
meshletIndex += meshletOffset;
|
||||
meshletIndex %= 48;
|
||||
uint4 meshletColor = meshletColours[meshletIndex / 4];
|
||||
if((meshletIndex % 4) == 0)
|
||||
col = unpackUnorm4x8(meshletColor.x);
|
||||
else if((meshletIndex % 4) == 1)
|
||||
col = unpackUnorm4x8(meshletColor.y);
|
||||
else if((meshletIndex % 4) == 2)
|
||||
col = unpackUnorm4x8(meshletColor.z);
|
||||
else if((meshletIndex % 4) == 3)
|
||||
col = unpackUnorm4x8(meshletColor.w);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
meshV2F RENDERDOC_MeshVS(meshA2V IN, uint vid : SV_VertexID)
|
||||
{
|
||||
meshV2F OUT = (meshV2F)0;
|
||||
@@ -56,6 +129,9 @@ meshV2F RENDERDOC_MeshVS(meshA2V IN, uint vid : SV_VertexID)
|
||||
OUT.norm = float3(0, 0, 1);
|
||||
OUT.secondary = IN.secondary;
|
||||
|
||||
if(vertMeshDisplayFormat == MESHDISPLAY_MESHLET)
|
||||
OUT.secondary = getMeshletColor(vid);
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
@@ -128,7 +204,7 @@ float4 RENDERDOC_MeshPS(meshV2F IN)
|
||||
{
|
||||
uint type = MeshDisplayFormat;
|
||||
|
||||
if(type == MESHDISPLAY_SECONDARY)
|
||||
if(type == MESHDISPLAY_SECONDARY || type == MESHDISPLAY_MESHLET)
|
||||
return float4(IN.secondary.xyz, 1);
|
||||
else if(type == MESHDISPLAY_SECONDARY_ALPHA)
|
||||
return float4(IN.secondary.www, 1);
|
||||
|
||||
@@ -267,6 +267,12 @@ void D3D11Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
m_pImmediateContext->IASetPrimitiveTopology(topo);
|
||||
|
||||
pixelData.MeshDisplayFormat = (int)cfg.solidShadeMode;
|
||||
if(cfg.solidShadeMode == SolidShade::Meshlet)
|
||||
{
|
||||
RDCERR("D3D11 does not support mesh rendering");
|
||||
pixelData.MeshDisplayFormat = (int)SolidShade::Solid;
|
||||
}
|
||||
|
||||
if(cfg.solidShadeMode == SolidShade::Secondary && cfg.second.showAlpha)
|
||||
pixelData.MeshDisplayFormat = MESHDISPLAY_SECONDARY_ALPHA;
|
||||
|
||||
|
||||
@@ -275,6 +275,8 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
|
||||
cbvParam(D3D12_SHADER_VISIBILITY_GEOMETRY, 0, 0),
|
||||
// 'push constant' CBV
|
||||
constParam(D3D12_SHADER_VISIBILITY_PIXEL, 0, 0, 4),
|
||||
// meshlet sizes SRV
|
||||
srvParam(D3D12_SHADER_VISIBILITY_VERTEX, 0, 0),
|
||||
},
|
||||
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
|
||||
|
||||
@@ -308,6 +310,41 @@ D3D12DebugManager::D3D12DebugManager(WrappedID3D12Device *wrapper)
|
||||
{}, "ps_5_0", &m_MeshPS);
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_DESC meshletSizeBuf = {};
|
||||
meshletSizeBuf.Alignment = 0;
|
||||
meshletSizeBuf.DepthOrArraySize = 1;
|
||||
meshletSizeBuf.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
meshletSizeBuf.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
meshletSizeBuf.Format = DXGI_FORMAT_UNKNOWN;
|
||||
meshletSizeBuf.Height = 1;
|
||||
meshletSizeBuf.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
meshletSizeBuf.MipLevels = 1;
|
||||
meshletSizeBuf.SampleDesc.Count = 1;
|
||||
meshletSizeBuf.SampleDesc.Quality = 0;
|
||||
meshletSizeBuf.Width = sizeof(uint32_t) * (4 + MAX_NUM_MESHLETS);
|
||||
|
||||
D3D12_HEAP_PROPERTIES heapProps;
|
||||
heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
heapProps.CreationNodeMask = 1;
|
||||
heapProps.VisibleNodeMask = 1;
|
||||
|
||||
hr = m_pDevice->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &meshletSizeBuf,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, NULL,
|
||||
__uuidof(ID3D12Resource), (void **)&m_MeshletBuf);
|
||||
m_pDevice->InternalRef();
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create meshlet size buffer, HRESULT: %s", ToStr(hr).c_str());
|
||||
}
|
||||
|
||||
if(m_MeshletBuf)
|
||||
m_MeshletBuf->SetName(L"m_MeshletBuf");
|
||||
}
|
||||
|
||||
{
|
||||
rdcstr hlsl = GetEmbeddedResource(misc_hlsl);
|
||||
|
||||
@@ -508,6 +545,7 @@ D3D12DebugManager::~D3D12DebugManager()
|
||||
SAFE_RELEASE(m_MeshGS);
|
||||
SAFE_RELEASE(m_MeshPS);
|
||||
SAFE_RELEASE(m_MeshRootSig);
|
||||
SAFE_RELEASE(m_MeshletBuf);
|
||||
|
||||
SAFE_RELEASE(m_ShaderDebugRootSig);
|
||||
SAFE_RELEASE(m_MathIntrinsicsPso);
|
||||
@@ -925,6 +963,39 @@ D3D12_GPU_VIRTUAL_ADDRESS D3D12DebugManager::UploadConstants(const void *data, s
|
||||
return ret;
|
||||
}
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS D3D12DebugManager::UploadMeshletSizes(uint32_t meshletIndexOffset,
|
||||
const rdcarray<MeshletSize> &sizes)
|
||||
{
|
||||
D3D12_GPU_VIRTUAL_ADDRESS ret = m_MeshletBuf->GetGPUVirtualAddress();
|
||||
|
||||
if(sizes.empty())
|
||||
return ret;
|
||||
|
||||
rdcarray<uint32_t> data;
|
||||
data.resize(sizes.size());
|
||||
uint32_t prefixCount = meshletIndexOffset;
|
||||
for(size_t i = 0; i < data.size(); i++)
|
||||
{
|
||||
prefixCount += sizes[i].numVertices;
|
||||
data[i] = prefixCount;
|
||||
}
|
||||
|
||||
if(m_CurMeshletOffset + data.byteSize() > m_MeshletBuf->GetDesc().Width)
|
||||
m_CurMeshletOffset = 0;
|
||||
|
||||
ret += m_CurMeshletOffset;
|
||||
|
||||
// passing the unwrapped object here is immaterial as all we do is Map/Unmap, but it means we can
|
||||
// call this function while capturing without worrying about serialising the map or deadlocking.
|
||||
FillBuffer(Unwrap(m_MeshletBuf), (size_t)m_CurMeshletOffset, data.data(), data.byteSize());
|
||||
|
||||
m_CurMeshletOffset += data.byteSize();
|
||||
m_CurMeshletOffset =
|
||||
AlignUp(m_CurMeshletOffset, (UINT64)D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandListX *D3D12DebugManager::ResetDebugList()
|
||||
{
|
||||
m_DebugList->Reset(m_DebugAlloc, NULL);
|
||||
|
||||
@@ -156,6 +156,8 @@ public:
|
||||
ID3D12Resource *MakeCBuffer(UINT64 size);
|
||||
void FillBuffer(ID3D12Resource *buf, size_t offset, const void *data, size_t size);
|
||||
D3D12_GPU_VIRTUAL_ADDRESS UploadConstants(const void *data, size_t size);
|
||||
D3D12_GPU_VIRTUAL_ADDRESS UploadMeshletSizes(uint32_t meshletIndexOffset,
|
||||
const rdcarray<MeshletSize> &sizes);
|
||||
|
||||
ID3D12RootSignature *GetMeshRootSig() { return m_MeshRootSig; }
|
||||
ID3D12RootSignature *GetShaderDebugRootSig() { return m_ShaderDebugRootSig; }
|
||||
@@ -244,6 +246,9 @@ private:
|
||||
ID3D12RootSignature *m_MeshRootSig = NULL;
|
||||
std::map<uint64_t, MeshDisplayPipelines> m_CachedMeshPipelines;
|
||||
|
||||
ID3D12Resource *m_MeshletBuf = NULL;
|
||||
UINT64 m_CurMeshletOffset = 0;
|
||||
|
||||
// Shader debugging resources
|
||||
ID3D12RootSignature *m_ShaderDebugRootSig = NULL;
|
||||
ID3D12PipelineState *m_MathIntrinsicsPso = NULL;
|
||||
|
||||
@@ -275,6 +275,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
vertexData.ModelViewProj = projMat.Mul(camMat.Mul(axisMapMat));
|
||||
vertexData.SpriteSize = Vec2f();
|
||||
vertexData.homogenousInput = cfg.position.unproject;
|
||||
vertexData.vertMeshDisplayFormat = MESHDISPLAY_SOLID;
|
||||
|
||||
MeshPixelCBuffer pixelData;
|
||||
|
||||
@@ -305,9 +306,16 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv));
|
||||
}
|
||||
|
||||
memcpy(&vertexData.meshletColours[0].x, uniqueColors, sizeof(uniqueColors));
|
||||
RDCCOMPILE_ASSERT(sizeof(vertexData.meshletColours) == sizeof(uniqueColors),
|
||||
"Unique colors array is wrongly sized");
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS vsCB =
|
||||
GetDebugManager()->UploadConstants(&vertexData, sizeof(vertexData));
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS meshletBuf = GetDebugManager()->UploadMeshletSizes(
|
||||
cfg.position.meshletIndexOffset, cfg.position.meshletSizes);
|
||||
|
||||
if(!secondaryDraws.empty())
|
||||
{
|
||||
D3D12MarkerRegion region(list, "Secondary draws");
|
||||
@@ -329,6 +337,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
list->SetGraphicsRootSignature(rootSig);
|
||||
list->SetGraphicsRootConstantBufferView(0, vsCB);
|
||||
list->SetGraphicsRootConstantBufferView(1, vsCB); // geometry - dummy fill
|
||||
list->SetGraphicsRootShaderResourceView(3, meshletBuf);
|
||||
}
|
||||
|
||||
pixelData.MeshColour.x = fmt.meshColor.x;
|
||||
@@ -460,6 +469,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
pipe = cache.pipes[MeshDisplayPipelines::ePipe_SolidDepth];
|
||||
break;
|
||||
case SolidShade::Secondary: pipe = cache.pipes[MeshDisplayPipelines::ePipe_Secondary]; break;
|
||||
case SolidShade::Meshlet: pipe = cache.pipes[MeshDisplayPipelines::ePipe_SolidDepth]; break;
|
||||
}
|
||||
|
||||
pixelData.MeshDisplayFormat = (int)cfg.solidShadeMode;
|
||||
@@ -470,7 +480,20 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
list->SetPipelineState(pipe);
|
||||
list->SetGraphicsRootSignature(cache.rootsig);
|
||||
|
||||
list->SetGraphicsRootConstantBufferView(0, vsCB);
|
||||
size_t numMeshlets = RDCMIN(cfg.position.meshletSizes.size(), (size_t)MAX_NUM_MESHLETS);
|
||||
|
||||
if(cfg.solidShadeMode == SolidShade::Meshlet)
|
||||
{
|
||||
vertexData.meshletCount = (uint32_t)numMeshlets;
|
||||
vertexData.meshletOffset = (uint32_t)cfg.position.meshletOffset;
|
||||
|
||||
vertexData.vertMeshDisplayFormat = MESHDISPLAY_MESHLET;
|
||||
}
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS vsCBSolid =
|
||||
GetDebugManager()->UploadConstants(&vertexData, sizeof(vertexData));
|
||||
|
||||
list->SetGraphicsRootConstantBufferView(0, vsCBSolid);
|
||||
|
||||
if(solidShadeMode == SolidShade::Lit)
|
||||
{
|
||||
@@ -484,6 +507,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
{
|
||||
list->SetGraphicsRootConstantBufferView(1, vsCB); // dummy fill for geometry
|
||||
}
|
||||
list->SetGraphicsRootShaderResourceView(3, meshletBuf);
|
||||
|
||||
Vec4f colour(0.8f, 0.8f, 0.0f, 1.0f);
|
||||
list->SetGraphicsRoot32BitConstants(2, 4, &pixelData, 0);
|
||||
@@ -530,6 +554,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
|
||||
list->SetGraphicsRootConstantBufferView(0, vsCB);
|
||||
list->SetGraphicsRootConstantBufferView(1, vsCB);
|
||||
list->SetGraphicsRootShaderResourceView(3, meshletBuf);
|
||||
|
||||
pixelData.MeshColour.x = cfg.position.meshColor.x;
|
||||
pixelData.MeshColour.y = cfg.position.meshColor.y;
|
||||
@@ -625,6 +650,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
|
||||
list->SetGraphicsRootConstantBufferView(0, vsCB);
|
||||
list->SetGraphicsRootConstantBufferView(1, vsCB);
|
||||
list->SetGraphicsRootShaderResourceView(3, meshletBuf);
|
||||
|
||||
list->DrawInstanced(24, 1, 0, 0);
|
||||
}
|
||||
@@ -652,6 +678,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
|
||||
list->SetGraphicsRootConstantBufferView(0, vsCB);
|
||||
list->SetGraphicsRootConstantBufferView(1, vsCB);
|
||||
list->SetGraphicsRootShaderResourceView(3, meshletBuf);
|
||||
|
||||
pixelData.MeshColour = Vec3f(1.0f, 0.0f, 0.0f);
|
||||
list->SetGraphicsRoot32BitConstants(2, 4, &pixelData, 0);
|
||||
@@ -706,6 +733,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
|
||||
list->SetGraphicsRootConstantBufferView(0, vsCB);
|
||||
list->SetGraphicsRootConstantBufferView(1, vsCB);
|
||||
list->SetGraphicsRootShaderResourceView(3, meshletBuf);
|
||||
|
||||
list->DrawInstanced(24, 1, 0, 0);
|
||||
}
|
||||
@@ -776,6 +804,7 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &secon
|
||||
|
||||
list->SetGraphicsRootConstantBufferView(
|
||||
0, GetDebugManager()->UploadConstants(&vertexData, sizeof(vertexData)));
|
||||
list->SetGraphicsRootShaderResourceView(3, meshletBuf);
|
||||
|
||||
list->SetPipelineState(cache.pipes[MeshDisplayPipelines::ePipe_Solid]);
|
||||
|
||||
|
||||
@@ -3989,13 +3989,19 @@ void VulkanReplay::OverlayRendering::Destroy(WrappedVulkan *driver)
|
||||
|
||||
void VulkanReplay::MeshRendering::Init(WrappedVulkan *driver, VkDescriptorPool descriptorPool)
|
||||
{
|
||||
CREATE_OBJECT(DescSetLayout,
|
||||
{{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL}});
|
||||
CREATE_OBJECT(
|
||||
DescSetLayout,
|
||||
{
|
||||
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL},
|
||||
{1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL},
|
||||
});
|
||||
|
||||
CREATE_OBJECT(PipeLayout, DescSetLayout, 0);
|
||||
CREATE_OBJECT(DescSet, descriptorPool, DescSetLayout);
|
||||
|
||||
UBO.Create(driver, driver->GetDev(), sizeof(MeshUBOData), 16, 0);
|
||||
MeshletSSBO.Create(driver, driver->GetDev(), sizeof(uint32_t) * (4 + MAX_NUM_MESHLETS), 16,
|
||||
GPUBuffer::eGPUBufferSSBO);
|
||||
BBoxVB.Create(driver, driver->GetDev(), sizeof(Vec4f) * 128, 16, GPUBuffer::eGPUBufferVBuffer);
|
||||
|
||||
Vec4f TLN = Vec4f(-1.0f, 1.0f, 0.0f, 1.0f); // TopLeftNear, etc...
|
||||
@@ -4057,13 +4063,17 @@ void VulkanReplay::MeshRendering::Init(WrappedVulkan *driver, VkDescriptorPool d
|
||||
|
||||
AxisFrustumVB.Unmap();
|
||||
|
||||
VkDescriptorBufferInfo meshrender = {};
|
||||
VkDescriptorBufferInfo meshubo = {};
|
||||
VkDescriptorBufferInfo meshssbo = {};
|
||||
|
||||
UBO.FillDescriptor(meshrender);
|
||||
UBO.FillDescriptor(meshubo);
|
||||
MeshletSSBO.FillDescriptor(meshssbo);
|
||||
|
||||
VkWriteDescriptorSet writes[] = {
|
||||
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(DescSet), 0, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, NULL, &meshrender, NULL},
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, NULL, &meshubo, NULL},
|
||||
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(DescSet), 1, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, NULL, &meshssbo, NULL},
|
||||
};
|
||||
|
||||
VkDevice dev = driver->GetDev();
|
||||
@@ -4078,6 +4088,7 @@ void VulkanReplay::MeshRendering::Destroy(WrappedVulkan *driver)
|
||||
|
||||
UBO.Destroy();
|
||||
BBoxVB.Destroy();
|
||||
MeshletSSBO.Destroy();
|
||||
AxisFrustumVB.Destroy();
|
||||
|
||||
driver->vkDestroyDescriptorSetLayout(driver->GetDev(), DescSetLayout, NULL);
|
||||
|
||||
@@ -526,6 +526,8 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv));
|
||||
}
|
||||
|
||||
uint32_t dynOffs[2] = {};
|
||||
|
||||
if(!secondaryDraws.empty())
|
||||
{
|
||||
size_t mapsUsed = 0;
|
||||
@@ -537,8 +539,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
if(fmt.vertexResourceId != ResourceId())
|
||||
{
|
||||
// TODO should move the color to a push constant so we don't have to map all the time
|
||||
uint32_t uboOffs = 0;
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
@@ -584,7 +585,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(secondaryCache.pipes[VKMeshDisplayPipelines::ePipe_WireDepth]));
|
||||
@@ -702,14 +703,14 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
case SolidShade::Secondary:
|
||||
pipe = cache.pipes[VKMeshDisplayPipelines::ePipe_Secondary];
|
||||
break;
|
||||
case SolidShade::Meshlet: pipe = cache.pipes[VKMeshDisplayPipelines::ePipe_SolidDepth]; break;
|
||||
}
|
||||
|
||||
// can't support lit rendering without the pipeline - maybe geometry shader wasn't supported.
|
||||
if(solidShadeMode == SolidShade::Lit && pipe == VK_NULL_HANDLE)
|
||||
pipe = cache.pipes[VKMeshDisplayPipelines::ePipe_SolidDepth];
|
||||
|
||||
uint32_t uboOffs = 0;
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
@@ -726,11 +727,42 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
if(solidShadeMode == SolidShade::Secondary && cfg.second.showAlpha)
|
||||
data->displayFormat = MESHDISPLAY_SECONDARY_ALPHA;
|
||||
|
||||
if(solidShadeMode == SolidShade::Meshlet)
|
||||
{
|
||||
size_t numMeshlets = RDCMIN(cfg.position.meshletSizes.size(), (size_t)MAX_NUM_MESHLETS);
|
||||
|
||||
uint32_t *meshletCounts = (uint32_t *)m_MeshRender.MeshletSSBO.Map(
|
||||
&dynOffs[1], AlignUp4(numMeshlets + 4) * sizeof(uint32_t));
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
if(cfg.position.meshletSizes.size() > MAX_NUM_MESHLETS)
|
||||
RDCWARN("Too many meshlets: %zu, only colouring first %zu of them",
|
||||
cfg.position.meshletSizes.size(), (size_t)MAX_NUM_MESHLETS);
|
||||
|
||||
meshletCounts[0] = (uint32_t)numMeshlets;
|
||||
meshletCounts[1] = (uint32_t)cfg.position.meshletOffset;
|
||||
meshletCounts += 4;
|
||||
|
||||
uint32_t prefixCount = cfg.position.meshletIndexOffset;
|
||||
for(size_t i = 0; i < numMeshlets; i++)
|
||||
{
|
||||
prefixCount += cfg.position.meshletSizes[i].numVertices;
|
||||
meshletCounts[i] = prefixCount;
|
||||
}
|
||||
|
||||
memcpy(&data->meshletColours[0].x, uniqueColors, sizeof(uniqueColors));
|
||||
RDCCOMPILE_ASSERT(sizeof(data->meshletColours) == sizeof(uniqueColors),
|
||||
"Unique colors array is wrongly sized");
|
||||
|
||||
m_MeshRender.MeshletSSBO.Unmap();
|
||||
}
|
||||
|
||||
m_MeshRender.UBO.Unmap();
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe));
|
||||
|
||||
@@ -764,8 +796,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
Vec4f wireCol =
|
||||
Vec4f(cfg.position.meshColor.x, cfg.position.meshColor.y, cfg.position.meshColor.z, 1.0f);
|
||||
|
||||
uint32_t uboOffs = 0;
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
@@ -780,7 +811,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(cache.pipes[VKMeshDisplayPipelines::ePipe_WireDepth]));
|
||||
@@ -858,8 +889,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(m_MeshRender.BBoxVB.buf), &vboffs);
|
||||
|
||||
uint32_t uboOffs = 0;
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
@@ -874,7 +904,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(cache.pipes[VKMeshDisplayPipelines::ePipe_WireDepth]));
|
||||
@@ -888,8 +918,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
VkDeviceSize vboffs = 0;
|
||||
vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(m_MeshRender.AxisFrustumVB.buf), &vboffs);
|
||||
|
||||
uint32_t uboOffs = 0;
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
@@ -904,7 +933,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(cache.pipes[VKMeshDisplayPipelines::ePipe_Wire]));
|
||||
@@ -912,7 +941,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
vt->CmdDraw(Unwrap(cmd), 2, 1, 0, 0);
|
||||
|
||||
// poke the color (this would be a good candidate for a push constant)
|
||||
data = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
data = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
@@ -927,10 +956,10 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
vt->CmdDraw(Unwrap(cmd), 2, 1, 2, 0);
|
||||
|
||||
data = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
data = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
@@ -945,7 +974,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
vt->CmdDraw(Unwrap(cmd), 2, 1, 4, 0);
|
||||
}
|
||||
|
||||
@@ -955,8 +984,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
VkDeviceSize vboffs = sizeof(Vec4f) * 6; // skim the axis helpers
|
||||
vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(m_MeshRender.AxisFrustumVB.buf), &vboffs);
|
||||
|
||||
uint32_t uboOffs = 0;
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
MeshUBOData *data = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
@@ -971,7 +999,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(cache.pipes[VKMeshDisplayPipelines::ePipe_Wire]));
|
||||
@@ -1067,8 +1095,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
uniforms.homogenousInput = cfg.position.unproject;
|
||||
uniforms.pointSpriteSize = Vec2f(0.0f, 0.0f);
|
||||
|
||||
uint32_t uboOffs = 0;
|
||||
MeshUBOData *ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
MeshUBOData *ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!ubodata)
|
||||
return;
|
||||
*ubodata = uniforms;
|
||||
@@ -1076,7 +1103,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(cache.pipes[VKMeshDisplayPipelines::ePipe_Solid]));
|
||||
@@ -1087,14 +1114,14 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
// Draw active primitive (red)
|
||||
uniforms.color = Vec4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
// poke the color (this would be a good candidate for a push constant)
|
||||
ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!ubodata)
|
||||
return;
|
||||
*ubodata = uniforms;
|
||||
m_MeshRender.UBO.Unmap();
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
if(activePrim.size() >= primSize)
|
||||
{
|
||||
@@ -1115,14 +1142,14 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
// Draw adjacent primitives (green)
|
||||
uniforms.color = Vec4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
// poke the color (this would be a good candidate for a push constant)
|
||||
ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!ubodata)
|
||||
return;
|
||||
*ubodata = uniforms;
|
||||
m_MeshRender.UBO.Unmap();
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
if(adjacentPrimVertices.size() >= primSize && (adjacentPrimVertices.size() % primSize) == 0)
|
||||
{
|
||||
@@ -1151,14 +1178,14 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
// Draw active vertex (blue)
|
||||
uniforms.color = Vec4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
// poke the color (this would be a good candidate for a push constant)
|
||||
ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!ubodata)
|
||||
return;
|
||||
*ubodata = uniforms;
|
||||
m_MeshRender.UBO.Unmap();
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
// vertices are drawn with tri strips
|
||||
helper.topology = Topology::TriangleStrip;
|
||||
@@ -1173,7 +1200,7 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(cache.pipes[VKMeshDisplayPipelines::ePipe_Solid]));
|
||||
@@ -1196,14 +1223,14 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray<MeshFormat> &seco
|
||||
// Draw inactive vertices (green)
|
||||
uniforms.color = Vec4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
// poke the color (this would be a good candidate for a push constant)
|
||||
ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&uboOffs);
|
||||
ubodata = (MeshUBOData *)m_MeshRender.UBO.Map(&dynOffs[0]);
|
||||
if(!ubodata)
|
||||
return;
|
||||
*ubodata = uniforms;
|
||||
m_MeshRender.UBO.Unmap();
|
||||
vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
Unwrap(m_MeshRender.PipeLayout), 0, 1,
|
||||
UnwrapPtr(m_MeshRender.DescSet), 1, &uboOffs);
|
||||
UnwrapPtr(m_MeshRender.DescSet), 2, dynOffs);
|
||||
|
||||
if(!inactiveVertices.empty())
|
||||
{
|
||||
|
||||
@@ -682,6 +682,7 @@ private:
|
||||
void Destroy(WrappedVulkan *driver);
|
||||
|
||||
GPUBuffer UBO;
|
||||
GPUBuffer MeshletSSBO;
|
||||
GPUBuffer BBoxVB;
|
||||
GPUBuffer AxisFrustumVB;
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ VulkanShaderCache::VulkanShaderCache(WrappedVulkan *driver)
|
||||
GenerateGLSLShader(source, ShaderType::Vulkan, 430, defines), blob);
|
||||
|
||||
// if we missed the inputHash, make a copy there too.
|
||||
if(m_CacheShaders)
|
||||
if(m_CacheShaders && blob)
|
||||
{
|
||||
m_ShaderCache[inputHash] = new rdcarray<uint32_t>(*blob);
|
||||
m_ShaderCacheDirty = true;
|
||||
|
||||
@@ -1345,6 +1345,17 @@ const Vec4f colorRamp[22] = {
|
||||
Vec4f(1.000000f, 0.878431f, 1.000000f, 1.0f), Vec4f(1.000000f, 1.000000f, 1.000000f, 1.0f),
|
||||
};
|
||||
|
||||
// unique colors generated from https://mokole.com/palette.html
|
||||
const uint32_t uniqueColors[48] = {
|
||||
0xff00008b, 0xff32cd32, 0xff8fbc8f, 0xff8b008b, 0xffb03060, 0xffd2b48c, 0xff9932cc, 0xffff0000,
|
||||
0xffff8c00, 0xffffd700, 0xff00ff00, 0xff00ff7f, 0xff4169e1, 0xffe9967a, 0xffdc143c, 0xff00ffff,
|
||||
0xff00bfff, 0xff0000ff, 0xffa020f0, 0xffadff2f, 0xffff6347, 0xffda70d6, 0xffff00ff, 0xfff0e68c,
|
||||
0xffffff54, 0xff6495ed, 0xffdda0dd, 0xff90ee90, 0xff87ceeb, 0xffff1493, 0xff7fffd4, 0xffff69b4,
|
||||
0xff808080, 0xffc0c0c0, 0xff2f4f4f, 0xff556b2f, 0xff8b4513, 0xff6b8e23, 0xff2e8b57, 0xff8b0000,
|
||||
0xff483d8b, 0xff008000, 0xffb8860b, 0xff008b8b, 0xff4682b4, 0xffd2691e, 0xff9acd32, 0xffcd5c5c,
|
||||
|
||||
};
|
||||
|
||||
bytebuf GetDiscardPattern(DiscardType type, const ResourceFormat &fmt, uint32_t rowPitch, bool invert)
|
||||
{
|
||||
static const rdcliteral patterns[] = {
|
||||
|
||||
@@ -352,6 +352,7 @@ struct HighlightCache
|
||||
};
|
||||
|
||||
extern const Vec4f colorRamp[22];
|
||||
extern const uint32_t uniqueColors[48];
|
||||
|
||||
enum class DiscardType : int
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user