Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rsx: Batch transform contants load methods #7939

Merged
merged 1 commit into from Apr 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions Utilities/address_range.h
Expand Up @@ -176,9 +176,7 @@ namespace utils

void set_min_max(const address_range &other)
{
const address_range _range = get_min_max(other);
start = _range.start;
end = _range.end;
*this = get_min_max(other);
}

bool is_page_range() const
Expand Down
5 changes: 3 additions & 2 deletions rpcs3/Emu/RSX/RSXFIFO.cpp
Expand Up @@ -537,10 +537,11 @@ namespace rsx
break;
default:
{
static constexpr std::array<std::pair<u32, u32>, 2> ranges
static constexpr std::array<std::pair<u32, u32>, 3> ranges
{{
{NV308A_COLOR, 0x700},
{NV4097_SET_TRANSFORM_PROGRAM, 32}
{NV4097_SET_TRANSFORM_PROGRAM, 32},
{NV4097_SET_TRANSFORM_CONSTANT, 32}
}};

// Use legacy logic - enqueue leading command with count
Expand Down
42 changes: 31 additions & 11 deletions rpcs3/Emu/RSX/rsx_methods.cpp
Expand Up @@ -422,34 +422,54 @@ namespace rsx
template<u32 index>
struct set_transform_constant
{
static void impl(thread* rsxthr, u32 _reg, u32 arg)
static void impl(thread* rsx, u32 /*_reg*/, u32 /*arg*/)
{
static constexpr u32 reg = index / 4;
static constexpr u8 subreg = index % 4;

// Get real args count
const u32 count = std::min<u32>({rsx->fifo_ctrl->get_remaining_args_count() + 1,
static_cast<u32>(((rsx->ctrl->put & ~3ull) - (rsx->fifo_ctrl->get_pos() - 4)) / 4), 32 - index});

const u32 load = rsx::method_registers.transform_constant_load();
const u32 address = load + reg;
if (address >= 468)

u32 rcount = count;
if (const u32 max = (load + reg) * 4 + count + subreg; max > 468 * 4)
{
// Ignore addresses outside the usable [0, 467] range
rsx_log.warning("Invalid transform register index (load=%d, index=%d)", load, index);
return;
rsx_log.warning("Invalid transform register index (load=%u, index=%u, count=%u)", load, index, count);
rcount -= max - (468 * 4);
}

auto &value = rsx::method_registers.transform_constants[load + reg][subreg];
if (value != arg)
alignas(64) u8 buffer[128];

const auto values = &rsx::method_registers.transform_constants[load + reg][subreg];

if (rsx->m_graphics_state & rsx::pipeline_state::transform_constants_dirty)
{
//Transform constants invalidation is expensive (~8k bytes per update)
value = arg;
rsxthr->m_graphics_state |= rsx::pipeline_state::transform_constants_dirty;
// Minor optimization: don't compare values if we already know we need invalidation
stream_data_to_memory_swapped_u32<true>(values, vm::base(rsx->fifo_ctrl->get_current_arg_ptr()), rcount, 4);
}
else
{
stream_data_to_memory_swapped_u32(buffer, vm::base(rsx->fifo_ctrl->get_current_arg_ptr()), rcount, 4);

if (std::memcmp(values, buffer, rcount * 4) != 0)
{
// Transform constants invalidation is expensive (~8k bytes per update)
std::memcpy(values, buffer, rcount * 4);
rsx->m_graphics_state |= rsx::pipeline_state::transform_constants_dirty;
}
}

rsx->fifo_ctrl->skip_methods(count - 1);
}
};

template<u32 index>
struct set_transform_program
{
static void impl(thread* rsx, u32 _reg, u32 arg)
static void impl(thread* rsx, u32 /*_reg*/, u32 /*arg*/)
{
// Get real args count
const u32 count = std::min<u32>({rsx->fifo_ctrl->get_remaining_args_count() + 1,
Expand Down