From 70d3a6d8404decaf619ebf0fde451d735c6e61be Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 26 Mar 2017 12:01:50 +0300 Subject: [PATCH] rsx: Support more base types for immediate rendering fix alignment --- rpcs3/Emu/RSX/RSXThread.cpp | 4 +-- rpcs3/Emu/RSX/RSXThread.h | 2 +- rpcs3/Emu/RSX/rsx_methods.cpp | 17 ++++++++++-- rpcs3/Emu/RSX/rsx_vertex_data.h | 46 ++++++++++++++++++++++++++++++--- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 891d528a05..1fcdc4061a 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -332,10 +332,10 @@ namespace rsx in_begin_end = true; } - void thread::append_to_push_buffer(u32 attribute, u32 size, u32 subreg_index, u32 value) + void thread::append_to_push_buffer(u32 attribute, u32 size, u32 subreg_index, vertex_base_type type, u32 value) { vertex_push_buffers[attribute].size = size; - vertex_push_buffers[attribute].append_vertex_data(subreg_index, value); + vertex_push_buffers[attribute].append_vertex_data(subreg_index, type, value); } u32 thread::get_push_buffer_vertex_count() diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 8490580c17..8483270017 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -277,7 +277,7 @@ namespace rsx * Immediate mode rendering requires a temp push buffer to hold attrib values * Appends a value to the push buffer (currently only supports 32-wide types) */ - void append_to_push_buffer(u32 attribute, u32 size, u32 subreg_index, u32 value); + void append_to_push_buffer(u32 attribute, u32 size, u32 subreg_index, vertex_base_type type, u32 value); u32 get_push_buffer_vertex_count(); private: diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 9db3807bac..ba212074e8 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -116,12 +116,14 @@ namespace rsx static const size_t attribute_index = index / increment_per_array_index; static const size_t vertex_subreg = index % increment_per_array_index; + const auto vtype = vertex_data_type_from_element_type::type; + if (rsx->in_begin_end) - rsx->append_to_push_buffer(attribute_index, count, vertex_subreg, arg); + rsx->append_to_push_buffer(attribute_index, count, vertex_subreg, vtype, arg); auto& info = rsx::method_registers.register_vertex_info[attribute_index]; - info.type = vertex_data_type_from_element_type::type; + info.type = vtype; info.size = count; info.frequency = 0; info.stride = 0; @@ -191,6 +193,16 @@ namespace rsx } }; + template + struct set_vertex_data_scaled4s_m + { + static void impl(thread* rsx, u32 _reg, u32 arg) + { + LOG_ERROR(RSX, "SCALED_4S vertex data format is not properly implemented"); + set_vertex_data_impl(rsx, arg); + } + }; + void draw_arrays(thread* rsx, u32 _reg, u32 arg) { rsx::method_registers.current_draw_clause.command = rsx::draw_command::array; @@ -1278,6 +1290,7 @@ namespace rsx bind(); bind(); bind(); + bind_range(); bind_range(); bind_range(); bind_range(); diff --git a/rpcs3/Emu/RSX/rsx_vertex_data.h b/rpcs3/Emu/RSX/rsx_vertex_data.h index c1e703873e..98db60f044 100644 --- a/rpcs3/Emu/RSX/rsx_vertex_data.h +++ b/rpcs3/Emu/RSX/rsx_vertex_data.h @@ -74,20 +74,58 @@ struct push_buffer_vertex_info vertex_count = 0; } - void append_vertex_data(u32 sub_index, u32 arg) + u8 get_vertex_size_in_dwords(vertex_base_type type) + { + //NOTE: Types are always provided to fit into 32-bits + //i.e no less than 4 8-bit values and no less than 2 16-bit values + + switch (type) + { + case vertex_base_type::f: + return size; + case vertex_base_type::ub: + case vertex_base_type::ub256: + return 1; + case vertex_base_type::s32k: + return size / 2; + default: + fmt::throw_exception("Unsupported vertex base type %d", (u8)type); + } + } + + void append_vertex_data(u32 sub_index, vertex_base_type type, u32 arg) { const u32 element_mask = (1 << sub_index); + const u8 vertex_size = get_vertex_size_in_dwords(type); + if (attribute_mask & element_mask) { attribute_mask = 0; vertex_count++; - data.resize(vertex_count * size); + data.resize(vertex_count * vertex_size); } attribute_mask |= element_mask; - u32* dst = data.data() + ((vertex_count - 1) * size) + sub_index; - *dst = se_storage::swap(arg); + + void* dst = data.data() + ((vertex_count - 1) * vertex_size) + sub_index; + + switch (type) + { + case vertex_base_type::f: + *(u32*)dst = se_storage::swap(arg); + break; + case vertex_base_type::ub: + case vertex_base_type::ub256: + *(u32*)dst = arg; + break; + case vertex_base_type::s32k: + ((u16*)dst)[0] = se_storage::swap((u16)(arg & 0xffff)); + ((u16*)dst)[1] = se_storage::swap((u16)(arg >> 16)); + break; + default: + fmt::throw_exception("Unsupported vertex base type %d", (u8)type); + } } };