Make sure to resize offsets and descSets at the same time

* Fixes a crash when selecting an object with no descriptor sets bound
  (as the fetching of post-VS output added a descriptor set, but not
  an offset array).
This commit is contained in:
baldurk
2016-04-18 20:45:55 +02:00
parent c43f40a063
commit 6aae7b31cc
5 changed files with 57 additions and 35 deletions
+2 -2
View File
@@ -2636,7 +2636,7 @@ struct QuadOverdrawCallback : public DrawcallCallback
pipestate.graphics.pipeline = GetResID(pipe.second);
RDCASSERT(pipestate.graphics.descSets.size() >= pipe.first);
pipestate.graphics.descSets.resize(pipe.first+1);
pipestate.graphics.descSets[pipe.first] = GetResID(m_pDebug->m_QuadDescSet);
pipestate.graphics.descSets[pipe.first].descSet = GetResID(m_pDebug->m_QuadDescSet);
if(cmd)
pipestate.BindPipeline(cmd);
@@ -5208,7 +5208,7 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t eventID)
// bind to the slot we're using
RDCASSERT(modifiedstate.graphics.descSets.size() >= descSet);
modifiedstate.graphics.descSets.resize(descSet+1);
modifiedstate.graphics.descSets[descSet] = GetResID(m_MeshFetchDescSet);
modifiedstate.graphics.descSets[descSet].descSet = GetResID(m_MeshFetchDescSet);
if((drawcall->flags & eDraw_UseIBuffer) == 0)
{
+2 -2
View File
@@ -3135,7 +3135,7 @@ void VulkanReplay::SavePipelineState()
&m_VulkanPipelineState.compute.DescSets,
};
const vector<ResourceId> *srcs[] = {
const vector<VulkanRenderState::Pipeline::DescriptorAndOffsets> *srcs[] = {
&state.graphics.descSets,
&state.compute.descSets,
};
@@ -3144,7 +3144,7 @@ void VulkanReplay::SavePipelineState()
{
for(size_t i=0; i < srcs[p]->size(); i++)
{
ResourceId src = (*srcs[p])[i];
ResourceId src = (*srcs[p])[i].descSet;
VulkanPipelineState::Pipeline::DescriptorSet &dst = (*dsts[p])[i];
ResourceId layoutId = m_pDriver->m_DescriptorSetState[src].layout;
+39 -14
View File
@@ -32,8 +32,6 @@ VulkanRenderState::VulkanRenderState(VulkanCreationInfo *createInfo)
compute.pipeline = graphics.pipeline = renderPass = framebuffer = ResourceId();
compute.descSets.clear();
graphics.descSets.clear();
compute.offsets.clear();
graphics.offsets.clear();
views.clear();
scissors.clear();
@@ -73,11 +71,9 @@ VulkanRenderState & VulkanRenderState::operator =(const VulkanRenderState &o)
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;
@@ -158,7 +154,7 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd)
{
const DescSetLayout &descLayout = m_CreationInfo->m_DescSetLayout[ descSetLayouts[i] ];
if(i < graphics.descSets.size() && graphics.descSets[i] != ResourceId())
if(i < graphics.descSets.size() && graphics.descSets[i].descSet != ResourceId())
{
// if there are dynamic buffers, pass along the offsets
@@ -166,16 +162,16 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd)
if(descLayout.dynamicCount > 0)
{
dynamicOffsets = &graphics.offsets[i][0];
dynamicOffsets = &graphics.descSets[i].offsets[0];
if(graphics.offsets[i].size() < descLayout.dynamicCount)
if(graphics.descSets[i].offsets.size() < descLayout.dynamicCount)
{
dynamicOffsets = new uint32_t[descLayout.dynamicCount];
for(uint32_t o = 0; o < descLayout.dynamicCount; o++)
{
if(o < graphics.offsets[i].size())
if(o < graphics.descSets[i].offsets.size())
{
dynamicOffsets[o] = graphics.offsets[i][o];
dynamicOffsets[o] = graphics.descSets[i].offsets[o];
}
else
{
@@ -187,10 +183,10 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd)
}
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i,
1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(graphics.descSets[i])),
1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(graphics.descSets[i].descSet)),
descLayout.dynamicCount, dynamicOffsets);
if(graphics.offsets[i].size() < descLayout.dynamicCount)
if(graphics.descSets[i].offsets.size() < descLayout.dynamicCount)
SAFE_DELETE_ARRAY(dynamicOffsets);
}
else
@@ -219,11 +215,40 @@ void VulkanRenderState::BindPipeline(VkCommandBuffer cmd)
{
const DescSetLayout &descLayout = m_CreationInfo->m_DescSetLayout[ descSetLayouts[i] ];
if(compute.descSets[i] != ResourceId())
if(i < compute.descSets.size() && compute.descSets[i].descSet != ResourceId())
{
// if there are dynamic buffers, pass along the offsets
uint32_t *dynamicOffsets = NULL;
if(descLayout.dynamicCount > 0)
{
dynamicOffsets = &compute.descSets[i].offsets[0];
if(compute.descSets[i].offsets.size() < descLayout.dynamicCount)
{
dynamicOffsets = new uint32_t[descLayout.dynamicCount];
for(uint32_t o = 0; o < descLayout.dynamicCount; o++)
{
if(o < compute.descSets[i].offsets.size())
{
dynamicOffsets[o] = compute.descSets[i].offsets[o];
}
else
{
dynamicOffsets[o] = 0;
RDCWARN("Missing dynamic offset for set %u!", (uint32_t)i);
}
}
}
}
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(layout), (uint32_t)i,
1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(compute.descSets[i])),
descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &compute.offsets[i][0]);
1, UnwrapPtr(GetResourceManager()->GetCurrentHandle<VkDescriptorSet>(compute.descSets[i].descSet)),
descLayout.dynamicCount, dynamicOffsets);
if(compute.descSets[i].offsets.size() < descLayout.dynamicCount)
SAFE_DELETE_ARRAY(dynamicOffsets);
}
}
}
+7 -2
View File
@@ -60,8 +60,13 @@ struct VulkanRenderState
struct Pipeline
{
ResourceId pipeline;
vector<ResourceId> descSets;
vector< vector<uint32_t> > offsets;
struct DescriptorAndOffsets
{
ResourceId descSet;
vector<uint32_t> offsets;
};
vector<DescriptorAndOffsets> descSets;
} compute, graphics;
struct IdxBuffer
@@ -1109,22 +1109,14 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets(
ObjDisp(commandBuffer)->CmdBindDescriptorSets(Unwrap(commandBuffer), bind, Unwrap(layout), first, numSets, sets, offsCount, offs);
vector<ResourceId> &descsets =
vector<VulkanRenderState::Pipeline::DescriptorAndOffsets> &descsets =
(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
? m_RenderState.graphics.descSets
: m_RenderState.compute.descSets;
vector< vector<uint32_t> > &offsets =
(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
? m_RenderState.graphics.offsets
: m_RenderState.compute.offsets;
// expand as necessary
if(descsets.size() < first + numSets)
{
descsets.resize(first + numSets);
offsets.resize(first + numSets);
}
const vector<ResourceId> &descSetLayouts = m_CreationInfo.m_PipelineLayout[GetResID(layout)].descSetLayouts;
@@ -1134,9 +1126,9 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets(
// consume the offsets linearly along the descriptor set layouts
for(uint32_t i=0; i < numSets; i++)
{
descsets[first+i] = descriptorIDs[i];
descsets[first+i].descSet = descriptorIDs[i];
uint32_t dynCount = m_CreationInfo.m_DescSetLayout[ descSetLayouts[first+i] ].dynamicCount;
offsets[first+i].assign(offsIter, offsIter+dynCount);
descsets[first+i].offsets.assign(offsIter, offsIter+dynCount);
dynConsumed += dynCount;
RDCASSERT(dynConsumed <= offsCount);
}
@@ -1181,17 +1173,17 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets(
layout = GetResourceManager()->GetLiveHandle<VkPipelineLayout>(layoutid);
// track while reading, as we need to track resource usage
vector<ResourceId> &descsets =
vector<VulkanRenderState::Pipeline::DescriptorAndOffsets> &descsets =
(bind == VK_PIPELINE_BIND_POINT_GRAPHICS)
? m_BakedCmdBufferInfo[m_LastCmdBufferID].state.graphicsDescSets
: m_BakedCmdBufferInfo[m_LastCmdBufferID].state.computeDescSets;
? m_RenderState.graphics.descSets
: m_RenderState.compute.descSets;
// expand as necessary
if(descsets.size() < first + numSets)
descsets.resize(first + numSets);
for(uint32_t i=0; i < numSets; i++)
descsets[first+i] = descriptorIDs[i];
descsets[first+i].descSet = descriptorIDs[i];
ObjDisp(commandBuffer)->CmdBindDescriptorSets(Unwrap(commandBuffer), bind, Unwrap(layout), first, numSets, sets, offsCount, offs);
}