graphics: synchronize raw storage reads with GPU image aliases

This commit is contained in:
Claxten
2026-10-07 19:49:50 +04:00
committed by nmzik
parent 9f83fd5f0c
commit 743fdc6990
2 changed files with 12 additions and 12 deletions
@@ -126,8 +126,8 @@ NativeStorageBuffer(RenderContext& context, const PreparedBindings::BufferSource
if (size > graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange) { if (size > graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange) {
EXIT("storage buffer range is unsupported\n"); EXIT("storage buffer range is unsupported\n");
} }
auto [buffer, offset] = context.GetBufferCache().ObtainBuffer(address, size, resource.written, auto [buffer, offset] = context.GetBufferCache().ObtainBuffer(
resource.formatted, id); address, size, resource.written, resource.read || resource.formatted, id);
const auto aligned_offset = Common::AlignDown(offset, alignment); const auto aligned_offset = Common::AlignDown(offset, alignment);
const auto adjustment = offset - aligned_offset; const auto adjustment = offset - aligned_offset;
const auto max_range = graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange; const auto max_range = graphics.GetPhysicalDeviceProperties().limits.maxStorageBufferRange;
+10 -10
View File
@@ -13947,8 +13947,8 @@ public:
"backing"); "backing");
RenderExecutorTestAccess::ResetBindings(executor); RenderExecutorTestAccess::ResetBindings(executor);
{ for (const bool formatted : {false, true}) {
constexpr uint32_t before = 0x13579bdfu; const uint32_t before = formatted ? 0x13579bdfu : 0x89abcdefu;
constexpr uint32_t guard = 0x2468ace0u; constexpr uint32_t guard = 0x2468ace0u;
constexpr uint32_t after = 0xa1b2c3d4u; constexpr uint32_t after = 0xa1b2c3d4u;
vk::ClearValue clear{}; vk::ClearValue clear{};
@@ -13962,7 +13962,7 @@ public:
{vk::ImageAspectFlagBits::eColor, 0, 1, 1, 1}, clear); {vk::ImageAspectFlagBits::eColor, 0, 1, 1, 1}, clear);
const auto buffer_program = make_buffer_program( const auto buffer_program = make_buffer_program(
ShaderType::Vertex, {.read = true, .formatted = true}); ShaderType::Vertex, {.read = true, .formatted = formatted});
constexpr uint64_t buffer_size = 2 * target_mip_size; constexpr uint64_t buffer_size = 2 * target_mip_size;
static_assert(buffer_size > BufferCache::CACHING_PAGESIZE); static_assert(buffer_size > BufferCache::CACHING_PAGESIZE);
@@ -13985,13 +13985,13 @@ public:
RenderExecutorTestAccess::PrepareGraphicsBindings( RenderExecutorTestAccess::PrepareGraphicsBindings(
executor, stages, std::span{&target, 1u}); executor, stages, std::span{&target, 1u});
const auto &buffer = buffer_bindings.buffers[0]; const auto &buffer = buffer_bindings.buffers[0];
Require(name, "rediscovered target formatted-buffer read", Require(name, "rediscovered target buffer read",
target.image_id == expanded_array_id && target.image_id == expanded_array_id &&
buffer.range == buffer_size && buffer.range == buffer_size &&
buffer_bindings.images.empty() && buffer_bindings.images.empty() &&
texture_cache.GetImage(target.image_id).backing.state.layout == texture_cache.GetImage(target.image_id).backing.state.layout ==
vk::ImageLayout::eTransferSrcOptimal, vk::ImageLayout::eTransferSrcOptimal,
"target discovery did not precede the formatted image-to-buffer copy"); "target discovery did not precede the image-to-buffer copy");
auto readback = CreateHostBuffer(name, 2 * sizeof(uint32_t), auto readback = CreateHostBuffer(name, 2 * sizeof(uint32_t),
vk::BufferUsageFlagBits::eTransferDst, {0, 0}); vk::BufferUsageFlagBits::eTransferDst, {0, 0});
const std::array copies{ const std::array copies{
@@ -14013,12 +14013,12 @@ public:
const auto rendering = RenderExecutorTestAccess::AcquireRenderTargets( const auto rendering = RenderExecutorTestAccess::AcquireRenderTargets(
executor, scheduler.Current(), &target, 1, no_array_depth); executor, scheduler.Current(), &target, 1, no_array_depth);
Require(name, "attachment layout after formatted-buffer read", Require(name, "attachment layout after buffer read",
rendering.color_attachments[0].image_layout == rendering.color_attachments[0].image_layout ==
vk::ImageLayout::eColorAttachmentOptimal && vk::ImageLayout::eColorAttachmentOptimal &&
texture_cache.GetImage(target.image_id).backing.state.layout == texture_cache.GetImage(target.image_id).backing.state.layout ==
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eColorAttachmentOptimal,
"the formatted buffer copy left the render attachment in its transfer layout"); "the buffer copy left the render attachment in its transfer layout");
vk::ClearAttachment clear_attachment{}; vk::ClearAttachment clear_attachment{};
clear_attachment.aspectMask = vk::ImageAspectFlagBits::eColor; clear_attachment.aspectMask = vk::ImageAspectFlagBits::eColor;
clear_attachment.colorAttachment = 0; clear_attachment.colorAttachment = 0;
@@ -14028,11 +14028,11 @@ public:
scheduler.Current().Handle().clearAttachments(1, &clear_attachment, 1, &clear_rect); scheduler.Current().Handle().clearAttachments(1, &clear_attachment, 1, &clear_rect);
scheduler.EndRendering(); scheduler.EndRendering();
scheduler.Finish(); scheduler.Finish();
Require(name, "formatted alias observes prior GPU contents", Require(name, "buffer alias observes prior GPU contents",
ReadBuffer(name, readback, 2) == std::vector<u32>{before, guard}, ReadBuffer(name, readback, 2) == std::vector<u32>{before, guard},
"formatted buffer acquisition copied stale guest bytes instead of the image"); "buffer acquisition copied stale guest bytes instead of the image");
DestroyBuffer(&readback); DestroyBuffer(&readback);
Require(name, "rendering after formatted-buffer acquisition", Require(name, "rendering after buffer acquisition",
ReadCachedTexel(name, context, target.image_id) == std::vector<u32>{after} && ReadCachedTexel(name, context, target.image_id) == std::vector<u32>{after} &&
ReadCachedTexel(name, context, target.image_id, {}, {1, 1, 1}, 1) == ReadCachedTexel(name, context, target.image_id, {}, {1, 1, 1}, 1) ==
std::vector<u32>{guard}, std::vector<u32>{guard},