summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-03-08 22:31:53 +0100
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:23 +0200
commitab463712474de5f99eec137a9c6233e55fe184f0 (patch)
tree30d79ac64dd03d5cfafd07c0c42c2baadc82de98 /src/video_core/renderer_vulkan
parentshader: Implement R2P (diff)
downloadyuzu-ab463712474de5f99eec137a9c6233e55fe184f0.tar
yuzu-ab463712474de5f99eec137a9c6233e55fe184f0.tar.gz
yuzu-ab463712474de5f99eec137a9c6233e55fe184f0.tar.bz2
yuzu-ab463712474de5f99eec137a9c6233e55fe184f0.tar.lz
yuzu-ab463712474de5f99eec137a9c6233e55fe184f0.tar.xz
yuzu-ab463712474de5f99eec137a9c6233e55fe184f0.tar.zst
yuzu-ab463712474de5f99eec137a9c6233e55fe184f0.zip
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp101
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp3
4 files changed, 111 insertions, 1 deletions
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
index a658a3276..ef8bef6ff 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
@@ -40,6 +40,16 @@ vk::DescriptorSetLayout CreateDescriptorSetLayout(const Device& device, const Sh
});
++binding;
}
+ for (const auto& desc : info.texture_descriptors) {
+ bindings.push_back({
+ .binding = binding,
+ .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+ .descriptorCount = 1,
+ .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
+ .pImmutableSamplers = nullptr,
+ });
+ ++binding;
+ }
return device.GetLogical().CreateDescriptorSetLayout({
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = nullptr,
@@ -79,6 +89,18 @@ vk::DescriptorUpdateTemplateKHR CreateDescriptorUpdateTemplate(
++binding;
offset += sizeof(DescriptorUpdateEntry);
}
+ for (const auto& desc : info.texture_descriptors) {
+ entries.push_back({
+ .dstBinding = binding,
+ .dstArrayElement = 0,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+ .offset = offset,
+ .stride = sizeof(DescriptorUpdateEntry),
+ });
+ ++binding;
+ offset += sizeof(DescriptorUpdateEntry);
+ }
return device.GetLogical().CreateDescriptorUpdateTemplateKHR({
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
.pNext = nullptr,
@@ -92,6 +114,44 @@ vk::DescriptorUpdateTemplateKHR CreateDescriptorUpdateTemplate(
.set = 0,
});
}
+
+struct TextureHandle {
+ explicit TextureHandle(u32 data, bool via_header_index) {
+ const Tegra::Texture::TextureHandle handle{data};
+ image = handle.tic_id;
+ sampler = via_header_index ? image : handle.tsc_id.Value();
+ }
+
+ u32 image;
+ u32 sampler;
+};
+
+VideoCommon::ImageViewType CastType(Shader::TextureType type) {
+ switch (type) {
+ case Shader::TextureType::Color1D:
+ case Shader::TextureType::Shadow1D:
+ return VideoCommon::ImageViewType::e1D;
+ case Shader::TextureType::ColorArray1D:
+ case Shader::TextureType::ShadowArray1D:
+ return VideoCommon::ImageViewType::e1DArray;
+ case Shader::TextureType::Color2D:
+ case Shader::TextureType::Shadow2D:
+ return VideoCommon::ImageViewType::e2D;
+ case Shader::TextureType::ColorArray2D:
+ case Shader::TextureType::ShadowArray2D:
+ return VideoCommon::ImageViewType::e2DArray;
+ case Shader::TextureType::Color3D:
+ case Shader::TextureType::Shadow3D:
+ return VideoCommon::ImageViewType::e3D;
+ case Shader::TextureType::ColorCube:
+ case Shader::TextureType::ShadowCube:
+ return VideoCommon::ImageViewType::Cube;
+ case Shader::TextureType::ColorArrayCube:
+ case Shader::TextureType::ShadowArrayCube:
+ return VideoCommon::ImageViewType::CubeArray;
+ }
+ UNREACHABLE_MSG("Invalid texture type {}", type);
+}
} // Anonymous namespace
ComputePipeline::ComputePipeline(const Device& device, VKDescriptorPool& descriptor_pool,
@@ -143,6 +203,47 @@ void ComputePipeline::ConfigureBufferCache(BufferCache& buffer_cache) {
buffer_cache.BindHostComputeBuffers();
}
+void ComputePipeline::ConfigureTextureCache(Tegra::Engines::KeplerCompute& kepler_compute,
+ Tegra::MemoryManager& gpu_memory,
+ TextureCache& texture_cache) {
+ texture_cache.SynchronizeComputeDescriptors();
+
+ static constexpr size_t max_elements = 64;
+ std::array<ImageId, max_elements> image_view_ids;
+ boost::container::static_vector<u32, max_elements> image_view_indices;
+ boost::container::static_vector<VkSampler, max_elements> sampler_handles;
+
+ const auto& launch_desc{kepler_compute.launch_description};
+ const auto& cbufs{launch_desc.const_buffer_config};
+ const bool via_header_index{launch_desc.linked_tsc};
+ for (const auto& desc : info.texture_descriptors) {
+ const u32 cbuf_index{desc.cbuf_index};
+ const u32 cbuf_offset{desc.cbuf_offset};
+ ASSERT(((launch_desc.const_buffer_enable_mask >> cbuf_index) & 1) != 0);
+
+ const GPUVAddr addr{cbufs[cbuf_index].Address() + cbuf_offset};
+ const u32 raw_handle{gpu_memory.Read<u32>(addr)};
+
+ const TextureHandle handle(raw_handle, via_header_index);
+ image_view_indices.push_back(handle.image);
+
+ Sampler* const sampler = texture_cache.GetComputeSampler(handle.sampler);
+ sampler_handles.push_back(sampler->Handle());
+ }
+
+ const std::span indices_span(image_view_indices.data(), image_view_indices.size());
+ texture_cache.FillComputeImageViews(indices_span, image_view_ids);
+
+ size_t index{};
+ for (const auto& desc : info.texture_descriptors) {
+ const VkSampler vk_sampler{sampler_handles[index]};
+ ImageView& image_view{texture_cache.GetImageView(image_view_ids[index])};
+ const VkImageView vk_image_view{image_view.Handle(CastType(desc.type))};
+ update_descriptor_queue->AddSampledImage(vk_image_view, vk_sampler);
+ ++index;
+ }
+}
+
VkDescriptorSet ComputePipeline::UpdateDescriptorSet() {
const VkDescriptorSet descriptor_set{descriptor_allocator.Commit()};
update_descriptor_queue->Send(*descriptor_update_template, descriptor_set);
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.h b/src/video_core/renderer_vulkan/vk_compute_pipeline.h
index dc045d524..08d73a2a4 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.h
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.h
@@ -6,9 +6,11 @@
#include "common/common_types.h"
#include "shader_recompiler/shader_info.h"
+#include "video_core/memory_manager.h"
#include "video_core/renderer_vulkan/vk_buffer_cache.h"
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
#include "video_core/renderer_vulkan/vk_pipeline.h"
+#include "video_core/renderer_vulkan/vk_texture_cache.h"
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -30,6 +32,8 @@ public:
ComputePipeline(const ComputePipeline&) = delete;
void ConfigureBufferCache(BufferCache& buffer_cache);
+ void ConfigureTextureCache(Tegra::Engines::KeplerCompute& kepler_compute,
+ Tegra::MemoryManager& gpu_memory, TextureCache& texture_cache);
[[nodiscard]] VkDescriptorSet UpdateDescriptorSet();
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 2497c2385..bcb7dd2eb 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -76,6 +76,10 @@ public:
return gpu_memory.Read<u64>(program_base + address);
}
+ u32 TextureBoundBuffer() override {
+ return kepler_compute.regs.tex_cb_index;
+ }
+
std::array<u32, 3> WorkgroupSize() override {
const auto& qmd{kepler_compute.launch_description};
return {qmd.block_dim_x, qmd.block_dim_y, qmd.block_dim_z};
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 1b662f9f3..c94419d29 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -241,9 +241,10 @@ void RasterizerVulkan::DispatchCompute() {
if (!pipeline) {
return;
}
- std::scoped_lock lock{buffer_cache.mutex};
+ std::scoped_lock lock{texture_cache.mutex, buffer_cache.mutex};
update_descriptor_queue.Acquire();
pipeline->ConfigureBufferCache(buffer_cache);
+ pipeline->ConfigureTextureCache(kepler_compute, gpu_memory, texture_cache);
const VkDescriptorSet descriptor_set{pipeline->UpdateDescriptorSet()};
const auto& qmd{kepler_compute.launch_description};