Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image binding and texture cache interface refactor #1481

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/core/linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void Linker::Execute() {
// Init primary thread.
Common::SetCurrentThreadName("GAME_MainThread");
DebugState.AddCurrentThreadToGuestList();
Libraries::Kernel::pthreadInitSelfMainThread();
::Libraries::Kernel::pthreadInitSelfMainThread();
EnsureThreadInitialized(true);

// Start shared library modules
Expand Down Expand Up @@ -365,7 +365,7 @@ void Linker::InitTlsForThread(bool is_primary) const {
void* addr_out{reinterpret_cast<void*>(KernelAllocBase)};
if (is_primary) {
const size_t tls_aligned = Common::AlignUp(total_tls_size, 16_KB);
const int ret = Libraries::Kernel::sceKernelMapNamedFlexibleMemory(
const int ret = ::Libraries::Kernel::sceKernelMapNamedFlexibleMemory(
&addr_out, tls_aligned, 3, 0, "SceKernelPrimaryTcbTls");
ASSERT_MSG(ret == 0, "Unable to allocate TLS+TCB for the primary thread");
} else {
Expand Down
8 changes: 4 additions & 4 deletions src/video_core/buffer_cache/buffer_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,10 +620,10 @@ void BufferCache::SynchronizeBuffer(Buffer& buffer, VAddr device_addr, u32 size,
bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, u32 size) {
static constexpr FindFlags find_flags =
FindFlags::NoCreate | FindFlags::RelaxDim | FindFlags::RelaxFmt | FindFlags::RelaxSize;
ImageInfo info{};
info.guest_address = device_addr;
info.guest_size_bytes = size;
const ImageId image_id = texture_cache.FindImage(info, find_flags);
TextureCache::BaseDesc desc{};
desc.info.guest_address = device_addr;
desc.info.guest_size_bytes = size;
const ImageId image_id = texture_cache.FindImage(desc, find_flags);
if (!image_id) {
return false;
}
Expand Down
13 changes: 8 additions & 5 deletions src/video_core/renderer_vulkan/renderer_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ class RendererVulkan {

Frame* PrepareFrame(const Libraries::VideoOut::BufferAttributeGroup& attribute,
VAddr cpu_address, bool is_eop) {
const auto info = VideoCore::ImageInfo{attribute, cpu_address};
const auto image_id = texture_cache.FindImage(info);
auto desc = VideoCore::TextureCache::VideoOutDesc{attribute, cpu_address};
const auto image_id = texture_cache.FindImage(desc);
texture_cache.UpdateImage(image_id, is_eop ? nullptr : &flip_scheduler);
auto& image = texture_cache.GetImage(image_id);
image.usage.vo_surface = 1u;
return PrepareFrameInternal(image, is_eop);
}

Expand All @@ -62,9 +63,11 @@ class RendererVulkan {
VideoCore::Image& RegisterVideoOutSurface(
const Libraries::VideoOut::BufferAttributeGroup& attribute, VAddr cpu_address) {
vo_buffers_addr.emplace_back(cpu_address);
const auto info = VideoCore::ImageInfo{attribute, cpu_address};
const auto image_id = texture_cache.FindImage(info);
return texture_cache.GetImage(image_id);
auto desc = VideoCore::TextureCache::VideoOutDesc{attribute, cpu_address};
const auto image_id = texture_cache.FindImage(desc);
auto& image = texture_cache.GetImage(image_id);
image.usage.vo_surface = 1u;
return image;
}

bool IsVideoOutSurface(const AmdGpu::Liverpool::ColorBuffer& color_buffer) {
Expand Down
84 changes: 62 additions & 22 deletions src/video_core/renderer_vulkan/vk_pipeline_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Vulkan {
boost::container::static_vector<vk::DescriptorImageInfo, 32> Pipeline::image_infos;
boost::container::static_vector<vk::BufferView, 8> Pipeline::buffer_views;
boost::container::static_vector<vk::DescriptorBufferInfo, 32> Pipeline::buffer_infos;
boost::container::static_vector<VideoCore::ImageId, 32> Pipeline::bound_images;

Pipeline::Pipeline(const Instance& instance_, Scheduler& scheduler_, DescriptorHeap& desc_heap_,
vk::PipelineCache pipeline_cache)
Expand Down Expand Up @@ -160,31 +161,43 @@ void Pipeline::BindBuffers(VideoCore::BufferCache& buffer_cache,
void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader::Info& stage,
Shader::Backend::Bindings& binding,
DescriptorWrites& set_writes) const {

using ImageBindingInfo = std::tuple<VideoCore::ImageId, AmdGpu::Image, Shader::ImageResource>;
using ImageBindingInfo = std::pair<VideoCore::ImageId, VideoCore::TextureCache::TextureDesc>;
static boost::container::static_vector<ImageBindingInfo, 32> image_bindings;

image_bindings.clear();

for (const auto& image_desc : stage.images) {
const auto tsharp = image_desc.GetSharp(stage);
if (tsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid) {
VideoCore::ImageInfo image_info{tsharp, image_desc};
const auto image_id = texture_cache.FindImage(image_info);
auto& image = texture_cache.GetImage(image_id);
image.flags |= VideoCore::ImageFlagBits::Bound;
image_bindings.emplace_back(image_id, tsharp, image_desc);
} else {
image_bindings.emplace_back(VideoCore::ImageId{}, tsharp, image_desc);
if (texture_cache.IsMeta(tsharp.Address())) {
LOG_WARNING(Render_Vulkan, "Unexpected metadata read by a shader (texture)");
}

if (texture_cache.IsMeta(tsharp.Address())) {
LOG_WARNING(Render_Vulkan, "Unexpected metadata read by a PS shader (texture)");
if (tsharp.GetDataFmt() == AmdGpu::DataFormat::FormatInvalid) {
image_bindings.emplace_back(std::piecewise_construct, std::tuple{}, std::tuple{});
continue;
}

auto& [image_id, desc] = image_bindings.emplace_back(std::piecewise_construct, std::tuple{},
std::tuple{tsharp, image_desc});
image_id = texture_cache.FindImage(desc);
auto& image = texture_cache.GetImage(image_id);
ASSERT(False(image.flags & VideoCore::ImageFlagBits::Virtual));
if (image.binding.is_bound) {
// The image is already bound. In case if it is about to be used as storage we need
// to force general layout on it.
image.binding.force_general |= image_desc.is_storage;
}
if (image.binding.is_target) {
// The image is already bound as target. Since we read and output to it need to force
// general layout too.
image.binding.force_general = 1u;
}
image.binding.is_bound = 1u;
}

// Second pass to re-bind images that were updated after binding
for (auto [image_id, tsharp, desc] : image_bindings) {
for (auto& [image_id, desc] : image_bindings) {
bool is_storage = desc.type == VideoCore::TextureCache::BindingType::Storage;
if (!image_id) {
if (instance.IsNullDescriptorSupported()) {
image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
Expand All @@ -194,25 +207,52 @@ void Pipeline::BindTextures(VideoCore::TextureCache& texture_cache, const Shader
vk::ImageLayout::eGeneral);
}
} else {
if (auto& old_image = texture_cache.GetImage(image_id);
old_image.binding.needs_rebind) {
old_image.binding.Reset(); // clean up previous image binding state
image_id = texture_cache.FindImage(desc);
}

bound_images.emplace_back(image_id);

auto& image = texture_cache.GetImage(image_id);
if (True(image.flags & VideoCore::ImageFlagBits::NeedsRebind)) {
image_id = texture_cache.FindImage(image.info);
auto& image_view = texture_cache.FindTexture(image_id, desc.view_info);

if (image.binding.force_general || image.binding.is_target) {
image.Transit(vk::ImageLayout::eGeneral,
vk::AccessFlagBits2::eShaderRead |
(image.info.IsDepthStencil()
? vk::AccessFlagBits2::eDepthStencilAttachmentWrite
: vk::AccessFlagBits2::eColorAttachmentWrite),
{});
} else {
if (is_storage) {
image.Transit(vk::ImageLayout::eGeneral,
vk::AccessFlagBits2::eShaderRead |
vk::AccessFlagBits2::eShaderWrite,
desc.view_info.range);
} else {
const auto new_layout = image.info.IsDepthStencil()
? vk::ImageLayout::eDepthStencilReadOnlyOptimal
: vk::ImageLayout::eShaderReadOnlyOptimal;
image.Transit(new_layout, vk::AccessFlagBits2::eShaderRead,
desc.view_info.range);
}
}
VideoCore::ImageViewInfo view_info{tsharp, desc};
auto& image_view = texture_cache.FindTexture(image_id, view_info);
image.usage.storage |= is_storage;
image.usage.texture |= !is_storage;

image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view,
texture_cache.GetImage(image_id).last_state.layout);
image.flags &=
~(VideoCore::ImageFlagBits::NeedsRebind | VideoCore::ImageFlagBits::Bound);
image.last_state.layout);
}

set_writes.push_back({
.dstSet = VK_NULL_HANDLE,
.dstBinding = binding.unified++,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = desc.is_storage ? vk::DescriptorType::eStorageImage
: vk::DescriptorType::eSampledImage,
.descriptorType =
is_storage ? vk::DescriptorType::eStorageImage : vk::DescriptorType::eSampledImage,
.pImageInfo = &image_infos.back(),
});
}
Expand Down
9 changes: 8 additions & 1 deletion src/video_core/renderer_vulkan/vk_pipeline_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
#include "shader_recompiler/backend/bindings.h"
#include "shader_recompiler/info.h"
#include "video_core/renderer_vulkan/vk_common.h"
#include "video_core/texture_cache/texture_cache.h"

namespace VideoCore {
class BufferCache;
class TextureCache;
} // namespace VideoCore

namespace Vulkan {
Expand Down Expand Up @@ -42,6 +42,12 @@ class Pipeline {

void BindTextures(VideoCore::TextureCache& texture_cache, const Shader::Info& stage,
Shader::Backend::Bindings& binding, DescriptorWrites& set_writes) const;
void ResetBindings(VideoCore::TextureCache& texture_cache) const {
for (auto& image_id : bound_images) {
texture_cache.GetImage(image_id).binding.Reset();
}
bound_images.clear();
}

protected:
const Instance& instance;
Expand All @@ -53,6 +59,7 @@ class Pipeline {
static boost::container::static_vector<vk::DescriptorImageInfo, 32> image_infos;
static boost::container::static_vector<vk::BufferView, 8> buffer_views;
static boost::container::static_vector<vk::DescriptorBufferInfo, 32> buffer_infos;
static boost::container::static_vector<VideoCore::ImageId, 32> bound_images;
};

} // namespace Vulkan
Loading