Maxwell3D: Rework CBData Upload
This commit is contained in:
parent
f2e7b29c14
commit
0d3db58657
2 changed files with 45 additions and 8 deletions
|
@ -183,6 +183,14 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
|
||||||
|
|
||||||
const u32 method = method_call.method;
|
const u32 method = method_call.method;
|
||||||
|
|
||||||
|
if (method == cb_data_state.current) {
|
||||||
|
regs.reg_array[method] = method_call.argument;
|
||||||
|
ProcessCBData(method_call.argument);
|
||||||
|
return;
|
||||||
|
} else if (cb_data_state.current != null_cb_data) {
|
||||||
|
FinishCBData();
|
||||||
|
}
|
||||||
|
|
||||||
// It is an error to write to a register other than the current macro's ARG register before it
|
// It is an error to write to a register other than the current macro's ARG register before it
|
||||||
// has finished execution.
|
// has finished execution.
|
||||||
if (executing_macro != 0) {
|
if (executing_macro != 0) {
|
||||||
|
@ -259,7 +267,7 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
|
||||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
|
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]):
|
||||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
|
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]):
|
||||||
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): {
|
case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): {
|
||||||
ProcessCBData(method_call.argument);
|
StartCBData(method);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): {
|
case MAXWELL3D_REG_INDEX(cb_bind[0].raw_config): {
|
||||||
|
@ -449,21 +457,39 @@ void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Maxwell3D::ProcessCBData(u32 value) {
|
void Maxwell3D::ProcessCBData(u32 value) {
|
||||||
|
const u32 id = cb_data_state.id;
|
||||||
|
cb_data_state.buff[id][cb_data_state.counter] = value;
|
||||||
|
// Increment the current buffer position.
|
||||||
|
regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;
|
||||||
|
cb_data_state.counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Maxwell3D::StartCBData(u32 method) {
|
||||||
|
constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]);
|
||||||
|
cb_data_state.start_pos = regs.const_buffer.cb_pos;
|
||||||
|
cb_data_state.id = method - first_cb_data;
|
||||||
|
cb_data_state.current = method;
|
||||||
|
cb_data_state.counter = 0;
|
||||||
|
ProcessCBData(regs.const_buffer.cb_data[cb_data_state.id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Maxwell3D::FinishCBData() {
|
||||||
// Write the input value to the current const buffer at the current position.
|
// Write the input value to the current const buffer at the current position.
|
||||||
const GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
|
const GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
|
||||||
ASSERT(buffer_address != 0);
|
ASSERT(buffer_address != 0);
|
||||||
|
|
||||||
// Don't allow writing past the end of the buffer.
|
// Don't allow writing past the end of the buffer.
|
||||||
ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size);
|
ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size);
|
||||||
|
|
||||||
const GPUVAddr address{buffer_address + regs.const_buffer.cb_pos};
|
const GPUVAddr address{buffer_address + cb_data_state.start_pos};
|
||||||
|
const std::size_t size = regs.const_buffer.cb_pos - cb_data_state.start_pos;
|
||||||
|
|
||||||
u8* ptr{memory_manager.GetPointer(address)};
|
const u32 id = cb_data_state.id;
|
||||||
rasterizer.InvalidateRegion(ToCacheAddr(ptr), sizeof(u32));
|
memory_manager.WriteBlock(address, cb_data_state.buff[id].data(), size);
|
||||||
memory_manager.Write<u32>(address, value);
|
dirty.ResetRenderTargets();
|
||||||
|
|
||||||
// Increment the current buffer position.
|
cb_data_state.id = null_cb_data;
|
||||||
regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;
|
cb_data_state.current = null_cb_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
|
Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
|
||||||
|
|
|
@ -1244,6 +1244,15 @@ private:
|
||||||
|
|
||||||
Upload::State upload_state;
|
Upload::State upload_state;
|
||||||
|
|
||||||
|
static constexpr u32 null_cb_data = 0xFFFFFFFF;
|
||||||
|
struct {
|
||||||
|
std::array<std::array<u32, 0x4000>, 16> buff;
|
||||||
|
u32 current{null_cb_data};
|
||||||
|
u32 id{null_cb_data};
|
||||||
|
u32 start_pos{};
|
||||||
|
u32 counter{};
|
||||||
|
} cb_data_state;
|
||||||
|
|
||||||
/// Retrieves information about a specific TIC entry from the TIC buffer.
|
/// Retrieves information about a specific TIC entry from the TIC buffer.
|
||||||
Texture::TICEntry GetTICEntry(u32 tic_index) const;
|
Texture::TICEntry GetTICEntry(u32 tic_index) const;
|
||||||
|
|
||||||
|
@ -1275,7 +1284,9 @@ private:
|
||||||
void ProcessSyncPoint();
|
void ProcessSyncPoint();
|
||||||
|
|
||||||
/// Handles a write to the CB_DATA[i] register.
|
/// Handles a write to the CB_DATA[i] register.
|
||||||
|
void StartCBData(u32 method);
|
||||||
void ProcessCBData(u32 value);
|
void ProcessCBData(u32 value);
|
||||||
|
void FinishCBData();
|
||||||
|
|
||||||
/// Handles a write to the CB_BIND register.
|
/// Handles a write to the CB_BIND register.
|
||||||
void ProcessCBBind(Regs::ShaderStage stage);
|
void ProcessCBBind(Regs::ShaderStage stage);
|
||||||
|
|
Loading…
Reference in a new issue