mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-22 04:24:44 +00:00
texture_cache: Use buffer cache in all cases for data source
* Allows to correctly handle compute written micro tiled textures
This commit is contained in:
parent
0f2892a93a
commit
e2b63bf4c8
3 changed files with 17 additions and 33 deletions
|
@ -404,27 +404,19 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
|
|||
|
||||
const VAddr image_addr = image.info.guest_address;
|
||||
const size_t image_size = image.info.guest_size_bytes;
|
||||
vk::Buffer buffer{};
|
||||
u32 offset{};
|
||||
if (auto upload_buffer = tile_manager.TryDetile(image); upload_buffer) {
|
||||
buffer = *upload_buffer;
|
||||
} else {
|
||||
const auto [vk_buffer, buf_offset] = buffer_cache.ObtainTempBuffer(image_addr, image_size);
|
||||
buffer = vk_buffer->Handle();
|
||||
offset = buf_offset;
|
||||
|
||||
// The obtained buffer may be written by a shader so we need to emit a barrier to prevent
|
||||
// RAW hazard
|
||||
if (auto barrier = vk_buffer->GetBarrier(vk::AccessFlagBits2::eTransferRead,
|
||||
vk::PipelineStageFlagBits2::eTransfer)) {
|
||||
auto dependencies = vk::DependencyInfo{
|
||||
.bufferMemoryBarrierCount = 1,
|
||||
.pBufferMemoryBarriers = &barrier.value(),
|
||||
};
|
||||
cmdbuf.pipelineBarrier2(dependencies);
|
||||
}
|
||||
const auto [vk_buffer, buf_offset] = buffer_cache.ObtainTempBuffer(image_addr, image_size);
|
||||
// The obtained buffer may be written by a shader so we need to emit a barrier to prevent RAW
|
||||
// hazard
|
||||
if (auto barrier = vk_buffer->GetBarrier(vk::AccessFlagBits2::eTransferRead,
|
||||
vk::PipelineStageFlagBits2::eTransfer)) {
|
||||
auto dependencies = vk::DependencyInfo{
|
||||
.bufferMemoryBarrierCount = 1,
|
||||
.pBufferMemoryBarriers = &barrier.value(),
|
||||
};
|
||||
cmdbuf.pipelineBarrier2(dependencies);
|
||||
}
|
||||
|
||||
const auto [buffer, offset] = tile_manager.TryDetile(vk_buffer->Handle(), buf_offset, image);
|
||||
for (auto& copy : image_copy) {
|
||||
copy.bufferOffset += offset;
|
||||
}
|
||||
|
|
|
@ -377,9 +377,10 @@ void TileManager::FreeBuffer(ScratchBuffer buffer) {
|
|||
vmaDestroyBuffer(instance.GetAllocator(), buffer.first, buffer.second);
|
||||
}
|
||||
|
||||
std::optional<vk::Buffer> TileManager::TryDetile(Image& image) {
|
||||
std::pair<vk::Buffer, u32> TileManager::TryDetile(vk::Buffer in_buffer, u32 in_offset,
|
||||
Image& image) {
|
||||
if (!image.info.props.is_tiled) {
|
||||
return std::nullopt;
|
||||
return {in_buffer, in_offset};
|
||||
}
|
||||
|
||||
const auto* detiler = GetDetiler(image);
|
||||
|
@ -388,19 +389,10 @@ std::optional<vk::Buffer> TileManager::TryDetile(Image& image) {
|
|||
LOG_ERROR(Render_Vulkan, "Unsupported tiled image: {} ({})",
|
||||
vk::to_string(image.info.pixel_format), NameOf(image.info.tiling_mode));
|
||||
}
|
||||
return std::nullopt;
|
||||
return {in_buffer, in_offset};
|
||||
}
|
||||
|
||||
// Prepare input buffer
|
||||
const u32 image_size = image.info.guest_size_bytes;
|
||||
const auto [in_buffer, in_offset] = [&] -> std::pair<vk::Buffer, u32> {
|
||||
// Request temporary host buffer for larger sizes.
|
||||
auto in_buffer = AllocBuffer(image_size);
|
||||
const auto addr = reinterpret_cast<const void*>(image.info.guest_address);
|
||||
Upload(in_buffer, addr, image_size);
|
||||
scheduler.DeferOperation([=, this]() { FreeBuffer(in_buffer); });
|
||||
return {in_buffer.first, 0};
|
||||
}();
|
||||
|
||||
// Prepare output buffer
|
||||
auto out_buffer = AllocBuffer(image_size, true);
|
||||
|
@ -471,7 +463,7 @@ std::optional<vk::Buffer> TileManager::TryDetile(Image& image) {
|
|||
vk::PipelineStageFlagBits::eTransfer, vk::DependencyFlagBits::eByRegion,
|
||||
{}, post_barrier, {});
|
||||
|
||||
return {out_buffer.first};
|
||||
return {out_buffer.first, 0};
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler);
|
||||
~TileManager();
|
||||
|
||||
std::optional<vk::Buffer> TryDetile(Image& image);
|
||||
std::pair<vk::Buffer, u32> TryDetile(vk::Buffer in_buffer, u32 in_offset, Image& image);
|
||||
|
||||
ScratchBuffer AllocBuffer(u32 size, bool is_storage = false);
|
||||
void Upload(ScratchBuffer buffer, const void* data, size_t size);
|
||||
|
|
Loading…
Add table
Reference in a new issue