Fix handling of S8 multisampled textures. Closes #2883

This commit is contained in:
baldurk
2023-03-14 16:32:06 +00:00
parent 31d5fa9eb3
commit 38afb7c8ad
10 changed files with 295 additions and 71 deletions
+1
View File
@@ -108,6 +108,7 @@ precision highp int;
#define SHADER_D24_UNORM_S8_UINT 3
#define SHADER_D32_SFLOAT 4
#define SHADER_D32_SFLOAT_S8_UINT 5
#define SHADER_S8_UINT 6
// divide MS<->buffer workgroups by 64
#define MS_DISPATCH_LOCAL_SIZE 64
+20
View File
@@ -102,6 +102,26 @@ void main()
uint stencilData = srcData[idx * 2 + 1];
stencil = stencilData & 0xFF;
}
else if(format == SHADER_S8_UINT)
{
uint stencilData = srcData[idx / 4];
if((idx % 4) == 0)
{
stencil = stencilData & 0x000000FF;
}
else if((idx % 4) == 1)
{
stencil = (stencilData & 0x0000FF00) >> 8;
}
else if((idx % 4) == 2)
{
stencil = (stencilData & 0x00FF0000) >> 16;
}
else
{
stencil = (stencilData & 0xFF000000) >> 24;
}
}
if(currentStencil < 256u)
{
@@ -115,4 +115,24 @@ void main()
result[dispatchOffset + (idx * 2 + 0)] = floatBitsToUint(depth);
result[dispatchOffset + (idx * 2 + 1)] = stencil;
}
// For S8, we need to sample 4 pixels at a time
else if(format == SHADER_S8_UINT)
{
int pxIdx = int(idx * 4);
int x0 = (pxIdx + 0) % textureWidth;
int y0 = (pxIdx + 0) / textureWidth;
int x1 = (pxIdx + 1) % textureWidth;
int y1 = (pxIdx + 1) / textureWidth;
int x2 = (pxIdx + 2) % textureWidth;
int y2 = (pxIdx + 2) / textureWidth;
int x3 = (pxIdx + 3) % textureWidth;
int y3 = (pxIdx + 3) / textureWidth;
uvec4 stencil = uvec4(texelFetch(srcStencilMS, ivec3(x0, y0, slice), sampleIdx).x,
texelFetch(srcStencilMS, ivec3(x1, y1, slice), sampleIdx).x,
texelFetch(srcStencilMS, ivec3(x2, y2, slice), sampleIdx).x,
texelFetch(srcStencilMS, ivec3(x3, y3, slice), sampleIdx).x);
result[dispatchOffset + idx] = ((stencil.x & 0xFF) << 0) | ((stencil.y & 0xFF) << 8) |
((stencil.z & 0xFF) << 16) | ((stencil.w & 0xFF) << 24);
}
}
+142 -30
View File
@@ -374,25 +374,6 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
//////////////////////////////////////////////////////////////////
// Color MS <-> Buffer copy (via compute)
VkDescriptorPoolSize bufferPoolTypes[] = {
{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2},
{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1},
{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1},
};
VkDescriptorPoolCreateInfo bufferPoolInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
NULL,
0,
1,
ARRAY_COUNT(bufferPoolTypes),
&bufferPoolTypes[0],
};
vkr = m_pDriver->vkCreateDescriptorPool(dev, &bufferPoolInfo, NULL, &m_BufferMSDescriptorPool);
CheckVkResult(vkr);
rm->SetInternalResource(GetResID(m_BufferMSDescriptorPool));
CREATE_OBJECT(m_BufferMSDescSetLayout,
{
@@ -419,12 +400,41 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
rm->SetInternalResource(GetResID(m_DepthMS2BufferPipe));
rm->SetInternalResource(GetResID(m_Buffer2MSPipe));
CREATE_OBJECT(m_BufferMSDescSet, m_BufferMSDescriptorPool, m_BufferMSDescSetLayout);
rm->SetInternalResource(GetResID(m_BufferMSDescSet));
//////////////////////////////////////////////////////////////////
// Depth MS to Buffer copy (via compute)
// need a dummy float formatted texture but that's easy as we can pick something guaranteed by the
// spec
{
VkImageCreateInfo imInfo = {
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
NULL,
0,
VK_IMAGE_TYPE_2D,
// format is required to be supported for sampling
VK_FORMAT_R8G8B8A8_UNORM,
{1, 1, 1},
1,
1,
// sampledImageColorSampleCounts must include VK_SAMPLE_COUNT_4_BIT for 2D non-integer
// optimal tiled textures
VK_SAMPLE_COUNT_4_BIT,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_SAMPLED_BIT,
VK_SHARING_MODE_EXCLUSIVE,
0,
NULL,
VK_IMAGE_LAYOUT_UNDEFINED,
};
vkr = driver->vkCreateImage(driver->GetDev(), &imInfo, NULL, &m_DummyDepthImage);
CheckVkResult(vkr);
NameVulkanObject(m_DummyDepthImage, "m_DummyDepthImage");
rm->SetInternalResource(GetResID(m_DummyDepthImage));
}
// need a dummy UINT texture to fill the binding when we don't have a stencil aspect to copy.
// unfortunately there's no single guaranteed UINT format that can be sampled as MSAA, so we try a
// few since hopefully we'll find one that will work.
@@ -502,24 +512,45 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
rm->SetInternalResource(GetResID(m_DummyStencilImage));
VkMemoryRequirements depthmrq = {};
driver->vkGetImageMemoryRequirements(driver->GetDev(), m_DummyDepthImage, &depthmrq);
VkMemoryRequirements mrq = {};
driver->vkGetImageMemoryRequirements(driver->GetDev(), m_DummyStencilImage, &mrq);
// assume we can combine these images into one allocation
RDCASSERT((mrq.memoryTypeBits & depthmrq.memoryTypeBits) != 0, mrq.memoryTypeBits,
depthmrq.memoryTypeBits);
// only use memory types that support both
mrq.memoryTypeBits &= depthmrq.memoryTypeBits;
// use worst case alignment
mrq.alignment = RDCMAX(mrq.alignment, depthmrq.alignment);
// align each size individually (to worst case alignment)
depthmrq.size = AlignUp(depthmrq.size, mrq.alignment);
mrq.size = AlignUp(mrq.size, mrq.alignment);
// allocate memory
VkMemoryAllocateInfo allocInfo = {
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size,
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, depthmrq.size + mrq.size,
driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits),
};
vkr = driver->vkAllocateMemory(driver->GetDev(), &allocInfo, NULL, &m_DummyStencilMemory);
vkr = driver->vkAllocateMemory(driver->GetDev(), &allocInfo, NULL, &m_DummyMemory);
CheckVkResult(vkr);
if(vkr != VK_SUCCESS)
return;
rm->SetInternalResource(GetResID(m_DummyStencilMemory));
rm->SetInternalResource(GetResID(m_DummyMemory));
vkr = driver->vkBindImageMemory(driver->GetDev(), m_DummyStencilImage, m_DummyStencilMemory, 0);
NameVulkanObject(m_DummyStencilImage, "m_DummyMemory");
vkr = driver->vkBindImageMemory(driver->GetDev(), m_DummyStencilImage, m_DummyMemory, 0);
CheckVkResult(vkr);
vkr = driver->vkBindImageMemory(driver->GetDev(), m_DummyDepthImage, m_DummyMemory, mrq.size);
CheckVkResult(vkr);
VkImageViewCreateInfo viewInfo = {
@@ -543,6 +574,16 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
rm->SetInternalResource(GetResID(m_DummyStencilView));
viewInfo.image = m_DummyDepthImage;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
vkr = driver->vkCreateImageView(driver->GetDev(), &viewInfo, NULL, &m_DummyDepthView);
CheckVkResult(vkr);
NameVulkanObject(m_DummyDepthView, "m_DummyDepthView");
rm->SetInternalResource(GetResID(m_DummyDepthView));
VkCommandBuffer cmd = driver->GetNextCmd();
if(cmd == VK_NULL_HANDLE)
@@ -570,6 +611,10 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
DoPipelineBarrier(cmd, 1, &barrier);
barrier.image = Unwrap(m_DummyDepthImage);
barrierAspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
DoPipelineBarrier(cmd, 1, &barrier);
ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
break;
@@ -583,6 +628,7 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver)
VkFormat formats[] = {
VK_FORMAT_D16_UNORM, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_X8_D24_UNORM_PACK32,
VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_S8_UINT,
};
VkSampleCountFlagBits sampleCounts[] = {
@@ -739,11 +785,14 @@ VulkanDebugManager::~VulkanDebugManager()
for(uint32_t i = 0; i < VKMeshDisplayPipelines::ePipe_Count; i++)
m_pDriver->vkDestroyPipeline(dev, it->second.pipes[i], NULL);
m_pDriver->vkDestroyDescriptorPool(dev, m_BufferMSDescriptorPool, NULL);
for(VkDescriptorPool pool : m_BufferMSDescriptorPools)
m_pDriver->vkDestroyDescriptorPool(dev, pool, NULL);
m_pDriver->vkDestroyImageView(dev, m_DummyDepthView, NULL);
m_pDriver->vkDestroyImage(dev, m_DummyDepthImage, NULL);
m_pDriver->vkDestroyImageView(dev, m_DummyStencilView, NULL);
m_pDriver->vkDestroyImage(dev, m_DummyStencilImage, NULL);
m_pDriver->vkFreeMemory(dev, m_DummyStencilMemory, NULL);
m_pDriver->vkFreeMemory(dev, m_DummyMemory, NULL);
m_pDriver->vkDestroyDescriptorSetLayout(dev, m_BufferMSDescSetLayout, NULL);
m_pDriver->vkDestroyPipelineLayout(dev, m_BufferMSPipeLayout, NULL);
@@ -1667,6 +1716,68 @@ const WrappedVulkan::DescriptorSetInfo &VulkanDebugManager::GetDescSetInfo(Resou
return it->second;
}
VkDescriptorSet VulkanDebugManager::GetBufferMSDescSet()
{
if(m_FreeBufferMSDescriptorSets.empty())
{
WrappedVulkan *driver = m_pDriver;
VulkanResourceManager *rm = driver->GetResourceManager();
VkResult vkr = VK_SUCCESS;
VkDevice dev = m_pDriver->GetDev();
VkDescriptorPoolSize bufferPoolTypes[] = {
{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2 * BufferMSDescriptorPoolSize},
{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 * BufferMSDescriptorPoolSize},
{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 * BufferMSDescriptorPoolSize},
};
VkDescriptorPoolCreateInfo bufferPoolInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
NULL,
0,
BufferMSDescriptorPoolSize,
ARRAY_COUNT(bufferPoolTypes),
&bufferPoolTypes[0],
};
VkDescriptorPool pool;
vkr = m_pDriver->vkCreateDescriptorPool(dev, &bufferPoolInfo, NULL, &pool);
CheckVkResult(vkr);
rm->SetInternalResource(GetResID(pool));
m_BufferMSDescriptorPools.push_back(pool);
rdcarray<VkDescriptorSetLayout> setLayouts;
setLayouts.fill(BufferMSDescriptorPoolSize, m_BufferMSDescSetLayout);
VkDescriptorSetAllocateInfo descSetAllocInfo = {
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
NULL,
pool,
(uint32_t)setLayouts.size(),
setLayouts.data(),
};
m_FreeBufferMSDescriptorSets.resize(BufferMSDescriptorPoolSize);
m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, m_FreeBufferMSDescriptorSets.data());
for(VkDescriptorSet set : m_FreeBufferMSDescriptorSets)
rm->SetInternalResource(GetResID(set));
}
VkDescriptorSet ret = m_FreeBufferMSDescriptorSets.back();
m_FreeBufferMSDescriptorSets.pop_back();
m_UsedBufferMSDescriptorSets.push_back(ret);
return ret;
}
void VulkanDebugManager::ResetBufferMSDescriptorPools()
{
m_FreeBufferMSDescriptorSets.append(m_UsedBufferMSDescriptorSets);
m_UsedBufferMSDescriptorSets.clear();
}
void VulkanDebugManager::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, bytebuf &ret)
{
VkDevice dev = m_pDriver->GetDev();
@@ -1847,7 +1958,7 @@ void VulkanDebugManager::FillWithDiscardPattern(VkCommandBuffer cmd, DiscardType
VkMarkerRegion marker(
cmd, StringFormat::Fmt("FillWithDiscardPattern %s", ToStr(GetResID(image)).c_str()));
VkImageAspectFlags imAspects = FormatImageAspects(imInfo.format);
const VkImageAspectFlags imAspects = FormatImageAspects(imInfo.format);
VkImageSubresourceRange barrierDiscardRange = discardRange;
barrierDiscardRange.aspectMask = imAspects;
@@ -2049,7 +2160,8 @@ void VulkanDebugManager::FillWithDiscardPattern(VkCommandBuffer cmd, DiscardType
&pass);
uint32_t offset = 0;
if(imAspects != discardRange.aspectMask)
if(imAspects != discardRange.aspectMask &&
imAspects == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
{
// if we're only discarding one of depth or stencil in a depth/stencil image, pick a
// framebuffer that only targets that aspect.
+10 -4
View File
@@ -124,21 +124,27 @@ private:
std::map<uint64_t, VKMeshDisplayPipelines> m_CachedMeshPipelines;
// CopyBufferToTex2DMS
VkDescriptorPool m_BufferMSDescriptorPool;
VkDescriptorSetLayout m_BufferMSDescSetLayout = VK_NULL_HANDLE;
VkPipelineLayout m_BufferMSPipeLayout = VK_NULL_HANDLE;
VkDescriptorSet m_BufferMSDescSet = VK_NULL_HANDLE;
static const uint32_t BufferMSDescriptorPoolSize = 64;
rdcarray<VkDescriptorPool> m_BufferMSDescriptorPools;
rdcarray<VkDescriptorSet> m_FreeBufferMSDescriptorSets;
rdcarray<VkDescriptorSet> m_UsedBufferMSDescriptorSets;
VkDescriptorSet GetBufferMSDescSet();
void ResetBufferMSDescriptorPools();
VkPipeline m_Buffer2MSPipe = VK_NULL_HANDLE;
VkPipeline m_MS2BufferPipe = VK_NULL_HANDLE;
VkPipeline m_DepthMS2BufferPipe = VK_NULL_HANDLE;
// MSAA dummy images
VkDeviceMemory m_DummyStencilMemory = VK_NULL_HANDLE;
VkDeviceMemory m_DummyMemory = VK_NULL_HANDLE;
VkImage m_DummyDepthImage = {VK_NULL_HANDLE};
VkImageView m_DummyDepthView = {VK_NULL_HANDLE};
VkImage m_DummyStencilImage = {VK_NULL_HANDLE};
VkImageView m_DummyStencilView = {VK_NULL_HANDLE};
// one per depth/stencil output format, per sample count
VkPipeline m_DepthArray2MSPipe[6][4] = {{VK_NULL_HANDLE}};
VkPipeline m_DepthArray2MSPipe[7][4] = {{VK_NULL_HANDLE}};
VkPipelineCache m_PipelineCache = VK_NULL_HANDLE;
+68 -25
View File
@@ -117,18 +117,20 @@ void VulkanDebugManager::CopyTex2DMSToBuffer(VkBuffer destBuffer, VkImage srcMS,
destdesc.offset = 0;
destdesc.range = VK_WHOLE_SIZE;
VkDescriptorSet descSet = GetBufferMSDescSet();
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 0, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 0, 0, 1,
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc, NULL, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 2, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 2, 0, 1,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL},
};
ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL);
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE,
Unwrap(m_BufferMSPipeLayout), 0, 1,
UnwrapPtr(m_BufferMSDescSet), 0, NULL);
Unwrap(m_BufferMSPipeLayout), 0, 1, UnwrapPtr(descSet), 0,
NULL);
for(uint32_t currentSlice = baseSlice; currentSlice < numSlices + baseSlice; currentSlice++)
{
@@ -168,6 +170,7 @@ void VulkanDebugManager::CopyTex2DMSToBuffer(VkBuffer destBuffer, VkImage srcMS,
RDCASSERT(cmd == VK_NULL_HANDLE);
ObjDisp(dev)->DestroyImageView(Unwrap(dev), srcView, NULL);
ResetBufferMSDescriptorPools();
}
void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage srcMS,
@@ -197,6 +200,10 @@ void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage s
fmtIndex = SHADER_D32_SFLOAT_S8_UINT;
aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
break;
case VK_FORMAT_S8_UINT:
fmtIndex = SHADER_S8_UINT;
aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT;
break;
default: RDCERR("Unexpected depth format: %d", fmt); return;
}
@@ -220,9 +227,12 @@ void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage s
},
};
vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &srcDepthView);
CheckVkResult(vkr);
NameUnwrappedVulkanObject(srcDepthView, "Depth MS -> Array srcDepthView");
if(aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT)
{
vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &srcDepthView);
CheckVkResult(vkr);
NameUnwrappedVulkanObject(srcDepthView, "Depth MS -> Array srcDepthView");
}
if(aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT)
{
@@ -254,6 +264,21 @@ void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage s
srcdesc[1].imageView = srcStencilView;
srcdesc[1].sampler = VK_NULL_HANDLE; // not used - we use texelFetch
if((aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT) == 0)
{
if(m_DummyDepthView != VK_NULL_HANDLE)
{
srcdesc[0].imageView = Unwrap(m_DummyDepthView);
}
else
{
// as a last fallback, hope that setting an incompatible view (float not int) will not break
// too badly. This only gets hit when the implementation has such poor format support that
// there are no float formats that can be sampled as MSAA.
srcdesc[0].imageView = srcStencilView;
}
}
if((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) == 0)
{
if(m_DummyStencilView != VK_NULL_HANDLE)
@@ -277,27 +302,30 @@ void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage s
destdesc.offset = 0;
destdesc.range = VK_WHOLE_SIZE;
VkDescriptorSet descSet = GetBufferMSDescSet();
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 0, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 0, 0, 1,
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc[0], NULL, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 1, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 1, 0, 1,
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc[1], NULL, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 2, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 2, 0, 1,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL},
};
ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL);
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE,
Unwrap(m_BufferMSPipeLayout), 0, 1,
UnwrapPtr(m_BufferMSDescSet), 0, NULL);
Unwrap(m_BufferMSPipeLayout), 0, 1, UnwrapPtr(descSet), 0,
NULL);
for(uint32_t currentSlice = baseSlice; currentSlice < numSlices + baseSlice; currentSlice++)
{
for(uint32_t currentSample = baseSample; currentSample < numSamples + baseSample; currentSample++)
{
// for D16 textures, we need to multisample.
const uint32_t msDivider = fmt == VK_FORMAT_D16_UNORM ? 2 : 1;
// for D16 and S8 textures, we need to multisample.
const uint32_t msDivider =
(fmt == VK_FORMAT_D16_UNORM) ? 2 : (fmt == VK_FORMAT_S8_UINT) ? 4 : 1;
const uint32_t workGroupDivider = MS_DISPATCH_LOCAL_SIZE * msDivider;
const uint32_t numWorkGroup =
AlignUp(extent.width * extent.height, workGroupDivider) / workGroupDivider;
@@ -326,9 +354,11 @@ void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage s
RDCASSERT(cmd == VK_NULL_HANDLE);
ObjDisp(dev)->DestroyImageView(Unwrap(dev), srcDepthView, NULL);
if(srcDepthView != VK_NULL_HANDLE)
ObjDisp(dev)->DestroyImageView(Unwrap(dev), srcDepthView, NULL);
if(srcStencilView != VK_NULL_HANDLE)
ObjDisp(dev)->DestroyImageView(Unwrap(dev), srcStencilView, NULL);
ResetBufferMSDescriptorPools();
}
void VulkanDebugManager::CopyBufferToTex2DMS(VkCommandBuffer cmd, VkImage destMS,
@@ -407,6 +437,8 @@ void VulkanDebugManager::CopyBufferToTex2DMS(VkCommandBuffer cmd, VkImage destMS
if(cmd == VK_NULL_HANDLE)
return;
VkDescriptorSet descSet = GetBufferMSDescSet();
{
VkMarkerRegion region(cmd, "CopyBufferToTex2DMS");
@@ -428,17 +460,17 @@ void VulkanDebugManager::CopyBufferToTex2DMS(VkCommandBuffer cmd, VkImage destMS
destdesc.sampler = VK_NULL_HANDLE;
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 2, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 2, 0, 1,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &srcdesc, NULL},
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 3, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 3, 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_BufferMSPipeLayout), 0, 1,
UnwrapPtr(m_BufferMSDescSet), 0, NULL);
Unwrap(m_BufferMSPipeLayout), 0, 1, UnwrapPtr(descSet), 0,
NULL);
for(uint32_t currentSlice = 0; currentSlice < numSlices; currentSlice++)
{
@@ -468,8 +500,10 @@ void VulkanDebugManager::CopyBufferToTex2DMS(VkCommandBuffer cmd, VkImage destMS
if(endCommand)
ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
m_pDriver->AddPendingObjectCleanup(
[dev, destView]() { ObjDisp(dev)->DestroyImageView(Unwrap(dev), destView, NULL); });
m_pDriver->AddPendingObjectCleanup([this, dev, destView]() {
ObjDisp(dev)->DestroyImageView(Unwrap(dev), destView, NULL);
ResetBufferMSDescriptorPools();
});
}
void VulkanDebugManager::CopyDepthBufferToTex2DMS(VkCommandBuffer cmd, VkImage destMS,
@@ -510,6 +544,11 @@ void VulkanDebugManager::CopyDepthBufferToTex2DMS(VkCommandBuffer cmd, VkImage d
aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
formatIndex = SHADER_D32_SFLOAT_S8_UINT;
break;
case VK_FORMAT_S8_UINT:
pipeIndex = 6;
aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT;
formatIndex = SHADER_S8_UINT;
break;
default: RDCERR("Unexpected depth format: %d", fmt); return;
}
@@ -563,8 +602,10 @@ void VulkanDebugManager::CopyDepthBufferToTex2DMS(VkCommandBuffer cmd, VkImage d
NameUnwrappedVulkanObject(destView[i], "Depth Array -> MS destView[i]");
}
VkDescriptorSet descSet = GetBufferMSDescSet();
VkWriteDescriptorSet writeSet[] = {
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 2, 0, 1,
{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descSet), 2, 0, 1,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &srcdesc, NULL},
};
@@ -672,8 +713,8 @@ void VulkanDebugManager::CopyDepthBufferToTex2DMS(VkCommandBuffer cmd, VkImage d
ObjDisp(cmd)->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
Unwrap(m_BufferMSPipeLayout), 0, 1,
UnwrapPtr(m_BufferMSDescSet), 0, NULL);
Unwrap(m_BufferMSPipeLayout), 0, 1, UnwrapPtr(descSet), 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);
@@ -697,12 +738,14 @@ void VulkanDebugManager::CopyDepthBufferToTex2DMS(VkCommandBuffer cmd, VkImage d
if(endCommand)
ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
m_pDriver->AddPendingObjectCleanup([dev, fb, rp, destView]() {
m_pDriver->AddPendingObjectCleanup([this, dev, fb, rp, destView]() {
for(uint32_t i = 0; i < fb.size(); i++)
ObjDisp(dev)->DestroyFramebuffer(Unwrap(dev), fb[i], NULL);
ObjDisp(dev)->DestroyRenderPass(Unwrap(dev), rp, NULL);
for(uint32_t i = 0; i < destView.size(); i++)
ObjDisp(dev)->DestroyImageView(Unwrap(dev), destView[i], NULL);
ResetBufferMSDescriptorPools();
});
}
@@ -746,12 +746,12 @@ void WrappedVulkan::ApplyRPLoadDiscards(VkCommandBuffer commandBuffer, VkRect2D
VkImageSubresourceRange range = viewInfo.range;
range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
if(depthDontCareLoad)
if(depthDontCareLoad && (viewInfo.range.aspectMask & range.aspectMask) != 0)
GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassLoad,
image, initialLayout, range, renderArea);
range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
if(stencilDontCareLoad)
if(stencilDontCareLoad && (viewInfo.range.aspectMask & range.aspectMask) != 0)
GetDebugManager()->FillWithDiscardPattern(commandBuffer, DiscardType::RenderPassLoad,
image, initialLayout, range, renderArea);
}
@@ -2295,13 +2295,13 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(SerialiserType &ser, VkCommandB
VkImageSubresourceRange range = viewInfo.range;
range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
if(depthDontCareStore)
if(depthDontCareStore && (viewInfo.range.aspectMask & range.aspectMask) != 0)
GetDebugManager()->FillWithDiscardPattern(
commandBuffer, DiscardType::RenderPassStore, image,
rpinfo.attachments[i].finalLayout, range, renderArea);
range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
if(stencilDontCareStore)
if(stencilDontCareStore && (viewInfo.range.aspectMask & range.aspectMask) != 0)
GetDebugManager()->FillWithDiscardPattern(
commandBuffer, DiscardType::RenderPassStore, image,
rpinfo.attachments[i].finalLayout, range, renderArea);
@@ -6942,14 +6942,20 @@ bool WrappedVulkan::Serialise_vkCmdBeginRendering(SerialiserType &ser, VkCommand
(RenderingInfo.flags & VK_RENDERING_RESUMING_BIT) == 0)
{
rdcarray<VkRenderingAttachmentInfo> dynAtts = renderstate.dynamicRendering.color;
dynAtts.push_back(renderstate.dynamicRendering.depth);
size_t depthIdx = dynAtts.size() - 1;
size_t depthIdx = ~0U;
size_t stencilIdx = ~0U;
VkImageAspectFlags depthAspects = VK_IMAGE_ASPECT_DEPTH_BIT;
if(renderstate.dynamicRendering.depth.imageView != VK_NULL_HANDLE)
{
dynAtts.push_back(renderstate.dynamicRendering.depth);
depthIdx = dynAtts.size() - 1;
}
// if we have different images attached, or different store ops, treat stencil separately
if(renderstate.dynamicRendering.stencil.imageView != VK_NULL_HANDLE &&
if(renderstate.dynamicRendering.depth.imageView != VK_NULL_HANDLE &&
renderstate.dynamicRendering.stencil.imageView != VK_NULL_HANDLE &&
(renderstate.dynamicRendering.depth.imageView !=
renderstate.dynamicRendering.stencil.imageView ||
renderstate.dynamicRendering.depth.loadOp !=
@@ -6962,6 +6968,12 @@ bool WrappedVulkan::Serialise_vkCmdBeginRendering(SerialiserType &ser, VkCommand
else if(renderstate.dynamicRendering.stencil.imageView != VK_NULL_HANDLE)
{
depthAspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
if(renderstate.dynamicRendering.depth.imageView == VK_NULL_HANDLE)
{
dynAtts.push_back(renderstate.dynamicRendering.stencil);
stencilIdx = dynAtts.size() - 1;
}
}
for(size_t i = 0; i < dynAtts.size(); i++)
@@ -6980,6 +6992,7 @@ bool WrappedVulkan::Serialise_vkCmdBeginRendering(SerialiserType &ser, VkCommand
if(i == depthIdx)
range.aspectMask = depthAspects;
// if this is a stencil-only attachment this will override depthAspects
if(i == stencilIdx)
range.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
@@ -2542,7 +2542,7 @@ bool WrappedVulkan::Serialise_vkCmdClearAttachments(SerialiserType &ser,
{
if(pAttachments[a].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)
action.flags |= ActionFlags::ClearColor;
if(pAttachments[a].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
if(pAttachments[a].aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
action.flags |= ActionFlags::ClearDepthStencil;
}
@@ -2575,7 +2575,8 @@ bool WrappedVulkan::Serialise_vkCmdClearAttachments(SerialiserType &ser,
}
}
}
else if(pAttachments[a].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
else if(pAttachments[a].aspectMask &
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
{
if(rp.subpasses[state.subpass].depthstencilAttachment >= 0)
{
+4
View File
@@ -551,6 +551,10 @@ void main()
DiscardImage(cmd, tex);
TEX_TEST("DiscardAll", MakeTex2D(VK_FORMAT_S8_UINT, 300, 300, 5, 4));
DiscardImage(cmd, tex);
TEX_TEST("DiscardAll", MakeTex2DMS(VK_FORMAT_S8_UINT, 300, 300, 4));
DiscardImage(cmd, tex);
TEX_TEST("DiscardAll", MakeTex2DMS(VK_FORMAT_S8_UINT, 300, 300, 4, 2));
DiscardImage(cmd, tex);
}
TEX_TEST("DiscardAll", MakeTex2D(depthFormat, 300, 300, 5));
+7 -3
View File
@@ -1068,6 +1068,8 @@ void main()
TEST_CASE(TextureType::Unknown, VK_FORMAT_D16_UNORM, VK_FORMAT_D16_UNORM, 0, 0,
DataType::Float),
TEST_CASE(TextureType::Unknown, VK_FORMAT_S8_UINT, VK_FORMAT_S8_UINT, 0, 0, DataType::UInt),
};
for(VKFormat f : depth_tests)
@@ -1121,9 +1123,11 @@ void main()
{
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
if(t.fmt.viewFmt == VK_FORMAT_S8_UINT || t.fmt.viewFmt == VK_FORMAT_D16_UNORM_S8_UINT ||
t.fmt.viewFmt == VK_FORMAT_D24_UNORM_S8_UINT ||
t.fmt.viewFmt == VK_FORMAT_D32_SFLOAT_S8_UINT)
if(t.fmt.viewFmt == VK_FORMAT_S8_UINT)
aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
else if(t.fmt.viewFmt == VK_FORMAT_D16_UNORM_S8_UINT ||
t.fmt.viewFmt == VK_FORMAT_D24_UNORM_S8_UINT ||
t.fmt.viewFmt == VK_FORMAT_D32_SFLOAT_S8_UINT)
aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
}