summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp67
-rw-r--r--src/video_core/engines/maxwell_3d.h15
2 files changed, 12 insertions, 70 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 8f2fd28c2..54a902f56 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -196,7 +196,7 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
196 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13: 196 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
197 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14: 197 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
198 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15: 198 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
199 return StartCBData(method); 199 return ProcessCBData(argument);
200 case MAXWELL3D_REG_INDEX(cb_bind[0]): 200 case MAXWELL3D_REG_INDEX(cb_bind[0]):
201 return ProcessCBBind(0); 201 return ProcessCBBind(0);
202 case MAXWELL3D_REG_INDEX(cb_bind[1]): 202 case MAXWELL3D_REG_INDEX(cb_bind[1]):
@@ -257,14 +257,6 @@ void Maxwell3D::CallMacroMethod(u32 method, const std::vector<u32>& parameters)
257} 257}
258 258
259void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { 259void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
260 if (method == cb_data_state.current) {
261 regs.reg_array[method] = method_argument;
262 ProcessCBData(method_argument);
263 return;
264 } else if (cb_data_state.current != null_cb_data) {
265 FinishCBData();
266 }
267
268 // It is an error to write to a register other than the current macro's ARG register before it 260 // It is an error to write to a register other than the current macro's ARG register before it
269 // has finished execution. 261 // has finished execution.
270 if (executing_macro != 0) { 262 if (executing_macro != 0) {
@@ -311,7 +303,7 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
311 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13: 303 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
312 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14: 304 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
313 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15: 305 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
314 ProcessCBMultiData(method, base_start, amount); 306 ProcessCBMultiData(base_start, amount);
315 break; 307 break;
316 default: 308 default:
317 for (std::size_t i = 0; i < amount; i++) { 309 for (std::size_t i = 0; i < amount; i++) {
@@ -629,46 +621,7 @@ void Maxwell3D::ProcessCBBind(size_t stage_index) {
629 rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.index, gpu_addr, size); 621 rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.index, gpu_addr, size);
630} 622}
631 623
632void Maxwell3D::ProcessCBData(u32 value) { 624void Maxwell3D::ProcessCBMultiData(const u32* start_base, u32 amount) {
633 const u32 id = cb_data_state.id;
634 cb_data_state.buffer[id][cb_data_state.counter] = value;
635 // Increment the current buffer position.
636 regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;
637 cb_data_state.counter++;
638}
639
640void Maxwell3D::StartCBData(u32 method) {
641 constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data);
642 cb_data_state.start_pos = regs.const_buffer.cb_pos;
643 cb_data_state.id = method - first_cb_data;
644 cb_data_state.current = method;
645 cb_data_state.counter = 0;
646 ProcessCBData(regs.const_buffer.cb_data[cb_data_state.id]);
647}
648
649void Maxwell3D::ProcessCBMultiData(u32 method, const u32* start_base, u32 amount) {
650 if (cb_data_state.current != method) {
651 if (cb_data_state.current != null_cb_data) {
652 FinishCBData();
653 }
654 constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data);
655 cb_data_state.start_pos = regs.const_buffer.cb_pos;
656 cb_data_state.id = method - first_cb_data;
657 cb_data_state.current = method;
658 cb_data_state.counter = 0;
659 }
660 const std::size_t id = cb_data_state.id;
661 const std::size_t size = amount;
662 std::size_t i = 0;
663 for (; i < size; i++) {
664 cb_data_state.buffer[id][cb_data_state.counter] = start_base[i];
665 cb_data_state.counter++;
666 }
667 // Increment the current buffer position.
668 regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4 * amount;
669}
670
671void Maxwell3D::FinishCBData() {
672 // Write the input value to the current const buffer at the current position. 625 // Write the input value to the current const buffer at the current position.
673 const GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); 626 const GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
674 ASSERT(buffer_address != 0); 627 ASSERT(buffer_address != 0);
@@ -676,14 +629,16 @@ void Maxwell3D::FinishCBData() {
676 // Don't allow writing past the end of the buffer. 629 // Don't allow writing past the end of the buffer.
677 ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size); 630 ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size);
678 631
679 const GPUVAddr address{buffer_address + cb_data_state.start_pos}; 632 const GPUVAddr address{buffer_address + regs.const_buffer.cb_pos};
680 const std::size_t size = regs.const_buffer.cb_pos - cb_data_state.start_pos; 633 const size_t copy_size = amount * sizeof(u32);
634 memory_manager.WriteBlock(address, start_base, copy_size);
681 635
682 const u32 id = cb_data_state.id; 636 // Increment the current buffer position.
683 memory_manager.WriteBlock(address, cb_data_state.buffer[id].data(), size); 637 regs.const_buffer.cb_pos += static_cast<u32>(copy_size);
638}
684 639
685 cb_data_state.id = null_cb_data; 640void Maxwell3D::ProcessCBData(u32 value) {
686 cb_data_state.current = null_cb_data; 641 ProcessCBMultiData(&value, 1);
687} 642}
688 643
689Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { 644Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 6d34da046..357a74c70 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1545,10 +1545,8 @@ private:
1545 void ProcessSyncPoint(); 1545 void ProcessSyncPoint();
1546 1546
1547 /// Handles a write to the CB_DATA[i] register. 1547 /// Handles a write to the CB_DATA[i] register.
1548 void StartCBData(u32 method);
1549 void ProcessCBData(u32 value); 1548 void ProcessCBData(u32 value);
1550 void ProcessCBMultiData(u32 method, const u32* start_base, u32 amount); 1549 void ProcessCBMultiData(const u32* start_base, u32 amount);
1551 void FinishCBData();
1552 1550
1553 /// Handles a write to the CB_BIND register. 1551 /// Handles a write to the CB_BIND register.
1554 void ProcessCBBind(size_t stage_index); 1552 void ProcessCBBind(size_t stage_index);
@@ -1583,17 +1581,6 @@ private:
1583 /// Interpreter for the macro codes uploaded to the GPU. 1581 /// Interpreter for the macro codes uploaded to the GPU.
1584 std::unique_ptr<MacroEngine> macro_engine; 1582 std::unique_ptr<MacroEngine> macro_engine;
1585 1583
1586 static constexpr u32 null_cb_data = 0xFFFFFFFF;
1587 struct CBDataState {
1588 static constexpr size_t inline_size = 0x4000;
1589 std::array<std::array<u32, inline_size>, 16> buffer;
1590 u32 current{null_cb_data};
1591 u32 id{null_cb_data};
1592 u32 start_pos{};
1593 u32 counter{};
1594 };
1595 CBDataState cb_data_state;
1596
1597 Upload::State upload_state; 1584 Upload::State upload_state;
1598 1585
1599 bool execute_on{true}; 1586 bool execute_on{true};