mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 16:50:44 +00:00
Fix handling of S8 multisampled textures. Closes #2883
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user