forked from eden-emu/eden
[vk] texture
This commit is contained in:
parent
14cf60bce8
commit
5ddb0b3d5f
1 changed files with 62 additions and 43 deletions
|
@ -144,8 +144,8 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
|
|||
.imageType = ConvertImageType(info.type),
|
||||
.format = format_info.format,
|
||||
.extent{
|
||||
.width = info.size.width >> samples_x,
|
||||
.height = info.size.height >> samples_y,
|
||||
.width = info.size.width,
|
||||
.height = info.size.height,
|
||||
.depth = info.size.depth,
|
||||
},
|
||||
.mipLevels = static_cast<u32>(info.resources.levels),
|
||||
|
@ -962,23 +962,35 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
|
|||
std::ranges::transform(copies, vk_out_copies.begin(), [dst_aspect_mask](const auto& copy) {
|
||||
return MakeBufferImageCopy(copy, false, dst_aspect_mask);
|
||||
});
|
||||
const u32 img_bpp = BytesPerBlock(dst.info.format);
|
||||
size_t total_size = 0;
|
||||
for (const auto& copy : copies) {
|
||||
total_size += copy.extent.width * copy.extent.height * copy.extent.depth * img_bpp;
|
||||
}
|
||||
const VkBuffer copy_buffer = GetTemporaryBuffer(total_size);
|
||||
const VkImage dst_image = dst.Handle();
|
||||
const VkImage src_image = src.Handle();
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
auto vk_in_sp = std::make_shared<decltype(vk_in_copies)>(std::move(vk_in_copies));
|
||||
auto vk_out_sp = std::make_shared<decltype(vk_out_copies)>(std::move(vk_out_copies));
|
||||
// Assign per-region offsets and compute total staging size (block-aware, 4-byte aligned)
|
||||
size_t staging_size = 0;
|
||||
const u32 dst_block_w = DefaultBlockWidth(dst.info.format);
|
||||
const u32 dst_block_h = DefaultBlockHeight(dst.info.format);
|
||||
const size_t dst_block_bytes = BytesPerBlock(dst.info.format);
|
||||
for (size_t i = 0; i < copies.size(); ++i) {
|
||||
const auto& c = copies[i];
|
||||
const u32 blocks_w = (c.extent.width + dst_block_w - 1) / dst_block_w;
|
||||
const u32 blocks_h = (c.extent.height + dst_block_h - 1) / dst_block_h;
|
||||
const size_t region_bytes = size_t(blocks_w) * blocks_h * c.extent.depth * dst_block_bytes;
|
||||
(*vk_in_sp)[i].bufferOffset = static_cast<VkDeviceSize>(staging_size);
|
||||
(*vk_out_sp)[i].bufferOffset = static_cast<VkDeviceSize>(staging_size);
|
||||
// Vulkan requires bufferOffset to be a multiple of 4.
|
||||
staging_size = (staging_size + region_bytes + 3) & ~size_t(3);
|
||||
}
|
||||
const VkBuffer copy_buffer = GetTemporaryBuffer(staging_size);
|
||||
scheduler.Record([dst_image, src_image, copy_buffer, src_aspect_mask, dst_aspect_mask,
|
||||
vk_in_copies, vk_out_copies](vk::CommandBuffer cmdbuf) {
|
||||
vk_in_sp, vk_out_sp](vk::CommandBuffer cmdbuf) {
|
||||
RangedBarrierRange dst_range;
|
||||
RangedBarrierRange src_range;
|
||||
for (const VkBufferImageCopy& copy : vk_in_copies) {
|
||||
for (const VkBufferImageCopy& copy : *vk_in_sp) {
|
||||
src_range.AddLayers(copy.imageSubresource);
|
||||
}
|
||||
for (const VkBufferImageCopy& copy : vk_out_copies) {
|
||||
for (const VkBufferImageCopy& copy : *vk_out_sp) {
|
||||
dst_range.AddLayers(copy.imageSubresource);
|
||||
}
|
||||
static constexpr VkMemoryBarrier READ_BARRIER{
|
||||
|
@ -1062,13 +1074,13 @@ void TextureCacheRuntime::ReinterpretImage(Image& dst, Image& src,
|
|||
0, {}, {}, pre_barriers);
|
||||
|
||||
cmdbuf.CopyImageToBuffer(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, copy_buffer,
|
||||
vk_in_copies);
|
||||
*vk_in_sp);
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
0, WRITE_BARRIER, nullptr, middle_in_barrier);
|
||||
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, READ_BARRIER, {}, middle_out_barrier);
|
||||
cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, vk_out_copies);
|
||||
cmdbuf.CopyBufferToImage(copy_buffer, dst_image, VK_IMAGE_LAYOUT_GENERAL, *vk_out_sp);
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
0, {}, {}, post_barriers);
|
||||
});
|
||||
|
@ -1397,10 +1409,11 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
|
|||
const VkImage dst_image = dst.Handle();
|
||||
const VkImage src_image = src.Handle();
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([dst_image, src_image, aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) {
|
||||
auto vk_copies_sp = std::make_shared<decltype(vk_copies)>(std::move(vk_copies));
|
||||
scheduler.Record([dst_image, src_image, aspect_mask, vk_copies_sp](vk::CommandBuffer cmdbuf) {
|
||||
RangedBarrierRange dst_range;
|
||||
RangedBarrierRange src_range;
|
||||
for (const VkImageCopy& copy : vk_copies) {
|
||||
for (const VkImageCopy& copy : *vk_copies_sp) {
|
||||
dst_range.AddLayers(copy.dstSubresource);
|
||||
src_range.AddLayers(copy.srcSubresource);
|
||||
}
|
||||
|
@ -1471,7 +1484,7 @@ void TextureCacheRuntime::CopyImage(Image& dst, Image& src,
|
|||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, nullptr, nullptr, pre_barriers);
|
||||
cmdbuf.CopyImage(src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk_copies);
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, *vk_copies_sp);
|
||||
cmdbuf.PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
|
||||
|
@ -1597,10 +1610,10 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset,
|
|||
const VkBuffer src_buffer = buffer;
|
||||
const VkImage temp_vk_image = *temp_wrapper->original_image;
|
||||
const VkImageAspectFlags vk_aspect_mask = temp_wrapper->aspect_mask;
|
||||
|
||||
scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies,
|
||||
auto vk_copies_sp = std::make_shared<decltype(vk_copies)>(std::move(vk_copies));
|
||||
scheduler->Record([src_buffer, temp_vk_image, vk_aspect_mask, vk_copies_sp,
|
||||
keep = temp_wrapper](vk::CommandBuffer cmdbuf) {
|
||||
CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false, vk_copies);
|
||||
CopyBufferToImage(cmdbuf, src_buffer, temp_vk_image, vk_aspect_mask, false, *vk_copies_sp);
|
||||
});
|
||||
|
||||
// Use MSAACopyPass to convert from non-MSAA to MSAA
|
||||
|
@ -1632,14 +1645,15 @@ void Image::UploadMemory(VkBuffer buffer, VkDeviceSize offset,
|
|||
// Regular non-MSAA upload (original behavior preserved)
|
||||
scheduler->RequestOutsideRenderPassOperationContext();
|
||||
auto vk_copies = TransformBufferImageCopies(copies, offset, aspect_mask);
|
||||
auto vk_copies_sp = std::make_shared<decltype(vk_copies)>(std::move(vk_copies));
|
||||
const VkBuffer src_buffer = buffer;
|
||||
const VkImage vk_image = *original_image;
|
||||
const VkImageAspectFlags vk_aspect_mask = aspect_mask;
|
||||
const bool was_initialized = std::exchange(initialized, true);
|
||||
|
||||
scheduler->Record([src_buffer, vk_image, vk_aspect_mask, was_initialized,
|
||||
vk_copies](vk::CommandBuffer cmdbuf) {
|
||||
CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, was_initialized, vk_copies);
|
||||
const bool is_initialized = std::exchange(initialized, true);
|
||||
scheduler->Record([src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies_sp]
|
||||
(vk::CommandBuffer cmdbuf) {
|
||||
CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized,
|
||||
*vk_copies_sp);
|
||||
});
|
||||
|
||||
if (is_rescaled) {
|
||||
|
@ -1678,13 +1692,11 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
|
|||
|
||||
VkImageCreateInfo image_ci = MakeImageCreateInfo(runtime->device, temp_info);
|
||||
image_ci.usage = original_image.UsageFlags();
|
||||
vk::Image temp_image = runtime->memory_allocator.CreateImage(image_ci);
|
||||
|
||||
Image temp_wrapper(*runtime, temp_info, 0, 0);
|
||||
temp_wrapper.original_image = std::move(temp_image);
|
||||
temp_wrapper.current_image = &Image::original_image;
|
||||
temp_wrapper.aspect_mask = aspect_mask;
|
||||
temp_wrapper.initialized = true;
|
||||
auto temp_wrapper = std::make_shared<Image>(*runtime, temp_info, 0, 0);
|
||||
temp_wrapper->original_image = runtime->memory_allocator.CreateImage(image_ci);
|
||||
temp_wrapper->current_image = &Image::original_image;
|
||||
temp_wrapper->aspect_mask = aspect_mask;
|
||||
temp_wrapper->initialized = true;
|
||||
|
||||
std::vector<VideoCommon::ImageCopy> image_copies;
|
||||
for (const auto& copy : copies) {
|
||||
|
@ -1697,7 +1709,7 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
|
|||
image_copies.push_back(image_copy);
|
||||
}
|
||||
|
||||
runtime->msaa_copy_pass->CopyImage(temp_wrapper, *this, image_copies, true);
|
||||
runtime->msaa_copy_pass->CopyImage(*temp_wrapper, *this, image_copies, true);
|
||||
|
||||
boost::container::small_vector<VkBuffer, 8> buffers_vector{};
|
||||
boost::container::small_vector<boost::container::small_vector<VkBufferImageCopy, 16>, 8>
|
||||
|
@ -1709,8 +1721,13 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
|
|||
}
|
||||
|
||||
scheduler->RequestOutsideRenderPassOperationContext();
|
||||
scheduler->Record([buffers = std::move(buffers_vector), image = *temp_wrapper.original_image,
|
||||
aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) {
|
||||
auto buffers_sp = std::make_shared<decltype(buffers_vector)>(std::move(buffers_vector));
|
||||
auto vk_copies_sp = std::make_shared<decltype(vk_copies)>(std::move(vk_copies));
|
||||
scheduler->Record([buffers_sp,
|
||||
image = *temp_wrapper->original_image,
|
||||
aspect_mask_ = aspect_mask,
|
||||
vk_copies_sp,
|
||||
keep = temp_wrapper](vk::CommandBuffer cmdbuf) {
|
||||
const VkImageMemoryBarrier read_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
|
@ -1732,9 +1749,9 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
|
|||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, read_barrier);
|
||||
|
||||
for (size_t index = 0; index < buffers.size(); index++) {
|
||||
cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers[index],
|
||||
vk_copies[index]);
|
||||
for (size_t index = 0; index < buffers_sp->size(); ++index) {
|
||||
cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
(*buffers_sp)[index], (*vk_copies_sp)[index]);
|
||||
}
|
||||
|
||||
const VkMemoryBarrier memory_write_barrier{
|
||||
|
@ -1776,8 +1793,10 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
|
|||
TransformBufferImageCopies(copies, offsets_span[index], aspect_mask));
|
||||
}
|
||||
scheduler->RequestOutsideRenderPassOperationContext();
|
||||
scheduler->Record([buffers = std::move(buffers_vector), image = *original_image,
|
||||
aspect_mask_ = aspect_mask, vk_copies](vk::CommandBuffer cmdbuf) {
|
||||
auto buffers_sp = std::make_shared<decltype(buffers_vector)>(std::move(buffers_vector));
|
||||
auto vk_copies_sp = std::make_shared<decltype(vk_copies)>(std::move(vk_copies));
|
||||
scheduler->Record([buffers_sp, image = *original_image,
|
||||
aspect_mask_ = aspect_mask, vk_copies_sp](vk::CommandBuffer cmdbuf) {
|
||||
const VkImageMemoryBarrier read_barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
|
@ -1799,9 +1818,9 @@ void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> o
|
|||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, read_barrier);
|
||||
|
||||
for (size_t index = 0; index < buffers.size(); index++) {
|
||||
cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffers[index],
|
||||
vk_copies[index]);
|
||||
for (size_t index = 0; index < buffers_sp->size(); index++) {
|
||||
cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, (*buffers_sp)[index],
|
||||
(*vk_copies_sp)[index]);
|
||||
}
|
||||
|
||||
const VkMemoryBarrier memory_write_barrier{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue