OpenGL renderer: improved vertex attributes setup

Minor fixes
This commit is contained in:
DH 2016-06-22 22:44:38 +03:00
parent d22ac91ee1
commit f30d71da6c
6 changed files with 131 additions and 51 deletions

View File

@ -310,16 +310,20 @@ void GLGSRender::end()
int texture_index = 0;
for (int i = 0; i < rsx::limits::textures_count; ++i)
{
if (!textures[i].enabled())
{
continue;
}
int location;
if (m_program->uniforms.has_location("texture" + std::to_string(i), &location))
{
__glcheck glProgramUniform1i(m_program->id(), location, texture_index);
__glcheck m_gl_textures[i].init(texture_index, textures[i]);
if (!textures[i].enabled())
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, 0);
glProgramUniform1i(m_program->id(), location, i);
continue;
}
__glcheck glProgramUniform1i(m_program->id(), location, i);
__glcheck m_gl_textures[i].init(i, textures[i]);
texture_index++;
@ -327,7 +331,11 @@ void GLGSRender::end()
{
if (textures[i].format() & CELL_GCM_TEXTURE_UN)
{
//glProgramUniform4f(m_program->id(), location, textures[i].width(), textures[i].height(), textures[i].depth(), 1.0f);
u32 width = std::max<u32>(textures[i].width(), 1);
u32 height = std::max<u32>(textures[i].height(), 1);
u32 depth = std::max<u32>(textures[i].depth(), 1);
glProgramUniform4f(m_program->id(), location, 1.f / width, 1.f / height, 1.f / depth, 1.0f);
}
}
}
@ -349,8 +357,6 @@ void GLGSRender::end()
*/
}
__glcheck 0;
u32 offset_in_index_buffer = set_vertex_buffer();
m_vao.bind();
@ -430,8 +436,6 @@ void GLGSRender::set_viewport()
}
glEnable(GL_SCISSOR_TEST);
__glcheck 0;
}
void GLGSRender::on_init_thread()
@ -685,8 +689,6 @@ bool GLGSRender::load_program()
auto mapping = m_uniform_ring_buffer.alloc_from_reserve(fragment_constants_size, m_uniform_buffer_offset_align);
fragment_constants_offset = mapping.second;
u32 buffer_offset = 0;
static const __m128i mask = _mm_set_epi8(
0xE, 0xF, 0xC, 0xD,
0xA, 0xB, 0x8, 0x9,
@ -695,20 +697,23 @@ bool GLGSRender::load_program()
auto ucode = (const rsx::fragment_program::ucode_instr *)info.fragment_shader.decompiled->raw->ucode_ptr;
auto dst = (const rsx::fragment_program::ucode_instr *)mapping.first;
for (const auto& constant : info.fragment_shader.decompiled->constants)
{
const void *data = ucode + u32(constant.id / sizeof(rsx::fragment_program::ucode_instr));
const __m128i &vector = _mm_loadu_si128((const __m128i*)data);
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
_mm_stream_si128((__m128i*)((char*)mapping.first + buffer_offset), shuffled_vector);
const void *src = ucode + u32(constant.id / sizeof(*ucode));
//float x = ((float*)((char*)mapping.first + buffer_offset))[0];
//float y = ((float*)((char*)mapping.first + buffer_offset))[1];
//float z = ((float*)((char*)mapping.first + buffer_offset))[2];
//float w = ((float*)((char*)mapping.first + buffer_offset))[3];
const __m128i &vector = _mm_loadu_si128((const __m128i*)src);
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
_mm_stream_si128((__m128i*)dst, shuffled_vector);
float x = ((float*)dst)[0];
float y = ((float*)dst)[1];
float z = ((float*)dst)[2];
float w = ((float*)dst)[3];
//LOG_WARNING(RSX, "fc%u = {%g, %g, %g, %g}", constant.id, x, y, z, w);
buffer_offset += 4 * sizeof(f32);
++dst;
}
}

View File

@ -259,17 +259,65 @@ rsx::complete_shader glsl_complete_shader(const rsx::decompiled_shader &shader,
" gl_Position.w = o0.w;\n";
}
for (std::size_t index = 0; index < 16; ++index)
{
if (shader.input_attributes & (1 << index))
{
// result.code += "in vec4 " + rsx::vertex_program::input_attrib_names[index] + ";\n";
std::string code_end;
// TODO: use actual information about vertex inputs
result.code += "layout(location=" + std::to_string(location++) + ") uniform samplerBuffer " + rsx::vertex_program::input_attrib_names[index] + "_buffer" + ";\n";
result.code += "vec4 " + rsx::vertex_program::input_attrib_names[index]
+ " = texelFetch(" + rsx::vertex_program::input_attrib_names[index] + "_buffer, gl_VertexID).rgba;\n";
for (std::size_t index = 0; index < 16; ++index)
{
if (shader.input_attributes & (1 << index))
{
// result.code += "in vec4 " + rsx::vertex_program::input_attrib_names[index] + ";\n";
// TODO: use actual information about vertex inputs
const std::string &attrib_name = rsx::vertex_program::input_attrib_names[index];
result.code += "uniform ";
if (state.is_int & (1 << index))
{
result.code += "isamplerBuffer ";
code_end += "ivec4 ";
}
else
{
result.code += "samplerBuffer ";
code_end += "vec4 ";
}
result.code += attrib_name + "_buffer" + ";\n";
code_end += attrib_name + ";\n";
std::string vertex_id;
if (state.is_array & (1 << index))
{
vertex_id = "gl_VertexID";
if (state.frequency[index] > 1)
{
if (state.divider_op & (1 << index))
{
vertex_id += " % ";
}
else
{
vertex_id += " / ";
}
vertex_id += std::to_string(state.frequency[index]);
}
}
else
{
vertex_id = "0";
}
prepare += '\t' + attrib_name + " = texelFetch(" + attrib_name + "_buffer, " + vertex_id + ");\n";
}
}
result.code += code_end;
}
{

View File

@ -160,17 +160,9 @@ u32 GLGSRender::set_vertex_buffer()
//initialize vertex attributes
//merge all vertex arrays
std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now();
static const u32 texture_index_offset = rsx::limits::textures_count + rsx::limits::vertex_textures_count;
const std::string reg_table[] =
{
"in_pos", "in_weight", "in_normal",
"in_diff_color", "in_spec_color",
"in_fog",
"in_point_size", "in_7",
"in_tc0", "in_tc1", "in_tc2", "in_tc3",
"in_tc4", "in_tc5", "in_tc6", "in_tc7"
};
std::chrono::time_point<std::chrono::system_clock> then = std::chrono::system_clock::now();
u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
u32 min_index = 0, max_index = 0;
@ -185,7 +177,9 @@ u32 GLGSRender::set_vertex_buffer()
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
{
if (vertex_arrays_info[index].size == 0)
{
continue;
}
max_vertex_attrib_size += 16;
}
@ -240,9 +234,9 @@ u32 GLGSRender::set_vertex_buffer()
if (!vertex_info.size) // disabled, bind a null sampler
{
glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count);
glActiveTexture(GL_TEXTURE0 + index + texture_index_offset);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count);
glProgramUniform1i(m_program->id(), location, index + texture_index_offset);
continue;
}
@ -279,7 +273,7 @@ u32 GLGSRender::set_vertex_buffer()
texture.copy_from(m_attrib_ring_buffer, gl_type, mapping.second, data_size);
//Link texture to uniform
m_program->uniforms.texture(location, index + rsx::limits::textures_count, texture);
m_program->uniforms.texture(location, index + texture_index_offset, texture);
if (!is_primitive_native(draw_mode))
{
std::tie(vertex_draw_count, offset_in_index_buffer) = get_index_array_for_emulated_non_indexed_draw({ { 0, vertex_draw_count } }, draw_mode, m_index_ring_buffer);
@ -309,9 +303,9 @@ u32 GLGSRender::set_vertex_buffer()
bool enabled = !!(input_mask & (1 << index));
if (!enabled)
{
glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count);
glActiveTexture(GL_TEXTURE0 + index + texture_index_offset);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count);
glProgramUniform1i(m_program->id(), location, index + texture_index_offset);
continue;
}
@ -367,7 +361,7 @@ u32 GLGSRender::set_vertex_buffer()
texture.copy_from(m_attrib_ring_buffer, gl_type, buffer_offset, data_size);
//Link texture to uniform
m_program->uniforms.texture(location, index + rsx::limits::textures_count, texture);
m_program->uniforms.texture(location, index + texture_index_offset, texture);
}
else if (register_vertex_info[index].size > 0)
{
@ -392,7 +386,7 @@ u32 GLGSRender::set_vertex_buffer()
texture.copy_from(m_attrib_ring_buffer, gl_type, mapping.second, data_size);
//Link texture to uniform
m_program->uniforms.texture(location, index + rsx::limits::textures_count, texture);
m_program->uniforms.texture(location, index + texture_index_offset, texture);
break;
}
default:
@ -402,9 +396,9 @@ u32 GLGSRender::set_vertex_buffer()
}
else
{
glActiveTexture(GL_TEXTURE0 + index + rsx::limits::textures_count);
glActiveTexture(GL_TEXTURE0 + index + texture_index_offset);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glProgramUniform1i(m_program->id(), location, index + rsx::limits::textures_count);
glProgramUniform1i(m_program->id(), location, index + texture_index_offset);
continue;
}
}

View File

@ -72,6 +72,8 @@ namespace rsx
case rsx::texture_dimension::dimension1d: return rsx::texture_dimension_extended::texture_dimension_1d;
case rsx::texture_dimension::dimension3d: return rsx::texture_dimension_extended::texture_dimension_2d;
case rsx::texture_dimension::dimension2d: return cubemap() ? rsx::texture_dimension_extended::texture_dimension_cubemap : rsx::texture_dimension_extended::texture_dimension_2d;
default: ASSUME(0);
}
}

View File

@ -751,8 +751,39 @@ namespace rsx
u32 fp_info = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
result.state.input_attributes = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
result.state.output_attributes = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK];
result.state.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
result.state.divider_op = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION];
result.state.is_array = 0;
result.state.is_int = 0;
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
{
bool is_int = false;
if (vertex_arrays_info[index].size > 0)
{
result.state.is_array |= 1 << index;
is_int = is_int_type(vertex_arrays_info[index].type);
result.state.frequency[index] = vertex_arrays_info[index].frequency;
}
else if (register_vertex_info[index].size > 0)
{
is_int = is_int_type(register_vertex_info[index].type);
result.state.frequency[index] = register_vertex_info[index].frequency;
}
else
{
result.state.frequency[index] = 0;
}
if (is_int)
{
result.state.is_int |= 1 << index;
}
}
result.vertex_shader.ucode_ptr = transform_program;
result.vertex_shader.offset = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];

@ -1 +1 @@
Subproject commit e4d938c76850549acd837326e2fe0890d5b4be03
Subproject commit e1bd56e959e4eaae181c7c19b94fe2fb1ec00c08