Vulkan: TextureDescription.byteSize double-counts MSAA samples when memory requirements are available

Open Beginner friendly
#3,928 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
80/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
cpp

Research direction

The bug is in VulkanReplay::GetTexture() in renderdoc/driver/vulkan/vk_replay.cpp, where ret.byteSize is set from mrq.size and then multiplied by ret.msSamp. Read how mrq is filled in the live-handle branch and where the fallback estimate runs. Done when the live path no longer multiplies by ret.msSamp, the fallback path still does, and a 4x MSAA color attachment reports 90 MiB rather than 360 MiB.

Written by the indexing model from the issue text.

Description

Summary

VulkanReplay::GetTexture() double-counts the MSAA sample count for Vulkan images when a live image handle is available.

vkGetImageMemoryRequirements already returns the memory requirement for the complete VkImage, including its VkSampleCountFlagBits. RenderDoc stores that value in TextureDescription.byteSize, then unconditionally multiplies it by ret.msSamp again.

This makes TextureDescription.byteSize incorrect for multisampled images.

Observed result

For a captured Vulkan color attachment:

  • Extent: 2512 x 1088 x 1
  • Mip levels: 1
  • Array layers: 1
  • Samples: VK_SAMPLE_COUNT_4_BIT
  • Bound VkDeviceMemory allocation size: 94,371,840 bytes (90 MiB)
  • TextureDescription.byteSize: 377,487,360 bytes (360 MiB)

The reported texture size is exactly 90 MiB * 4.

Root cause

Current code in renderdoc/driver/vulkan/vk_replay.cpp, VulkanReplay::GetTexture():

if(liveWrappedImage != VK_NULL_HANDLE) ObjDisp(dev)->GetImageMemoryRequirements(Unwrap(dev), Unwrap(liveWrappedImage), &mrq);

ret.byteSize = mrq.size;

// ...

ret.msQual = 0;
ret.msSamp = RDCMAX(1U, (uint32_t)iminfo.samples);

ret.byteSize *= ret.msSamp;

 mrq.size  is already the Vulkan driver's memory requirement for the multisampled image. Multiplying it by  ret.msSamp  applies the sample count a second time.

Proposed fix

Only apply the sample-count multiplier in the fallback path, where RenderDoc estimates the byte size itself because no live Vulkan image handle is available:

ret.msQual = 0;
ret.msSamp = RDCMAX(1U, (uint32_t)iminfo.samples);

ret.byteSize = mrq.size;
if(ret.byteSize == 0)
{ for(uint32_t s = 0; s < ret.mips; s++)
    ret.byteSize += GetByteSize(ret.width, ret.height, ret.depth, iminfo.format, s);

  ret.byteSize *= ret.arraysize; ret.byteSize *= ret.msSamp;
}

The normal  vkGetImageMemoryRequirements  path must not multiply by  ret.msSamp .
Dominant language
C++
Stars
11.2k
Forks
1.8k
Avg merge
5h 27m
Merged PRs (30d)
5

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from baldurk/renderdoc

All issues in baldurk/renderdoc

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.