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)
{
// 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);
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)

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)
{
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 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;
}
OS << "uniform " << PT.type << " " << PI.name << ";\n";
}
@ -272,10 +276,14 @@ void GLVertexProgram::Decompile(const RSXVertexProgram& prog)
GLVertexDecompilerThread decompiler(prog, source, parr);
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);
id = shader.id();
has_indexed_constants = decompiler.properties.has_indexed_constants;
constant_ids = std::move(decompiler.m_constant_ids);
}
void GLVertexProgram::Delete()

View File

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

View File

@ -127,7 +127,7 @@ std::string VertexProgramDecompiler::GetSRC(const u32 n)
case RSX_VP_REGISTER_TYPE_CONSTANT:
m_parr.AddParam(PF_PARAM_UNIFORM, getFloatTypeName(4), std::string("vc[468]"));
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() : "") + "]";
break;
@ -399,20 +399,20 @@ std::string VertexProgramDecompiler::BuildCode()
std::vector<std::pair<std::string, std::string>> reloc_table;
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
int offset = 0;
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
main_body = fmt::replace_all(main_body, reloc_table);
// 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);
type_list->ReplaceOrInsert("vc[468]", item);
}

View File

@ -63,7 +63,7 @@ struct VertexProgramDecompiler
const RSXVertexProgram& m_prog;
ParamArray m_parr;
std::vector<u16> m_constant_ids;
std::set<u16> m_constant_ids;
static std::string NotZeroPositive(const std::string& code);
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)
{
if (!reloc_table.empty()) [[ likely ]]
{
memcpy(buffer, rsx::method_registers.transform_constants.data(), 468 * 4 * sizeof(float));
}
else
{
char* dst = reinterpret_cast<char*>(buffer);
for (const auto& index : reloc_table)
@ -875,6 +871,10 @@ namespace rsx
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*/)

View File

@ -1955,12 +1955,15 @@ void VKGSRender::load_program_env()
check_heap_status(VK_HEAP_CHECK_TRANSFORM_CONSTANTS_STORAGE);
// Transform constants
auto mem = m_transform_constants_ring_info.alloc<256>(8192);
auto buf = m_transform_constants_ring_info.map(mem, 8192);
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 : 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_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)

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)
{
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;
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;
for (const ParamType &PT : constants)
{
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;
}
if (PT.type == "sampler2D" ||
PT.type == "samplerCube" ||
@ -349,9 +350,13 @@ void VKVertexProgram::Decompile(const RSXVertexProgram& prog)
VKVertexDecompilerThread decompiler(prog, source, parr, *this);
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);
has_indexed_constants = decompiler.properties.has_indexed_constants;
constant_ids = std::move(decompiler.m_constant_ids);
}
void VKVertexProgram::Compile()