diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index 655f589749..b76c767453 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -49,12 +49,11 @@ namespace D3D12_SHADER_RESOURCE_VIEW_DESC get_vertex_attribute_srv(const rsx::data_array_format_info &info, UINT64 offset_in_vertex_buffers_buffer, UINT buffer_size) { - 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()); D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = { - get_vertex_attribute_format(info.type, info.size), - D3D12_SRV_DIMENSION_BUFFER, - get_component_mapping_from_vector_size(info.size) - }; + get_vertex_attribute_format(info.type(), info.size()), + D3D12_SRV_DIMENSION_BUFFER, + get_component_mapping_from_vector_size(info.size())}; vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size; vertex_buffer_view.Buffer.NumElements = buffer_size / element_size; return vertex_buffer_view; @@ -186,10 +185,10 @@ std::tuple, size_t> upload_inlined_ { initial_offsets[index++] = stride; - if (!info.size) // disabled + if (!info.size()) // disabled continue; - stride += rsx::get_vertex_type_size_on_host(info.type, info.size); + stride += rsx::get_vertex_type_size_on_host(info.type(), info.size()); } u32 element_count = ::narrow(inlined_array_raw_data.size_bytes()) / stride; @@ -199,13 +198,13 @@ std::tuple, size_t> upload_inlined_ index = 0; for (const auto &info : vertex_attribute_infos) { - if (!info.size) + if (!info.size()) { index++; 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; size_t heap_offset = ring_buffer_data.alloc(buffer_size); @@ -216,7 +215,7 @@ std::tuple, size_t> upload_inlined_ { auto subdst = dst.subspan(i * element_size, 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[1] = subsrc[2]; diff --git a/rpcs3/Emu/RSX/GL/vertex_buffer.cpp b/rpcs3/Emu/RSX/GL/vertex_buffer.cpp index fe04557745..624d93d5b7 100644 --- a/rpcs3/Emu/RSX/GL/vertex_buffer.cpp +++ b/rpcs3/Emu/RSX/GL/vertex_buffer.cpp @@ -214,7 +214,7 @@ std::tuple > > GLGSRender::set_vertex for (u8 index = 0; index < rsx::limits::vertex_count; ++index) { - if (rsx::method_registers.vertex_arrays_info[index].size || rsx::method_registers.register_vertex_info[index].size) + if (rsx::method_registers.vertex_arrays_info[index].size() || rsx::method_registers.register_vertex_info[index].size) { max_vertex_attrib_size += 16; } @@ -412,10 +412,10 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32 for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { const auto &info = rsx::method_registers.vertex_arrays_info[i]; - if (!info.size) continue; + if (!info.size()) continue; offsets[i] = stride; - stride += rsx::get_vertex_type_size_on_host(info.type, info.size); + stride += rsx::get_vertex_type_size_on_host(info.type(), info.size()); } u32 vertex_draw_count = (u32)(inline_vertex_array.size() * sizeof(u32)) / stride; @@ -429,7 +429,7 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32 if (!m_program->uniforms.has_location(s_reg_table[index], &location)) continue; - if (!vertex_info.size) // disabled, bind a null sampler + if (!vertex_info.size()) // disabled, bind a null sampler { glActiveTexture(GL_TEXTURE0 + index + texture_index_offset); glBindTexture(GL_TEXTURE_BUFFER, 0); @@ -437,9 +437,9 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32 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()); u32 data_size = element_size * vertex_draw_count; - 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()); auto &texture = m_gl_attrib_buffers[index]; @@ -448,12 +448,12 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32 u8 *dst = static_cast(mapping.first); src += offsets[index]; - prepare_buffer_for_writing(dst, vertex_info.type, vertex_info.size, vertex_draw_count); + prepare_buffer_for_writing(dst, vertex_info.type(), vertex_info.size(), vertex_draw_count); //TODO: properly handle compressed data for (u32 i = 0; i < vertex_draw_count; ++i) { - if (vertex_info.type == rsx::vertex_base_type::ub && vertex_info.size == 4) + if (vertex_info.type() == rsx::vertex_base_type::ub && vertex_info.size() == 4) { dst[0] = src[3]; dst[1] = src[2]; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index a99075f835..c3e1cc62d3 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -531,12 +531,12 @@ namespace rsx { const auto &info = rsx::method_registers.vertex_arrays_info[index]; - if (!info.size) // disabled + if (!info.size()) // disabled 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()); - if (info.type == vertex_base_type::ub && info.size == 4) + if (info.type() == vertex_base_type::ub && info.size() == 4) { dst[0] = src[3]; dst[1] = src[2]; @@ -587,7 +587,7 @@ namespace rsx u32 offset = vertex_array_info.offset(); u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31); - u32 element_size = rsx::get_vertex_type_size_on_host(vertex_array_info.type, vertex_array_info.size); + u32 element_size = rsx::get_vertex_type_size_on_host(vertex_array_info.type(), vertex_array_info.size()); // Disjoint first_counts ranges not supported atm for (int i = 0; i < vertex_ranges.size() - 1; i++) @@ -600,7 +600,7 @@ namespace rsx u32 count = std::get<0>(vertex_ranges.back()) + std::get<1>(vertex_ranges.back()) - first; const gsl::byte* ptr = gsl::narrow_cast(vm::base(address)); - return {ptr + first * vertex_array_info.stride, count * vertex_array_info.stride + element_size}; + return {ptr + first * vertex_array_info.stride(), count * vertex_array_info.stride() + element_size}; } std::vector> thread::get_vertex_buffers(const rsx::rsx_state& state, const std::vector>& vertex_ranges) const @@ -613,10 +613,10 @@ namespace rsx if (!enabled) continue; - if (state.vertex_arrays_info[index].size > 0) + if (state.vertex_arrays_info[index].size() > 0) { const rsx::data_array_format_info& info = state.vertex_arrays_info[index]; - result.push_back(vertex_array_buffer{info.type, info.size, info.stride, + result.push_back(vertex_array_buffer{info.type(), info.size(), info.stride(), get_raw_vertex_buffer(info, state.vertex_data_base_offset(), vertex_ranges), index}); continue; } @@ -760,31 +760,25 @@ namespace rsx if (!enabled) continue; - if (rsx::method_registers.vertex_arrays_info[index].size > 0) + if (rsx::method_registers.vertex_arrays_info[index].size() > 0) { result.rsx_vertex_inputs.push_back( - { - index, - rsx::method_registers.vertex_arrays_info[index].size, - rsx::method_registers.vertex_arrays_info[index].frequency, - !!((modulo_mask >> index) & 0x1), - true, - is_int_type(rsx::method_registers.vertex_arrays_info[index].type) - } - ); + {index, + rsx::method_registers.vertex_arrays_info[index].size(), + rsx::method_registers.vertex_arrays_info[index].frequency(), + !!((modulo_mask >> index) & 0x1), + true, + is_int_type(rsx::method_registers.vertex_arrays_info[index].type())}); } else if (rsx::method_registers.register_vertex_info[index].size > 0) { result.rsx_vertex_inputs.push_back( - { - index, - rsx::method_registers.register_vertex_info[index].size, - rsx::method_registers.register_vertex_info[index].frequency, - !!((modulo_mask >> index) & 0x1), - false, - is_int_type(rsx::method_registers.vertex_arrays_info[index].type) - } - ); + {index, + rsx::method_registers.register_vertex_info[index].size, + rsx::method_registers.register_vertex_info[index].frequency, + !!((modulo_mask >> index) & 0x1), + false, + is_int_type(rsx::method_registers.vertex_arrays_info[index].type())}); } } return result; @@ -843,10 +837,10 @@ namespace rsx { bool is_int = false; - if (rsx::method_registers.vertex_arrays_info[index].size > 0) + if (rsx::method_registers.vertex_arrays_info[index].size() > 0) { - is_int = is_int_type(rsx::method_registers.vertex_arrays_info[index].type); - result.state.frequency[index] = rsx::method_registers.vertex_arrays_info[index].frequency; + is_int = is_int_type(rsx::method_registers.vertex_arrays_info[index].type()); + result.state.frequency[index] = rsx::method_registers.vertex_arrays_info[index].frequency(); } else if (rsx::method_registers.register_vertex_info[index].size > 0) { diff --git a/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp b/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp index 567480f234..412176974e 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp @@ -388,10 +388,10 @@ u32 VKGSRender::upload_inlined_array() for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { const auto &info = rsx::method_registers.vertex_arrays_info[i]; - if (!info.size) continue; + if (!info.size()) continue; offsets[i] = stride; - stride += rsx::get_vertex_type_size_on_host(info.type, info.size); + stride += rsx::get_vertex_type_size_on_host(info.type(), info.size()); } u32 vertex_draw_count = (u32)(inline_vertex_array.size() * sizeof(u32)) / stride; @@ -403,48 +403,48 @@ u32 VKGSRender::upload_inlined_array() if (!m_program->has_uniform(s_reg_table[index])) continue; - if (!vertex_info.size) // disabled + if (!vertex_info.size()) // disabled { continue; } - const u32 element_size = vk::get_suitable_vk_size(vertex_info.type, vertex_info.size); + const u32 element_size = vk::get_suitable_vk_size(vertex_info.type(), vertex_info.size()); const u32 data_size = element_size * vertex_draw_count; - const VkFormat format = vk::get_suitable_vk_format(vertex_info.type, vertex_info.size); + const VkFormat format = vk::get_suitable_vk_format(vertex_info.type(), vertex_info.size()); u32 offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(data_size); u8 *src = reinterpret_cast(inline_vertex_array.data()); u8 *dst = static_cast(m_attrib_ring_info.map(offset_in_attrib_buffer, data_size)); src += offsets[index]; - u8 opt_size = vertex_info.size; + u8 opt_size = vertex_info.size(); - if (vertex_info.size == 3) + if (vertex_info.size() == 3) opt_size = 4; //TODO: properly handle cmp type - if (vertex_info.type == rsx::vertex_base_type::cmp) + if (vertex_info.type() == rsx::vertex_base_type::cmp) LOG_ERROR(RSX, "Compressed vertex attributes not supported for inlined arrays yet"); - switch (vertex_info.type) + switch (vertex_info.type()) { case rsx::vertex_base_type::f: - vk::copy_inlined_data_to_buffer(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); + vk::copy_inlined_data_to_buffer(src, dst, vertex_draw_count, vertex_info.type(), vertex_info.size(), opt_size, element_size, stride); break; case rsx::vertex_base_type::sf: - vk::copy_inlined_data_to_buffer(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); + vk::copy_inlined_data_to_buffer(src, dst, vertex_draw_count, vertex_info.type(), vertex_info.size(), opt_size, element_size, stride); break; case rsx::vertex_base_type::s1: case rsx::vertex_base_type::ub: case rsx::vertex_base_type::ub256: - vk::copy_inlined_data_to_buffer(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); + vk::copy_inlined_data_to_buffer(src, dst, vertex_draw_count, vertex_info.type(), vertex_info.size(), opt_size, element_size, stride); break; case rsx::vertex_base_type::s32k: case rsx::vertex_base_type::cmp: - vk::copy_inlined_data_to_buffer(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); + vk::copy_inlined_data_to_buffer(src, dst, vertex_draw_count, vertex_info.type(), vertex_info.size(), opt_size, element_size, stride); break; default: - fmt::throw_exception("Unknown base type %d" HERE, (u32)vertex_info.type); + fmt::throw_exception("Unknown base type %d" HERE, (u32)vertex_info.type()); } m_attrib_ring_info.unmap(); diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index ea9f01ff53..2675e26d29 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -185,19 +185,6 @@ namespace rsx } }; - template - struct set_vertex_data_array_format - { - static void impl(thread* rsx, u32 _reg, u32 arg) - { - const typename rsx::registers_decoder::decoded_type decoded_value(arg); - rsx::method_registers.vertex_arrays_info[index].frequency = decoded_value.frequency(); - rsx::method_registers.vertex_arrays_info[index].stride = decoded_value.stride(); - rsx::method_registers.vertex_arrays_info[index].size = decoded_value.size(); - rsx::method_registers.vertex_arrays_info[index].type = decoded_value.type(); - } - }; - void draw_arrays(thread* rsx, u32 _reg, u32 arg) { rsx::method_registers.current_draw_clause.command = rsx::draw_command::array; @@ -877,7 +864,6 @@ namespace rsx registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff; - for (auto& info : vertex_arrays_info) info.size = 0; for (auto& tex : fragment_textures) tex.init(); for (auto& tex : vertex_textures) tex.init(); } @@ -1275,7 +1261,6 @@ namespace rsx bind(); bind(); bind(); - bind_range(); bind_range(); bind_range(); bind_range(); diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index 7925aeb6e2..86b547dd28 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -137,13 +137,6 @@ namespace rsx transform_program = in.transform_program; transform_constants = in.transform_constants; register_vertex_info = in.register_vertex_info; - for (int i = 0; i < 16; i++) - { - vertex_arrays_info[i].size = in.vertex_arrays_info[i].size; - vertex_arrays_info[i].stride = in.vertex_arrays_info[i].stride; - vertex_arrays_info[i].frequency = in.vertex_arrays_info[i].frequency; - vertex_arrays_info[i].type = in.vertex_arrays_info[i].type; - } return *this; } diff --git a/rpcs3/Emu/RSX/rsx_vertex_data.h b/rpcs3/Emu/RSX/rsx_vertex_data.h index 82a64236b8..7f6a89345d 100644 --- a/rpcs3/Emu/RSX/rsx_vertex_data.h +++ b/rpcs3/Emu/RSX/rsx_vertex_data.h @@ -9,19 +9,46 @@ namespace rsx struct data_array_format_info { private: - u32& m_offset_register; -public: - u16 frequency = 0; - u8 stride = 0; - u8 size = 0; - vertex_base_type type = vertex_base_type::f; + u8 index; + std::array& registers; - data_array_format_info(int id, std::array ®isters) - : m_offset_register(registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + id]) {} + auto decode_reg() const + { + const typename rsx::registers_decoder::decoded_type + decoded_value(registers[NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + index]); + return decoded_value; + } + +public: + data_array_format_info(int id, std::array& r) + : registers(r) + , index(id) + { + } u32 offset() const { - return m_offset_register; + return registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index]; + } + + u8 stride() const + { + return decode_reg().stride(); + } + + u8 size() const + { + return decode_reg().size(); + } + + u16 frequency() const + { + return decode_reg().frequency(); + } + + vertex_base_type type() const + { + return decode_reg().type(); } };