diff options
Diffstat (limited to 'src/video_core/engines/maxwell_3d.cpp')
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 165 |
1 files changed, 78 insertions, 87 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 4a2f2c1fd..34bbc72cf 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -217,22 +217,25 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume regs.index_buffer.count = regs.index_buffer32_first.count; regs.index_buffer.first = regs.index_buffer32_first.first; dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + draw_indexed = true; return ProcessDraw(); case MAXWELL3D_REG_INDEX(index_buffer16_first): regs.index_buffer.count = regs.index_buffer16_first.count; regs.index_buffer.first = regs.index_buffer16_first.first; dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + draw_indexed = true; return ProcessDraw(); case MAXWELL3D_REG_INDEX(index_buffer8_first): regs.index_buffer.count = regs.index_buffer8_first.count; regs.index_buffer.first = regs.index_buffer8_first.first; dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + draw_indexed = true; return ProcessDraw(); case MAXWELL3D_REG_INDEX(topology_override): use_topology_override = true; return; case MAXWELL3D_REG_INDEX(clear_surface): - return ProcessClearBuffers(); + return ProcessClearBuffers(1); case MAXWELL3D_REG_INDEX(report_semaphore.query): return ProcessQueryGet(); case MAXWELL3D_REG_INDEX(render_enable.mode): @@ -249,6 +252,8 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume return; case MAXWELL3D_REG_INDEX(fragment_barrier): return rasterizer->FragmentBarrier(); + case MAXWELL3D_REG_INDEX(tiled_cache_barrier): + return rasterizer->TiledCacheBarrier(); } } @@ -283,31 +288,63 @@ void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { ASSERT_MSG(method < Regs::NUM_REGS, "Invalid Maxwell3D register, increase the size of the Regs structure"); + const u32 argument = ProcessShadowRam(method, method_argument); + ProcessDirtyRegisters(method, argument); + if (draw_command[method]) { regs.reg_array[method] = method_argument; deferred_draw_method.push_back(method); - auto u32_to_u8 = [&](const u32 argument) { - inline_index_draw_indexes.push_back(static_cast<u8>(argument & 0x000000ff)); - inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0x0000ff00) >> 8)); - inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0x00ff0000) >> 16)); - inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0xff000000) >> 24)); + auto update_inline_index = [&](const u32 index) { + inline_index_draw_indexes.push_back(static_cast<u8>(index & 0x000000ff)); + inline_index_draw_indexes.push_back(static_cast<u8>((index & 0x0000ff00) >> 8)); + inline_index_draw_indexes.push_back(static_cast<u8>((index & 0x00ff0000) >> 16)); + inline_index_draw_indexes.push_back(static_cast<u8>((index & 0xff000000) >> 24)); + draw_mode = DrawMode::InlineIndex; }; - if (MAXWELL3D_REG_INDEX(draw_inline_index) == method) { - u32_to_u8(method_argument); - } else if (MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method) { - u32_to_u8(regs.inline_index_2x16.even); - u32_to_u8(regs.inline_index_2x16.odd); - } else if (MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) { - u32_to_u8(regs.inline_index_4x8.index0); - u32_to_u8(regs.inline_index_4x8.index1); - u32_to_u8(regs.inline_index_4x8.index2); - u32_to_u8(regs.inline_index_4x8.index3); + switch (method) { + case MAXWELL3D_REG_INDEX(draw.begin): { + draw_mode = + (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || + (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged) + ? DrawMode::Instance + : DrawMode::General; + break; + } + case MAXWELL3D_REG_INDEX(draw.end): + switch (draw_mode) { + case DrawMode::General: + ProcessDraw(); + break; + case DrawMode::InlineIndex: + regs.index_buffer.count = static_cast<u32>(inline_index_draw_indexes.size() / 4); + regs.index_buffer.format = Regs::IndexFormat::UnsignedInt; + draw_indexed = true; + ProcessDraw(); + inline_index_draw_indexes.clear(); + break; + case DrawMode::Instance: + break; + } + break; + case MAXWELL3D_REG_INDEX(index_buffer.count): + draw_indexed = true; + break; + case MAXWELL3D_REG_INDEX(draw_inline_index): + update_inline_index(method_argument); + break; + case MAXWELL3D_REG_INDEX(inline_index_2x16.even): + update_inline_index(regs.inline_index_2x16.even); + update_inline_index(regs.inline_index_2x16.odd); + break; + case MAXWELL3D_REG_INDEX(inline_index_4x8.index0): + update_inline_index(regs.inline_index_4x8.index0); + update_inline_index(regs.inline_index_4x8.index1); + update_inline_index(regs.inline_index_4x8.index2); + update_inline_index(regs.inline_index_4x8.index3); + break; } } else { ProcessDeferredDraw(); - - const u32 argument = ProcessShadowRam(method, method_argument); - ProcessDirtyRegisters(method, argument); ProcessMethodCall(method, argument, method_argument, is_last_call); } } @@ -340,11 +377,11 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, ProcessCBMultiData(base_start, amount); break; case MAXWELL3D_REG_INDEX(inline_data): - upload_state.ProcessData(base_start, static_cast<size_t>(amount)); + upload_state.ProcessData(base_start, amount); return; default: - for (std::size_t i = 0; i < amount; i++) { - CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1); + for (u32 i = 0; i < amount; i++) { + CallMethod(method, base_start[i], methods_pending - i <= 1); } break; } @@ -506,10 +543,7 @@ void Maxwell3D::ProcessCounterReset() { void Maxwell3D::ProcessSyncPoint() { const u32 sync_point = regs.sync_info.sync_point.Value(); - const u32 cache_flush = regs.sync_info.clean_l2.Value(); - if (cache_flush != 0) { - rasterizer->InvalidateGPUCache(); - } + [[maybe_unused]] const u32 cache_flush = regs.sync_info.clean_l2.Value(); rasterizer->SignalSyncPoint(sync_point); } @@ -591,87 +625,44 @@ u32 Maxwell3D::GetRegisterValue(u32 method) const { return regs.reg_array[method]; } -void Maxwell3D::ProcessClearBuffers() { - rasterizer->Clear(); +void Maxwell3D::ProcessClearBuffers(u32 layer_count) { + rasterizer->Clear(layer_count); } void Maxwell3D::ProcessDraw(u32 instance_count) { LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), - regs.vertex_buffer.count); - - ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?"); - - // Both instance configuration registers can not be set at the same time. - ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First || - regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged, - "Illegal combination of instancing parameters"); + draw_indexed ? regs.index_buffer.count : regs.vertex_buffer.count); ProcessTopologyOverride(); - const bool is_indexed = regs.index_buffer.count && !regs.vertex_buffer.count; if (ShouldExecute()) { - rasterizer->Draw(is_indexed, instance_count); + rasterizer->Draw(draw_indexed, instance_count); } - if (is_indexed) { - regs.index_buffer.count = 0; - } else { - regs.vertex_buffer.count = 0; - } + draw_indexed = false; + deferred_draw_method.clear(); } void Maxwell3D::ProcessDeferredDraw() { - if (deferred_draw_method.empty()) { + if (draw_mode != DrawMode::Instance || deferred_draw_method.empty()) { return; } - enum class DrawMode { - Undefined, - General, - Instance, - }; - DrawMode draw_mode{DrawMode::Undefined}; - u32 method_count = static_cast<u32>(deferred_draw_method.size()); - u32 method = deferred_draw_method[method_count - 1]; - if (MAXWELL3D_REG_INDEX(draw.end) != method) { - return; - } - draw_mode = (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || - (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged) - ? DrawMode::Instance - : DrawMode::General; - u32 instance_count = 0; - if (draw_mode == DrawMode::Instance) { - u32 vertex_buffer_count = 0; - u32 index_buffer_count = 0; - for (u32 index = 0; index < method_count; ++index) { - method = deferred_draw_method[index]; - if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) { - instance_count = ++vertex_buffer_count; - } else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) { - instance_count = ++index_buffer_count; - } - } - ASSERT_MSG(!(vertex_buffer_count && index_buffer_count), - "Instance both indexed and direct?"); - } else { - instance_count = 1; - for (u32 index = 0; index < method_count; ++index) { - method = deferred_draw_method[index]; - if (MAXWELL3D_REG_INDEX(draw_inline_index) == method || - MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method || - MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) { - regs.index_buffer.count = static_cast<u32>(inline_index_draw_indexes.size() / 4); - regs.index_buffer.format = Regs::IndexFormat::UnsignedInt; - break; - } + const auto method_count = deferred_draw_method.size(); + u32 instance_count = 1; + u32 vertex_buffer_count = 0; + u32 index_buffer_count = 0; + for (size_t index = 0; index < method_count; ++index) { + const u32 method = deferred_draw_method[index]; + if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) { + instance_count = ++vertex_buffer_count; + } else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) { + instance_count = ++index_buffer_count; } } + ASSERT_MSG(!(vertex_buffer_count && index_buffer_count), "Instance both indexed and direct?"); ProcessDraw(instance_count); - - deferred_draw_method.clear(); - inline_index_draw_indexes.clear(); } } // namespace Tegra::Engines |