mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-08 20:58:41 +00:00
video_core: Fix some image copy and buffer offset validation errors. (#3673)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user