shader: Initial support for textures and TEX
This commit is contained in:
parent
7d6ba5b984
commit
ab46371247
33 changed files with 1489 additions and 342 deletions
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue