mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 21:32:50 +00:00
rsx: Fix program generation and compact referenced data blocks
This commit is contained in:
parent
9a2d4fe46b
commit
d057ffe80f
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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*/)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user