mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
vk: Factor out common pipeline layout generator into reusable parts
This commit is contained in:
parent
10e0fb2b54
commit
b5b93e962b
7 changed files with 182 additions and 144 deletions
|
@ -595,6 +595,7 @@ if(TARGET 3rdparty_vulkan)
|
|||
RSX/VK/VKAsyncScheduler.cpp
|
||||
RSX/VK/VKCommandStream.cpp
|
||||
RSX/VK/VKCommonDecompiler.cpp
|
||||
RSX/VK/VKCommonPipelineLayout.cpp
|
||||
RSX/VK/VKCompute.cpp
|
||||
RSX/VK/VKDMA.cpp
|
||||
RSX/VK/VKDraw.cpp
|
||||
|
|
160
rpcs3/Emu/RSX/VK/VKCommonPipelineLayout.cpp
Normal file
160
rpcs3/Emu/RSX/VK/VKCommonPipelineLayout.cpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
#include "stdafx.h"
|
||||
#include "vkutils/device.h"
|
||||
#include "vkutils/descriptors.h"
|
||||
#include "VKCommonPipelineLayout.h"
|
||||
#include "VKHelpers.h"
|
||||
|
||||
#include "Emu/RSX/Common/simple_array.hpp"
|
||||
|
||||
namespace vk
|
||||
{
|
||||
rsx::simple_array<VkDescriptorSetLayoutBinding> get_common_binding_table()
|
||||
{
|
||||
const auto& binding_table = vk::get_current_renderer()->get_pipeline_binding_table();
|
||||
rsx::simple_array<VkDescriptorSetLayoutBinding> bindings(binding_table.instancing_constants_buffer_slot + 1);
|
||||
|
||||
u32 idx = 0;
|
||||
|
||||
// Vertex stream, one stream for cacheable data, one stream for transient data
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_buffers_first_bind_slot + i;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_constant_buffers_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_state_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_texture_params_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_constant_buffers_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||
bindings[idx].binding = binding_table.vertex_params_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.conditional_render_predicate_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.rasterizer_env_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.instancing_lookup_table_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.instancing_constants_buffer_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
return bindings;
|
||||
}
|
||||
|
||||
std::tuple<VkPipelineLayout, VkDescriptorSetLayout> get_common_pipeline_layout(VkDevice dev)
|
||||
{
|
||||
const auto& binding_table = vk::get_current_renderer()->get_pipeline_binding_table();
|
||||
auto bindings = get_common_binding_table();
|
||||
u32 idx = ::size32(bindings);
|
||||
|
||||
bindings.resize(binding_table.total_descriptor_bindings);
|
||||
|
||||
for (auto binding = binding_table.textures_first_bind_slot;
|
||||
binding < binding_table.vertex_textures_first_bind_slot;
|
||||
binding++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rsx::limits::vertex_textures_count; i++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_textures_first_bind_slot + i;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
ensure(idx == binding_table.total_descriptor_bindings);
|
||||
|
||||
std::array<VkPushConstantRange, 1> push_constants;
|
||||
push_constants[0].offset = 0;
|
||||
push_constants[0].size = 16;
|
||||
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
||||
if (vk::emulate_conditional_rendering())
|
||||
{
|
||||
// Conditional render toggle
|
||||
push_constants[0].size = 20;
|
||||
}
|
||||
|
||||
const auto set_layout = vk::descriptors::create_layout(bindings);
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_info = {};
|
||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layout_info.setLayoutCount = 1;
|
||||
layout_info.pSetLayouts = &set_layout;
|
||||
layout_info.pushConstantRangeCount = 1;
|
||||
layout_info.pPushConstantRanges = push_constants.data();
|
||||
|
||||
VkPipelineLayout result;
|
||||
CHECK_RESULT(vkCreatePipelineLayout(dev, &layout_info, nullptr, &result));
|
||||
return std::make_tuple(result, set_layout);
|
||||
}
|
||||
}
|
14
rpcs3/Emu/RSX/VK/VKCommonPipelineLayout.h
Normal file
14
rpcs3/Emu/RSX/VK/VKCommonPipelineLayout.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "vkutils/shared.h"
|
||||
#include "Emu/RSX/Common/simple_array.hpp"
|
||||
|
||||
namespace vk
|
||||
{
|
||||
// Grab standard layout for decompiled RSX programs. Also used by the interpreter.
|
||||
// FIXME: This generates a bloated monstrosity that needs to die.
|
||||
std::tuple<VkPipelineLayout, VkDescriptorSetLayout> get_common_pipeline_layout(VkDevice dev);
|
||||
|
||||
// Returns the standard binding layout without texture slots. Those have special handling depending on the consumer.
|
||||
rsx::simple_array<VkDescriptorSetLayoutBinding> get_common_binding_table();
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
#include "VKAsyncScheduler.h"
|
||||
#include "VKCommandStream.h"
|
||||
#include "VKCommonDecompiler.h"
|
||||
#include "VKCommonPipelineLayout.h"
|
||||
#include "VKCompute.h"
|
||||
#include "VKGSRender.h"
|
||||
#include "VKHelpers.h"
|
||||
|
@ -401,148 +402,6 @@ namespace vk
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
std::tuple<VkPipelineLayout, VkDescriptorSetLayout> get_shared_pipeline_layout(VkDevice dev)
|
||||
{
|
||||
const auto& binding_table = vk::get_current_renderer()->get_pipeline_binding_table();
|
||||
rsx::simple_array<VkDescriptorSetLayoutBinding> bindings(binding_table.total_descriptor_bindings);
|
||||
|
||||
u32 idx = 0;
|
||||
|
||||
// Vertex stream, one stream for cacheable data, one stream for transient data
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_buffers_first_bind_slot + i;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_constant_buffers_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_state_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.fragment_texture_params_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_constant_buffers_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||
bindings[idx].binding = binding_table.vertex_params_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.conditional_render_predicate_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding_table.rasterizer_env_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.instancing_lookup_table_bind_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.instancing_constants_buffer_slot;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
|
||||
idx++;
|
||||
|
||||
for (auto binding = binding_table.textures_first_bind_slot;
|
||||
binding < binding_table.vertex_textures_first_bind_slot;
|
||||
binding++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
bindings[idx].binding = binding;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rsx::limits::vertex_textures_count; i++)
|
||||
{
|
||||
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
bindings[idx].descriptorCount = 1;
|
||||
bindings[idx].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
bindings[idx].binding = binding_table.vertex_textures_first_bind_slot + i;
|
||||
bindings[idx].pImmutableSamplers = nullptr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
ensure(idx == binding_table.total_descriptor_bindings);
|
||||
|
||||
std::array<VkPushConstantRange, 1> push_constants;
|
||||
push_constants[0].offset = 0;
|
||||
push_constants[0].size = 16;
|
||||
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
||||
if (vk::emulate_conditional_rendering())
|
||||
{
|
||||
// Conditional render toggle
|
||||
push_constants[0].size = 20;
|
||||
}
|
||||
|
||||
const auto set_layout = vk::descriptors::create_layout(bindings);
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_info = {};
|
||||
layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layout_info.setLayoutCount = 1;
|
||||
layout_info.pSetLayouts = &set_layout;
|
||||
layout_info.pushConstantRangeCount = 1;
|
||||
layout_info.pPushConstantRanges = push_constants.data();
|
||||
|
||||
VkPipelineLayout result;
|
||||
CHECK_RESULT(vkCreatePipelineLayout(dev, &layout_info, nullptr, &result));
|
||||
return std::make_tuple(result, set_layout);
|
||||
}
|
||||
}
|
||||
|
||||
u64 VKGSRender::get_cycles()
|
||||
{
|
||||
return thread_ctrl::get_cycles(static_cast<named_thread<VKGSRender>&>(*this));
|
||||
|
@ -633,7 +492,7 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar)
|
|||
m_secondary_cb_list.create(m_secondary_command_buffer_pool, vk::command_buffer::access_type_hint::all);
|
||||
|
||||
//Precalculated stuff
|
||||
std::tie(m_pipeline_layout, m_descriptor_layouts) = get_shared_pipeline_layout(*m_device);
|
||||
std::tie(m_pipeline_layout, m_descriptor_layouts) = vk::get_common_pipeline_layout(*m_device);
|
||||
|
||||
//Occlusion
|
||||
m_occlusion_query_manager = std::make_unique<vk::query_pool_manager>(*m_device, VK_QUERY_TYPE_OCCLUSION, OCCLUSION_MAX_POOL_SIZE);
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace vk
|
|||
const std::vector<glsl::program_input>& vs_inputs, const std::vector<glsl::program_input>& fs_inputs)
|
||||
{
|
||||
VkPipeline pipeline;
|
||||
CHECK_RESULT(vkCreateGraphicsPipelines(*m_device, nullptr, 1, &create_info, NULL, &pipeline));
|
||||
CHECK_RESULT(vkCreateGraphicsPipelines(*m_device, VK_NULL_HANDLE, 1, &create_info, nullptr, &pipeline));
|
||||
auto result = std::make_unique<vk::glsl::program>(*m_device, pipeline, pipe_layout, vs_inputs, fs_inputs);
|
||||
result->link();
|
||||
return result;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
<ClInclude Include="Emu\RSX\VK\VKResolveHelper.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKResourceManager.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKShaderInterpreter.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKCommonPipelineLayout.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\VKTextureCache.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\vkutils\buffer_object.h" />
|
||||
<ClInclude Include="Emu\RSX\VK\vkutils\chip_class.h" />
|
||||
|
@ -84,6 +85,7 @@
|
|||
<ClCompile Include="Emu\RSX\VK\VKResolveHelper.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKResourceManager.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKShaderInterpreter.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKCommonPipelineLayout.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\VKTexture.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\vkutils\barriers.cpp" />
|
||||
<ClCompile Include="Emu\RSX\VK\vkutils\buffer_object.cpp" />
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
<ClCompile Include="Emu\RSX\VK\upscalers\fsr1\fsr_pass.cpp">
|
||||
<Filter>upscalers\fsr1</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\VK\VKCommonPipelineLayout.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Emu\RSX\VK\VKCommonDecompiler.h" />
|
||||
|
@ -173,6 +174,7 @@
|
|||
<ClInclude Include="Emu\RSX\VK\vkutils\garbage_collector.h">
|
||||
<Filter>vkutils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\VK\VKCommonPipelineLayout.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="vkutils">
|
||||
|
|
Loading…
Add table
Reference in a new issue