summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan/pipeline_helper.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_vulkan/pipeline_helper.h73
1 files changed, 62 insertions, 11 deletions
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h
index 4847db6b6..11c160570 100644
--- a/src/video_core/renderer_vulkan/pipeline_helper.h
+++ b/src/video_core/renderer_vulkan/pipeline_helper.h
@@ -10,6 +10,7 @@
#include "common/assert.h"
#include "common/common_types.h"
+#include "shader_recompiler/backend/spirv/emit_spirv.h"
#include "shader_recompiler/shader_info.h"
#include "video_core/renderer_vulkan/vk_texture_cache.h"
#include "video_core/renderer_vulkan/vk_update_descriptor.h"
@@ -20,6 +21,8 @@
namespace Vulkan {
+using Shader::Backend::SPIRV::NUM_TEXTURE_AND_IMAGE_SCALING_WORDS;
+
class DescriptorLayoutBuilder {
public:
DescriptorLayoutBuilder(const Device& device_) : device{&device_} {}
@@ -68,18 +71,28 @@ public:
}
vk::PipelineLayout CreatePipelineLayout(VkDescriptorSetLayout descriptor_set_layout) const {
+ using Shader::Backend::SPIRV::RescalingLayout;
+ const u32 size_offset = is_compute ? sizeof(RescalingLayout::down_factor) : 0u;
+ const VkPushConstantRange range{
+ .stageFlags = static_cast<VkShaderStageFlags>(
+ is_compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_ALL_GRAPHICS),
+ .offset = 0,
+ .size = static_cast<u32>(sizeof(RescalingLayout)) - size_offset,
+ };
return device->GetLogical().CreatePipelineLayout({
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.setLayoutCount = descriptor_set_layout ? 1U : 0U,
.pSetLayouts = bindings.empty() ? nullptr : &descriptor_set_layout,
- .pushConstantRangeCount = 0,
- .pPushConstantRanges = nullptr,
+ .pushConstantRangeCount = 1,
+ .pPushConstantRanges = &range,
});
}
void Add(const Shader::Info& info, VkShaderStageFlags stage) {
+ is_compute |= (stage & VK_SHADER_STAGE_COMPUTE_BIT) != 0;
+
Add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stage, info.constant_buffer_descriptors);
Add(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, stage, info.storage_buffers_descriptors);
Add(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, stage, info.texture_buffer_descriptors);
@@ -115,6 +128,7 @@ private:
}
const Device* device{};
+ bool is_compute{};
boost::container::small_vector<VkDescriptorSetLayoutBinding, 32> bindings;
boost::container::small_vector<VkDescriptorUpdateTemplateEntryKHR, 32> entries;
u32 binding{};
@@ -122,31 +136,68 @@ private:
size_t offset{};
};
-inline void PushImageDescriptors(const Shader::Info& info, const VkSampler*& samplers,
- const ImageId*& image_view_ids, TextureCache& texture_cache,
- VKUpdateDescriptorQueue& update_descriptor_queue) {
- for (const auto& desc : info.texture_buffer_descriptors) {
- image_view_ids += desc.count;
+class RescalingPushConstant {
+public:
+ explicit RescalingPushConstant() noexcept {}
+
+ void PushTexture(bool is_rescaled) noexcept {
+ *texture_ptr |= is_rescaled ? texture_bit : 0u;
+ texture_bit <<= 1u;
+ if (texture_bit == 0u) {
+ texture_bit = 1u;
+ ++texture_ptr;
+ }
}
- for (const auto& desc : info.image_buffer_descriptors) {
- image_view_ids += desc.count;
+
+ void PushImage(bool is_rescaled) noexcept {
+ *image_ptr |= is_rescaled ? image_bit : 0u;
+ image_bit <<= 1u;
+ if (image_bit == 0u) {
+ image_bit = 1u;
+ ++image_ptr;
+ }
}
+
+ const std::array<u32, NUM_TEXTURE_AND_IMAGE_SCALING_WORDS>& Data() const noexcept {
+ return words;
+ }
+
+private:
+ std::array<u32, NUM_TEXTURE_AND_IMAGE_SCALING_WORDS> words{};
+ u32* texture_ptr{words.data()};
+ u32* image_ptr{words.data() + Shader::Backend::SPIRV::NUM_TEXTURE_SCALING_WORDS};
+ u32 texture_bit{1u};
+ u32 image_bit{1u};
+};
+
+inline void PushImageDescriptors(TextureCache& texture_cache,
+ VKUpdateDescriptorQueue& update_descriptor_queue,
+ const Shader::Info& info, RescalingPushConstant& rescaling,
+ const VkSampler*& samplers,
+ const VideoCommon::ImageViewInOut*& views) {
+ const u32 num_texture_buffers = Shader::NumDescriptors(info.texture_buffer_descriptors);
+ const u32 num_image_buffers = Shader::NumDescriptors(info.image_buffer_descriptors);
+ views += num_texture_buffers;
+ views += num_image_buffers;
for (const auto& desc : info.texture_descriptors) {
for (u32 index = 0; index < desc.count; ++index) {
+ const VideoCommon::ImageViewId image_view_id{(views++)->id};
const VkSampler sampler{*(samplers++)};
- ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))};
+ ImageView& image_view{texture_cache.GetImageView(image_view_id)};
const VkImageView vk_image_view{image_view.Handle(desc.type)};
update_descriptor_queue.AddSampledImage(vk_image_view, sampler);
+ rescaling.PushTexture(texture_cache.IsRescaling(image_view));
}
}
for (const auto& desc : info.image_descriptors) {
for (u32 index = 0; index < desc.count; ++index) {
- ImageView& image_view{texture_cache.GetImageView(*(image_view_ids++))};
+ ImageView& image_view{texture_cache.GetImageView((views++)->id)};
if (desc.is_written) {
texture_cache.MarkModification(image_view.image_id);
}
const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)};
update_descriptor_queue.AddImage(vk_image_view);
+ rescaling.PushImage(texture_cache.IsRescaling(image_view));
}
}
}