mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-26 04:32:35 +01:00
Properly handle inlined vertex data
Fix initial array offsets for dx12
This commit is contained in:
parent
3b7d0bc3fc
commit
3813c09be6
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user