summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 5d6d217bb..ba19d1ca2 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -195,7 +195,7 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
195 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13: 195 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
196 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14: 196 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
197 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15: 197 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
198 return StartCBData(method); 198 return ProcessCBData(argument);
199 case MAXWELL3D_REG_INDEX(cb_bind[0]): 199 case MAXWELL3D_REG_INDEX(cb_bind[0]):
200 return ProcessCBBind(0); 200 return ProcessCBBind(0);
201 case MAXWELL3D_REG_INDEX(cb_bind[1]): 201 case MAXWELL3D_REG_INDEX(cb_bind[1]):
@@ -248,14 +248,6 @@ void Maxwell3D::CallMacroMethod(u32 method, const std::vector<u32>& parameters)
248} 248}
249 249
250void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { 250void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
251 if (method == cb_data_state.current) {
252 regs.reg_array[method] = method_argument;
253 ProcessCBData(method_argument);
254 return;
255 } else if (cb_data_state.current != null_cb_data) {
256 FinishCBData();
257 }
258
259 // It is an error to write to a register other than the current macro's ARG register before it 251 // It is an error to write to a register other than the current macro's ARG register before it
260 // has finished execution. 252 // has finished execution.
261 if (executing_macro != 0) { 253 if (executing_macro != 0) {
@@ -302,7 +294,7 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
302 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13: 294 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
303 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14: 295 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
304 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15: 296 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
305 ProcessCBMultiData(method, base_start, amount); 297 ProcessCBMultiData(base_start, amount);
306 break; 298 break;
307 default: 299 default:
308 for (std::size_t i = 0; i < amount; i++) { 300 for (std::size_t i = 0; i < amount; i++) {
@@ -587,46 +579,7 @@ void Maxwell3D::ProcessCBBind(size_t stage_index) {
587 rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.index, gpu_addr, size); 579 rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.index, gpu_addr, size);
588} 580}
589 581
590void Maxwell3D::ProcessCBData(u32 value) { 582void Maxwell3D::ProcessCBMultiData(const u32* start_base, u32 amount) {
591 const u32 id = cb_data_state.id;
592 cb_data_state.buffer[id][cb_data_state.counter] = value;
593 // Increment the current buffer position.
594 regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4;
595 cb_data_state.counter++;
596}
597
598void Maxwell3D::StartCBData(u32 method) {
599 constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data);
600 cb_data_state.start_pos = regs.const_buffer.cb_pos;
601 cb_data_state.id = method - first_cb_data;
602 cb_data_state.current = method;
603 cb_data_state.counter = 0;
604 ProcessCBData(regs.const_buffer.cb_data[cb_data_state.id]);
605}
606
607void Maxwell3D::ProcessCBMultiData(u32 method, const u32* start_base, u32 amount) {
608 if (cb_data_state.current != method) {
609 if (cb_data_state.current != null_cb_data) {
610 FinishCBData();
611 }
612 constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data);
613 cb_data_state.start_pos = regs.const_buffer.cb_pos;
614 cb_data_state.id = method - first_cb_data;
615 cb_data_state.current = method;
616 cb_data_state.counter = 0;
617 }
618 const std::size_t id = cb_data_state.id;
619 const std::size_t size = amount;
620 std::size_t i = 0;
621 for (; i < size; i++) {
622 cb_data_state.buffer[id][cb_data_state.counter] = start_base[i];
623 cb_data_state.counter++;
624 }
625 // Increment the current buffer position.
626 regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4 * amount;
627}
628
629void Maxwell3D::FinishCBData() {
630 // Write the input value to the current const buffer at the current position. 583 // Write the input value to the current const buffer at the current position.
631 const GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); 584 const GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
632 ASSERT(buffer_address != 0); 585 ASSERT(buffer_address != 0);
@@ -634,14 +587,16 @@ void Maxwell3D::FinishCBData() {
634 // Don't allow writing past the end of the buffer. 587 // Don't allow writing past the end of the buffer.
635 ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size); 588 ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size);
636 589
637 const GPUVAddr address{buffer_address + cb_data_state.start_pos}; 590 const GPUVAddr address{buffer_address + regs.const_buffer.cb_pos};
638 const std::size_t size = regs.const_buffer.cb_pos - cb_data_state.start_pos; 591 const size_t copy_size = amount * sizeof(u32);
592 memory_manager.WriteBlock(address, start_base, copy_size);
639 593
640 const u32 id = cb_data_state.id; 594 // Increment the current buffer position.
641 memory_manager.WriteBlock(address, cb_data_state.buffer[id].data(), size); 595 regs.const_buffer.cb_pos += static_cast<u32>(copy_size);
596}
642 597
643 cb_data_state.id = null_cb_data; 598void Maxwell3D::ProcessCBData(u32 value) {
644 cb_data_state.current = null_cb_data; 599 ProcessCBMultiData(&value, 1);
645} 600}
646 601
647Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { 602Texture::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 dc9df6c8b..38d9b6660 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1520,10 +1520,8 @@ private:
1520 void ProcessSyncPoint(); 1520 void ProcessSyncPoint();
1521 1521
1522 /// Handles a write to the CB_DATA[i] register. 1522 /// Handles a write to the CB_DATA[i] register.
1523 void StartCBData(u32 method);
1524 void ProcessCBData(u32 value); 1523 void ProcessCBData(u32 value);
1525 void ProcessCBMultiData(u32 method, const u32* start_base, u32 amount); 1524 void ProcessCBMultiData(const u32* start_base, u32 amount);
1526 void FinishCBData();
1527 1525
1528 /// Handles a write to the CB_BIND register. 1526 /// Handles a write to the CB_BIND register.
1529 void ProcessCBBind(size_t stage_index); 1527 void ProcessCBBind(size_t stage_index);
@@ -1555,17 +1553,6 @@ private:
1555 /// Interpreter for the macro codes uploaded to the GPU. 1553 /// Interpreter for the macro codes uploaded to the GPU.
1556 std::unique_ptr<MacroEngine> macro_engine; 1554 std::unique_ptr<MacroEngine> macro_engine;
1557 1555
1558 static constexpr u32 null_cb_data = 0xFFFFFFFF;
1559 struct CBDataState {
1560 static constexpr size_t inline_size = 0x4000;
1561 std::array<std::array<u32, inline_size>, 16> buffer;
1562 u32 current{null_cb_data};
1563 u32 id{null_cb_data};
1564 u32 start_pos{};
1565 u32 counter{};
1566 };
1567 CBDataState cb_data_state;
1568
1569 Upload::State upload_state; 1556 Upload::State upload_state;
1570 1557
1571 bool execute_on{true}; 1558 bool execute_on{true};