rsx: Fix program generation and compact referenced data blocks

This commit is contained in:
kd-11 2022-03-23 23:59:42 +03:00 committed by kd-11
parent 9a2d4fe46b
commit d057ffe80f
8 changed files with 61 additions and 41 deletions

View File

@ -800,11 +800,14 @@ void GLGSRender::load_program_env()
if (update_transform_constants) if (update_transform_constants)
{ {
// Vertex constants // Vertex constants
auto mapping = m_transform_constants_buffer->alloc_from_heap(8192, m_uniform_buffer_offset_align); const std::vector<u16>& constant_ids = m_vertex_prog ? m_vertex_prog->constant_ids : std::vector<u16>{};
const usz transform_constants_size = constant_ids.empty() ? 8192 : constant_ids.size() * 16;
auto mapping = m_transform_constants_buffer->alloc_from_heap(transform_constants_size, m_uniform_buffer_offset_align);
auto buf = static_cast<u8*>(mapping.first); auto buf = static_cast<u8*>(mapping.first);
fill_vertex_program_constants_data(buf, m_vertex_prog ? m_vertex_prog->constant_ids : std::vector<u16>{}); fill_vertex_program_constants_data(buf, m_vertex_prog ? m_vertex_prog->constant_ids : std::vector<u16>{});
m_transform_constants_buffer->bind_range(GL_VERTEX_CONSTANT_BUFFERS_BIND_SLOT, mapping.second, 8192); m_transform_constants_buffer->bind_range(GL_VERTEX_CONSTANT_BUFFERS_BIND_SLOT, mapping.second, transform_constants_size);
} }
if (update_fragment_constants && !update_instruction_buffers) if (update_fragment_constants && !update_instruction_buffers)

View File

@ -58,17 +58,21 @@ void GLVertexDecompilerThread::insertInputs(std::stringstream& OS, const std::ve
void GLVertexDecompilerThread::insertConstants(std::stringstream& OS, const std::vector<ParamType>& constants) void GLVertexDecompilerThread::insertConstants(std::stringstream& OS, const std::vector<ParamType>& constants)
{ {
OS << "layout(std140, binding = 2) uniform VertexConstantsBuffer\n";
OS << "{\n";
OS << " vec4 vc[468];\n";
OS << "};\n\n";
for (const ParamType &PT: constants) for (const ParamType &PT: constants)
{ {
for (const ParamItem &PI : PT.items) for (const ParamItem &PI : PT.items)
{ {
if (PI.name == "vc[468]") if (PI.name.starts_with("vc["))
{
OS << "layout(std140, binding = 2) uniform VertexConstantsBuffer\n";
OS << "{\n";
OS << " vec4 " << PI.name << ";\n";
OS << "};\n\n";
continue; continue;
}
OS << "uniform " << PT.type << " " << PI.name << ";\n"; OS << "uniform " << PT.type << " " << PI.name << ";\n";
} }
@ -272,10 +276,14 @@ void GLVertexProgram::Decompile(const RSXVertexProgram& prog)
GLVertexDecompilerThread decompiler(prog, source, parr); GLVertexDecompilerThread decompiler(prog, source, parr);
decompiler.Task(); decompiler.Task();
if (has_indexed_constants = decompiler.properties.has_indexed_constants;
!has_indexed_constants)
{
constant_ids = std::vector<u16>(decompiler.m_constant_ids.begin(), decompiler.m_constant_ids.end());
}
shader.create(::glsl::program_domain::glsl_vertex_program, source); shader.create(::glsl::program_domain::glsl_vertex_program, source);
id = shader.id(); id = shader.id();
has_indexed_constants = decompiler.properties.has_indexed_constants;
constant_ids = std::move(decompiler.m_constant_ids);
} }
void GLVertexProgram::Delete() void GLVertexProgram::Delete()

View File

@ -145,7 +145,7 @@ struct ParamType
std::vector<ParamItem> new_list; std::vector<ParamItem> new_list;
for (const auto& it : items) for (const auto& it : items)
{ {
if (it.name != item.name) if (it.name != name)
{ {
new_list.emplace_back(it.name, it.location, it.value); new_list.emplace_back(it.name, it.location, it.value);
} }
@ -156,6 +156,7 @@ struct ParamType
} }
std::swap(items, new_list); std::swap(items, new_list);
return true;
} }
items.push_back(item); items.push_back(item);

View File

@ -127,7 +127,7 @@ std::string VertexProgramDecompiler::GetSRC(const u32 n)
case RSX_VP_REGISTER_TYPE_CONSTANT: case RSX_VP_REGISTER_TYPE_CONSTANT:
m_parr.AddParam(PF_PARAM_UNIFORM, getFloatTypeName(4), std::string("vc[468]")); m_parr.AddParam(PF_PARAM_UNIFORM, getFloatTypeName(4), std::string("vc[468]"));
properties.has_indexed_constants |= !!d3.index_const; properties.has_indexed_constants |= !!d3.index_const;
m_constant_ids.push_back(d1.const_src); m_constant_ids.insert(static_cast<u16>(d1.const_src));
ret += std::string("vc[") + std::to_string(d1.const_src) + (d3.index_const ? " + " + AddAddrReg() : "") + "]"; ret += std::string("vc[") + std::to_string(d1.const_src) + (d3.index_const ? " + " + AddAddrReg() : "") + "]";
break; break;
@ -399,20 +399,20 @@ std::string VertexProgramDecompiler::BuildCode()
std::vector<std::pair<std::string, std::string>> reloc_table; std::vector<std::pair<std::string, std::string>> reloc_table;
reloc_table.reserve(m_constant_ids.size()); reloc_table.reserve(m_constant_ids.size());
// First sort the data in ascending order
std::sort(m_constant_ids.begin(), m_constant_ids.end());
// Build the string lookup table // Build the string lookup table
int offset = 0;
for (const auto& index : m_constant_ids) for (const auto& index : m_constant_ids)
{ {
reloc_table.emplace_back(fmt::format("vc[%d]", index), fmt::format("vc[%llu]", reloc_table.size())); const auto i = offset++;
if (i == index) continue; // Replace with self
reloc_table.emplace_back(fmt::format("vc[%d]", index), fmt::format("vc[%d]", i));
} }
// One-time patch // One-time patch
main_body = fmt::replace_all(main_body, reloc_table); main_body = fmt::replace_all(main_body, reloc_table);
// Rename the array type // Rename the array type
auto type_list = ensure(m_parr.SearchParam(PF_PARAM_CONST, getFloatTypeName(4))); auto type_list = ensure(m_parr.SearchParam(PF_PARAM_UNIFORM, getFloatTypeName(4)));
const auto item = ParamItem(fmt::format("vc[%llu]", m_constant_ids.size()), -1); const auto item = ParamItem(fmt::format("vc[%llu]", m_constant_ids.size()), -1);
type_list->ReplaceOrInsert("vc[468]", item); type_list->ReplaceOrInsert("vc[468]", item);
} }

View File

@ -63,7 +63,7 @@ struct VertexProgramDecompiler
const RSXVertexProgram& m_prog; const RSXVertexProgram& m_prog;
ParamArray m_parr; ParamArray m_parr;
std::vector<u16> m_constant_ids; std::set<u16> m_constant_ids;
static std::string NotZeroPositive(const std::string& code); static std::string NotZeroPositive(const std::string& code);
std::string GetMask(bool is_sca) const; std::string GetMask(bool is_sca) const;

View File

@ -863,10 +863,6 @@ namespace rsx
void thread::fill_vertex_program_constants_data(void* buffer, const std::vector<u16>& reloc_table) void thread::fill_vertex_program_constants_data(void* buffer, const std::vector<u16>& reloc_table)
{ {
if (!reloc_table.empty()) [[ likely ]] if (!reloc_table.empty()) [[ likely ]]
{
memcpy(buffer, rsx::method_registers.transform_constants.data(), 468 * 4 * sizeof(float));
}
else
{ {
char* dst = reinterpret_cast<char*>(buffer); char* dst = reinterpret_cast<char*>(buffer);
for (const auto& index : reloc_table) for (const auto& index : reloc_table)
@ -875,6 +871,10 @@ namespace rsx
dst += 16; dst += 16;
} }
} }
else
{
memcpy(buffer, rsx::method_registers.transform_constants.data(), 468 * 4 * sizeof(float));
}
} }
void thread::fill_fragment_state_buffer(void* buffer, const RSXFragmentProgram& /*fragment_program*/) void thread::fill_fragment_state_buffer(void* buffer, const RSXFragmentProgram& /*fragment_program*/)

View File

@ -1955,12 +1955,15 @@ void VKGSRender::load_program_env()
check_heap_status(VK_HEAP_CHECK_TRANSFORM_CONSTANTS_STORAGE); check_heap_status(VK_HEAP_CHECK_TRANSFORM_CONSTANTS_STORAGE);
// Transform constants // Transform constants
auto mem = m_transform_constants_ring_info.alloc<256>(8192); const std::vector<u16>& constant_ids = m_vertex_prog ? m_vertex_prog->constant_ids : std::vector<u16>{};
auto buf = m_transform_constants_ring_info.map(mem, 8192); const usz transform_constants_size = constant_ids.empty() ? 8192 : utils::align(constant_ids.size() * 16, m_device->gpu().get_limits().minUniformBufferOffsetAlignment);
fill_vertex_program_constants_data(buf, m_vertex_prog ? m_vertex_prog->constant_ids : std::vector<u16>{}); auto mem = m_transform_constants_ring_info.alloc<1>(transform_constants_size);
auto buf = m_transform_constants_ring_info.map(mem, transform_constants_size);
fill_vertex_program_constants_data(buf, constant_ids);
m_transform_constants_ring_info.unmap(); m_transform_constants_ring_info.unmap();
m_vertex_constants_buffer_info = { m_transform_constants_ring_info.heap->value, mem, 8192 }; m_vertex_constants_buffer_info = { m_transform_constants_ring_info.heap->value, mem, transform_constants_size };
} }
if (update_fragment_constants && !update_instruction_buffers) if (update_fragment_constants && !update_instruction_buffers)

View File

@ -101,27 +101,28 @@ void VKVertexDecompilerThread::insertInputs(std::stringstream& OS, const std::ve
void VKVertexDecompilerThread::insertConstants(std::stringstream & OS, const std::vector<ParamType> & constants) void VKVertexDecompilerThread::insertConstants(std::stringstream & OS, const std::vector<ParamType> & constants)
{ {
OS << "layout(std140, set=0, binding = 1) uniform VertexConstantsBuffer\n";
OS << "{\n";
OS << " vec4 vc[468];\n";
OS << "};\n\n";
vk::glsl::program_input in; vk::glsl::program_input in;
in.location = m_binding_table.vertex_constant_buffers_bind_slot;
in.domain = glsl::glsl_vertex_program;
in.name = "VertexConstantsBuffer";
in.type = vk::glsl::input_type_uniform_buffer;
inputs.push_back(in);
u32 location = m_binding_table.vertex_textures_first_bind_slot; u32 location = m_binding_table.vertex_textures_first_bind_slot;
for (const ParamType &PT : constants) for (const ParamType &PT : constants)
{ {
for (const ParamItem &PI : PT.items) for (const ParamItem &PI : PT.items)
{ {
if (PI.name == "vc[468]") if (PI.name.starts_with("vc["))
{
OS << "layout(std140, set=0, binding = " << static_cast<int>(m_binding_table.vertex_constant_buffers_bind_slot) << ") uniform VertexConstantsBuffer\n";
OS << "{\n";
OS << " vec4 " << PI.name << ";\n";
OS << "};\n\n";
in.location = m_binding_table.vertex_constant_buffers_bind_slot;
in.domain = glsl::glsl_vertex_program;
in.name = "VertexConstantsBuffer";
in.type = vk::glsl::input_type_uniform_buffer;
inputs.push_back(in);
continue; continue;
}
if (PT.type == "sampler2D" || if (PT.type == "sampler2D" ||
PT.type == "samplerCube" || PT.type == "samplerCube" ||
@ -349,9 +350,13 @@ void VKVertexProgram::Decompile(const RSXVertexProgram& prog)
VKVertexDecompilerThread decompiler(prog, source, parr, *this); VKVertexDecompilerThread decompiler(prog, source, parr, *this);
decompiler.Task(); decompiler.Task();
if (has_indexed_constants = decompiler.properties.has_indexed_constants;
!has_indexed_constants)
{
constant_ids = std::vector<u16>(decompiler.m_constant_ids.begin(), decompiler.m_constant_ids.end());
}
shader.create(::glsl::program_domain::glsl_vertex_program, source); shader.create(::glsl::program_domain::glsl_vertex_program, source);
has_indexed_constants = decompiler.properties.has_indexed_constants;
constant_ids = std::move(decompiler.m_constant_ids);
} }
void VKVertexProgram::Compile() void VKVertexProgram::Compile()