Separate out vulkan current state values to separate proper structure

* This lets us remove a hack for mesh output readback that replays a
  single drawcall with different index count by setting a magic number.
This commit is contained in:
baldurk
2016-02-07 18:48:09 +01:00
parent 521ec84b8b
commit 930e013c9f
12 changed files with 436 additions and 323 deletions
+1
View File
@@ -19,6 +19,7 @@ vk_resources.o \
vk_debug.o \
vk_replay.o \
vk_info.o \
vk_state.o \
vk_linux.o \
wrappers/vk_cmd_funcs.o \
wrappers/vk_dynamic_funcs.o \
@@ -22,6 +22,7 @@
<ClCompile Include="vk_dispatchtables.cpp" />
<ClCompile Include="vk_initstate.cpp" />
<ClCompile Include="vk_memory.cpp" />
<ClCompile Include="vk_state.cpp" />
<ClCompile Include="vk_tracelayer.cpp" />
<ClCompile Include="vk_common.cpp" />
<ClCompile Include="vk_core.cpp" />
@@ -67,6 +68,7 @@
<ClInclude Include="vk_manager.h" />
<ClInclude Include="vk_replay.h" />
<ClInclude Include="vk_resources.h" />
<ClInclude Include="vk_state.h" />
</ItemGroup>
<ItemGroup>
<None Include="windows\renderdoc.json" />
@@ -76,6 +76,9 @@
<ClCompile Include="wrappers\vk_sync_funcs.cpp">
<Filter>Wrappers</Filter>
</ClCompile>
<ClCompile Include="vk_state.cpp">
<Filter>Util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="vk_replay.h">
@@ -105,6 +108,9 @@
<ClInclude Include="vk_core.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="vk_state.h">
<Filter>Util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="OS">
+13 -113
View File
@@ -241,6 +241,7 @@ void VkInitParams::Set(const VkInstanceCreateInfo* pCreateInfo, ResourceId inst)
}
WrappedVulkan::WrappedVulkan(const char *logFilename)
: m_RenderState(m_CreationInfo)
{
#if defined(RELEASE)
const bool debugSerialiser = false;
@@ -285,8 +286,6 @@ WrappedVulkan::WrappedVulkan(const char *logFilename)
m_FirstEventID = 0;
m_LastEventID = ~0U;
m_HackDrawIndices = ~0U;
m_LastCmdBufferID = ResourceId();
m_PartialReplayData.renderPassActive = false;
@@ -300,6 +299,7 @@ WrappedVulkan::WrappedVulkan(const char *logFilename)
m_ResourceManager = new VulkanResourceManager(m_State, m_pSerialiser, this);
m_pSerialiser->SetUserData(m_ResourceManager);
m_RenderState.m_ResourceManager = GetResourceManager();
m_HeaderChunk = NULL;
@@ -1736,7 +1736,8 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
RDCASSERT(m_PartialReplayData.resultPartialCmdBuffer == VK_NULL_HANDLE);
m_PartialReplayData.partialParent = ResourceId();
m_PartialReplayData.baseEvent = 0;
m_PartialReplayData.state = PartialReplayData::StateVector();
m_RenderState = VulkanRenderState(m_CreationInfo);
m_RenderState.m_ResourceManager = GetResourceManager();
}
if(replayType == eReplay_Full)
@@ -1755,124 +1756,23 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
VkResult vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
bool rpWasActive = m_PartialReplayData.renderPassActive;
// if a render pass was active, begin it and set up the partial replay state
if(m_PartialReplayData.renderPassActive)
{
auto &s = m_PartialReplayData.state;
RDCASSERT(s.renderPass != ResourceId());
// clear values don't matter as we're using the load renderpass here, that
// has all load ops set to load (as we're doing a partial replay - can't
// just clear the targets that are partially written to).
VkClearValue empty[16] = {0};
RDCASSERT(ARRAY_COUNT(empty) >= m_CreationInfo.m_RenderPass[s.renderPass].attachments.size());
VkRenderPassBeginInfo rpbegin = {
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL,
Unwrap(m_CreationInfo.m_RenderPass[s.renderPass].loadRP),
Unwrap(GetResourceManager()->GetCurrentHandle<VkFramebuffer>(s.framebuffer)),
s.renderArea,
(uint32_t)m_CreationInfo.m_RenderPass[s.renderPass].attachments.size(), empty,
};
ObjDisp(cmd)->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_RENDER_PASS_CONTENTS_INLINE);
for(uint32_t i=0; i < s.subpass; i++)
ObjDisp(cmd)->CmdNextSubpass(Unwrap(cmd), VK_RENDER_PASS_CONTENTS_INLINE);
if(s.graphics.pipeline != ResourceId())
{
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetResourceManager()->GetCurrentHandle<VkPipeline>(s.graphics.pipeline)));
ResourceId pipeLayoutId = m_CreationInfo.m_Pipeline[s.graphics.pipeline].layout;
VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle<VkPipelineLayout>(pipeLayoutId);
const vector<VkPushConstantRange> &pushRanges = m_CreationInfo.m_PipelineLayout[pipeLayoutId].pushRanges;
// only set push constant ranges that the layout uses
for(size_t i=0; i < pushRanges.size(); i++)
ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags, pushRanges[i].start, pushRanges[i].length, s.pushconsts+pushRanges[i].start);
const vector<ResourceId> &descSetLayouts = m_CreationInfo.m_PipelineLayout[pipeLayoutId].descSetLayouts;
// only iterate over the desc sets that this layout actually uses, not all that were bound
for(size_t i=0; i < descSetLayouts.size(); i++)
{
const DescSetLayout &descLayout = m_CreationInfo.m_DescSetLayout[ descSetLayouts[i] ];
if(i < s.graphics.descSets.size() && s.graphics.descSets[i] != ResourceId())
{
// if there are dynamic buffers, pass along the offsets
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i,
1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(s.graphics.descSets[i])),
descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &s.graphics.offsets[i][0]);
}
else
{
RDCWARN("Descriptor set is not bound but pipeline layout expects one");
}
}
}
if(s.compute.pipeline != ResourceId())
{
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetResourceManager()->GetCurrentHandle<VkPipeline>(s.compute.pipeline)));
ResourceId pipeLayoutId = m_CreationInfo.m_Pipeline[s.compute.pipeline].layout;
VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle<VkPipelineLayout>(pipeLayoutId);
const vector<ResourceId> &descSetLayouts = m_CreationInfo.m_PipelineLayout[pipeLayoutId].descSetLayouts;
for(size_t i=0; i < descSetLayouts.size(); i++)
{
const DescSetLayout &descLayout = m_CreationInfo.m_DescSetLayout[ descSetLayouts[i] ];
if(s.compute.descSets[i] != ResourceId())
{
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i,
1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(s.compute.descSets[i])),
descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &s.compute.offsets[i][0]);
}
}
}
if(!s.views.empty())
ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), (uint32_t)s.views.size(), &s.views[0]);
if(!s.scissors.empty())
ObjDisp(cmd)->CmdSetScissor(Unwrap(cmd), (uint32_t)s.scissors.size(), &s.scissors[0]);
ObjDisp(cmd)->CmdSetBlendConstants(Unwrap(cmd), s.blendConst);
ObjDisp(cmd)->CmdSetDepthBounds(Unwrap(cmd), s.mindepth, s.maxdepth);
ObjDisp(cmd)->CmdSetLineWidth(Unwrap(cmd), s.lineWidth);
ObjDisp(cmd)->CmdSetDepthBias(Unwrap(cmd), s.bias.depth, s.bias.biasclamp, s.bias.slope);
ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, s.back.ref);
ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, s.back.compare);
ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, s.back.write);
ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, s.front.ref);
ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, s.front.compare);
ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, s.front.write);
if(s.ibuffer.buf != ResourceId())
ObjDisp(cmd)->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(GetResourceManager()->GetCurrentHandle<VkBuffer>(s.ibuffer.buf)), s.ibuffer.offs, s.ibuffer.bytewidth == 4 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16);
for(size_t i=0; i < s.vbuffers.size(); i++)
ObjDisp(cmd)->CmdBindVertexBuffers(Unwrap(cmd), (uint32_t)i, 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkBuffer>(s.vbuffers[i].buf)), &s.vbuffers[i].offs);
}
bool rpWasActive = m_PartialReplayData.renderPassActive;
m_RenderState.BeginRenderPassAndApplyState(cmd);
ContextReplayLog(EXECUTING, endEventID, endEventID, partial);
// check if the render pass is active - it could have become active
// even if it wasn't before (if the above event was a CmdBeginRenderPass)
if(m_PartialReplayData.renderPassActive)
ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd));
// we might have replayed a CmdBeginRenderPass or CmdEndRenderPass,
// but we want to keep the partial replay data state intact.
// but we want to keep the partial replay data state intact, so restore
// whether or not a render pass was active.
m_PartialReplayData.renderPassActive = rpWasActive;
ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
@@ -1912,13 +1812,13 @@ void WrappedVulkan::AddDrawcall(FetchDrawcall d, bool hasEvents)
draw.depthOut = ResourceId();
ResourceId pipe = m_PartialReplayData.state.graphics.pipeline;
ResourceId pipe = m_RenderState.graphics.pipeline;
if(pipe != ResourceId())
draw.topology = MakePrimitiveTopology(m_CreationInfo.m_Pipeline[pipe].topology, m_CreationInfo.m_Pipeline[pipe].patchControlPoints);
else
draw.topology = eTopology_Unknown;
draw.indexByteWidth = m_PartialReplayData.state.ibuffer.bytewidth;
draw.indexByteWidth = m_RenderState.ibuffer.bytewidth;
if(m_LastCmdBufferID != ResourceId())
m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount++;
+5 -67
View File
@@ -33,6 +33,7 @@
#include "vk_common.h"
#include "vk_info.h"
#include "vk_state.h"
#include "vk_manager.h"
#include "vk_replay.h"
@@ -304,75 +305,12 @@ private:
// reach the vkEndCommandBuffer that we also need to end a render
// pass.
bool renderPassActive;
// There is only a state while currently partially replaying, it's
// undefined/empty otherwise.
// All IDs are original IDs, not live.
struct StateVector
{
StateVector()
{
compute.pipeline = graphics.pipeline = renderPass = framebuffer = ResourceId();
compute.descSets.clear();
graphics.descSets.clear();
compute.offsets.clear();
graphics.offsets.clear();
lineWidth = 1.0f;
RDCEraseEl(bias);
RDCEraseEl(blendConst);
mindepth = 0.0f; maxdepth = 1.0f;
RDCEraseEl(front);
RDCEraseEl(back);
RDCEraseEl(renderArea);
RDCEraseEl(ibuffer);
vbuffers.clear();
}
// dynamic state
vector<VkViewport> views;
vector<VkRect2D> scissors;
float lineWidth;
struct { float depth, biasclamp, slope; } bias;
float blendConst[4];
float mindepth, maxdepth;
struct { uint32_t compare, write, ref; } front, back;
// this should be big enough for any implementation
byte pushconsts[1024];
ResourceId renderPass;
uint32_t subpass;
ResourceId framebuffer;
VkRect2D renderArea;
struct Pipeline
{
ResourceId pipeline;
vector<ResourceId> descSets;
vector< vector<uint32_t> > offsets;
} compute, graphics;
struct IdxBuffer
{
ResourceId buf;
VkDeviceSize offs;
int bytewidth;
} ibuffer;
struct VertBuffer
{
ResourceId buf;
VkDeviceSize offs;
};
vector<VertBuffer> vbuffers;
} state;
} m_PartialReplayData;
uint32_t m_HackDrawIndices;
// There is only a state while currently partially replaying, it's
// undefined/empty otherwise.
// All IDs are original IDs, not live.
VulkanRenderState m_RenderState;
bool IsPartialCmd(ResourceId cmdid)
{
+68 -71
View File
@@ -2178,7 +2178,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
highlightCol[3] = 1.0f;
// backup state
WrappedVulkan::PartialReplayData::StateVector prevstate = m_pDriver->m_PartialReplayData.state;
VulkanRenderState prevstate = m_pDriver->m_RenderState;
// make patched shader
VkShaderModule mod = VK_NULL_HANDLE;
@@ -2266,23 +2266,23 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
RDCASSERT(vkr == VK_SUCCESS);
// modify state
m_pDriver->m_PartialReplayData.state.renderPass = GetResID(m_OverlayNoDepthRP);
m_pDriver->m_PartialReplayData.state.subpass = 0;
m_pDriver->m_PartialReplayData.state.framebuffer = GetResID(m_OverlayNoDepthFB);
m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP);
m_pDriver->m_RenderState.subpass = 0;
m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB);
m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe);
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe);
// set dynamic scissors in case pipeline was using them
for(size_t i=0; i < m_pDriver->m_PartialReplayData.state.scissors.size(); i++)
for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++)
{
m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0;
m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0;
m_pDriver->m_PartialReplayData.state.scissors[i].extent.width = 4096;
m_pDriver->m_PartialReplayData.state.scissors[i].extent.height = 4096;
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
m_pDriver->m_RenderState.scissors[i].extent.width = 4096;
m_pDriver->m_RenderState.scissors[i].extent.height = 4096;
}
if(overlay == eTexOverlay_Wireframe)
m_pDriver->m_PartialReplayData.state.lineWidth = 1.0f;
m_pDriver->m_RenderState.lineWidth = 1.0f;
m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw);
@@ -2296,7 +2296,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
RDCASSERT(vkr == VK_SUCCESS);
// restore state
m_pDriver->m_PartialReplayData.state = prevstate;
m_pDriver->m_RenderState = prevstate;
m_pDriver->vkDestroyPipeline(m_Device, pipe);
m_pDriver->vkDestroyShaderModule(m_Device, mod);
@@ -2316,26 +2316,26 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
VkRenderPassBeginInfo rpbegin = {
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL,
Unwrap(m_OverlayNoDepthRP), Unwrap(m_OverlayNoDepthFB),
m_pDriver->m_PartialReplayData.state.renderArea,
m_pDriver->m_RenderState.renderArea,
1, &clearval,
};
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_RENDER_PASS_CONTENTS_INLINE);
VkRect3D rect = {
{
m_pDriver->m_PartialReplayData.state.renderArea.offset.x,
m_pDriver->m_PartialReplayData.state.renderArea.offset.y,
m_pDriver->m_RenderState.renderArea.offset.x,
m_pDriver->m_RenderState.renderArea.offset.y,
0,
},
{
m_pDriver->m_PartialReplayData.state.renderArea.extent.width,
m_pDriver->m_PartialReplayData.state.renderArea.extent.height,
m_pDriver->m_RenderState.renderArea.extent.width,
m_pDriver->m_RenderState.renderArea.extent.height,
1,
},
};
vt->CmdClearColorAttachment(Unwrap(cmd), 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, (VkClearColorValue *)black, 1, &rect);
VkViewport viewport = m_pDriver->m_PartialReplayData.state.views[0];
VkViewport viewport = m_pDriver->m_RenderState.views[0];
vt->CmdSetViewport(Unwrap(cmd), 1, &viewport);
uint32_t uboOffs = 0;
@@ -2355,12 +2355,12 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0);
if(!m_pDriver->m_PartialReplayData.state.scissors.empty())
if(!m_pDriver->m_RenderState.scissors.empty())
{
Vec4f scissor((float)m_pDriver->m_PartialReplayData.state.scissors[0].offset.x,
(float)m_pDriver->m_PartialReplayData.state.scissors[0].offset.y,
(float)m_pDriver->m_PartialReplayData.state.scissors[0].extent.width,
(float)m_pDriver->m_PartialReplayData.state.scissors[0].extent.height);
Vec4f scissor((float)m_pDriver->m_RenderState.scissors[0].offset.x,
(float)m_pDriver->m_RenderState.scissors[0].offset.y,
(float)m_pDriver->m_RenderState.scissors[0].extent.width,
(float)m_pDriver->m_RenderState.scissors[0].extent.height);
outlineuniforms *ubo = (outlineuniforms *)m_OutlineUBO.Map(vt, m_Device, &uboOffs);
@@ -2397,7 +2397,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
highlightCol[3] = 1.0f;
// backup state
WrappedVulkan::PartialReplayData::StateVector prevstate = m_pDriver->m_PartialReplayData.state;
VulkanRenderState prevstate = m_pDriver->m_RenderState;
// make patched shader
VkShaderModule mod[2] = {0};
@@ -2495,24 +2495,24 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
RDCASSERT(vkr == VK_SUCCESS);
// modify state
m_pDriver->m_PartialReplayData.state.renderPass = GetResID(m_OverlayNoDepthRP);
m_pDriver->m_PartialReplayData.state.subpass = 0;
m_pDriver->m_PartialReplayData.state.framebuffer = GetResID(m_OverlayNoDepthFB);
m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP);
m_pDriver->m_RenderState.subpass = 0;
m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB);
m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe[0]);
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]);
// set dynamic scissors in case pipeline was using them
for(size_t i=0; i < m_pDriver->m_PartialReplayData.state.scissors.size(); i++)
for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++)
{
m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0;
m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0;
m_pDriver->m_PartialReplayData.state.scissors[i].extent.width = 4096;
m_pDriver->m_PartialReplayData.state.scissors[i].extent.height = 4096;
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
m_pDriver->m_RenderState.scissors[i].extent.width = 4096;
m_pDriver->m_RenderState.scissors[i].extent.height = 4096;
}
m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw);
m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe[1]);
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]);
m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw);
@@ -2526,7 +2526,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
RDCASSERT(vkr == VK_SUCCESS);
// restore state
m_pDriver->m_PartialReplayData.state = prevstate;
m_pDriver->m_RenderState = prevstate;
for(int i=0; i < 2; i++)
{
@@ -2544,7 +2544,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
VkFramebuffer depthFB;
VkRenderPass depthRP;
const WrappedVulkan::PartialReplayData::StateVector &state = m_pDriver->m_PartialReplayData.state;
const VulkanRenderState &state = m_pDriver->m_RenderState;
VulkanCreationInfo &createinfo = m_pDriver->m_CreationInfo;
RDCASSERT(state.subpass < createinfo.m_RenderPass[state.renderPass].subpasses.size());
@@ -2623,7 +2623,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
highlightCol[3] = 1.0f;
// backup state
WrappedVulkan::PartialReplayData::StateVector prevstate = m_pDriver->m_PartialReplayData.state;
VulkanRenderState prevstate = m_pDriver->m_RenderState;
// make patched shader
VkShaderModule mod[2] = {0};
@@ -2730,28 +2730,28 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
RDCASSERT(vkr == VK_SUCCESS);
// modify state
m_pDriver->m_PartialReplayData.state.renderPass = GetResID(m_OverlayNoDepthRP);
m_pDriver->m_PartialReplayData.state.subpass = 0;
m_pDriver->m_PartialReplayData.state.framebuffer = GetResID(m_OverlayNoDepthFB);
m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP);
m_pDriver->m_RenderState.subpass = 0;
m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB);
m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe[0]);
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]);
// set dynamic scissors in case pipeline was using them
for(size_t i=0; i < m_pDriver->m_PartialReplayData.state.scissors.size(); i++)
for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++)
{
m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0;
m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0;
m_pDriver->m_PartialReplayData.state.scissors[i].extent.width = 4096;
m_pDriver->m_PartialReplayData.state.scissors[i].extent.height = 4096;
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
m_pDriver->m_RenderState.scissors[i].extent.width = 4096;
m_pDriver->m_RenderState.scissors[i].extent.height = 4096;
}
m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw);
m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe[1]);
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]);
if(depthRP != VK_NULL_HANDLE)
{
m_pDriver->m_PartialReplayData.state.renderPass = GetResID(depthRP);
m_pDriver->m_PartialReplayData.state.framebuffer = GetResID(depthFB);
m_pDriver->m_RenderState.renderPass = GetResID(depthRP);
m_pDriver->m_RenderState.framebuffer = GetResID(depthFB);
}
m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw);
@@ -2766,7 +2766,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
RDCASSERT(vkr == VK_SUCCESS);
// restore state
m_pDriver->m_PartialReplayData.state = prevstate;
m_pDriver->m_RenderState = prevstate;
for(int i=0; i < 2; i++)
{
@@ -3806,7 +3806,7 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
if(!m_pDriver->GetDeviceFeatures().vertexSideEffects)
return;
WrappedVulkan::PartialReplayData::StateVector &state = m_pDriver->m_PartialReplayData.state;
const VulkanRenderState &state = m_pDriver->m_RenderState;
VulkanCreationInfo &c = m_pDriver->m_CreationInfo;
if(state.graphics.pipeline == ResourceId())
@@ -4079,14 +4079,14 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, &pipe);
RDCASSERT(vkr == VK_SUCCESS);
// backup state
WrappedVulkan::PartialReplayData::StateVector prevstate = state;
// make copy of state to draw from
VulkanRenderState modifiedstate = state;
// bind created pipeline to partial replay state
state.graphics.pipeline = GetResID(pipe);
modifiedstate.graphics.pipeline = GetResID(pipe);
// push back extra descriptor set to partial replay state
state.graphics.descSets.push_back( GetResID(m_MeshFetchDescSet) );
modifiedstate.graphics.descSets.push_back( GetResID(m_MeshFetchDescSet) );
if((drawcall->flags & eDraw_UseIBuffer) == 0)
{
@@ -4151,9 +4151,6 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
};
m_pDriver->vkUpdateDescriptorSets(dev, 1, &write, 0, NULL);
// do single draw
m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw);
VkCmdBuffer cmd = m_pDriver->GetNextCmd();
VkCmdBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, NULL, VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT };
@@ -4161,6 +4158,11 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
// do single draw
modifiedstate.BeginRenderPassAndApplyState(cmd);
ObjDisp(cmd)->CmdDraw(Unwrap(cmd), drawcall->numIndices, drawcall->numInstances, drawcall->vertexOffset, drawcall->instanceOffset);
ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd));
VkBufferMemoryBarrier meshbufbarrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL,
VK_MEMORY_OUTPUT_SHADER_WRITE_BIT, VK_MEMORY_INPUT_TRANSFER_BIT|VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT,
@@ -4280,9 +4282,9 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
bufSize = numVerts*RDCMAX(1U, drawcall->numInstances)*bufStride;
// bind unique'd ibuffer
state.ibuffer.bytewidth = 4;
state.ibuffer.offs = 0;
state.ibuffer.buf = GetResID(uniqIdxBuf);
modifiedstate.ibuffer.bytewidth = 4;
modifiedstate.ibuffer.offs = 0;
modifiedstate.ibuffer.buf = GetResID(uniqIdxBuf);
// vkUpdateDescriptorSet desc set to point to buffer
VkDescriptorInfo fetchdesc = { 0 };
@@ -4299,21 +4301,19 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
// a bit of a hack to ensure we have the right number of indices for rendering.
// we want to have a nicer 'apply current state' function so we can reuse that
// then do our own draw.
m_pDriver->m_HackDrawIndices = (uint32_t)indices.size();
// do single draw
m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw);
m_pDriver->m_HackDrawIndices = ~0U;
cmd = m_pDriver->GetNextCmd();
vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
// do single draw
modifiedstate.BeginRenderPassAndApplyState(cmd);
ObjDisp(cmd)->CmdDrawIndexed(Unwrap(cmd), (uint32_t)indices.size(), drawcall->numInstances, 0, drawcall->vertexOffset, drawcall->instanceOffset);
ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd));
// rebase existing index buffer to point to the right elements in our stream-out'd
// vertex buffer
@@ -4447,9 +4447,6 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
m_pDriver->vkDestroyBuffer(m_Device, uniqIdxBuf);
m_pDriver->vkFreeMemory(m_Device, uniqIdxBufMem);
}
// reset pipeline state back to normal
state = prevstate;
// fill out m_PostVSData
m_PostVSData[idx].vsin.topo = topo;
+3 -3
View File
@@ -2584,7 +2584,7 @@ void VulkanReplay::FileChanged()
void VulkanReplay::SavePipelineState()
{
{
const WrappedVulkan::PartialReplayData::StateVector &state = m_pDriver->m_PartialReplayData.state;
const VulkanRenderState &state = m_pDriver->m_RenderState;
VulkanCreationInfo &c = m_pDriver->m_CreationInfo;
VulkanResourceManager *rm = m_pDriver->GetResourceManager();
@@ -3245,8 +3245,8 @@ void VulkanReplay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, ve
else
{
vector<byte> pushdata;
pushdata.resize(sizeof(m_pDriver->m_PartialReplayData.state.pushconsts));
memcpy(&pushdata[0], m_pDriver->m_PartialReplayData.state.pushconsts, pushdata.size());
pushdata.resize(sizeof(m_pDriver->m_RenderState.pushconsts));
memcpy(&pushdata[0], m_pDriver->m_RenderState.pushconsts, pushdata.size());
FillCBufferVariables(c.variables, outvars, pushdata, zero);
}
+191
View File
@@ -0,0 +1,191 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2015 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.
******************************************************************************/
#include "vk_state.h"
#include "vk_info.h"
#include "vk_resources.h"
VulkanRenderState::VulkanRenderState(VulkanCreationInfo &createInfo)
: m_CreationInfo(createInfo)
{
compute.pipeline = graphics.pipeline = renderPass = framebuffer = ResourceId();
compute.descSets.clear();
graphics.descSets.clear();
compute.offsets.clear();
graphics.offsets.clear();
views.clear();
scissors.clear();
lineWidth = 1.0f;
RDCEraseEl(bias);
RDCEraseEl(blendConst);
mindepth = 0.0f; maxdepth = 1.0f;
RDCEraseEl(front);
RDCEraseEl(back);
RDCEraseEl(pushconsts);
renderPass = ResourceId();
subpass = 0;
RDCEraseEl(renderArea);
RDCEraseEl(ibuffer);
vbuffers.clear();
}
VulkanRenderState & VulkanRenderState::operator =(const VulkanRenderState &o)
{
views = o.views;
scissors = o.scissors;
lineWidth = o.lineWidth;
bias = o.bias;
memcpy(blendConst, o.blendConst, sizeof(blendConst));
mindepth = o.mindepth;
maxdepth = o.maxdepth;
front = o.front;
back = o.back;
memcpy(pushconsts, o.pushconsts, sizeof(pushconsts));
renderPass = o.renderPass;
subpass = o.subpass;
framebuffer = o.framebuffer;
renderArea = o.renderArea;
compute.pipeline = o.compute.pipeline;
compute.descSets = o.compute.descSets;
compute.offsets = o.compute.offsets;
graphics.pipeline = o.graphics.pipeline;
graphics.descSets = o.graphics.descSets;
graphics.offsets = o.graphics.offsets;
ibuffer = o.ibuffer;
vbuffers = o.vbuffers;
return *this;
}
void VulkanRenderState::BeginRenderPassAndApplyState(VkCmdBuffer cmd)
{
RDCASSERT(renderPass != ResourceId());
// clear values don't matter as we're using the load renderpass here, that
// has all load ops set to load (as we're doing a partial replay - can't
// just clear the targets that are partially written to).
VkClearValue empty[16] = {0};
RDCASSERT(ARRAY_COUNT(empty) >= m_CreationInfo.m_RenderPass[renderPass].attachments.size());
VkRenderPassBeginInfo rpbegin = {
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL,
Unwrap(m_CreationInfo.m_RenderPass[renderPass].loadRP),
Unwrap(GetResourceManager()->GetCurrentHandle<VkFramebuffer>(framebuffer)),
renderArea,
(uint32_t)m_CreationInfo.m_RenderPass[renderPass].attachments.size(), empty,
};
ObjDisp(cmd)->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_RENDER_PASS_CONTENTS_INLINE);
for(uint32_t i=0; i < subpass; i++)
ObjDisp(cmd)->CmdNextSubpass(Unwrap(cmd), VK_RENDER_PASS_CONTENTS_INLINE);
if(graphics.pipeline != ResourceId())
{
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetResourceManager()->GetCurrentHandle<VkPipeline>(graphics.pipeline)));
ResourceId pipeLayoutId = m_CreationInfo.m_Pipeline[graphics.pipeline].layout;
VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle<VkPipelineLayout>(pipeLayoutId);
const vector<VkPushConstantRange> &pushRanges = m_CreationInfo.m_PipelineLayout[pipeLayoutId].pushRanges;
// only set push constant ranges that the layout uses
for(size_t i=0; i < pushRanges.size(); i++)
ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags, pushRanges[i].start, pushRanges[i].length, pushconsts+pushRanges[i].start);
const vector<ResourceId> &descSetLayouts = m_CreationInfo.m_PipelineLayout[pipeLayoutId].descSetLayouts;
// only iterate over the desc sets that this layout actually uses, not all that were bound
for(size_t i=0; i < descSetLayouts.size(); i++)
{
const DescSetLayout &descLayout = m_CreationInfo.m_DescSetLayout[ descSetLayouts[i] ];
if(i < graphics.descSets.size() && graphics.descSets[i] != ResourceId())
{
// if there are dynamic buffers, pass along the offsets
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i,
1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(graphics.descSets[i])),
descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &graphics.offsets[i][0]);
}
else
{
RDCWARN("Descriptor set is not bound but pipeline layout expects one");
}
}
}
if(compute.pipeline != ResourceId())
{
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetResourceManager()->GetCurrentHandle<VkPipeline>(compute.pipeline)));
ResourceId pipeLayoutId = m_CreationInfo.m_Pipeline[compute.pipeline].layout;
VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle<VkPipelineLayout>(pipeLayoutId);
const vector<ResourceId> &descSetLayouts = m_CreationInfo.m_PipelineLayout[pipeLayoutId].descSetLayouts;
for(size_t i=0; i < descSetLayouts.size(); i++)
{
const DescSetLayout &descLayout = m_CreationInfo.m_DescSetLayout[ descSetLayouts[i] ];
if(compute.descSets[i] != ResourceId())
{
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i,
1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(compute.descSets[i])),
descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &compute.offsets[i][0]);
}
}
}
if(!views.empty())
ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), (uint32_t)views.size(), &views[0]);
if(!scissors.empty())
ObjDisp(cmd)->CmdSetScissor(Unwrap(cmd), (uint32_t)scissors.size(), &scissors[0]);
ObjDisp(cmd)->CmdSetBlendConstants(Unwrap(cmd), blendConst);
ObjDisp(cmd)->CmdSetDepthBounds(Unwrap(cmd), mindepth, maxdepth);
ObjDisp(cmd)->CmdSetLineWidth(Unwrap(cmd), lineWidth);
ObjDisp(cmd)->CmdSetDepthBias(Unwrap(cmd), bias.depth, bias.biasclamp, bias.slope);
ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.ref);
ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.compare);
ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.write);
ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.ref);
ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.compare);
ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.write);
if(ibuffer.buf != ResourceId())
ObjDisp(cmd)->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(GetResourceManager()->GetCurrentHandle<VkBuffer>(ibuffer.buf)), ibuffer.offs, ibuffer.bytewidth == 4 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16);
for(size_t i=0; i < vbuffers.size(); i++)
ObjDisp(cmd)->CmdBindVertexBuffers(Unwrap(cmd), (uint32_t)i, 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkBuffer>(vbuffers[i].buf)), &vbuffers[i].offs);
}
+85
View File
@@ -0,0 +1,85 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2015 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.
******************************************************************************/
#pragma once
#include <vector>
#include "vk_common.h"
struct VulkanCreationInfo;
class VulkanResourceManager;
struct VulkanRenderState
{
VulkanRenderState(VulkanCreationInfo &createInfo);
VulkanRenderState &operator =(const VulkanRenderState &o);
void BeginRenderPassAndApplyState(VkCmdBuffer cmd);
// dynamic state
vector<VkViewport> views;
vector<VkRect2D> scissors;
float lineWidth;
struct { float depth, biasclamp, slope; } bias;
float blendConst[4];
float mindepth, maxdepth;
struct { uint32_t compare, write, ref; } front, back;
// this should be big enough for any implementation
byte pushconsts[1024];
ResourceId renderPass;
uint32_t subpass;
ResourceId framebuffer;
VkRect2D renderArea;
struct Pipeline
{
ResourceId pipeline;
vector<ResourceId> descSets;
vector< vector<uint32_t> > offsets;
} compute, graphics;
struct IdxBuffer
{
ResourceId buf;
VkDeviceSize offs;
int bytewidth;
} ibuffer;
struct VertBuffer
{
ResourceId buf;
VkDeviceSize offs;
};
vector<VertBuffer> vbuffers;
VulkanResourceManager *GetResourceManager() { return m_ResourceManager; }
VulkanResourceManager *m_ResourceManager;
VulkanCreationInfo &m_CreationInfo;
};
@@ -28,8 +28,8 @@ string WrappedVulkan::MakeRenderPassOpString(bool store)
{
string opDesc = "";
const VulkanCreationInfo::RenderPass &info = m_CreationInfo.m_RenderPass[m_PartialReplayData.state.renderPass];
const VulkanCreationInfo::Framebuffer &fbinfo = m_CreationInfo.m_Framebuffer[m_PartialReplayData.state.framebuffer];
const VulkanCreationInfo::RenderPass &info = m_CreationInfo.m_RenderPass[m_RenderState.renderPass];
const VulkanCreationInfo::Framebuffer &fbinfo = m_CreationInfo.m_Framebuffer[m_RenderState.framebuffer];
const vector<VulkanCreationInfo::RenderPass::Attachment> &atts = info.attachments;
@@ -42,7 +42,7 @@ string WrappedVulkan::MakeRenderPassOpString(bool store)
bool colsame = true;
// find which attachment is the depth-stencil one
int32_t dsAttach = info.subpasses[m_PartialReplayData.state.subpass].depthstencilAttachment;
int32_t dsAttach = info.subpasses[m_RenderState.subpass].depthstencilAttachment;
bool hasStencil = false;
bool depthonly = false;
@@ -51,7 +51,7 @@ string WrappedVulkan::MakeRenderPassOpString(bool store)
if(dsAttach >= 0)
{
hasStencil = !IsDepthOnlyFormat(fbinfo.attachments[dsAttach].format);
depthonly = info.subpasses[m_PartialReplayData.state.subpass].colorAttachments.size() == 0;
depthonly = info.subpasses[m_RenderState.subpass].colorAttachments.size() == 0;
}
// first colour attachment, if there is one
@@ -585,11 +585,11 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(
m_PartialReplayData.renderPassActive = true;
ObjDisp(cmdBuffer)->CmdBeginRenderPass(Unwrap(cmdBuffer), &beginInfo, cont);
m_PartialReplayData.state.subpass = 0;
m_RenderState.subpass = 0;
m_PartialReplayData.state.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id;
m_PartialReplayData.state.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id;
m_PartialReplayData.state.renderArea = beginInfo.renderArea;
m_RenderState.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id;
m_RenderState.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id;
m_RenderState.renderArea = beginInfo.renderArea;
}
}
else if(m_State == READING)
@@ -599,9 +599,9 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(
ObjDisp(cmdBuffer)->CmdBeginRenderPass(Unwrap(cmdBuffer), &beginInfo, cont);
// track during reading
m_PartialReplayData.state.subpass = 0;
m_PartialReplayData.state.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id;
m_PartialReplayData.state.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id;
m_RenderState.subpass = 0;
m_RenderState.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id;
m_RenderState.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id;
const string desc = localSerialiser->GetDebugStr();
@@ -674,7 +674,7 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass(
{
cmdBuffer = PartialCmdBuf();
m_PartialReplayData.state.subpass++;
m_RenderState.subpass++;
ObjDisp(cmdBuffer)->CmdNextSubpass(Unwrap(cmdBuffer), cont);
}
@@ -686,13 +686,13 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass(
ObjDisp(cmdBuffer)->CmdNextSubpass(Unwrap(cmdBuffer), cont);
// track during reading
m_PartialReplayData.state.subpass++;
m_RenderState.subpass++;
const string desc = localSerialiser->GetDebugStr();
AddEvent(NEXT_SUBPASS, desc);
FetchDrawcall draw;
draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", m_PartialReplayData.state.subpass);
draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", m_RenderState.subpass);
draw.flags |= eDraw_Clear;
AddDrawcall(draw, true);
@@ -893,51 +893,51 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline(
ResourceId liveid = GetResID(pipeline);
if(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
m_PartialReplayData.state.graphics.pipeline = liveid;
m_RenderState.graphics.pipeline = liveid;
else
m_PartialReplayData.state.compute.pipeline = liveid;
m_RenderState.compute.pipeline = liveid;
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_VIEWPORT])
{
m_PartialReplayData.state.views = m_CreationInfo.m_Pipeline[liveid].viewports;
m_RenderState.views = m_CreationInfo.m_Pipeline[liveid].viewports;
}
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_SCISSOR])
{
m_PartialReplayData.state.scissors = m_CreationInfo.m_Pipeline[liveid].scissors;
m_RenderState.scissors = m_CreationInfo.m_Pipeline[liveid].scissors;
}
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_LINE_WIDTH])
{
m_PartialReplayData.state.lineWidth = m_CreationInfo.m_Pipeline[liveid].lineWidth;
m_RenderState.lineWidth = m_CreationInfo.m_Pipeline[liveid].lineWidth;
}
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BIAS])
{
m_PartialReplayData.state.bias.depth = m_CreationInfo.m_Pipeline[liveid].depthBias;
m_PartialReplayData.state.bias.biasclamp = m_CreationInfo.m_Pipeline[liveid].depthBiasClamp;
m_PartialReplayData.state.bias.slope = m_CreationInfo.m_Pipeline[liveid].slopeScaledDepthBias;
m_RenderState.bias.depth = m_CreationInfo.m_Pipeline[liveid].depthBias;
m_RenderState.bias.biasclamp = m_CreationInfo.m_Pipeline[liveid].depthBiasClamp;
m_RenderState.bias.slope = m_CreationInfo.m_Pipeline[liveid].slopeScaledDepthBias;
}
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_BLEND_CONSTANTS])
{
memcpy(m_PartialReplayData.state.blendConst, m_CreationInfo.m_Pipeline[liveid].blendConst, sizeof(float)*4);
memcpy(m_RenderState.blendConst, m_CreationInfo.m_Pipeline[liveid].blendConst, sizeof(float)*4);
}
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BOUNDS])
{
m_PartialReplayData.state.mindepth = m_CreationInfo.m_Pipeline[liveid].minDepthBounds;
m_PartialReplayData.state.maxdepth = m_CreationInfo.m_Pipeline[liveid].maxDepthBounds;
m_RenderState.mindepth = m_CreationInfo.m_Pipeline[liveid].minDepthBounds;
m_RenderState.maxdepth = m_CreationInfo.m_Pipeline[liveid].maxDepthBounds;
}
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK])
{
m_PartialReplayData.state.front.compare = m_CreationInfo.m_Pipeline[liveid].front.stencilCompareMask;
m_PartialReplayData.state.back.compare = m_CreationInfo.m_Pipeline[liveid].back.stencilCompareMask;
m_RenderState.front.compare = m_CreationInfo.m_Pipeline[liveid].front.stencilCompareMask;
m_RenderState.back.compare = m_CreationInfo.m_Pipeline[liveid].back.stencilCompareMask;
}
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK])
{
m_PartialReplayData.state.front.write = m_CreationInfo.m_Pipeline[liveid].front.stencilWriteMask;
m_PartialReplayData.state.back.write = m_CreationInfo.m_Pipeline[liveid].back.stencilWriteMask;
m_RenderState.front.write = m_CreationInfo.m_Pipeline[liveid].front.stencilWriteMask;
m_RenderState.back.write = m_CreationInfo.m_Pipeline[liveid].back.stencilWriteMask;
}
if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_REFERENCE])
{
m_PartialReplayData.state.front.ref = m_CreationInfo.m_Pipeline[liveid].front.stencilReference;
m_PartialReplayData.state.back.ref = m_CreationInfo.m_Pipeline[liveid].back.stencilReference;
m_RenderState.front.ref = m_CreationInfo.m_Pipeline[liveid].front.stencilReference;
m_RenderState.back.ref = m_CreationInfo.m_Pipeline[liveid].back.stencilReference;
}
}
}
@@ -948,9 +948,9 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline(
// track this while reading, as we need to bind current topology & index byte width to draws
if(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
m_PartialReplayData.state.graphics.pipeline = GetResID(pipeline);
m_RenderState.graphics.pipeline = GetResID(pipeline);
else
m_PartialReplayData.state.compute.pipeline = GetResID(pipeline);
m_RenderState.compute.pipeline = GetResID(pipeline);
ObjDisp(cmdBuffer)->CmdBindPipeline(Unwrap(cmdBuffer), bind, Unwrap(pipeline));
}
@@ -1036,13 +1036,13 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets(
vector<ResourceId> &descsets =
(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
? m_PartialReplayData.state.graphics.descSets
: m_PartialReplayData.state.compute.descSets;
? m_RenderState.graphics.descSets
: m_RenderState.compute.descSets;
vector< vector<uint32_t> > &offsets =
(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
? m_PartialReplayData.state.graphics.offsets
: m_PartialReplayData.state.compute.offsets;
? m_RenderState.graphics.offsets
: m_RenderState.compute.offsets;
// expand as necessary
if(descsets.size() < first + numSets)
@@ -1195,13 +1195,13 @@ bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers(
cmdBuffer = PartialCmdBuf();
ObjDisp(cmdBuffer)->CmdBindVertexBuffers(Unwrap(cmdBuffer), start, count, &bufs[0], &offs[0]);
if(m_PartialReplayData.state.vbuffers.size() < start + count)
m_PartialReplayData.state.vbuffers.resize(start + count);
if(m_RenderState.vbuffers.size() < start + count)
m_RenderState.vbuffers.resize(start + count);
for(uint32_t i=0; i < count; i++)
{
m_PartialReplayData.state.vbuffers[start + i].buf = bufids[i];
m_PartialReplayData.state.vbuffers[start + i].offs = offs[i];
m_RenderState.vbuffers[start + i].buf = bufids[i];
m_RenderState.vbuffers[start + i].offs = offs[i];
}
}
}
@@ -1272,9 +1272,9 @@ bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer(
cmdBuffer = PartialCmdBuf();
ObjDisp(cmdBuffer)->CmdBindIndexBuffer(Unwrap(cmdBuffer), Unwrap(buffer), offs, idxType);
m_PartialReplayData.state.ibuffer.buf = GetResID(buffer);
m_PartialReplayData.state.ibuffer.offs = offs;
m_PartialReplayData.state.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2;
m_RenderState.ibuffer.buf = GetResID(buffer);
m_RenderState.ibuffer.offs = offs;
m_RenderState.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2;
}
}
else if(m_State == READING)
@@ -1283,7 +1283,7 @@ bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer(
buffer = GetResourceManager()->GetLiveHandle<VkBuffer>(bufid);
// track this while reading, as we need to bind current topology & index byte width to draws
m_PartialReplayData.state.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2;
m_RenderState.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2;
ObjDisp(cmdBuffer)->CmdBindIndexBuffer(Unwrap(cmdBuffer), Unwrap(buffer), offs, idxType);
}
@@ -1486,9 +1486,9 @@ bool WrappedVulkan::Serialise_vkCmdPushConstants(
layout = GetResourceManager()->GetLiveHandle<VkPipelineLayout>(layid);
ObjDisp(cmdBuffer)->CmdPushConstants(Unwrap(cmdBuffer), Unwrap(layout), flags, s, len, vals);
RDCASSERT(s+len < (uint32_t)ARRAY_COUNT(m_PartialReplayData.state.pushconsts));
RDCASSERT(s+len < (uint32_t)ARRAY_COUNT(m_RenderState.pushconsts));
memcpy(m_PartialReplayData.state.pushconsts + s, vals, len);
memcpy(m_RenderState.pushconsts + s, vals, len);
}
}
else if(m_State == READING)
@@ -1048,13 +1048,6 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexed(
if(IsPartialCmd(cmdid) && InPartialRange())
{
cmdBuffer = PartialCmdBuf();
if(m_HackDrawIndices != ~0U)
{
firstIdx = 0;
idxCount = m_HackDrawIndices;
}
ObjDisp(cmdBuffer)->CmdDrawIndexed(Unwrap(cmdBuffer), idxCount, instCount, firstIdx, vtxOffs, firstInst);
}
}
@@ -43,7 +43,7 @@ bool WrappedVulkan::Serialise_vkCmdSetViewport(
{
cmdBuffer = PartialCmdBuf();
ObjDisp(cmdBuffer)->CmdSetViewport(Unwrap(cmdBuffer), count, views);
m_PartialReplayData.state.views.assign(views, views + count);
m_RenderState.views.assign(views, views + count);
}
}
else if(m_State == READING)
@@ -97,7 +97,7 @@ bool WrappedVulkan::Serialise_vkCmdSetScissor(
{
cmdBuffer = PartialCmdBuf();
ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), count, scissors);
m_PartialReplayData.state.scissors.assign(scissors, scissors + count);
m_RenderState.scissors.assign(scissors, scissors + count);
}
}
else if(m_State == READING)
@@ -149,7 +149,7 @@ bool WrappedVulkan::Serialise_vkCmdSetLineWidth(
{
cmdBuffer = PartialCmdBuf();
ObjDisp(cmdBuffer)->CmdSetLineWidth(Unwrap(cmdBuffer), width);
m_PartialReplayData.state.lineWidth = width;
m_RenderState.lineWidth = width;
}
}
else if(m_State == READING)
@@ -202,9 +202,9 @@ bool WrappedVulkan::Serialise_vkCmdSetDepthBias(
{
cmdBuffer = PartialCmdBuf();
ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope);
m_PartialReplayData.state.bias.depth = bias;
m_PartialReplayData.state.bias.biasclamp = biasclamp;
m_PartialReplayData.state.bias.slope = slope;
m_RenderState.bias.depth = bias;
m_RenderState.bias.biasclamp = biasclamp;
m_RenderState.bias.slope = slope;
}
}
else if(m_State == READING)
@@ -263,7 +263,7 @@ bool WrappedVulkan::Serialise_vkCmdSetBlendConstants(
{
cmdBuffer = PartialCmdBuf();
ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendFactor);
memcpy(m_PartialReplayData.state.blendConst, blendFactor, sizeof(blendFactor));
memcpy(m_RenderState.blendConst, blendFactor, sizeof(blendFactor));
}
}
else if(m_State == READING)
@@ -314,8 +314,8 @@ bool WrappedVulkan::Serialise_vkCmdSetDepthBounds(
{
cmdBuffer = PartialCmdBuf();
ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd);
m_PartialReplayData.state.mindepth = mind;
m_PartialReplayData.state.maxdepth = maxd;
m_RenderState.mindepth = mind;
m_RenderState.maxdepth = maxd;
}
}
else if(m_State == READING)
@@ -369,9 +369,9 @@ bool WrappedVulkan::Serialise_vkCmdSetStencilCompareMask(
ObjDisp(cmdBuffer)->CmdSetStencilCompareMask(Unwrap(cmdBuffer), face, mask);
if(face & VK_STENCIL_FACE_FRONT_BIT)
m_PartialReplayData.state.front.compare = mask;
m_RenderState.front.compare = mask;
if(face & VK_STENCIL_FACE_BACK_BIT)
m_PartialReplayData.state.back.compare = mask;
m_RenderState.back.compare = mask;
}
}
else if(m_State == READING)
@@ -425,9 +425,9 @@ bool WrappedVulkan::Serialise_vkCmdSetStencilWriteMask(
ObjDisp(cmdBuffer)->CmdSetStencilWriteMask(Unwrap(cmdBuffer), face, mask);
if(face & VK_STENCIL_FACE_FRONT_BIT)
m_PartialReplayData.state.front.write = mask;
m_RenderState.front.write = mask;
if(face & VK_STENCIL_FACE_BACK_BIT)
m_PartialReplayData.state.back.write = mask;
m_RenderState.back.write = mask;
}
}
else if(m_State == READING)
@@ -481,9 +481,9 @@ bool WrappedVulkan::Serialise_vkCmdSetStencilReference(
ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), face, mask);
if(face & VK_STENCIL_FACE_FRONT_BIT)
m_PartialReplayData.state.front.ref = mask;
m_RenderState.front.ref = mask;
if(face & VK_STENCIL_FACE_BACK_BIT)
m_PartialReplayData.state.back.ref = mask;
m_RenderState.back.ref = mask;
}
}
else if(m_State == READING)