mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-12-06 07:12:28 +01:00
vk: Combine all draw-time constants to a single struct and update only the offset id
- Reduces push constants consumed per draw to 4 bytes total
This commit is contained in:
parent
335f3dbe2f
commit
3452aaf5d5
|
|
@ -22,12 +22,16 @@ struct vertex_context_t
|
|||
float reserved[3];
|
||||
};
|
||||
|
||||
struct vertex_layout_t
|
||||
struct draw_parameters_t
|
||||
{
|
||||
uint vertex_base_index;
|
||||
uint vertex_index_offset;
|
||||
uint draw_id;
|
||||
uint reserved;
|
||||
uint xform_constants_offset;
|
||||
uint vs_context_offset;
|
||||
uint fs_constants_offset;
|
||||
uint fs_context_offset;
|
||||
uint fs_texture_base_index;
|
||||
uvec2 attrib_data[16];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ attribute_desc fetch_desc(const in int location)
|
|||
|
||||
#ifdef VULKAN
|
||||
// Fetch parameters streamed separately from draw parameters
|
||||
uvec2 attrib = vertex_layouts[vs_attrib_layout_offset].attrib_data[location];
|
||||
uvec2 attrib = get_draw_params().attrib_data[location];
|
||||
#else
|
||||
// Data is packed into a ubo
|
||||
const int block = (location >> 1);
|
||||
|
|
@ -179,8 +179,8 @@ attribute_desc fetch_desc(const in int location)
|
|||
}
|
||||
|
||||
#ifdef VULKAN
|
||||
#define vertex_index_offset vertex_layouts[vs_attrib_layout_offset].vertex_index_offset
|
||||
#define vertex_base_index vertex_layouts[vs_attrib_layout_offset].vertex_base_index
|
||||
#define vertex_index_offset get_draw_params().vertex_index_offset
|
||||
#define vertex_base_index get_draw_params().vertex_base_index
|
||||
#endif
|
||||
|
||||
vec4 read_location(const in int location)
|
||||
|
|
|
|||
|
|
@ -820,7 +820,7 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
|||
update_descriptors = true;
|
||||
|
||||
// Allocate stream layout memory for this batch
|
||||
const u64 alloc_size = rsx::method_registers.current_draw_clause.pass_count() * 144;
|
||||
const u64 alloc_size = rsx::method_registers.current_draw_clause.pass_count() * 160;
|
||||
m_vertex_layout_dynamic_offset = m_vertex_layout_ring_info.alloc<16>(alloc_size);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,6 +225,18 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
|||
}
|
||||
}
|
||||
|
||||
// Always provided by vertex program, not part of local bindings
|
||||
OS <<
|
||||
"layout(std430, set=0, binding=2) readonly buffer DrawParametersBuffer\n"
|
||||
"{\n"
|
||||
" draw_parameters_t draw_parameters[];\n"
|
||||
"};\n\n"
|
||||
|
||||
"#define get_draw_params() draw_parameters[draw_parameters_offset]\n"
|
||||
"#define fs_constants_offset get_draw_params().fs_constants_offset\n"
|
||||
"#define fs_context_offset get_draw_params().fs_context_offset\n"
|
||||
"#define fs_texture_base_index get_draw_params().fs_texture_base_index\n\n";
|
||||
|
||||
if (!properties.constant_offsets.empty())
|
||||
{
|
||||
OS << "layout(std430, set=1, binding=" << vk_prog->binding_table.cbuf_location << ") readonly buffer FragmentConstantsBuffer\n";
|
||||
|
|
@ -282,16 +294,14 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
|||
OS <<
|
||||
"layout(push_constant) uniform push_constants_block\n"
|
||||
"{\n"
|
||||
" layout(offset=12) uint fs_constants_offset;\n"
|
||||
" uint fs_context_offset;\n"
|
||||
" uint fs_texture_base_index;\n"
|
||||
" uint draw_parameters_offset;\n"
|
||||
"};\n\n";
|
||||
|
||||
const vk::glsl::program_input push_constants
|
||||
{
|
||||
.domain = glsl::glsl_fragment_program,
|
||||
.type = vk::glsl::input_type_push_constant,
|
||||
.bound_data = vk::glsl::push_constant_ref{.offset = 12, .size = 12 },
|
||||
.bound_data = vk::glsl::push_constant_ref{.offset = 0, .size = 4 },
|
||||
.set = vk::glsl::binding_set_index_vertex,
|
||||
.location = umax,
|
||||
.name = "fs_push_constants_block"
|
||||
|
|
|
|||
|
|
@ -2184,26 +2184,16 @@ void VKGSRender::upload_transform_constants(const rsx::io_buffer& buffer)
|
|||
void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_info)
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct rsx_vs_prog_push_constants_block_t
|
||||
{
|
||||
u32 xform_constants_offset;
|
||||
u32 vs_context_offset;
|
||||
u32 vs_attrib_layout_offset;
|
||||
};
|
||||
|
||||
struct rsx_fs_prog_push_constants_block_t
|
||||
{
|
||||
u32 fs_constants_offset;
|
||||
u32 fs_context_offset;
|
||||
u32 fs_texture_base_index;
|
||||
};
|
||||
|
||||
struct rsx_prog_vertex_layout_entry_t
|
||||
{
|
||||
u32 vertex_base_index;
|
||||
u32 vertex_index_offset;
|
||||
u32 draw_id;
|
||||
u32 reserved;
|
||||
u32 xform_constants_offset;
|
||||
u32 vs_context_offset;
|
||||
u32 fs_constants_offset;
|
||||
u32 fs_context_offset;
|
||||
u32 fs_texture_base_index;
|
||||
s32 attrib_data[1];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
|
@ -2211,46 +2201,36 @@ void VKGSRender::update_vertex_env(u32 id, const vk::vertex_upload_info& vertex_
|
|||
// Actual allocation must have been done previously
|
||||
const u32 vs_constant_id_offset = static_cast<u32>(m_xform_constants_dynamic_offset) / 16u;
|
||||
const u32 vertex_context_offset = static_cast<u32>(m_vertex_env_dynamic_offset) / 96u;
|
||||
const u32 vertex_layout_offset = static_cast<u32>(m_vertex_layout_dynamic_offset) / 144u;
|
||||
const u32 vertex_layout_offset = static_cast<u32>(m_vertex_layout_dynamic_offset) / 160u;
|
||||
const u32 fs_constant_id_offset = static_cast<u32>(m_fragment_constants_dynamic_offset) / 16u;
|
||||
const u32 fs_context_offset = static_cast<u32>(m_fragment_env_dynamic_offset) / 32u;
|
||||
const u32 fs_texture_base_index = static_cast<u32>(m_texture_parameters_dynamic_offset) / 48u;
|
||||
|
||||
// Pack
|
||||
rsx_vs_prog_push_constants_block_t vs_push_constants;
|
||||
vs_push_constants.xform_constants_offset = vs_constant_id_offset;
|
||||
vs_push_constants.vs_context_offset = vertex_context_offset;
|
||||
vs_push_constants.vs_attrib_layout_offset = vertex_layout_offset + id;
|
||||
|
||||
rsx_fs_prog_push_constants_block_t fs_push_constants;
|
||||
fs_push_constants.fs_constants_offset = fs_constant_id_offset;
|
||||
fs_push_constants.fs_context_offset = fs_context_offset;
|
||||
fs_push_constants.fs_texture_base_index = fs_texture_base_index;
|
||||
|
||||
vkCmdPushConstants(
|
||||
*m_current_command_buffer,
|
||||
m_program->layout(),
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0,
|
||||
sizeof(vs_push_constants),
|
||||
&vs_push_constants);
|
||||
|
||||
vkCmdPushConstants(
|
||||
*m_current_command_buffer,
|
||||
m_program->layout(),
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
sizeof(vs_push_constants),
|
||||
sizeof(fs_push_constants),
|
||||
&fs_push_constants);
|
||||
|
||||
// Now actually fill in the data
|
||||
auto buf = m_vertex_layout_ring_info.map(m_vertex_layout_dynamic_offset + (144u * id), 144);
|
||||
auto buf = m_vertex_layout_ring_info.map(m_vertex_layout_dynamic_offset + (160u * id), 160u);
|
||||
auto dst = reinterpret_cast<rsx_prog_vertex_layout_entry_t*>(buf);
|
||||
|
||||
// Pack
|
||||
dst->vertex_base_index = vertex_info.vertex_index_base;
|
||||
dst->vertex_index_offset = vertex_info.vertex_index_offset;
|
||||
dst->draw_id = id;
|
||||
dst->reserved = 0;
|
||||
|
||||
dst->xform_constants_offset = vs_constant_id_offset;
|
||||
dst->vs_context_offset = vertex_context_offset;
|
||||
|
||||
dst->fs_constants_offset = fs_constant_id_offset;
|
||||
dst->fs_context_offset = fs_context_offset;
|
||||
dst->fs_texture_base_index = fs_texture_base_index;
|
||||
|
||||
const u32 push_val = vertex_layout_offset + id;
|
||||
vkCmdPushConstants(
|
||||
*m_current_command_buffer,
|
||||
m_program->layout(),
|
||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0,
|
||||
4,
|
||||
&push_val);
|
||||
|
||||
// Now actually fill in the data
|
||||
m_draw_processor.fill_vertex_layout_state(
|
||||
m_vertex_layout,
|
||||
current_vp_metadata,
|
||||
|
|
|
|||
|
|
@ -651,7 +651,7 @@ namespace vk
|
|||
.binding = input.location,
|
||||
.descriptorType = type,
|
||||
.descriptorCount = descriptor_count(input.name),
|
||||
.stageFlags = to_shader_stage_flags(input.domain)
|
||||
.stageFlags = to_shader_stage_flags(input.domain) | input.ex_stages
|
||||
};
|
||||
bindings.push_back(binding);
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ namespace vk
|
|||
u32 location = umax;
|
||||
std::string name = "undefined";
|
||||
|
||||
VkFlags ex_stages = 0;
|
||||
|
||||
inline bound_buffer& as_buffer() { return *std::get_if<bound_buffer>(&bound_data); }
|
||||
inline bound_sampler& as_sampler() { return *std::get_if<bound_sampler>(&bound_data); }
|
||||
inline push_constant_ref& as_push_constant() { return *std::get_if<push_constant_ref>(&bound_data); }
|
||||
|
|
|
|||
|
|
@ -79,14 +79,20 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
|||
|
||||
glsl::insert_subheader_block(OS);
|
||||
|
||||
OS <<
|
||||
// Variable redirection
|
||||
"#define get_draw_params() draw_parameters[draw_parameters_offset]\n"
|
||||
"#define vs_context_offset get_draw_params().vs_context_offset\n"
|
||||
"#define xform_constants_offset get_draw_params().xform_constants_offset\n\n"
|
||||
// Helpers
|
||||
"#define get_vertex_context() vertex_contexts[vs_context_offset]\n"
|
||||
"#define get_user_clip_config() get_vertex_context().user_clip_configuration_bits\n\n";
|
||||
|
||||
OS <<
|
||||
"layout(std430, set=0, binding=" << vk_prog->binding_table.context_buffer_location << ") readonly buffer VertexContextBuffer\n"
|
||||
"{\n"
|
||||
" vertex_context_t vertex_contexts[];\n"
|
||||
"};\n\n"
|
||||
""
|
||||
"#define get_vertex_context() vertex_contexts[vs_context_offset]\n"
|
||||
"#define get_user_clip_config() get_vertex_context().user_clip_configuration_bits\n\n";
|
||||
"};\n\n";
|
||||
|
||||
const vk::glsl::program_input context_input
|
||||
{
|
||||
|
|
@ -118,9 +124,9 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
|||
}
|
||||
|
||||
OS <<
|
||||
"layout(std430, set=0, binding=" << vk_prog->binding_table.vertex_buffers_location + 2 << ") readonly buffer VertexLayoutBuffer\n"
|
||||
"layout(std430, set=0, binding=" << vk_prog->binding_table.vertex_buffers_location + 2 << ") readonly buffer DrawParametersBuffer\n"
|
||||
"{\n"
|
||||
" vertex_layout_t vertex_layouts[];\n"
|
||||
" draw_parameters_t draw_parameters[];\n"
|
||||
"};\n\n";
|
||||
|
||||
const vk::glsl::program_input layouts_input
|
||||
|
|
@ -129,23 +135,22 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
|||
.type = vk::glsl::input_type_storage_buffer,
|
||||
.set = vk::glsl::binding_set_index_vertex,
|
||||
.location = vk_prog->binding_table.vertex_buffers_location + 2,
|
||||
.name = "VertexLayoutBuffer"
|
||||
.name = "DrawParametersBuffer",
|
||||
.ex_stages = VK_SHADER_STAGE_FRAGMENT_BIT // Shared with fragment shader
|
||||
};
|
||||
inputs.push_back(layouts_input);
|
||||
|
||||
OS <<
|
||||
"layout(push_constant) uniform push_constants_block\n"
|
||||
"{\n"
|
||||
" uint xform_constants_offset;\n"
|
||||
" uint vs_context_offset;\n"
|
||||
" uint vs_attrib_layout_offset;\n"
|
||||
" uint draw_parameters_offset;\n"
|
||||
"};\n\n";
|
||||
|
||||
const vk::glsl::program_input push_constants
|
||||
{
|
||||
.domain = glsl::glsl_vertex_program,
|
||||
.type = vk::glsl::input_type_push_constant,
|
||||
.bound_data = vk::glsl::push_constant_ref{ .offset = 0, .size = 12 },
|
||||
.bound_data = vk::glsl::push_constant_ref{ .offset = 0, .size = 4 },
|
||||
.set = vk::glsl::binding_set_index_vertex,
|
||||
.location = umax,
|
||||
.name = "push_constants_block"
|
||||
|
|
|
|||
Loading…
Reference in a new issue