Patch VkImageFormatListCreateInfo for MSAA textures

* Since we're using mutable format to cast them to UINT for copies, we need to
  ensure that the correct format is in the create info list.
This commit is contained in:
baldurk
2021-02-22 10:31:14 +00:00
parent baf0e3ea70
commit 4a379408f9
3 changed files with 117 additions and 2 deletions
@@ -1951,6 +1951,53 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device
}
}
rdcarray<VkFormat> patchedFormatList;
// similarly for the image format list for MSAA textures, add the UINT cast format we will need
if(CreateInfo.samples != VK_SAMPLE_COUNT_1_BIT)
{
VkImageFormatListCreateInfo *formatListInfo = (VkImageFormatListCreateInfo *)FindNextStruct(
&CreateInfo, VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
if(formatListInfo)
{
uint32_t bs = GetByteSize(1, 1, 1, CreateInfo.format, 0);
VkFormat msaaCopyFormat = VK_FORMAT_UNDEFINED;
if(bs == 1)
msaaCopyFormat = VK_FORMAT_R8_UINT;
else if(bs == 2)
msaaCopyFormat = VK_FORMAT_R16_UINT;
else if(bs == 4)
msaaCopyFormat = VK_FORMAT_R32_UINT;
else if(bs == 8)
msaaCopyFormat = VK_FORMAT_R32G32_UINT;
else if(bs == 16)
msaaCopyFormat = VK_FORMAT_R32G32B32A32_UINT;
patchedFormatList.resize(formatListInfo->viewFormatCount + 1);
const VkFormat *oldFmts = formatListInfo->pViewFormats;
VkFormat *newFmts = patchedFormatList.data();
formatListInfo->pViewFormats = newFmts;
bool needAdded = true;
uint32_t i = 0;
for(; i < formatListInfo->viewFormatCount; i++)
{
newFmts[i] = oldFmts[i];
if(newFmts[i] == msaaCopyFormat)
needAdded = false;
}
if(needAdded)
{
newFmts[i] = msaaCopyFormat;
formatListInfo->viewFormatCount++;
}
}
}
VkImageCreateInfo patched = CreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));
@@ -2066,7 +2113,19 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
// create non-subsampled image to be able to copy its content
createInfo_adjusted.flags &= ~VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT;
byte *tempMem = GetTempMemory(GetNextPatchSize(createInfo_adjusted.pNext));
size_t tempMemSize = GetNextPatchSize(createInfo_adjusted.pNext);
// reserve space for a patched view format list if necessary
if(createInfo_adjusted.samples != VK_SAMPLE_COUNT_1_BIT)
{
VkImageFormatListCreateInfo *formatListInfo = (VkImageFormatListCreateInfo *)FindNextStruct(
&createInfo_adjusted, VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
if(formatListInfo)
tempMemSize += sizeof(VkFormat) * (formatListInfo->viewFormatCount + 1);
}
byte *tempMem = GetTempMemory(tempMemSize);
UnwrapNextChain(m_State, "VkImageCreateInfo", tempMem, (VkBaseInStructure *)&createInfo_adjusted);
@@ -2091,6 +2150,49 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
}
}
// similarly for the image format list for MSAA textures, add the UINT cast format we will need
if(createInfo_adjusted.samples != VK_SAMPLE_COUNT_1_BIT)
{
VkImageFormatListCreateInfo *formatListInfo = (VkImageFormatListCreateInfo *)FindNextStruct(
&createInfo_adjusted, VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
if(formatListInfo)
{
uint32_t bs = GetByteSize(1, 1, 1, createInfo_adjusted.format, 0);
VkFormat msaaCopyFormat = VK_FORMAT_UNDEFINED;
if(bs == 1)
msaaCopyFormat = VK_FORMAT_R8_UINT;
else if(bs == 2)
msaaCopyFormat = VK_FORMAT_R16_UINT;
else if(bs == 4)
msaaCopyFormat = VK_FORMAT_R32_UINT;
else if(bs == 8)
msaaCopyFormat = VK_FORMAT_R32G32_UINT;
else if(bs == 16)
msaaCopyFormat = VK_FORMAT_R32G32B32A32_UINT;
const VkFormat *oldFmts = formatListInfo->pViewFormats;
VkFormat *newFmts = (VkFormat *)tempMem;
formatListInfo->pViewFormats = newFmts;
bool needAdded = true;
uint32_t i = 0;
for(; i < formatListInfo->viewFormatCount; i++)
{
newFmts[i] = oldFmts[i];
if(newFmts[i] == msaaCopyFormat)
needAdded = false;
}
if(needAdded)
{
newFmts[i] = msaaCopyFormat;
formatListInfo->viewFormatCount++;
}
}
}
VkResult ret;
SERIALISE_TIME_CALL(
ret = ObjDisp(device)->CreateImage(Unwrap(device), &createInfo_adjusted, pAllocator, pImage));
+6
View File
@@ -516,6 +516,12 @@ struct ImageCreateInfo : public VkImageCreateInfo
imageType = VK_IMAGE_TYPE_1D;
}
VkImageCreateInfo &next(const void *next)
{
this->pNext = next;
return *this;
}
operator const VkImageCreateInfo *() const { return this; }
};
+8 -1
View File
@@ -464,11 +464,17 @@ void main()
viewAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
}
VkImageFormatListCreateInfoKHR formatList = {VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR};
formatList.viewFormatCount = 2;
VkFormat fmts[] = {test.fmt.texFmt, test.fmt.viewFmt};
formatList.pViewFormats = fmts;
test.res = AllocatedImage(
this,
vkh::ImageCreateInfo(
w, h, d, test.fmt.texFmt, usage, test.isMSAA ? 1 : texMips, test.isArray ? texSlices : 1,
test.isMSAA ? VkSampleCountFlagBits(texSamples) : VK_SAMPLE_COUNT_1_BIT, flags),
test.isMSAA ? VkSampleCountFlagBits(texSamples) : VK_SAMPLE_COUNT_1_BIT, flags)
.next(hasExt(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME) ? &formatList : NULL),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
test.view = createImageView(vkh::ImageViewCreateInfo(
test.res.image, test.viewType, test.fmt.viewFmt, {}, vkh::ImageSubresourceRange(viewAspect)));
@@ -619,6 +625,7 @@ void main()
void Prepare(int argc, char **argv)
{
devExts.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
optDevExts.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
features.sampleRateShading = true;