mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
Merge pull request #1501 from kd-11/gl_inline_array_fix
Properly handle inlined vertex data
This commit is contained in:
commit
71a975c685
@ -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
|
// We can't rely on vertex_attribute_infos strides here so compute it
|
||||||
// assuming all attributes are packed
|
// assuming all attributes are packed
|
||||||
u32 stride = 0;
|
u32 stride = 0;
|
||||||
|
u32 initial_offsets[rsx::limits::vertex_count];
|
||||||
|
u8 index = 0;
|
||||||
for (const auto &info : vertex_attribute_infos)
|
for (const auto &info : vertex_attribute_infos)
|
||||||
{
|
{
|
||||||
|
initial_offsets[index++] = stride;
|
||||||
|
|
||||||
if (!info.size) // disabled
|
if (!info.size) // disabled
|
||||||
continue;
|
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;
|
std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> result;
|
||||||
|
|
||||||
UINT64 vertex_buffer_offset = 0;
|
UINT64 vertex_buffer_offset = 0;
|
||||||
|
index = 0;
|
||||||
for (const auto &info : vertex_attribute_infos)
|
for (const auto &info : vertex_attribute_infos)
|
||||||
{
|
{
|
||||||
if (!info.size) // disabled
|
if (!info.size)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||||
UINT buffer_size = element_size * element_count;
|
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++)
|
for (u32 i = 0; i < element_count; i++)
|
||||||
{
|
{
|
||||||
auto subdst = dst.subspan(i * element_size, element_size);
|
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)
|
if (info.type == rsx::vertex_base_type::ub && info.size == 4)
|
||||||
{
|
{
|
||||||
subdst[0] = subsrc[3];
|
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));
|
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
|
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);
|
return std::make_tuple(result, element_count);
|
||||||
|
@ -451,9 +451,20 @@ void GLGSRender::end()
|
|||||||
|
|
||||||
if (draw_command == rsx::draw_command::inlined_array)
|
if (draw_command == rsx::draw_command::inlined_array)
|
||||||
{
|
{
|
||||||
vertex_arrays_data.resize(inline_vertex_array.size() * sizeof(u32));
|
u32 stride = 0;
|
||||||
write_inline_array_to_buffer(vertex_arrays_data.data());
|
u32 offsets[rsx::limits::vertex_count] = { 0 };
|
||||||
u32 offset = 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)
|
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||||
{
|
{
|
||||||
auto &vertex_info = vertex_arrays_info[index];
|
auto &vertex_info = vertex_arrays_info[index];
|
||||||
@ -466,22 +477,66 @@ void GLGSRender::end()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
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);
|
u32 data_size = element_size * vertex_draw_count;
|
||||||
const 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 &buffer = m_gl_attrib_buffers[index].buffer;
|
||||||
auto &texture = m_gl_attrib_buffers[index].texture;
|
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->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
|
//Attach buffer to texture
|
||||||
texture->copy_from(*buffer, gl_type);
|
texture->copy_from(*buffer, gl_type);
|
||||||
|
|
||||||
//Link texture to uniform
|
//Link texture to uniform
|
||||||
m_program->uniforms.texture(location, index +rsx::limits::vertex_count, *texture);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,14 +589,40 @@ void GLGSRender::end()
|
|||||||
vertex_arrays_offsets[index] = gsl::narrow<u32>(position);
|
vertex_arrays_offsets[index] = gsl::narrow<u32>(position);
|
||||||
vertex_arrays_data.resize(position + size);
|
vertex_arrays_data.resize(position + size);
|
||||||
|
|
||||||
const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
|
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;
|
||||||
|
|
||||||
auto &buffer = m_gl_attrib_buffers[index].buffer;
|
auto &buffer = m_gl_attrib_buffers[index].buffer;
|
||||||
auto &texture = m_gl_attrib_buffers[index].texture;
|
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->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
|
//Attach buffer to texture
|
||||||
texture->copy_from(*buffer, gl_type);
|
texture->copy_from(*buffer, gl_type);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user