1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

Merge pull request #1501 from kd-11/gl_inline_array_fix

Properly handle inlined vertex data
This commit is contained in:
vlj 2016-02-16 18:07:16 +01:00
commit 71a975c685
2 changed files with 104 additions and 14 deletions

View File

@ -147,8 +147,12 @@ std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_
// We can't rely on vertex_attribute_infos strides here so compute it
// assuming all attributes are packed
u32 stride = 0;
u32 initial_offsets[rsx::limits::vertex_count];
u8 index = 0;
for (const auto &info : vertex_attribute_infos)
{
initial_offsets[index++] = stride;
if (!info.size) // disabled
continue;
@ -159,10 +163,14 @@ std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_
std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> result;
UINT64 vertex_buffer_offset = 0;
index = 0;
for (const auto &info : vertex_attribute_infos)
{
if (!info.size) // disabled
if (!info.size)
{
index++;
continue;
}
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
UINT buffer_size = element_size * element_count;
@ -174,7 +182,7 @@ std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_
for (u32 i = 0; i < element_count; i++)
{
auto subdst = dst.subspan(i * element_size, element_size);
auto subsrc = inlined_array_raw_data.subspan(i * stride, element_size);
auto subsrc = inlined_array_raw_data.subspan(initial_offsets[index] + (i * stride), element_size);
if (info.type == rsx::vertex_base_type::ub && info.size == 4)
{
subdst[0] = subsrc[3];
@ -194,6 +202,7 @@ std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_
result.emplace_back(get_vertex_attribute_srv(info, vertex_buffer_offset, buffer_size));
vertex_buffer_offset = get_next_multiple_of<48>(vertex_buffer_offset + buffer_size); // 48 is multiple of 2, 4, 6, 8, 12, 16
index++;
}
return std::make_tuple(result, element_count);

View File

@ -451,9 +451,20 @@ void GLGSRender::end()
if (draw_command == rsx::draw_command::inlined_array)
{
vertex_arrays_data.resize(inline_vertex_array.size() * sizeof(u32));
write_inline_array_to_buffer(vertex_arrays_data.data());
u32 offset = 0;
u32 stride = 0;
u32 offsets[rsx::limits::vertex_count] = { 0 };
for (u32 i = 0; i < rsx::limits::vertex_count; ++i)
{
const auto &info = vertex_arrays_info[i];
if (!info.size) continue;
offsets[i] = stride;
stride += rsx::get_vertex_type_size_on_host(info.type, info.size);
}
vertex_draw_count = (u32)(inline_vertex_array.size() * sizeof(u32)) / stride;
for (int index = 0; index < rsx::limits::vertex_count; ++index)
{
auto &vertex_info = vertex_arrays_info[index];
@ -466,22 +477,66 @@ void GLGSRender::end()
continue;
const u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
const u32 data_size = element_size * vertex_draw_count;
u32 data_size = element_size * vertex_draw_count;
u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
auto &buffer = m_gl_attrib_buffers[index].buffer;
auto &texture = m_gl_attrib_buffers[index].texture;
vertex_arrays_data.resize(data_size);
u8 *src = reinterpret_cast<u8*>(inline_vertex_array.data());
u8 *dst = vertex_arrays_data.data();
src += offsets[index];
for (u32 i = 0; i < vertex_draw_count; ++i)
{
if (vertex_info.type == rsx::vertex_base_type::ub && vertex_info.size == 4)
{
dst[0] = src[3];
dst[1] = src[2];
dst[2] = src[1];
dst[3] = src[0];
}
else
memcpy(dst, src, element_size);
src += stride;
dst += element_size;
}
void *vertex_data = static_cast<void*>(vertex_arrays_data.data());
std::vector<float> conversion_buf;
//Normalize diffuse color and specular color from 0-255 to 0-1; texelFetch does not normalize texels
if (index == 3 || index == 4)
{
if (vertex_info.type == rsx::vertex_base_type::ub ||
vertex_info.type == rsx::vertex_base_type::s1)
{
const u32 num_values = vertex_draw_count * vertex_info.size;
conversion_buf.resize(num_values);
u8 *source_values = (u8*)vertex_data;
for (u32 i = 0; i < num_values; ++i)
{
conversion_buf[i] = (float)source_values[i] / 255.f;
}
gl_type = to_gl_internal_type(rsx::vertex_base_type::f, vertex_info.size);
vertex_data = conversion_buf.data();
data_size *= sizeof(float);
}
}
buffer->data(data_size, nullptr);
buffer->sub_data(0, data_size, vertex_arrays_data.data()+offset);
buffer->sub_data(0, data_size, vertex_data);
//Attach buffer to texture
texture->copy_from(*buffer, gl_type);
//Link texture to uniform
m_program->uniforms.texture(location, index +rsx::limits::vertex_count, *texture);
offset += rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
m_program->uniforms.texture(location, index + rsx::limits::vertex_count, *texture);
}
}
@ -534,14 +589,40 @@ void GLGSRender::end()
vertex_arrays_offsets[index] = gsl::narrow<u32>(position);
vertex_arrays_data.resize(position + size);
const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
const u32 data_size = element_size * vertex_draw_count;
u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
u32 data_size = element_size * vertex_draw_count;
auto &buffer = m_gl_attrib_buffers[index].buffer;
auto &texture = m_gl_attrib_buffers[index].texture;
std::chrono::time_point<std::chrono::system_clock> u0 = std::chrono::system_clock::now();
void *vertex_data = static_cast<void*>(vertex_array.data());
std::vector<float> conversion_buf;
//Normalize color inputs if given in ub format
if (index == 3 || index == 4)
{
if (vertex_info.type == rsx::vertex_base_type::ub ||
vertex_info.type == rsx::vertex_base_type::s1)
{
const u32 num_values = vertex_draw_count * vertex_info.size;
conversion_buf.resize(num_values);
u8 *source_values = (u8*)vertex_data;
for (u32 i = 0; i < num_values; ++i)
{
conversion_buf[i] = (float)source_values[i] / 255.f;
}
gl_type = to_gl_internal_type(rsx::vertex_base_type::f, vertex_info.size);
vertex_data = conversion_buf.data();
data_size *= sizeof(float);
}
}
buffer->data(data_size, nullptr);
buffer->sub_data(0, data_size, vertex_array.data());
buffer->sub_data(0, data_size, vertex_data);
//Attach buffer to texture
texture->copy_from(*buffer, gl_type);