video_core: Fix some image copy and buffer offset validation errors. (#3673)

This commit is contained in:
squidbus
2025-09-30 06:17:22 -07:00
committed by GitHub
parent ad99bda08d
commit 505e80e756
2 changed files with 15 additions and 13 deletions

View File

@@ -541,6 +541,8 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
const auto& [buffer_id, vsharp, size] = buffer_bindings[i];
const auto& desc = stage.buffers[i];
const bool is_storage = desc.IsStorage(vsharp, pipeline_cache.GetProfile());
const u32 alignment =
is_storage ? instance.StorageMinAlignment() : instance.UniformMinAlignment();
// Buffer is not from the cache, either a special buffer or unbound.
if (!buffer_id) {
if (desc.buffer_type == Shader::BufferType::GdsBuffer) {
@@ -549,8 +551,8 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
} else if (desc.buffer_type == Shader::BufferType::Flatbuf) {
auto& vk_buffer = buffer_cache.GetUtilityBuffer(VideoCore::MemoryUsage::Stream);
const u32 ubo_size = stage.flattened_ud_buf.size() * sizeof(u32);
const u64 offset = vk_buffer.Copy(stage.flattened_ud_buf.data(), ubo_size,
instance.UniformMinAlignment());
const u64 offset =
vk_buffer.Copy(stage.flattened_ud_buf.data(), ubo_size, alignment);
buffer_infos.emplace_back(vk_buffer.Handle(), offset, ubo_size);
} else if (desc.buffer_type == Shader::BufferType::BdaPagetable) {
const auto* bda_buffer = buffer_cache.GetBdaPageTableBuffer();
@@ -562,8 +564,7 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
auto& lds_buffer = buffer_cache.GetUtilityBuffer(VideoCore::MemoryUsage::Stream);
const auto& cs_program = liverpool->GetCsRegs();
const auto lds_size = cs_program.SharedMemSize() * cs_program.NumWorkgroups();
const auto [data, offset] =
lds_buffer.Map(lds_size, instance.StorageMinAlignment());
const auto [data, offset] = lds_buffer.Map(lds_size, alignment);
std::memset(data, 0, lds_size);
buffer_infos.emplace_back(lds_buffer.Handle(), offset, lds_size);
} else if (instance.IsNullDescriptorSupported()) {
@@ -575,8 +576,6 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
} else {
const auto [vk_buffer, offset] = buffer_cache.ObtainBuffer(
vsharp.base_address, size, desc.is_written, desc.is_formatted, buffer_id);
const u32 alignment =
is_storage ? instance.StorageMinAlignment() : instance.UniformMinAlignment();
const u32 offset_aligned = Common::AlignDown(offset, alignment);
const u32 adjust = offset - offset_aligned;
ASSERT(adjust % 4 == 0);

View File

@@ -416,6 +416,7 @@ void Image::Download(std::span<const vk::BufferImageCopy> download_copies, vk::B
void Image::CopyImage(Image& src_image) {
const auto& src_info = src_image.info;
const u32 num_mips = std::min(src_info.resources.levels, info.resources.levels);
const u32 num_layers = std::min(src_info.resources.layers, info.resources.layers);
ASSERT(src_info.resources.layers == info.resources.layers || num_mips == 1);
const u32 width = src_info.size.width;
@@ -437,13 +438,13 @@ void Image::CopyImage(Image& src_image) {
.aspectMask = src_image.aspect_mask & ~vk::ImageAspectFlagBits::eStencil,
.mipLevel = mip,
.baseArrayLayer = 0,
.layerCount = src_info.resources.layers,
.layerCount = num_layers,
},
.dstSubresource{
.aspectMask = aspect_mask & ~vk::ImageAspectFlagBits::eStencil,
.mipLevel = mip,
.baseArrayLayer = 0,
.layerCount = info.resources.layers,
.layerCount = num_layers,
},
.extent = {mip_w, mip_h, mip_d},
});
@@ -464,6 +465,7 @@ void Image::CopyImage(Image& src_image) {
void Image::CopyImageWithBuffer(Image& src_image, vk::Buffer buffer, u64 offset) {
const auto& src_info = src_image.info;
const u32 num_mips = std::min(src_info.resources.levels, info.resources.levels);
const u32 num_layers = std::min(src_info.resources.layers, info.resources.layers);
ASSERT(src_info.resources.layers == info.resources.layers || num_mips == 1);
SetBackingSamples(info.num_samples, false);
@@ -483,7 +485,7 @@ void Image::CopyImageWithBuffer(Image& src_image, vk::Buffer buffer, u64 offset)
.aspectMask = src_image.aspect_mask & ~vk::ImageAspectFlagBits::eStencil,
.mipLevel = mip,
.baseArrayLayer = 0,
.layerCount = src_info.resources.layers,
.layerCount = num_layers,
},
.imageOffset = {0, 0, 0},
.imageExtent = {mip_w, mip_h, mip_d},
@@ -585,20 +587,21 @@ void Image::Resolve(Image& src_image, const VideoCore::SubresourceRange& mrt0_ra
mrt0_range);
Transit(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlagBits2::eTransferWrite, mrt1_range);
const u32 num_layers = std::min(mrt0_range.extent.layers, mrt1_range.extent.layers);
if (src_image.backing->num_samples == 1) {
const vk::ImageCopy region = {
.srcSubresource{
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseArrayLayer = mrt0_range.base.layer,
.layerCount = mrt0_range.extent.layers,
.layerCount = num_layers,
},
.srcOffset = {0, 0, 0},
.dstSubresource{
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseArrayLayer = mrt1_range.base.layer,
.layerCount = mrt1_range.extent.layers,
.layerCount = num_layers,
},
.dstOffset = {0, 0, 0},
.extent = {info.size.width, info.size.height, 1},
@@ -612,14 +615,14 @@ void Image::Resolve(Image& src_image, const VideoCore::SubresourceRange& mrt0_ra
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseArrayLayer = mrt0_range.base.layer,
.layerCount = mrt0_range.extent.layers,
.layerCount = num_layers,
},
.srcOffset = {0, 0, 0},
.dstSubresource{
.aspectMask = vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseArrayLayer = mrt1_range.base.layer,
.layerCount = mrt1_range.extent.layers,
.layerCount = num_layers,
},
.dstOffset = {0, 0, 0},
.extent = {info.size.width, info.size.height, 1},