mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 15:01:28 +12:00
dx12/vk/gl: implement use of vertex_data_base_index when calculating index
This commit is contained in:
parent
3e863f2189
commit
6d6d6fa827
7 changed files with 37 additions and 26 deletions
|
@ -525,7 +525,7 @@ void write_vertex_array_data_to_buffer(gsl::span<gsl::byte> raw_dst_span, gsl::s
|
|||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
std::tuple<T, T, u32> upload_untouched(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index)
|
||||
std::tuple<T, T, u32> upload_untouched(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index, u32 base_index)
|
||||
{
|
||||
T min_index = -1;
|
||||
T max_index = 0;
|
||||
|
@ -545,6 +545,7 @@ std::tuple<T, T, u32> upload_untouched(gsl::span<to_be_t<const T>> src, gsl::spa
|
|||
}
|
||||
else
|
||||
{
|
||||
index = rsx::get_index_from_base(index, base_index);
|
||||
max_index = std::max(max_index, index);
|
||||
min_index = std::min(min_index, index);
|
||||
}
|
||||
|
@ -555,7 +556,7 @@ std::tuple<T, T, u32> upload_untouched(gsl::span<to_be_t<const T>> src, gsl::spa
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
std::tuple<T, T, u32> expand_indexed_triangle_fan(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index)
|
||||
std::tuple<T, T, u32> expand_indexed_triangle_fan(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index, u32 base_index)
|
||||
{
|
||||
const T invalid_index = (T)-1;
|
||||
|
||||
|
@ -573,12 +574,15 @@ std::tuple<T, T, u32> expand_indexed_triangle_fan(gsl::span<to_be_t<const T>> sr
|
|||
|
||||
for (size_t src_idx = 0; src_idx < src.size(); ++src_idx)
|
||||
{
|
||||
T index = src[src_idx];
|
||||
index = rsx::get_index_from_base(index, base_index);
|
||||
|
||||
if (needs_anchor)
|
||||
{
|
||||
if (is_primitive_restart_enabled && src[src_idx] == primitive_restart_index)
|
||||
continue;
|
||||
|
||||
anchor = src[src_idx];
|
||||
anchor = index;
|
||||
needs_anchor = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -590,7 +594,6 @@ std::tuple<T, T, u32> expand_indexed_triangle_fan(gsl::span<to_be_t<const T>> sr
|
|||
continue;
|
||||
}
|
||||
|
||||
T index = src[src_idx];
|
||||
max_index = std::max(max_index, index);
|
||||
min_index = std::min(min_index, index);
|
||||
|
||||
|
@ -612,7 +615,7 @@ std::tuple<T, T, u32> expand_indexed_triangle_fan(gsl::span<to_be_t<const T>> sr
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
std::tuple<T, T, u32> expand_indexed_quads(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index)
|
||||
std::tuple<T, T, u32> expand_indexed_quads(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index, u32 base_index)
|
||||
{
|
||||
T min_index = -1;
|
||||
T max_index = 0;
|
||||
|
@ -626,7 +629,8 @@ std::tuple<T, T, u32> expand_indexed_quads(gsl::span<to_be_t<const T>> src, gsl:
|
|||
for (int src_idx = 0; src_idx < src.size(); ++src_idx)
|
||||
{
|
||||
T index = src[src_idx];
|
||||
if (is_primitive_restart_enabled && index == primitive_restart_index)
|
||||
index = rsx::get_index_from_base(index, base_index);
|
||||
if (is_primitive_restart_enabled && src[src_idx] == primitive_restart_index)
|
||||
{
|
||||
//empty temp buffer
|
||||
set_size = 0;
|
||||
|
@ -780,27 +784,27 @@ namespace
|
|||
std::tuple<T, T, u32> write_index_array_data_to_buffer_impl(gsl::span<T> dst,
|
||||
gsl::span<const be_t<T>> src,
|
||||
rsx::primitive_type draw_mode, bool restart_index_enabled, u32 restart_index, const std::vector<std::pair<u32, u32> > &first_count_arguments,
|
||||
std::function<bool(rsx::primitive_type)> expands)
|
||||
u32 base_index, std::function<bool(rsx::primitive_type)> expands)
|
||||
{
|
||||
u32 first;
|
||||
u32 count;
|
||||
std::tie(first, count) = get_first_count_from_draw_indexed_clause(first_count_arguments);
|
||||
|
||||
if (!expands(draw_mode)) return upload_untouched<T>(src, dst, restart_index_enabled, restart_index);
|
||||
if (!expands(draw_mode)) return upload_untouched<T>(src, dst, restart_index_enabled, restart_index, base_index);
|
||||
|
||||
switch (draw_mode)
|
||||
{
|
||||
case rsx::primitive_type::line_loop:
|
||||
{
|
||||
const auto &returnvalue = upload_untouched<T>(src, dst, restart_index_enabled, restart_index);
|
||||
const auto &returnvalue = upload_untouched<T>(src, dst, restart_index_enabled, restart_index, base_index);
|
||||
dst[count] = src[0];
|
||||
return returnvalue;
|
||||
}
|
||||
case rsx::primitive_type::polygon:
|
||||
case rsx::primitive_type::triangle_fan:
|
||||
return expand_indexed_triangle_fan<T>(src, dst, restart_index_enabled, restart_index);
|
||||
return expand_indexed_triangle_fan<T>(src, dst, restart_index_enabled, restart_index, base_index);
|
||||
case rsx::primitive_type::quads:
|
||||
return expand_indexed_quads<T>(src, dst, restart_index_enabled, restart_index);
|
||||
return expand_indexed_quads<T>(src, dst, restart_index_enabled, restart_index, base_index);
|
||||
default:
|
||||
fmt::throw_exception("Unknown draw mode (0x%x)" HERE, (u32)draw_mode);
|
||||
}
|
||||
|
@ -810,16 +814,16 @@ namespace
|
|||
std::tuple<u32, u32, u32> write_index_array_data_to_buffer(gsl::span<gsl::byte> dst,
|
||||
gsl::span<const gsl::byte> src,
|
||||
rsx::index_array_type type, rsx::primitive_type draw_mode, bool restart_index_enabled, u32 restart_index, const std::vector<std::pair<u32, u32> > &first_count_arguments,
|
||||
std::function<bool(rsx::primitive_type)> expands)
|
||||
u32 base_index, std::function<bool(rsx::primitive_type)> expands)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case rsx::index_array_type::u16:
|
||||
return write_index_array_data_to_buffer_impl<u16>(as_span_workaround<u16>(dst),
|
||||
gsl::as_span<const be_t<u16>>(src), draw_mode, restart_index_enabled, restart_index, first_count_arguments, expands);
|
||||
gsl::as_span<const be_t<u16>>(src), draw_mode, restart_index_enabled, restart_index, first_count_arguments, base_index, expands);
|
||||
case rsx::index_array_type::u32:
|
||||
return write_index_array_data_to_buffer_impl<u32>(as_span_workaround<u32>(dst),
|
||||
gsl::as_span<const be_t<u32>>(src), draw_mode, restart_index_enabled, restart_index, first_count_arguments, expands);
|
||||
gsl::as_span<const be_t<u32>>(src), draw_mode, restart_index_enabled, restart_index, first_count_arguments, base_index, expands);
|
||||
}
|
||||
fmt::throw_exception("Unknown index type" HERE);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ u32 get_index_type_size(rsx::index_array_type type);
|
|||
*/
|
||||
std::tuple<u32, u32, u32> write_index_array_data_to_buffer(gsl::span<gsl::byte> dst, gsl::span<const gsl::byte> src,
|
||||
rsx::index_array_type, rsx::primitive_type draw_mode, bool restart_index_enabled, u32 restart_index, const std::vector<std::pair<u32, u32> > &first_count_arguments,
|
||||
std::function<bool(rsx::primitive_type)> expands);
|
||||
u32 base_index, std::function<bool(rsx::primitive_type)> expands);
|
||||
|
||||
/**
|
||||
* Write index data needed to emulate non indexed non native primitive mode.
|
||||
|
|
|
@ -269,7 +269,6 @@ namespace
|
|||
D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, D3D12_RESOURCE_STATE_COPY_DEST));
|
||||
|
||||
u32 vertex_count = get_vertex_count(vertex_ranges);
|
||||
verify(HERE), rsx::method_registers.vertex_data_base_index() == 0;
|
||||
|
||||
vertex_buffer_visitor visitor(
|
||||
vertex_count, command_list, m_vertex_buffer_data, m_buffer_data);
|
||||
|
@ -415,7 +414,7 @@ namespace
|
|||
rsx::method_registers.current_draw_clause.primitive,
|
||||
rsx::method_registers.restart_index_enabled(),
|
||||
rsx::method_registers.restart_index(), command.ranges_to_fetch_in_index_buffer,
|
||||
[](auto prim) { return !is_primitive_native(prim); });
|
||||
rsx::method_registers.vertex_data_base_index(), [](auto prim) { return !is_primitive_native(prim); });
|
||||
|
||||
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
D3D12_INDEX_BUFFER_VIEW index_buffer_view = {
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace
|
|||
gsl::span<gsl::byte> dst{ reinterpret_cast<gsl::byte*>(ptr), ::narrow<u32>(block_sz) };
|
||||
std::tie(min_index, max_index, vertex_draw_count) = write_index_array_data_to_buffer(dst, raw_index_buffer,
|
||||
type, draw_mode, rsx::method_registers.restart_index_enabled(), rsx::method_registers.restart_index(), first_count_commands,
|
||||
[](auto prim) { return !gl::is_primitive_native(prim); });
|
||||
rsx::method_registers.vertex_data_base_index(), [](auto prim) { return !gl::is_primitive_native(prim); });
|
||||
|
||||
return std::make_tuple(min_index, max_index, vertex_draw_count);
|
||||
}
|
||||
|
|
|
@ -89,13 +89,6 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
// The rsx internally adds the 'data_base_offset' and the 'vert_offset' and masks it
|
||||
// before actually attempting to translate to the internal address. Seen happening heavily in R&C games
|
||||
u32 get_vertex_offset_from_base(u32 vert_data_base_offset, u32 vert_base_offset)
|
||||
{
|
||||
return ((u64)vert_data_base_offset + vert_base_offset) & 0xFFFFFFF;
|
||||
}
|
||||
|
||||
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size)
|
||||
{
|
||||
switch (type)
|
||||
|
|
|
@ -171,7 +171,7 @@ namespace
|
|||
rsx::method_registers.current_draw_clause.primitive,
|
||||
rsx::method_registers.restart_index_enabled(),
|
||||
rsx::method_registers.restart_index(), command.ranges_to_fetch_in_index_buffer,
|
||||
[](auto prim) { return !vk::is_primitive_native(prim); });
|
||||
rsx::method_registers.vertex_data_base_index(), [](auto prim) { return !vk::is_primitive_native(prim); });
|
||||
|
||||
if (min_index >= max_index)
|
||||
{
|
||||
|
|
|
@ -344,4 +344,19 @@ namespace rsx
|
|||
if (last_start >= 0)
|
||||
out.push_back(std::make_pair(last_start, last_valid_index - last_start + 1));
|
||||
}
|
||||
|
||||
// The rsx internally adds the 'data_base_offset' and the 'vert_offset' and masks it
|
||||
// before actually attempting to translate to the internal address. Seen happening heavily in R&C games
|
||||
static inline u32 get_vertex_offset_from_base(u32 vert_data_base_offset, u32 vert_base_offset)
|
||||
{
|
||||
return ((u64)vert_data_base_offset + vert_base_offset) & 0xFFFFFFF;
|
||||
}
|
||||
|
||||
// Similar to vertex_offset_base calculation, the rsx internally adds and masks index
|
||||
// before using
|
||||
static inline u32 get_index_from_base(u32 index, u32 index_base)
|
||||
{
|
||||
return ((u64)index + index_base) & 0x000FFFFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue