Work around presumed QC driver bug storing to array slices

This commit is contained in:
baldurk
2020-05-14 20:33:20 +01:00
parent b1b33d5605
commit e31ebd0f55
4 changed files with 92 additions and 70 deletions
+8 -21
View File
@@ -43,16 +43,14 @@ layout(binding = 2) writeonly uniform PRECISION uimage2DArray dstArray;
layout(push_constant) uniform multisamplePush
{
int numMultiSamples;
int currentSample;
int currentSlice;
uint currentStencil;
int baseSlice;
int baseSample;
}
mscopy;
#define numMultiSamples (mscopy.numMultiSamples)
#define currentSample (mscopy.currentSample)
#define currentSlice (mscopy.currentSlice)
#define currentStencil (mscopy.currentStencil)
#define baseSlice (mscopy.baseSlice)
#define baseSample (mscopy.baseSample)
#else
@@ -61,27 +59,16 @@ layout(rgba32ui, binding = 2) writeonly uniform PRECISION uimage2DArray dstArray
uniform ivec4 mscopy;
#define numMultiSamples (mscopy.x)
#define currentSample (mscopy.y)
#define currentSlice (mscopy.z)
#define currentStencil (mscopy.w)
#define baseSlice (mscopy.y)
#define baseSample (mscopy.z)
#endif
void main()
{
ivec3 id = ivec3(gl_GlobalInvocationID);
int slice;
int sampleIdx;
if(numMultiSamples == 0)
{
slice = currentSlice;
sampleIdx = currentSample;
}
else
{
slice = int(id.z / numMultiSamples);
sampleIdx = int(id.z % numMultiSamples);
}
int slice = baseSlice + int(id.z / numMultiSamples);
int sampleIdx = baseSample + int(id.z % numMultiSamples);
uvec4 data = texelFetch(srcMS, ivec3(int(id.x), int(id.y), slice), sampleIdx);
+8 -5
View File
@@ -415,16 +415,16 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
VulkanShaderCache *shaderCache = driver->GetShaderCache();
// we need just one descriptor for MS<->Array
VkDescriptorPoolSize poolTypes[] = {
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2}, {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1},
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2 * ARRAY_COUNT(m_ArrayMSDescSet)},
{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 * ARRAY_COUNT(m_ArrayMSDescSet)},
};
VkDescriptorPoolCreateInfo poolInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
NULL,
0,
1,
ARRAY_COUNT(m_ArrayMSDescSet),
ARRAY_COUNT(poolTypes),
&poolTypes[0],
};
@@ -638,9 +638,12 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
RDCERR("Couldn't find any integer format we could generate a dummy multisampled image with");
}
CREATE_OBJECT(m_ArrayMSDescSet, m_ArrayMSDescriptorPool, m_ArrayMSDescSetLayout);
for(size_t i = 0; i < ARRAY_COUNT(m_ArrayMSDescSet); i++)
{
CREATE_OBJECT(m_ArrayMSDescSet[i], m_ArrayMSDescriptorPool, m_ArrayMSDescSetLayout);
rm->SetInternalResource(GetResID(m_ArrayMSDescSet));
rm->SetInternalResource(GetResID(m_ArrayMSDescSet[i]));
}
VkFormat formats[] = {
VK_FORMAT_D16_UNORM, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_X8_D24_UNORM_PACK32,
+2 -1
View File
@@ -117,7 +117,8 @@ private:
VkDescriptorPool m_ArrayMSDescriptorPool;
VkDescriptorSetLayout m_ArrayMSDescSetLayout = VK_NULL_HANDLE;
VkPipelineLayout m_ArrayMSPipeLayout = VK_NULL_HANDLE;
VkDescriptorSet m_ArrayMSDescSet = VK_NULL_HANDLE;
// 8 descriptor sets allows for 4x MSAA with 2 array slices, common for VR targets
VkDescriptorSet m_ArrayMSDescSet[8] = {};
VkPipeline m_Array2MSPipe = VK_NULL_HANDLE;
VkPipeline m_MS2ArrayPipe = VK_NULL_HANDLE;
VkSampler m_ArrayMSSampler = VK_NULL_HANDLE;
+74 -43
View File
@@ -96,54 +96,85 @@ void VulkanDebugManager::CopyTex2DMSToArray(VkImage destArray, VkImage srcMS, Vk
viewInfo.image = destArray;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &destView);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
const uint32_t batchSize = ARRAY_COUNT(m_ArrayMSDescSet);
VkDescriptorImageInfo srcdesc = {0};
srcdesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
srcdesc.imageView = srcView;
srcdesc.sampler = Unwrap(m_ArrayMSSampler); // not used - we use texelFetch
rdcarray<VkImageView> views;
VkDescriptorImageInfo destdesc = {0};
destdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
destdesc.imageView = destView;
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 0, 0, 1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc, NULL, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 2, 0, 1,
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &destdesc, NULL, NULL},
};
ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL);
VkCommandBuffer cmd = m_pDriver->GetNextCmd();
VkCommandBuffer cmd = VK_NULL_HANDLE;
VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
for(uint32_t slice = 0; slice < layers * samples; slice++)
{
// if we don't have a current cmd buffer, start a new one
if(cmd == VK_NULL_HANDLE)
{
cmd = m_pDriver->GetNextCmd();
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(m_MS2ArrayPipe));
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE,
Unwrap(m_ArrayMSPipeLayout), 0, 1,
UnwrapPtr(m_ArrayMSDescSet), 0, NULL);
ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
Vec4u params = {samples, 0, 0, 0};
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE,
Unwrap(m_MS2ArrayPipe));
}
ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(m_ArrayMSPipeLayout), VK_SHADER_STAGE_ALL, 0,
sizeof(Vec4u), &params);
uint32_t batchIndex = slice % batchSize;
ObjDisp(cmd)->CmdDispatch(Unwrap(cmd), extent.width, extent.height, layers * samples);
viewInfo.subresourceRange.baseArrayLayer = slice;
ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &destView);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
// submit cmds and wait for idle so we can readback
m_pDriver->SubmitCmds();
m_pDriver->FlushQ();
views.push_back(destView);
VkDescriptorImageInfo srcdesc = {0};
srcdesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
srcdesc.imageView = srcView;
srcdesc.sampler = Unwrap(m_ArrayMSSampler); // not used - we use texelFetch
VkDescriptorImageInfo destdesc = {0};
destdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
destdesc.imageView = destView;
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet[batchIndex]), 0, 0,
1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc, NULL, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet[batchIndex]), 2, 0,
1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &destdesc, NULL, NULL},
};
ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL);
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE,
Unwrap(m_ArrayMSPipeLayout), 0, 1,
UnwrapPtr(m_ArrayMSDescSet[batchIndex]), 0, NULL);
Vec4u params = {samples, slice / samples, slice % samples, 0};
ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(m_ArrayMSPipeLayout), VK_SHADER_STAGE_ALL, 0,
sizeof(Vec4u), &params);
ObjDisp(cmd)->CmdDispatch(Unwrap(cmd), extent.width, extent.height, 1);
// if we're about to end a batch, or we're done entirely, submit and flush
if(batchIndex == batchSize - 1 || slice == layers * samples - 1)
{
ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
cmd = VK_NULL_HANDLE;
// submit cmds and wait for idle so we can readback
m_pDriver->SubmitCmds();
m_pDriver->FlushQ();
}
}
RDCASSERT(cmd == VK_NULL_HANDLE);
for(VkImageView view : views)
ObjDisp(dev)->DestroyImageView(Unwrap(dev), view, NULL);
ObjDisp(dev)->DestroyImageView(Unwrap(dev), srcView, NULL);
ObjDisp(dev)->DestroyImageView(Unwrap(dev), destView, NULL);
}
void VulkanDebugManager::CopyDepthTex2DMSToArray(VkImage destArray, VkImage srcMS, VkExtent3D extent,
@@ -251,9 +282,9 @@ void VulkanDebugManager::CopyDepthTex2DMSToArray(VkImage destArray, VkImage srcM
}
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 0, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet[0]), 0, 0, 1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc[0], NULL, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 1, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet[0]), 1, 0, 1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc[1], NULL, NULL},
};
@@ -345,7 +376,7 @@ void VulkanDebugManager::CopyDepthTex2DMSToArray(VkImage destArray, VkImage srcM
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe));
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
Unwrap(m_ArrayMSPipeLayout), 0, 1,
UnwrapPtr(m_ArrayMSDescSet), 0, NULL);
UnwrapPtr(m_ArrayMSDescSet[0]), 0, NULL);
VkViewport viewport = {0.0f, 0.0f, (float)extent.width, (float)extent.height, 0.0f, 1.0f};
ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport);
@@ -467,9 +498,9 @@ void VulkanDebugManager::CopyArrayToTex2DMS(VkImage destMS, VkImage srcArray, Vk
destdesc.imageView = destView;
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 0, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet[0]), 0, 0, 1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc, NULL, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 2, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet[0]), 2, 0, 1,
VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &destdesc, NULL, NULL},
};
@@ -485,7 +516,7 @@ void VulkanDebugManager::CopyArrayToTex2DMS(VkImage destMS, VkImage srcArray, Vk
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(m_Array2MSPipe));
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE,
Unwrap(m_ArrayMSPipeLayout), 0, 1,
UnwrapPtr(m_ArrayMSDescSet), 0, NULL);
UnwrapPtr(m_ArrayMSDescSet[0]), 0, NULL);
Vec4u params = {samples, 0, 0, 0};
@@ -618,9 +649,9 @@ void VulkanDebugManager::CopyDepthArrayToTex2DMS(VkImage destMS, VkImage srcArra
}
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 0, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet[0]), 0, 0, 1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc[0], NULL, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet), 1, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_ArrayMSDescSet[0]), 1, 0, 1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &srcdesc[1], NULL, NULL},
};
@@ -713,7 +744,7 @@ void VulkanDebugManager::CopyDepthArrayToTex2DMS(VkImage destMS, VkImage srcArra
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe));
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
Unwrap(m_ArrayMSPipeLayout), 0, 1,
UnwrapPtr(m_ArrayMSDescSet), 0, NULL);
UnwrapPtr(m_ArrayMSDescSet[0]), 0, NULL);
VkViewport viewport = {0.0f, 0.0f, (float)extent.width, (float)extent.height, 0.0f, 1.0f};
ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport);