diff options
29 files changed, 3974 insertions, 2043 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 8e26b3f95..2ba33543c 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -994,13 +994,13 @@ void BufferCache<P>::BindHostIndexBuffer() { | |||
| 994 | const u32 size = index_buffer.size; | 994 | const u32 size = index_buffer.size; |
| 995 | SynchronizeBuffer(buffer, index_buffer.cpu_addr, size); | 995 | SynchronizeBuffer(buffer, index_buffer.cpu_addr, size); |
| 996 | if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) { | 996 | if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) { |
| 997 | const u32 new_offset = offset + maxwell3d->regs.index_array.first * | 997 | const u32 new_offset = offset + maxwell3d->regs.index_buffer.first * |
| 998 | maxwell3d->regs.index_array.FormatSizeInBytes(); | 998 | maxwell3d->regs.index_buffer.FormatSizeInBytes(); |
| 999 | runtime.BindIndexBuffer(buffer, new_offset, size); | 999 | runtime.BindIndexBuffer(buffer, new_offset, size); |
| 1000 | } else { | 1000 | } else { |
| 1001 | runtime.BindIndexBuffer(maxwell3d->regs.draw.topology, maxwell3d->regs.index_array.format, | 1001 | runtime.BindIndexBuffer(maxwell3d->regs.draw.topology, maxwell3d->regs.index_buffer.format, |
| 1002 | maxwell3d->regs.index_array.first, | 1002 | maxwell3d->regs.index_buffer.first, |
| 1003 | maxwell3d->regs.index_array.count, buffer, offset, size); | 1003 | maxwell3d->regs.index_buffer.count, buffer, offset, size); |
| 1004 | } | 1004 | } |
| 1005 | } | 1005 | } |
| 1006 | 1006 | ||
| @@ -1017,7 +1017,7 @@ void BufferCache<P>::BindHostVertexBuffers() { | |||
| 1017 | } | 1017 | } |
| 1018 | flags[Dirty::VertexBuffer0 + index] = false; | 1018 | flags[Dirty::VertexBuffer0 + index] = false; |
| 1019 | 1019 | ||
| 1020 | const u32 stride = maxwell3d->regs.vertex_array[index].stride; | 1020 | const u32 stride = maxwell3d->regs.vertex_streams[index].stride; |
| 1021 | const u32 offset = buffer.Offset(binding.cpu_addr); | 1021 | const u32 offset = buffer.Offset(binding.cpu_addr); |
| 1022 | runtime.BindVertexBuffer(index, buffer, offset, binding.size, stride); | 1022 | runtime.BindVertexBuffer(index, buffer, offset, binding.size, stride); |
| 1023 | } | 1023 | } |
| @@ -1157,7 +1157,7 @@ void BufferCache<P>::BindHostGraphicsTextureBuffers(size_t stage) { | |||
| 1157 | 1157 | ||
| 1158 | template <class P> | 1158 | template <class P> |
| 1159 | void BufferCache<P>::BindHostTransformFeedbackBuffers() { | 1159 | void BufferCache<P>::BindHostTransformFeedbackBuffers() { |
| 1160 | if (maxwell3d->regs.tfb_enabled == 0) { | 1160 | if (maxwell3d->regs.transform_feedback_enabled == 0) { |
| 1161 | return; | 1161 | return; |
| 1162 | } | 1162 | } |
| 1163 | for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) { | 1163 | for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) { |
| @@ -1268,7 +1268,7 @@ template <class P> | |||
| 1268 | void BufferCache<P>::UpdateIndexBuffer() { | 1268 | void BufferCache<P>::UpdateIndexBuffer() { |
| 1269 | // We have to check for the dirty flags and index count | 1269 | // We have to check for the dirty flags and index count |
| 1270 | // The index count is currently changed without updating the dirty flags | 1270 | // The index count is currently changed without updating the dirty flags |
| 1271 | const auto& index_array = maxwell3d->regs.index_array; | 1271 | const auto& index_array = maxwell3d->regs.index_buffer; |
| 1272 | auto& flags = maxwell3d->dirty.flags; | 1272 | auto& flags = maxwell3d->dirty.flags; |
| 1273 | if (!flags[Dirty::IndexBuffer] && last_index_count == index_array.count) { | 1273 | if (!flags[Dirty::IndexBuffer] && last_index_count == index_array.count) { |
| 1274 | return; | 1274 | return; |
| @@ -1311,10 +1311,10 @@ void BufferCache<P>::UpdateVertexBuffer(u32 index) { | |||
| 1311 | if (!maxwell3d->dirty.flags[Dirty::VertexBuffer0 + index]) { | 1311 | if (!maxwell3d->dirty.flags[Dirty::VertexBuffer0 + index]) { |
| 1312 | return; | 1312 | return; |
| 1313 | } | 1313 | } |
| 1314 | const auto& array = maxwell3d->regs.vertex_array[index]; | 1314 | const auto& array = maxwell3d->regs.vertex_streams[index]; |
| 1315 | const auto& limit = maxwell3d->regs.vertex_array_limit[index]; | 1315 | const auto& limit = maxwell3d->regs.vertex_stream_limits[index]; |
| 1316 | const GPUVAddr gpu_addr_begin = array.StartAddress(); | 1316 | const GPUVAddr gpu_addr_begin = array.Address(); |
| 1317 | const GPUVAddr gpu_addr_end = limit.LimitAddress() + 1; | 1317 | const GPUVAddr gpu_addr_end = limit.Address() + 1; |
| 1318 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr_begin); | 1318 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr_begin); |
| 1319 | u32 address_size = static_cast<u32>( | 1319 | u32 address_size = static_cast<u32>( |
| 1320 | std::min(gpu_addr_end - gpu_addr_begin, static_cast<u64>(std::numeric_limits<u32>::max()))); | 1320 | std::min(gpu_addr_end - gpu_addr_begin, static_cast<u64>(std::numeric_limits<u32>::max()))); |
| @@ -1380,7 +1380,7 @@ void BufferCache<P>::UpdateTextureBuffers(size_t stage) { | |||
| 1380 | 1380 | ||
| 1381 | template <class P> | 1381 | template <class P> |
| 1382 | void BufferCache<P>::UpdateTransformFeedbackBuffers() { | 1382 | void BufferCache<P>::UpdateTransformFeedbackBuffers() { |
| 1383 | if (maxwell3d->regs.tfb_enabled == 0) { | 1383 | if (maxwell3d->regs.transform_feedback_enabled == 0) { |
| 1384 | return; | 1384 | return; |
| 1385 | } | 1385 | } |
| 1386 | for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) { | 1386 | for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) { |
| @@ -1390,11 +1390,11 @@ void BufferCache<P>::UpdateTransformFeedbackBuffers() { | |||
| 1390 | 1390 | ||
| 1391 | template <class P> | 1391 | template <class P> |
| 1392 | void BufferCache<P>::UpdateTransformFeedbackBuffer(u32 index) { | 1392 | void BufferCache<P>::UpdateTransformFeedbackBuffer(u32 index) { |
| 1393 | const auto& binding = maxwell3d->regs.tfb_bindings[index]; | 1393 | const auto& binding = maxwell3d->regs.transform_feedback.buffers[index]; |
| 1394 | const GPUVAddr gpu_addr = binding.Address() + binding.buffer_offset; | 1394 | const GPUVAddr gpu_addr = binding.Address() + binding.start_offset; |
| 1395 | const u32 size = binding.buffer_size; | 1395 | const u32 size = binding.size; |
| 1396 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); | 1396 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); |
| 1397 | if (binding.buffer_enable == 0 || size == 0 || !cpu_addr) { | 1397 | if (binding.enable == 0 || size == 0 || !cpu_addr) { |
| 1398 | transform_feedback_buffers[index] = NULL_BINDING; | 1398 | transform_feedback_buffers[index] = NULL_BINDING; |
| 1399 | return; | 1399 | return; |
| 1400 | } | 1400 | } |
diff --git a/src/video_core/dirty_flags.cpp b/src/video_core/dirty_flags.cpp index 9dc4341f0..1039e036f 100644 --- a/src/video_core/dirty_flags.cpp +++ b/src/video_core/dirty_flags.cpp | |||
| @@ -17,21 +17,23 @@ using Tegra::Engines::Maxwell3D; | |||
| 17 | void SetupDirtyVertexBuffers(Maxwell3D::DirtyState::Tables& tables) { | 17 | void SetupDirtyVertexBuffers(Maxwell3D::DirtyState::Tables& tables) { |
| 18 | static constexpr std::size_t num_array = 3; | 18 | static constexpr std::size_t num_array = 3; |
| 19 | for (std::size_t i = 0; i < Maxwell3D::Regs::NumVertexArrays; ++i) { | 19 | for (std::size_t i = 0; i < Maxwell3D::Regs::NumVertexArrays; ++i) { |
| 20 | const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]); | 20 | const std::size_t array_offset = OFF(vertex_streams) + i * NUM(vertex_streams[0]); |
| 21 | const std::size_t limit_offset = OFF(vertex_array_limit) + i * NUM(vertex_array_limit[0]); | 21 | const std::size_t limit_offset = |
| 22 | OFF(vertex_stream_limits) + i * NUM(vertex_stream_limits[0]); | ||
| 22 | 23 | ||
| 23 | FillBlock(tables, array_offset, num_array, VertexBuffer0 + i, VertexBuffers); | 24 | FillBlock(tables, array_offset, num_array, VertexBuffer0 + i, VertexBuffers); |
| 24 | FillBlock(tables, limit_offset, NUM(vertex_array_limit), VertexBuffer0 + i, VertexBuffers); | 25 | FillBlock(tables, limit_offset, NUM(vertex_stream_limits), VertexBuffer0 + i, |
| 26 | VertexBuffers); | ||
| 25 | } | 27 | } |
| 26 | } | 28 | } |
| 27 | 29 | ||
| 28 | void SetupIndexBuffer(Maxwell3D::DirtyState::Tables& tables) { | 30 | void SetupIndexBuffer(Maxwell3D::DirtyState::Tables& tables) { |
| 29 | FillBlock(tables[0], OFF(index_array), NUM(index_array), IndexBuffer); | 31 | FillBlock(tables[0], OFF(index_buffer), NUM(index_buffer), IndexBuffer); |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | void SetupDirtyDescriptors(Maxwell3D::DirtyState::Tables& tables) { | 34 | void SetupDirtyDescriptors(Maxwell3D::DirtyState::Tables& tables) { |
| 33 | FillBlock(tables[0], OFF(tic), NUM(tic), Descriptors); | 35 | FillBlock(tables[0], OFF(tex_header), NUM(tex_header), Descriptors); |
| 34 | FillBlock(tables[0], OFF(tsc), NUM(tsc), Descriptors); | 36 | FillBlock(tables[0], OFF(tex_sampler), NUM(tex_sampler), Descriptors); |
| 35 | } | 37 | } |
| 36 | 38 | ||
| 37 | void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) { | 39 | void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) { |
| @@ -42,7 +44,7 @@ void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) { | |||
| 42 | FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt); | 44 | FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt); |
| 43 | } | 45 | } |
| 44 | FillBlock(tables[1], begin, num, RenderTargets); | 46 | FillBlock(tables[1], begin, num, RenderTargets); |
| 45 | FillBlock(tables[0], OFF(render_area), NUM(render_area), RenderTargets); | 47 | FillBlock(tables[0], OFF(surface_clip), NUM(surface_clip), RenderTargets); |
| 46 | 48 | ||
| 47 | tables[0][OFF(rt_control)] = RenderTargets; | 49 | tables[0][OFF(rt_control)] = RenderTargets; |
| 48 | tables[1][OFF(rt_control)] = RenderTargetControl; | 50 | tables[1][OFF(rt_control)] = RenderTargetControl; |
| @@ -52,15 +54,15 @@ void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) { | |||
| 52 | const u8 flag = zeta_flags[i]; | 54 | const u8 flag = zeta_flags[i]; |
| 53 | auto& table = tables[i]; | 55 | auto& table = tables[i]; |
| 54 | table[OFF(zeta_enable)] = flag; | 56 | table[OFF(zeta_enable)] = flag; |
| 55 | table[OFF(zeta_width)] = flag; | 57 | table[OFF(zeta_size.width)] = flag; |
| 56 | table[OFF(zeta_height)] = flag; | 58 | table[OFF(zeta_size.height)] = flag; |
| 57 | FillBlock(table, OFF(zeta), NUM(zeta), flag); | 59 | FillBlock(table, OFF(zeta), NUM(zeta), flag); |
| 58 | } | 60 | } |
| 59 | } | 61 | } |
| 60 | 62 | ||
| 61 | void SetupDirtyShaders(Maxwell3D::DirtyState::Tables& tables) { | 63 | void SetupDirtyShaders(Maxwell3D::DirtyState::Tables& tables) { |
| 62 | FillBlock(tables[0], OFF(shader_config[0]), | 64 | FillBlock(tables[0], OFF(pipelines), NUM(pipelines) * Maxwell3D::Regs::MaxShaderProgram, |
| 63 | NUM(shader_config[0]) * Maxwell3D::Regs::MaxShaderProgram, Shaders); | 65 | Shaders); |
| 64 | } | 66 | } |
| 65 | } // Anonymous namespace | 67 | } // Anonymous namespace |
| 66 | 68 | ||
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 3c6e44a25..84c1abf3d 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -56,37 +56,37 @@ void Maxwell3D::InitializeRegisterDefaults() { | |||
| 56 | 56 | ||
| 57 | // Doom and Bomberman seems to use the uninitialized registers and just enable blend | 57 | // Doom and Bomberman seems to use the uninitialized registers and just enable blend |
| 58 | // so initialize blend registers with sane values | 58 | // so initialize blend registers with sane values |
| 59 | regs.blend.equation_rgb = Regs::Blend::Equation::Add; | 59 | regs.blend.color_op = Regs::Blend::Equation::Add_D3D; |
| 60 | regs.blend.factor_source_rgb = Regs::Blend::Factor::One; | 60 | regs.blend.color_source = Regs::Blend::Factor::One_D3D; |
| 61 | regs.blend.factor_dest_rgb = Regs::Blend::Factor::Zero; | 61 | regs.blend.color_dest = Regs::Blend::Factor::Zero_D3D; |
| 62 | regs.blend.equation_a = Regs::Blend::Equation::Add; | 62 | regs.blend.alpha_op = Regs::Blend::Equation::Add_D3D; |
| 63 | regs.blend.factor_source_a = Regs::Blend::Factor::One; | 63 | regs.blend.alpha_source = Regs::Blend::Factor::One_D3D; |
| 64 | regs.blend.factor_dest_a = Regs::Blend::Factor::Zero; | 64 | regs.blend.alpha_dest = Regs::Blend::Factor::Zero_D3D; |
| 65 | for (auto& blend : regs.independent_blend) { | 65 | for (auto& blend : regs.blend_per_target) { |
| 66 | blend.equation_rgb = Regs::Blend::Equation::Add; | 66 | blend.color_op = Regs::Blend::Equation::Add_D3D; |
| 67 | blend.factor_source_rgb = Regs::Blend::Factor::One; | 67 | blend.color_source = Regs::Blend::Factor::One_D3D; |
| 68 | blend.factor_dest_rgb = Regs::Blend::Factor::Zero; | 68 | blend.color_dest = Regs::Blend::Factor::Zero_D3D; |
| 69 | blend.equation_a = Regs::Blend::Equation::Add; | 69 | blend.alpha_op = Regs::Blend::Equation::Add_D3D; |
| 70 | blend.factor_source_a = Regs::Blend::Factor::One; | 70 | blend.alpha_source = Regs::Blend::Factor::One_D3D; |
| 71 | blend.factor_dest_a = Regs::Blend::Factor::Zero; | 71 | blend.alpha_dest = Regs::Blend::Factor::Zero_D3D; |
| 72 | } | 72 | } |
| 73 | regs.stencil_front_op_fail = Regs::StencilOp::Keep; | 73 | regs.stencil_front_op.fail = Regs::StencilOp::Op::Keep_D3D; |
| 74 | regs.stencil_front_op_zfail = Regs::StencilOp::Keep; | 74 | regs.stencil_front_op.zfail = Regs::StencilOp::Op::Keep_D3D; |
| 75 | regs.stencil_front_op_zpass = Regs::StencilOp::Keep; | 75 | regs.stencil_front_op.zpass = Regs::StencilOp::Op::Keep_D3D; |
| 76 | regs.stencil_front_func_func = Regs::ComparisonOp::Always; | 76 | regs.stencil_front_op.func = Regs::ComparisonOp::Always_GL; |
| 77 | regs.stencil_front_func_mask = 0xFFFFFFFF; | 77 | regs.stencil_front_func.func_mask = 0xFFFFFFFF; |
| 78 | regs.stencil_front_mask = 0xFFFFFFFF; | 78 | regs.stencil_front_func.mask = 0xFFFFFFFF; |
| 79 | regs.stencil_two_side_enable = 1; | 79 | regs.stencil_two_side_enable = 1; |
| 80 | regs.stencil_back_op_fail = Regs::StencilOp::Keep; | 80 | regs.stencil_back_op.fail = Regs::StencilOp::Op::Keep_D3D; |
| 81 | regs.stencil_back_op_zfail = Regs::StencilOp::Keep; | 81 | regs.stencil_back_op.zfail = Regs::StencilOp::Op::Keep_D3D; |
| 82 | regs.stencil_back_op_zpass = Regs::StencilOp::Keep; | 82 | regs.stencil_back_op.zpass = Regs::StencilOp::Op::Keep_D3D; |
| 83 | regs.stencil_back_func_func = Regs::ComparisonOp::Always; | 83 | regs.stencil_back_op.func = Regs::ComparisonOp::Always_GL; |
| 84 | regs.stencil_back_func_mask = 0xFFFFFFFF; | 84 | regs.stencil_back_func.func_mask = 0xFFFFFFFF; |
| 85 | regs.stencil_back_mask = 0xFFFFFFFF; | 85 | regs.stencil_back_func.mask = 0xFFFFFFFF; |
| 86 | 86 | ||
| 87 | regs.depth_test_func = Regs::ComparisonOp::Always; | 87 | regs.depth_test_func = Regs::ComparisonOp::Always_GL; |
| 88 | regs.front_face = Regs::FrontFace::CounterClockWise; | 88 | regs.gl_front_face = Regs::FrontFace::CounterClockWise; |
| 89 | regs.cull_face = Regs::CullFace::Back; | 89 | regs.gl_cull_face = Regs::CullFace::Back; |
| 90 | 90 | ||
| 91 | // TODO(Rodrigo): Most games do not set a point size. I think this is a case of a | 91 | // TODO(Rodrigo): Most games do not set a point size. I think this is a case of a |
| 92 | // register carrying a default value. Assume it's OpenGL's default (1). | 92 | // register carrying a default value. Assume it's OpenGL's default (1). |
| @@ -107,20 +107,20 @@ void Maxwell3D::InitializeRegisterDefaults() { | |||
| 107 | 107 | ||
| 108 | // NVN games expect these values to be enabled at boot | 108 | // NVN games expect these values to be enabled at boot |
| 109 | regs.rasterize_enable = 1; | 109 | regs.rasterize_enable = 1; |
| 110 | regs.rt_separate_frag_data = 1; | 110 | regs.color_target_mrt_enable = 1; |
| 111 | regs.framebuffer_srgb = 1; | 111 | regs.framebuffer_srgb = 1; |
| 112 | regs.line_width_aliased = 1.0f; | 112 | regs.line_width_aliased = 1.0f; |
| 113 | regs.line_width_smooth = 1.0f; | 113 | regs.line_width_smooth = 1.0f; |
| 114 | regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise; | 114 | regs.gl_front_face = Maxwell3D::Regs::FrontFace::ClockWise; |
| 115 | regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill; | 115 | regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill; |
| 116 | regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill; | 116 | regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill; |
| 117 | 117 | ||
| 118 | shadow_state = regs; | 118 | shadow_state = regs; |
| 119 | 119 | ||
| 120 | mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true; | 120 | mme_inline[MAXWELL3D_REG_INDEX(draw.end)] = true; |
| 121 | mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true; | 121 | mme_inline[MAXWELL3D_REG_INDEX(draw.begin)] = true; |
| 122 | mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true; | 122 | mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true; |
| 123 | mme_inline[MAXWELL3D_REG_INDEX(index_array.count)] = true; | 123 | mme_inline[MAXWELL3D_REG_INDEX(index_buffer.count)] = true; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) { | 126 | void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) { |
| @@ -173,51 +173,56 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume | |||
| 173 | case MAXWELL3D_REG_INDEX(shadow_ram_control): | 173 | case MAXWELL3D_REG_INDEX(shadow_ram_control): |
| 174 | shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument); | 174 | shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument); |
| 175 | return; | 175 | return; |
| 176 | case MAXWELL3D_REG_INDEX(macros.upload_address): | 176 | case MAXWELL3D_REG_INDEX(load_mme.instruction_ptr): |
| 177 | return macro_engine->ClearCode(regs.macros.upload_address); | 177 | return macro_engine->ClearCode(regs.load_mme.instruction_ptr); |
| 178 | case MAXWELL3D_REG_INDEX(macros.data): | 178 | case MAXWELL3D_REG_INDEX(load_mme.instruction): |
| 179 | return macro_engine->AddCode(regs.macros.upload_address, argument); | 179 | return macro_engine->AddCode(regs.load_mme.instruction_ptr, argument); |
| 180 | case MAXWELL3D_REG_INDEX(macros.bind): | 180 | case MAXWELL3D_REG_INDEX(load_mme.start_address): |
| 181 | return ProcessMacroBind(argument); | 181 | return ProcessMacroBind(argument); |
| 182 | case MAXWELL3D_REG_INDEX(firmware[4]): | 182 | case MAXWELL3D_REG_INDEX(falcon[4]): |
| 183 | return ProcessFirmwareCall4(); | 183 | return ProcessFirmwareCall4(); |
| 184 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data): | 184 | case MAXWELL3D_REG_INDEX(const_buffer.buffer): |
| 185 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1: | 185 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1: |
| 186 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2: | 186 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2: |
| 187 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3: | 187 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3: |
| 188 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4: | 188 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4: |
| 189 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5: | 189 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5: |
| 190 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6: | 190 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6: |
| 191 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7: | 191 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7: |
| 192 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8: | 192 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8: |
| 193 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9: | 193 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9: |
| 194 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10: | 194 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10: |
| 195 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11: | 195 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11: |
| 196 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12: | 196 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12: |
| 197 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13: | 197 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13: |
| 198 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14: | 198 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14: |
| 199 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15: | 199 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15: |
| 200 | return ProcessCBData(argument); | 200 | return ProcessCBData(argument); |
| 201 | case MAXWELL3D_REG_INDEX(cb_bind[0]): | 201 | case MAXWELL3D_REG_INDEX(bind_groups[0].raw_config): |
| 202 | return ProcessCBBind(0); | 202 | return ProcessCBBind(0); |
| 203 | case MAXWELL3D_REG_INDEX(cb_bind[1]): | 203 | case MAXWELL3D_REG_INDEX(bind_groups[1].raw_config): |
| 204 | return ProcessCBBind(1); | 204 | return ProcessCBBind(1); |
| 205 | case MAXWELL3D_REG_INDEX(cb_bind[2]): | 205 | case MAXWELL3D_REG_INDEX(bind_groups[2].raw_config): |
| 206 | return ProcessCBBind(2); | 206 | return ProcessCBBind(2); |
| 207 | case MAXWELL3D_REG_INDEX(cb_bind[3]): | 207 | case MAXWELL3D_REG_INDEX(bind_groups[3].raw_config): |
| 208 | return ProcessCBBind(3); | 208 | return ProcessCBBind(3); |
| 209 | case MAXWELL3D_REG_INDEX(cb_bind[4]): | 209 | case MAXWELL3D_REG_INDEX(bind_groups[4].raw_config): |
| 210 | return ProcessCBBind(4); | 210 | return ProcessCBBind(4); |
| 211 | case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): | 211 | case MAXWELL3D_REG_INDEX(draw.end): |
| 212 | return DrawArrays(); | 212 | return DrawArrays(); |
| 213 | case MAXWELL3D_REG_INDEX(small_index): | 213 | case MAXWELL3D_REG_INDEX(index_buffer32_first): |
| 214 | regs.index_array.count = regs.small_index.count; | 214 | regs.index_buffer.count = regs.index_buffer32_first.count; |
| 215 | regs.index_array.first = regs.small_index.first; | 215 | regs.index_buffer.first = regs.index_buffer32_first.first; |
| 216 | dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; | 216 | dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; |
| 217 | return DrawArrays(); | 217 | return DrawArrays(); |
| 218 | case MAXWELL3D_REG_INDEX(small_index_2): | 218 | case MAXWELL3D_REG_INDEX(index_buffer16_first): |
| 219 | regs.index_array.count = regs.small_index_2.count; | 219 | regs.index_buffer.count = regs.index_buffer16_first.count; |
| 220 | regs.index_array.first = regs.small_index_2.first; | 220 | regs.index_buffer.first = regs.index_buffer16_first.first; |
| 221 | dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; | ||
| 222 | return DrawArrays(); | ||
| 223 | case MAXWELL3D_REG_INDEX(index_buffer8_first): | ||
| 224 | regs.index_buffer.count = regs.index_buffer8_first.count; | ||
| 225 | regs.index_buffer.first = regs.index_buffer8_first.first; | ||
| 221 | dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; | 226 | dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; |
| 222 | // a macro calls this one over and over, should it increase instancing? | 227 | // a macro calls this one over and over, should it increase instancing? |
| 223 | // Used by Hades and likely other Vulkan games. | 228 | // Used by Hades and likely other Vulkan games. |
| @@ -225,28 +230,24 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume | |||
| 225 | case MAXWELL3D_REG_INDEX(topology_override): | 230 | case MAXWELL3D_REG_INDEX(topology_override): |
| 226 | use_topology_override = true; | 231 | use_topology_override = true; |
| 227 | return; | 232 | return; |
| 228 | case MAXWELL3D_REG_INDEX(clear_buffers): | 233 | case MAXWELL3D_REG_INDEX(clear_surface): |
| 229 | return ProcessClearBuffers(); | 234 | return ProcessClearBuffers(); |
| 230 | case MAXWELL3D_REG_INDEX(query.query_get): | 235 | case MAXWELL3D_REG_INDEX(report_semaphore.query): |
| 231 | return ProcessQueryGet(); | 236 | return ProcessQueryGet(); |
| 232 | case MAXWELL3D_REG_INDEX(condition.mode): | 237 | case MAXWELL3D_REG_INDEX(render_enable.mode): |
| 233 | return ProcessQueryCondition(); | 238 | return ProcessQueryCondition(); |
| 234 | case MAXWELL3D_REG_INDEX(counter_reset): | 239 | case MAXWELL3D_REG_INDEX(clear_report_value): |
| 235 | return ProcessCounterReset(); | 240 | return ProcessCounterReset(); |
| 236 | case MAXWELL3D_REG_INDEX(sync_info): | 241 | case MAXWELL3D_REG_INDEX(sync_info): |
| 237 | return ProcessSyncPoint(); | 242 | return ProcessSyncPoint(); |
| 238 | case MAXWELL3D_REG_INDEX(exec_upload): | 243 | case MAXWELL3D_REG_INDEX(launch_dma): |
| 239 | return upload_state.ProcessExec(regs.exec_upload.linear != 0); | 244 | return upload_state.ProcessExec(regs.launch_dma.memory_layout.Value() == |
| 240 | case MAXWELL3D_REG_INDEX(data_upload): | 245 | Regs::LaunchDMA::Layout::Pitch); |
| 246 | case MAXWELL3D_REG_INDEX(inline_data): | ||
| 241 | upload_state.ProcessData(argument, is_last_call); | 247 | upload_state.ProcessData(argument, is_last_call); |
| 242 | return; | 248 | return; |
| 243 | case MAXWELL3D_REG_INDEX(fragment_barrier): | 249 | case MAXWELL3D_REG_INDEX(fragment_barrier): |
| 244 | return rasterizer->FragmentBarrier(); | 250 | return rasterizer->FragmentBarrier(); |
| 245 | case MAXWELL3D_REG_INDEX(invalidate_texture_data_cache): | ||
| 246 | rasterizer->InvalidateGPUCache(); | ||
| 247 | return rasterizer->WaitForIdle(); | ||
| 248 | case MAXWELL3D_REG_INDEX(tiled_cache_barrier): | ||
| 249 | return rasterizer->TiledCacheBarrier(); | ||
| 250 | } | 251 | } |
| 251 | } | 252 | } |
| 252 | 253 | ||
| @@ -296,25 +297,25 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, | |||
| 296 | return; | 297 | return; |
| 297 | } | 298 | } |
| 298 | switch (method) { | 299 | switch (method) { |
| 299 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data): | 300 | case MAXWELL3D_REG_INDEX(const_buffer.buffer): |
| 300 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1: | 301 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1: |
| 301 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2: | 302 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2: |
| 302 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3: | 303 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3: |
| 303 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4: | 304 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4: |
| 304 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5: | 305 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5: |
| 305 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6: | 306 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6: |
| 306 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7: | 307 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7: |
| 307 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8: | 308 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8: |
| 308 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9: | 309 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9: |
| 309 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10: | 310 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10: |
| 310 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11: | 311 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11: |
| 311 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12: | 312 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12: |
| 312 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13: | 313 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13: |
| 313 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14: | 314 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14: |
| 314 | case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15: | 315 | case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15: |
| 315 | ProcessCBMultiData(base_start, amount); | 316 | ProcessCBMultiData(base_start, amount); |
| 316 | break; | 317 | break; |
| 317 | case MAXWELL3D_REG_INDEX(data_upload): | 318 | case MAXWELL3D_REG_INDEX(inline_data): |
| 318 | upload_state.ProcessData(base_start, static_cast<size_t>(amount)); | 319 | upload_state.ProcessData(base_start, static_cast<size_t>(amount)); |
| 319 | return; | 320 | return; |
| 320 | default: | 321 | default: |
| @@ -353,14 +354,15 @@ void Maxwell3D::CallMethodFromMME(u32 method, u32 method_argument) { | |||
| 353 | if (mme_inline[method]) { | 354 | if (mme_inline[method]) { |
| 354 | regs.reg_array[method] = method_argument; | 355 | regs.reg_array[method] = method_argument; |
| 355 | if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) || | 356 | if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) || |
| 356 | method == MAXWELL3D_REG_INDEX(index_array.count)) { | 357 | method == MAXWELL3D_REG_INDEX(index_buffer.count)) { |
| 357 | const MMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count) | 358 | const MMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count) |
| 358 | ? MMEDrawMode::Array | 359 | ? MMEDrawMode::Array |
| 359 | : MMEDrawMode::Indexed; | 360 | : MMEDrawMode::Indexed; |
| 360 | StepInstance(expected_mode, method_argument); | 361 | StepInstance(expected_mode, method_argument); |
| 361 | } else if (method == MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)) { | 362 | } else if (method == MAXWELL3D_REG_INDEX(draw.begin)) { |
| 362 | mme_draw.instance_mode = | 363 | mme_draw.instance_mode = |
| 363 | (regs.draw.instance_next != 0) || (regs.draw.instance_cont != 0); | 364 | (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || |
| 365 | (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged); | ||
| 364 | mme_draw.gl_begin_consume = true; | 366 | mme_draw.gl_begin_consume = true; |
| 365 | } else { | 367 | } else { |
| 366 | mme_draw.gl_end_count++; | 368 | mme_draw.gl_end_count++; |
| @@ -405,11 +407,12 @@ void Maxwell3D::ProcessTopologyOverride() { | |||
| 405 | void Maxwell3D::FlushMMEInlineDraw() { | 407 | void Maxwell3D::FlushMMEInlineDraw() { |
| 406 | LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), | 408 | LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), |
| 407 | regs.vertex_buffer.count); | 409 | regs.vertex_buffer.count); |
| 408 | ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); | 410 | ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?"); |
| 409 | ASSERT(mme_draw.instance_count == mme_draw.gl_end_count); | 411 | ASSERT(mme_draw.instance_count == mme_draw.gl_end_count); |
| 410 | 412 | ||
| 411 | // Both instance configuration registers can not be set at the same time. | 413 | // Both instance configuration registers can not be set at the same time. |
| 412 | ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, | 414 | ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First || |
| 415 | regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged, | ||
| 413 | "Illegal combination of instancing parameters"); | 416 | "Illegal combination of instancing parameters"); |
| 414 | 417 | ||
| 415 | ProcessTopologyOverride(); | 418 | ProcessTopologyOverride(); |
| @@ -424,7 +427,7 @@ void Maxwell3D::FlushMMEInlineDraw() { | |||
| 424 | // it's possible that it is incorrect and that there is some other register used to specify the | 427 | // it's possible that it is incorrect and that there is some other register used to specify the |
| 425 | // drawing mode. | 428 | // drawing mode. |
| 426 | if (is_indexed) { | 429 | if (is_indexed) { |
| 427 | regs.index_array.count = 0; | 430 | regs.index_buffer.count = 0; |
| 428 | } else { | 431 | } else { |
| 429 | regs.vertex_buffer.count = 0; | 432 | regs.vertex_buffer.count = 0; |
| 430 | } | 433 | } |
| @@ -437,11 +440,11 @@ void Maxwell3D::FlushMMEInlineDraw() { | |||
| 437 | } | 440 | } |
| 438 | 441 | ||
| 439 | void Maxwell3D::ProcessMacroUpload(u32 data) { | 442 | void Maxwell3D::ProcessMacroUpload(u32 data) { |
| 440 | macro_engine->AddCode(regs.macros.upload_address++, data); | 443 | macro_engine->AddCode(regs.load_mme.instruction_ptr++, data); |
| 441 | } | 444 | } |
| 442 | 445 | ||
| 443 | void Maxwell3D::ProcessMacroBind(u32 data) { | 446 | void Maxwell3D::ProcessMacroBind(u32 data) { |
| 444 | macro_positions[regs.macros.entry++] = data; | 447 | macro_positions[regs.load_mme.start_address_ptr++] = data; |
| 445 | } | 448 | } |
| 446 | 449 | ||
| 447 | void Maxwell3D::ProcessFirmwareCall4() { | 450 | void Maxwell3D::ProcessFirmwareCall4() { |
| @@ -449,11 +452,11 @@ void Maxwell3D::ProcessFirmwareCall4() { | |||
| 449 | 452 | ||
| 450 | // Firmware call 4 is a blob that changes some registers depending on its parameters. | 453 | // Firmware call 4 is a blob that changes some registers depending on its parameters. |
| 451 | // These registers don't affect emulation and so are stubbed by setting 0xd00 to 1. | 454 | // These registers don't affect emulation and so are stubbed by setting 0xd00 to 1. |
| 452 | regs.reg_array[0xd00] = 1; | 455 | regs.shadow_scratch[0] = 1; |
| 453 | } | 456 | } |
| 454 | 457 | ||
| 455 | void Maxwell3D::StampQueryResult(u64 payload, bool long_query) { | 458 | void Maxwell3D::StampQueryResult(u64 payload, bool long_query) { |
| 456 | const GPUVAddr sequence_address{regs.query.QueryAddress()}; | 459 | const GPUVAddr sequence_address{regs.report_semaphore.Address()}; |
| 457 | if (long_query) { | 460 | if (long_query) { |
| 458 | memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks()); | 461 | memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks()); |
| 459 | memory_manager.Write<u64>(sequence_address, payload); | 462 | memory_manager.Write<u64>(sequence_address, payload); |
| @@ -464,15 +467,17 @@ void Maxwell3D::StampQueryResult(u64 payload, bool long_query) { | |||
| 464 | 467 | ||
| 465 | void Maxwell3D::ProcessQueryGet() { | 468 | void Maxwell3D::ProcessQueryGet() { |
| 466 | // TODO(Subv): Support the other query units. | 469 | // TODO(Subv): Support the other query units. |
| 467 | if (regs.query.query_get.unit != Regs::QueryUnit::Crop) { | 470 | if (regs.report_semaphore.query.location != Regs::ReportSemaphore::Location::All) { |
| 468 | LOG_DEBUG(HW_GPU, "Units other than CROP are unimplemented"); | 471 | LOG_DEBUG(HW_GPU, "Locations other than ALL are unimplemented"); |
| 469 | } | 472 | } |
| 470 | 473 | ||
| 471 | switch (regs.query.query_get.operation) { | 474 | switch (regs.report_semaphore.query.operation) { |
| 472 | case Regs::QueryOperation::Release: | 475 | case Regs::ReportSemaphore::Operation::Release: |
| 473 | if (regs.query.query_get.fence == 1 || regs.query.query_get.short_query != 0) { | 476 | if (regs.report_semaphore.query.release == |
| 474 | const GPUVAddr sequence_address{regs.query.QueryAddress()}; | 477 | Regs::ReportSemaphore::Release::AfterAllPreceedingWrites || |
| 475 | const u32 payload = regs.query.query_sequence; | 478 | regs.report_semaphore.query.short_query != 0) { |
| 479 | const GPUVAddr sequence_address{regs.report_semaphore.Address()}; | ||
| 480 | const u32 payload = regs.report_semaphore.payload; | ||
| 476 | std::function<void()> operation([this, sequence_address, payload] { | 481 | std::function<void()> operation([this, sequence_address, payload] { |
| 477 | memory_manager.Write<u32>(sequence_address, payload); | 482 | memory_manager.Write<u32>(sequence_address, payload); |
| 478 | }); | 483 | }); |
| @@ -482,8 +487,8 @@ void Maxwell3D::ProcessQueryGet() { | |||
| 482 | u64_le value; | 487 | u64_le value; |
| 483 | u64_le timestamp; | 488 | u64_le timestamp; |
| 484 | }; | 489 | }; |
| 485 | const GPUVAddr sequence_address{regs.query.QueryAddress()}; | 490 | const GPUVAddr sequence_address{regs.report_semaphore.Address()}; |
| 486 | const u32 payload = regs.query.query_sequence; | 491 | const u32 payload = regs.report_semaphore.payload; |
| 487 | std::function<void()> operation([this, sequence_address, payload] { | 492 | std::function<void()> operation([this, sequence_address, payload] { |
| 488 | memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks()); | 493 | memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks()); |
| 489 | memory_manager.Write<u64>(sequence_address, payload); | 494 | memory_manager.Write<u64>(sequence_address, payload); |
| @@ -491,19 +496,19 @@ void Maxwell3D::ProcessQueryGet() { | |||
| 491 | rasterizer->SyncOperation(std::move(operation)); | 496 | rasterizer->SyncOperation(std::move(operation)); |
| 492 | } | 497 | } |
| 493 | break; | 498 | break; |
| 494 | case Regs::QueryOperation::Acquire: | 499 | case Regs::ReportSemaphore::Operation::Acquire: |
| 495 | // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that | 500 | // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that |
| 496 | // matches the current payload. | 501 | // matches the current payload. |
| 497 | UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE"); | 502 | UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE"); |
| 498 | break; | 503 | break; |
| 499 | case Regs::QueryOperation::Counter: | 504 | case Regs::ReportSemaphore::Operation::ReportOnly: |
| 500 | if (const std::optional<u64> result = GetQueryResult()) { | 505 | if (const std::optional<u64> result = GetQueryResult()) { |
| 501 | // If the query returns an empty optional it means it's cached and deferred. | 506 | // If the query returns an empty optional it means it's cached and deferred. |
| 502 | // In this case we have a non-empty result, so we stamp it immediately. | 507 | // In this case we have a non-empty result, so we stamp it immediately. |
| 503 | StampQueryResult(*result, regs.query.query_get.short_query == 0); | 508 | StampQueryResult(*result, regs.report_semaphore.query.short_query == 0); |
| 504 | } | 509 | } |
| 505 | break; | 510 | break; |
| 506 | case Regs::QueryOperation::Trap: | 511 | case Regs::ReportSemaphore::Operation::Trap: |
| 507 | UNIMPLEMENTED_MSG("Unimplemented query operation TRAP"); | 512 | UNIMPLEMENTED_MSG("Unimplemented query operation TRAP"); |
| 508 | break; | 513 | break; |
| 509 | default: | 514 | default: |
| @@ -513,31 +518,31 @@ void Maxwell3D::ProcessQueryGet() { | |||
| 513 | } | 518 | } |
| 514 | 519 | ||
| 515 | void Maxwell3D::ProcessQueryCondition() { | 520 | void Maxwell3D::ProcessQueryCondition() { |
| 516 | const GPUVAddr condition_address{regs.condition.Address()}; | 521 | const GPUVAddr condition_address{regs.render_enable.Address()}; |
| 517 | switch (regs.condition.mode) { | 522 | switch (regs.render_enable.mode) { |
| 518 | case Regs::ConditionMode::Always: { | 523 | case Regs::RenderEnable::Mode::True: { |
| 519 | execute_on = true; | 524 | execute_on = true; |
| 520 | break; | 525 | break; |
| 521 | } | 526 | } |
| 522 | case Regs::ConditionMode::Never: { | 527 | case Regs::RenderEnable::Mode::False: { |
| 523 | execute_on = false; | 528 | execute_on = false; |
| 524 | break; | 529 | break; |
| 525 | } | 530 | } |
| 526 | case Regs::ConditionMode::ResNonZero: { | 531 | case Regs::RenderEnable::Mode::Conditional: { |
| 527 | Regs::QueryCompare cmp; | 532 | Regs::ReportSemaphore::Compare cmp; |
| 528 | memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); | 533 | memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); |
| 529 | execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U; | 534 | execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U; |
| 530 | break; | 535 | break; |
| 531 | } | 536 | } |
| 532 | case Regs::ConditionMode::Equal: { | 537 | case Regs::RenderEnable::Mode::IfEqual: { |
| 533 | Regs::QueryCompare cmp; | 538 | Regs::ReportSemaphore::Compare cmp; |
| 534 | memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); | 539 | memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); |
| 535 | execute_on = | 540 | execute_on = |
| 536 | cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode; | 541 | cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode; |
| 537 | break; | 542 | break; |
| 538 | } | 543 | } |
| 539 | case Regs::ConditionMode::NotEqual: { | 544 | case Regs::RenderEnable::Mode::IfNotEqual: { |
| 540 | Regs::QueryCompare cmp; | 545 | Regs::ReportSemaphore::Compare cmp; |
| 541 | memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); | 546 | memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); |
| 542 | execute_on = | 547 | execute_on = |
| 543 | cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode; | 548 | cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode; |
| @@ -552,21 +557,21 @@ void Maxwell3D::ProcessQueryCondition() { | |||
| 552 | } | 557 | } |
| 553 | 558 | ||
| 554 | void Maxwell3D::ProcessCounterReset() { | 559 | void Maxwell3D::ProcessCounterReset() { |
| 555 | switch (regs.counter_reset) { | 560 | switch (regs.clear_report_value) { |
| 556 | case Regs::CounterReset::SampleCnt: | 561 | case Regs::ClearReport::ZPassPixelCount: |
| 557 | rasterizer->ResetCounter(QueryType::SamplesPassed); | 562 | rasterizer->ResetCounter(QueryType::SamplesPassed); |
| 558 | break; | 563 | break; |
| 559 | default: | 564 | default: |
| 560 | LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", regs.counter_reset); | 565 | LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", regs.clear_report_value); |
| 561 | break; | 566 | break; |
| 562 | } | 567 | } |
| 563 | } | 568 | } |
| 564 | 569 | ||
| 565 | void Maxwell3D::ProcessSyncPoint() { | 570 | void Maxwell3D::ProcessSyncPoint() { |
| 566 | const u32 sync_point = regs.sync_info.sync_point.Value(); | 571 | const u32 sync_point = regs.sync_info.sync_point.Value(); |
| 567 | const u32 increment = regs.sync_info.increment.Value(); | 572 | const auto condition = regs.sync_info.condition.Value(); |
| 568 | [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value(); | 573 | [[maybe_unused]] const u32 cache_flush = regs.sync_info.clean_l2.Value(); |
| 569 | if (increment) { | 574 | if (condition == Regs::SyncInfo::Condition::RopWritesDone) { |
| 570 | rasterizer->SignalSyncPoint(sync_point); | 575 | rasterizer->SignalSyncPoint(sync_point); |
| 571 | } | 576 | } |
| 572 | } | 577 | } |
| @@ -574,23 +579,24 @@ void Maxwell3D::ProcessSyncPoint() { | |||
| 574 | void Maxwell3D::DrawArrays() { | 579 | void Maxwell3D::DrawArrays() { |
| 575 | LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), | 580 | LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), |
| 576 | regs.vertex_buffer.count); | 581 | regs.vertex_buffer.count); |
| 577 | ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); | 582 | ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?"); |
| 578 | 583 | ||
| 579 | // Both instance configuration registers can not be set at the same time. | 584 | // Both instance configuration registers can not be set at the same time. |
| 580 | ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, | 585 | ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First || |
| 586 | regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged, | ||
| 581 | "Illegal combination of instancing parameters"); | 587 | "Illegal combination of instancing parameters"); |
| 582 | 588 | ||
| 583 | ProcessTopologyOverride(); | 589 | ProcessTopologyOverride(); |
| 584 | 590 | ||
| 585 | if (regs.draw.instance_next) { | 591 | if (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) { |
| 586 | // Increment the current instance *before* drawing. | 592 | // Increment the current instance *before* drawing. |
| 587 | state.current_instance += 1; | 593 | state.current_instance++; |
| 588 | } else if (!regs.draw.instance_cont) { | 594 | } else if (regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged) { |
| 589 | // Reset the current instance to 0. | 595 | // Reset the current instance to 0. |
| 590 | state.current_instance = 0; | 596 | state.current_instance = 0; |
| 591 | } | 597 | } |
| 592 | 598 | ||
| 593 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; | 599 | const bool is_indexed{regs.index_buffer.count && !regs.vertex_buffer.count}; |
| 594 | if (ShouldExecute()) { | 600 | if (ShouldExecute()) { |
| 595 | rasterizer->Draw(is_indexed, false); | 601 | rasterizer->Draw(is_indexed, false); |
| 596 | } | 602 | } |
| @@ -600,60 +606,60 @@ void Maxwell3D::DrawArrays() { | |||
| 600 | // it's possible that it is incorrect and that there is some other register used to specify the | 606 | // it's possible that it is incorrect and that there is some other register used to specify the |
| 601 | // drawing mode. | 607 | // drawing mode. |
| 602 | if (is_indexed) { | 608 | if (is_indexed) { |
| 603 | regs.index_array.count = 0; | 609 | regs.index_buffer.count = 0; |
| 604 | } else { | 610 | } else { |
| 605 | regs.vertex_buffer.count = 0; | 611 | regs.vertex_buffer.count = 0; |
| 606 | } | 612 | } |
| 607 | } | 613 | } |
| 608 | 614 | ||
| 609 | std::optional<u64> Maxwell3D::GetQueryResult() { | 615 | std::optional<u64> Maxwell3D::GetQueryResult() { |
| 610 | switch (regs.query.query_get.select) { | 616 | switch (regs.report_semaphore.query.report) { |
| 611 | case Regs::QuerySelect::Payload: | 617 | case Regs::ReportSemaphore::Report::Payload: |
| 612 | return regs.query.query_sequence; | 618 | return regs.report_semaphore.payload; |
| 613 | case Regs::QuerySelect::SamplesPassed: | 619 | case Regs::ReportSemaphore::Report::ZPassPixelCount64: |
| 614 | // Deferred. | 620 | // Deferred. |
| 615 | rasterizer->Query(regs.query.QueryAddress(), QueryType::SamplesPassed, | 621 | rasterizer->Query(regs.report_semaphore.Address(), QueryType::SamplesPassed, |
| 616 | system.GPU().GetTicks()); | 622 | system.GPU().GetTicks()); |
| 617 | return std::nullopt; | 623 | return std::nullopt; |
| 618 | default: | 624 | default: |
| 619 | LOG_DEBUG(HW_GPU, "Unimplemented query select type {}", | 625 | LOG_DEBUG(HW_GPU, "Unimplemented query report type {}", |
| 620 | regs.query.query_get.select.Value()); | 626 | regs.report_semaphore.query.report.Value()); |
| 621 | return 1; | 627 | return 1; |
| 622 | } | 628 | } |
| 623 | } | 629 | } |
| 624 | 630 | ||
| 625 | void Maxwell3D::ProcessCBBind(size_t stage_index) { | 631 | void Maxwell3D::ProcessCBBind(size_t stage_index) { |
| 626 | // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. | 632 | // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. |
| 627 | const auto& bind_data = regs.cb_bind[stage_index]; | 633 | const auto& bind_data = regs.bind_groups[stage_index]; |
| 628 | auto& buffer = state.shader_stages[stage_index].const_buffers[bind_data.index]; | 634 | auto& buffer = state.shader_stages[stage_index].const_buffers[bind_data.shader_slot]; |
| 629 | buffer.enabled = bind_data.valid.Value() != 0; | 635 | buffer.enabled = bind_data.valid.Value() != 0; |
| 630 | buffer.address = regs.const_buffer.BufferAddress(); | 636 | buffer.address = regs.const_buffer.Address(); |
| 631 | buffer.size = regs.const_buffer.cb_size; | 637 | buffer.size = regs.const_buffer.size; |
| 632 | 638 | ||
| 633 | const bool is_enabled = bind_data.valid.Value() != 0; | 639 | const bool is_enabled = bind_data.valid.Value() != 0; |
| 634 | if (!is_enabled) { | 640 | if (!is_enabled) { |
| 635 | rasterizer->DisableGraphicsUniformBuffer(stage_index, bind_data.index); | 641 | rasterizer->DisableGraphicsUniformBuffer(stage_index, bind_data.shader_slot); |
| 636 | return; | 642 | return; |
| 637 | } | 643 | } |
| 638 | const GPUVAddr gpu_addr = regs.const_buffer.BufferAddress(); | 644 | const GPUVAddr gpu_addr = regs.const_buffer.Address(); |
| 639 | const u32 size = regs.const_buffer.cb_size; | 645 | const u32 size = regs.const_buffer.size; |
| 640 | rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.index, gpu_addr, size); | 646 | rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.shader_slot, gpu_addr, size); |
| 641 | } | 647 | } |
| 642 | 648 | ||
| 643 | void Maxwell3D::ProcessCBMultiData(const u32* start_base, u32 amount) { | 649 | void Maxwell3D::ProcessCBMultiData(const u32* start_base, u32 amount) { |
| 644 | // Write the input value to the current const buffer at the current position. | 650 | // Write the input value to the current const buffer at the current position. |
| 645 | const GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); | 651 | const GPUVAddr buffer_address = regs.const_buffer.Address(); |
| 646 | ASSERT(buffer_address != 0); | 652 | ASSERT(buffer_address != 0); |
| 647 | 653 | ||
| 648 | // Don't allow writing past the end of the buffer. | 654 | // Don't allow writing past the end of the buffer. |
| 649 | ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size); | 655 | ASSERT(regs.const_buffer.offset <= regs.const_buffer.size); |
| 650 | 656 | ||
| 651 | const GPUVAddr address{buffer_address + regs.const_buffer.cb_pos}; | 657 | const GPUVAddr address{buffer_address + regs.const_buffer.offset}; |
| 652 | const size_t copy_size = amount * sizeof(u32); | 658 | const size_t copy_size = amount * sizeof(u32); |
| 653 | memory_manager.WriteBlock(address, start_base, copy_size); | 659 | memory_manager.WriteBlock(address, start_base, copy_size); |
| 654 | 660 | ||
| 655 | // Increment the current buffer position. | 661 | // Increment the current buffer position. |
| 656 | regs.const_buffer.cb_pos += static_cast<u32>(copy_size); | 662 | regs.const_buffer.offset += static_cast<u32>(copy_size); |
| 657 | } | 663 | } |
| 658 | 664 | ||
| 659 | void Maxwell3D::ProcessCBData(u32 value) { | 665 | void Maxwell3D::ProcessCBData(u32 value) { |
| @@ -661,7 +667,8 @@ void Maxwell3D::ProcessCBData(u32 value) { | |||
| 661 | } | 667 | } |
| 662 | 668 | ||
| 663 | Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { | 669 | Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { |
| 664 | const GPUVAddr tic_address_gpu{regs.tic.Address() + tic_index * sizeof(Texture::TICEntry)}; | 670 | const GPUVAddr tic_address_gpu{regs.tex_header.Address() + |
| 671 | tic_index * sizeof(Texture::TICEntry)}; | ||
| 665 | 672 | ||
| 666 | Texture::TICEntry tic_entry; | 673 | Texture::TICEntry tic_entry; |
| 667 | memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry)); | 674 | memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry)); |
| @@ -670,7 +677,8 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { | |||
| 670 | } | 677 | } |
| 671 | 678 | ||
| 672 | Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { | 679 | Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { |
| 673 | const GPUVAddr tsc_address_gpu{regs.tsc.Address() + tsc_index * sizeof(Texture::TSCEntry)}; | 680 | const GPUVAddr tsc_address_gpu{regs.tex_sampler.Address() + |
| 681 | tsc_index * sizeof(Texture::TSCEntry)}; | ||
| 674 | 682 | ||
| 675 | Texture::TSCEntry tsc_entry; | 683 | Texture::TSCEntry tsc_entry; |
| 676 | memory_manager.ReadBlockUnsafe(tsc_address_gpu, &tsc_entry, sizeof(Texture::TSCEntry)); | 684 | memory_manager.ReadBlockUnsafe(tsc_address_gpu, &tsc_entry, sizeof(Texture::TSCEntry)); |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 5f9eb208c..efe1073b0 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -39,12 +39,15 @@ namespace Tegra::Engines { | |||
| 39 | 39 | ||
| 40 | /** | 40 | /** |
| 41 | * This Engine is known as GF100_3D. Documentation can be found in: | 41 | * This Engine is known as GF100_3D. Documentation can be found in: |
| 42 | * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/3d/clb197.h | ||
| 42 | * https://github.com/envytools/envytools/blob/master/rnndb/graph/gf100_3d.xml | 43 | * https://github.com/envytools/envytools/blob/master/rnndb/graph/gf100_3d.xml |
| 43 | * https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h | 44 | * https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h |
| 45 | * | ||
| 46 | * Note: nVidia have confirmed that their open docs have had parts redacted, so this list is | ||
| 47 | * currently incomplete, and the gaps are still worth exploring. | ||
| 44 | */ | 48 | */ |
| 45 | 49 | ||
| 46 | #define MAXWELL3D_REG_INDEX(field_name) \ | 50 | #define MAXWELL3D_REG_INDEX(field_name) (offsetof(Maxwell3D::Regs, field_name) / sizeof(u32)) |
| 47 | (offsetof(Tegra::Engines::Maxwell3D::Regs, field_name) / sizeof(u32)) | ||
| 48 | 51 | ||
| 49 | class Maxwell3D final : public EngineInterface { | 52 | class Maxwell3D final : public EngineInterface { |
| 50 | public: | 53 | public: |
| @@ -55,7 +58,6 @@ public: | |||
| 55 | void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); | 58 | void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); |
| 56 | 59 | ||
| 57 | /// Register structure of the Maxwell3D engine. | 60 | /// Register structure of the Maxwell3D engine. |
| 58 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. | ||
| 59 | struct Regs { | 61 | struct Regs { |
| 60 | static constexpr std::size_t NUM_REGS = 0xE00; | 62 | static constexpr std::size_t NUM_REGS = 0xE00; |
| 61 | 63 | ||
| @@ -74,90 +76,515 @@ public: | |||
| 74 | static constexpr std::size_t MaxConstBuffers = 18; | 76 | static constexpr std::size_t MaxConstBuffers = 18; |
| 75 | static constexpr std::size_t MaxConstBufferSize = 0x10000; | 77 | static constexpr std::size_t MaxConstBufferSize = 0x10000; |
| 76 | 78 | ||
| 77 | enum class QueryOperation : u32 { | 79 | struct ID { |
| 78 | Release = 0, | 80 | union { |
| 79 | Acquire = 1, | 81 | BitField<0, 16, u32> cls; |
| 80 | Counter = 2, | 82 | BitField<16, 5, u32> engine; |
| 81 | Trap = 3, | 83 | }; |
| 82 | }; | 84 | }; |
| 83 | 85 | ||
| 84 | enum class QueryUnit : u32 { | 86 | struct LoadMME { |
| 85 | VFetch = 1, | 87 | u32 instruction_ptr; |
| 86 | VP = 2, | 88 | u32 instruction; |
| 87 | Rast = 4, | 89 | u32 start_address_ptr; |
| 88 | StrmOut = 5, | 90 | u32 start_address; |
| 89 | GP = 6, | ||
| 90 | ZCull = 7, | ||
| 91 | Prop = 10, | ||
| 92 | Crop = 15, | ||
| 93 | }; | 91 | }; |
| 94 | 92 | ||
| 95 | enum class QuerySelect : u32 { | 93 | struct Notify { |
| 96 | Payload = 0, | 94 | u32 address_high; |
| 97 | TimeElapsed = 2, | 95 | u32 address_low; |
| 98 | TransformFeedbackPrimitivesGenerated = 11, | 96 | u32 type; |
| 99 | PrimitivesGenerated = 18, | 97 | |
| 100 | SamplesPassed = 21, | 98 | GPUVAddr Address() const { |
| 101 | TransformFeedbackUnknown = 26, | 99 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 100 | address_low); | ||
| 101 | } | ||
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | struct QueryCompare { | 104 | struct PeerSemaphore { |
| 105 | u32 initial_sequence; | 105 | u32 address_high; |
| 106 | u32 initial_mode; | 106 | u32 address_low; |
| 107 | u32 unknown1; | 107 | |
| 108 | u32 unknown2; | 108 | GPUVAddr Address() const { |
| 109 | u32 current_sequence; | 109 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 110 | u32 current_mode; | 110 | address_low); |
| 111 | } | ||
| 111 | }; | 112 | }; |
| 112 | 113 | ||
| 113 | enum class QuerySyncCondition : u32 { | 114 | struct GlobalRender { |
| 114 | NotEqual = 0, | 115 | enum class Mode : u32 { |
| 115 | GreaterThan = 1, | 116 | False = 0, |
| 117 | True = 1, | ||
| 118 | Conditional = 2, | ||
| 119 | IfEqual = 3, | ||
| 120 | IfNotEqual = 4, | ||
| 121 | }; | ||
| 122 | u32 offset_high; | ||
| 123 | u32 offset_low; | ||
| 124 | Mode mode; | ||
| 125 | |||
| 126 | GPUVAddr Address() const { | ||
| 127 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(offset_high) << 32) | | ||
| 128 | offset_low); | ||
| 129 | } | ||
| 116 | }; | 130 | }; |
| 117 | 131 | ||
| 118 | enum class ConditionMode : u32 { | 132 | enum class ReductionOp : u32 { |
| 119 | Never = 0, | 133 | RedAdd = 0, |
| 120 | Always = 1, | 134 | RedMin = 1, |
| 121 | ResNonZero = 2, | 135 | RedMax = 2, |
| 122 | Equal = 3, | 136 | RedInc = 3, |
| 123 | NotEqual = 4, | 137 | RedDec = 4, |
| 138 | RedAnd = 5, | ||
| 139 | RedOr = 6, | ||
| 140 | RedXor = 7, | ||
| 124 | }; | 141 | }; |
| 125 | 142 | ||
| 126 | enum class ShaderProgram : u32 { | 143 | struct LaunchDMA { |
| 127 | VertexA = 0, | 144 | enum class Layout : u32 { |
| 128 | VertexB = 1, | 145 | Blocklinear = 0, |
| 129 | TesselationControl = 2, | 146 | Pitch = 1, |
| 130 | TesselationEval = 3, | 147 | }; |
| 131 | Geometry = 4, | 148 | |
| 132 | Fragment = 5, | 149 | enum class CompletionType : u32 { |
| 150 | FlushDisable = 0, | ||
| 151 | FlushOnly = 1, | ||
| 152 | Release = 2, | ||
| 153 | }; | ||
| 154 | |||
| 155 | union { | ||
| 156 | BitField<0, 1, Layout> memory_layout; | ||
| 157 | BitField<4, 2, CompletionType> completion_type; | ||
| 158 | BitField<8, 2, u32> interrupt_type; | ||
| 159 | BitField<12, 1, u32> sem_size; | ||
| 160 | BitField<1, 1, u32> reduction_enable; | ||
| 161 | BitField<13, 3, ReductionOp> reduction_op; | ||
| 162 | BitField<2, 2, u32> reduction_format; | ||
| 163 | BitField<6, 1, u32> sysmembar_disable; | ||
| 164 | }; | ||
| 165 | }; | ||
| 166 | |||
| 167 | struct I2M { | ||
| 168 | u32 address_high; | ||
| 169 | u32 address_low; | ||
| 170 | u32 payload; | ||
| 171 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 172 | u32 nop0; | ||
| 173 | u32 nop1; | ||
| 174 | u32 nop2; | ||
| 175 | u32 nop3; | ||
| 176 | }; | ||
| 177 | |||
| 178 | struct OpportunisticEarlyZ { | ||
| 179 | BitField<0, 5, u32> threshold; | ||
| 180 | |||
| 181 | u32 Threshold() const { | ||
| 182 | switch (threshold) { | ||
| 183 | case 0x0: | ||
| 184 | return 0; | ||
| 185 | case 0x1F: | ||
| 186 | return 0x1F; | ||
| 187 | default: | ||
| 188 | // Thresholds begin at 0x10 (1 << 4) | ||
| 189 | // Threshold is in the range 0x1 to 0x13 | ||
| 190 | return 1 << (4 + threshold.Value() - 1); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | }; | ||
| 194 | |||
| 195 | struct GeometryShaderDmFifo { | ||
| 196 | union { | ||
| 197 | BitField<0, 13, u32> raster_on; | ||
| 198 | BitField<16, 13, u32> raster_off; | ||
| 199 | BitField<31, 1, u32> spill_enabled; | ||
| 200 | }; | ||
| 201 | }; | ||
| 202 | |||
| 203 | struct L2CacheControl { | ||
| 204 | enum class EvictPolicy : u32 { | ||
| 205 | First = 0, | ||
| 206 | Normal = 1, | ||
| 207 | Last = 2, | ||
| 208 | }; | ||
| 209 | |||
| 210 | union { | ||
| 211 | BitField<4, 2, EvictPolicy> policy; | ||
| 212 | }; | ||
| 213 | }; | ||
| 214 | |||
| 215 | struct InvalidateShaderCache { | ||
| 216 | union { | ||
| 217 | BitField<0, 1, u32> instruction; | ||
| 218 | BitField<4, 1, u32> data; | ||
| 219 | BitField<12, 1, u32> constant; | ||
| 220 | BitField<1, 1, u32> locks; | ||
| 221 | BitField<2, 1, u32> flush_data; | ||
| 222 | }; | ||
| 223 | }; | ||
| 224 | |||
| 225 | struct SyncInfo { | ||
| 226 | enum class Condition : u32 { | ||
| 227 | StreamOutWritesDone = 0, | ||
| 228 | RopWritesDone = 1, | ||
| 229 | }; | ||
| 230 | |||
| 231 | union { | ||
| 232 | BitField<0, 16, u32> sync_point; | ||
| 233 | BitField<16, 1, u32> clean_l2; | ||
| 234 | BitField<20, 1, Condition> condition; | ||
| 235 | }; | ||
| 236 | }; | ||
| 237 | |||
| 238 | struct SurfaceClipBlockId { | ||
| 239 | union { | ||
| 240 | BitField<0, 4, u32> block_width; | ||
| 241 | BitField<4, 4, u32> block_height; | ||
| 242 | BitField<8, 4, u32> block_depth; | ||
| 243 | }; | ||
| 244 | }; | ||
| 245 | |||
| 246 | struct DecompressSurface { | ||
| 247 | union { | ||
| 248 | BitField<0, 3, u32> mrt_select; | ||
| 249 | BitField<4, 16, u32> rt_array_index; | ||
| 250 | }; | ||
| 251 | }; | ||
| 252 | |||
| 253 | struct ZCullRopBypass { | ||
| 254 | union { | ||
| 255 | BitField<0, 1, u32> enable; | ||
| 256 | BitField<4, 1, u32> no_stall; | ||
| 257 | BitField<8, 1, u32> cull_everything; | ||
| 258 | BitField<12, 4, u32> threshold; | ||
| 259 | }; | ||
| 260 | }; | ||
| 261 | |||
| 262 | struct ZCullSubregion { | ||
| 263 | union { | ||
| 264 | BitField<0, 1, u32> enable; | ||
| 265 | BitField<4, 24, u32> normalized_aliquots; | ||
| 266 | }; | ||
| 267 | }; | ||
| 268 | |||
| 269 | struct RasterBoundingBox { | ||
| 270 | enum class Mode : u32 { | ||
| 271 | BoundingBox = 0, | ||
| 272 | FullViewport = 1, | ||
| 273 | }; | ||
| 274 | |||
| 275 | union { | ||
| 276 | BitField<0, 1, Mode> mode; | ||
| 277 | BitField<4, 8, u32> pad; | ||
| 278 | }; | ||
| 279 | }; | ||
| 280 | |||
| 281 | struct IteratedBlendOptimization { | ||
| 282 | enum class Noop : u32 { | ||
| 283 | Never = 0, | ||
| 284 | SourceRGBA0000 = 1, | ||
| 285 | SourceAlpha = 2, | ||
| 286 | SourceRGBA0001 = 3, | ||
| 287 | }; | ||
| 288 | |||
| 289 | union { | ||
| 290 | BitField<0, 1, Noop> noop; | ||
| 291 | }; | ||
| 292 | }; | ||
| 293 | |||
| 294 | struct ZCullSubregionAllocation { | ||
| 295 | enum class Format : u32 { | ||
| 296 | Z_16x16x2_4x4 = 0, | ||
| 297 | ZS_16x16_4x4 = 1, | ||
| 298 | Z_16x16_4x2 = 2, | ||
| 299 | Z_16x16_2x4 = 3, | ||
| 300 | Z_16x8_4x4 = 4, | ||
| 301 | Z_8x8_4x2 = 5, | ||
| 302 | Z_8x8_2x4 = 6, | ||
| 303 | Z_16x16_4x8 = 7, | ||
| 304 | Z_4x8_2x2 = 8, | ||
| 305 | ZS_16x8_4x2 = 9, | ||
| 306 | ZS_16x8_2x4 = 10, | ||
| 307 | ZS_8x8_2x2 = 11, | ||
| 308 | Z_4x8_1x1 = 12, | ||
| 309 | None = 15, | ||
| 310 | }; | ||
| 311 | |||
| 312 | union { | ||
| 313 | BitField<0, 8, u32> id; | ||
| 314 | BitField<8, 16, u32> aliquots; | ||
| 315 | BitField<24, 4, Format> format; | ||
| 316 | }; | ||
| 317 | }; | ||
| 318 | |||
| 319 | enum class ZCullSubregionAlgorithm : u32 { | ||
| 320 | Static = 0, | ||
| 321 | Adaptive = 1, | ||
| 322 | }; | ||
| 323 | |||
| 324 | struct PixelShaderOutputSampleMaskUsage { | ||
| 325 | union { | ||
| 326 | BitField<0, 1, u32> enable; | ||
| 327 | BitField<1, 1, u32> qualify_by_aa; | ||
| 328 | }; | ||
| 329 | }; | ||
| 330 | |||
| 331 | struct L1Configuration { | ||
| 332 | enum class AddressableMemory : u32 { | ||
| 333 | Size16Kb = 0, | ||
| 334 | Size48Kb = 3, | ||
| 335 | }; | ||
| 336 | union { | ||
| 337 | BitField<0, 3, AddressableMemory> direct_addressable_memory; | ||
| 338 | }; | ||
| 339 | }; | ||
| 340 | |||
| 341 | struct SPAVersion { | ||
| 342 | union { | ||
| 343 | BitField<0, 8, u32> minor; | ||
| 344 | BitField<8, 8, u32> major; | ||
| 345 | }; | ||
| 346 | }; | ||
| 347 | |||
| 348 | struct SnapGrid { | ||
| 349 | enum class Location : u32 { | ||
| 350 | Pixel2x2 = 1, | ||
| 351 | Pixel4x4 = 2, | ||
| 352 | Pixel8x8 = 3, | ||
| 353 | Pixel16x16 = 4, | ||
| 354 | Pixel32x32 = 5, | ||
| 355 | Pixel64x64 = 6, | ||
| 356 | Pixel128x128 = 7, | ||
| 357 | Pixel256x256 = 8, | ||
| 358 | }; | ||
| 359 | |||
| 360 | enum class Mode : u32 { | ||
| 361 | RTNE = 0, | ||
| 362 | Tesla = 1, | ||
| 363 | }; | ||
| 364 | |||
| 365 | struct { | ||
| 366 | union { | ||
| 367 | BitField<0, 4, Location> location; | ||
| 368 | BitField<8, 1, Mode> rounding_mode; | ||
| 369 | }; | ||
| 370 | } line; | ||
| 371 | |||
| 372 | struct { | ||
| 373 | union { | ||
| 374 | BitField<0, 4, Location> location; | ||
| 375 | BitField<8, 1, Mode> rounding_mode; | ||
| 376 | }; | ||
| 377 | } non_line; | ||
| 378 | }; | ||
| 379 | |||
| 380 | struct Tessellation { | ||
| 381 | enum class DomainType : u32 { | ||
| 382 | Isolines = 0, | ||
| 383 | Triangles = 1, | ||
| 384 | Quads = 2, | ||
| 385 | }; | ||
| 386 | |||
| 387 | enum class Spacing : u32 { | ||
| 388 | Integer = 0, | ||
| 389 | FractionalOdd = 1, | ||
| 390 | FractionalEven = 2, | ||
| 391 | }; | ||
| 392 | |||
| 393 | enum class OutputPrimitves : u32 { | ||
| 394 | Points = 0, | ||
| 395 | Lines = 1, | ||
| 396 | Triangles_CW = 2, | ||
| 397 | Triangles_CCW = 3, | ||
| 398 | }; | ||
| 399 | |||
| 400 | struct Parameters { | ||
| 401 | union { | ||
| 402 | BitField<0, 2, DomainType> domain_type; | ||
| 403 | BitField<4, 2, Spacing> spacing; | ||
| 404 | BitField<8, 2, OutputPrimitves> output_primitives; | ||
| 405 | }; | ||
| 406 | } params; | ||
| 407 | |||
| 408 | struct LOD { | ||
| 409 | std::array<f32, 4> outer; | ||
| 410 | std::array<f32, 2> inner; | ||
| 411 | } lod; | ||
| 412 | |||
| 413 | std::array<u32, 9> reserved; | ||
| 414 | }; | ||
| 415 | |||
| 416 | struct SubTilingPerf { | ||
| 417 | struct { | ||
| 418 | union { | ||
| 419 | BitField<0, 8, u32> spm_triangle_register_file_per; | ||
| 420 | BitField<8, 8, u32> spm_pixel_output_buffer_per; | ||
| 421 | BitField<16, 8, u32> spm_triangle_ram_per; | ||
| 422 | BitField<24, 8, u32> max_quads_per; | ||
| 423 | }; | ||
| 424 | } knob_a; | ||
| 425 | |||
| 426 | struct { | ||
| 427 | union { | ||
| 428 | BitField<0, 8, u32> max_primitives_per; | ||
| 429 | }; | ||
| 430 | } knob_b; | ||
| 431 | |||
| 432 | u32 knob_c; | ||
| 433 | }; | ||
| 434 | |||
| 435 | struct ZCullSubregionReport { | ||
| 436 | enum class ReportType : u32 { | ||
| 437 | DepthTest = 0, | ||
| 438 | DepthTestNoAccept = 1, | ||
| 439 | DepthTestLateZ = 2, | ||
| 440 | StencilTest = 3, | ||
| 441 | }; | ||
| 442 | |||
| 443 | union { | ||
| 444 | BitField<0, 1, u32> enabled; | ||
| 445 | BitField<4, 8, u32> subregion_id; | ||
| 446 | } to_report; | ||
| 447 | |||
| 448 | union { | ||
| 449 | BitField<0, 1, u32> enabled; | ||
| 450 | BitField<4, 3, ReportType> type; | ||
| 451 | } report_type; | ||
| 452 | }; | ||
| 453 | |||
| 454 | struct BalancedPrimitiveWorkload { | ||
| 455 | union { | ||
| 456 | BitField<0, 1, u32> unpartitioned_mode; | ||
| 457 | BitField<4, 1, u32> timesliced_mode; | ||
| 458 | }; | ||
| 459 | }; | ||
| 460 | |||
| 461 | struct TransformFeedback { | ||
| 462 | struct Buffer { | ||
| 463 | u32 enable; | ||
| 464 | u32 address_high; | ||
| 465 | u32 address_low; | ||
| 466 | s32 size; | ||
| 467 | s32 start_offset; | ||
| 468 | INSERT_PADDING_BYTES_NOINIT(0xC); | ||
| 469 | |||
| 470 | GPUVAddr Address() const { | ||
| 471 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 472 | address_low); | ||
| 473 | } | ||
| 474 | }; | ||
| 475 | static_assert(sizeof(Buffer) == 0x20); | ||
| 476 | |||
| 477 | struct Control { | ||
| 478 | u32 stream; | ||
| 479 | u32 varying_count; | ||
| 480 | u32 stride; | ||
| 481 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 482 | }; | ||
| 483 | static_assert(sizeof(Control) == 0x10); | ||
| 484 | |||
| 485 | std::array<TransformFeedback::Buffer, NumTransformFeedbackBuffers> buffers; | ||
| 486 | |||
| 487 | INSERT_PADDING_BYTES_NOINIT(0x300); | ||
| 488 | |||
| 489 | std::array<TransformFeedback::Control, NumTransformFeedbackBuffers> controls; | ||
| 490 | }; | ||
| 491 | |||
| 492 | struct HybridAntiAliasControl { | ||
| 493 | enum class Centroid : u32 { | ||
| 494 | PerFragment = 0, | ||
| 495 | PerPass = 1, | ||
| 496 | }; | ||
| 497 | union { | ||
| 498 | BitField<0, 4, u32> passes; | ||
| 499 | BitField<4, 1, Centroid> centroid; | ||
| 500 | BitField<5, 1, u32> passes_extended; | ||
| 501 | }; | ||
| 502 | }; | ||
| 503 | |||
| 504 | struct ShaderLocalMemory { | ||
| 505 | u32 base_address; | ||
| 506 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 507 | u32 address_high; | ||
| 508 | u32 address_low; | ||
| 509 | u32 size_high; | ||
| 510 | u32 size_low; | ||
| 511 | u32 default_size_per_warp; | ||
| 512 | |||
| 513 | GPUVAddr Address() const { | ||
| 514 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 515 | address_low); | ||
| 516 | } | ||
| 517 | |||
| 518 | u64 Size() const { | ||
| 519 | return (static_cast<u64>(size_high) << 32) | size_low; | ||
| 520 | } | ||
| 521 | }; | ||
| 522 | |||
| 523 | struct ZCullRegion { | ||
| 524 | u32 width; | ||
| 525 | u32 height; | ||
| 526 | u32 depth; | ||
| 527 | u32 offset; | ||
| 528 | INSERT_PADDING_BYTES_NOINIT(0xC); | ||
| 529 | u32 fetch_streams_once; | ||
| 530 | union { | ||
| 531 | BitField<0, 16, u32> start_aliquot; | ||
| 532 | BitField<16, 16, u32> aliquot_count; | ||
| 533 | } location; | ||
| 534 | u32 aliquots_per_layer; | ||
| 535 | u32 storage_address_high; | ||
| 536 | u32 storage_address_low; | ||
| 537 | u32 storage_limit_address_high; | ||
| 538 | u32 storage_limit_address_low; | ||
| 539 | |||
| 540 | GPUVAddr StorageAddress() const { | ||
| 541 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(storage_address_high) << 32) | | ||
| 542 | storage_address_low); | ||
| 543 | } | ||
| 544 | GPUVAddr StorageLimitAddress() const { | ||
| 545 | return static_cast<GPUVAddr>( | ||
| 546 | (static_cast<GPUVAddr>(storage_limit_address_high) << 32) | | ||
| 547 | storage_limit_address_low); | ||
| 548 | } | ||
| 549 | }; | ||
| 550 | |||
| 551 | struct ZetaReadOnly { | ||
| 552 | union { | ||
| 553 | BitField<0, 1, u32> enable_z; | ||
| 554 | BitField<4, 1, u32> enable_stencil; | ||
| 555 | }; | ||
| 133 | }; | 556 | }; |
| 134 | 557 | ||
| 135 | struct VertexAttribute { | 558 | struct VertexAttribute { |
| 136 | enum class Size : u32 { | 559 | enum class Size : u32 { |
| 137 | Invalid = 0x0, | 560 | Invalid = 0x0, |
| 138 | Size_32_32_32_32 = 0x01, | 561 | Size_R32_G32_B32_A32 = 0x01, |
| 139 | Size_32_32_32 = 0x02, | 562 | Size_R32_G32_B32 = 0x02, |
| 140 | Size_16_16_16_16 = 0x03, | 563 | Size_R16_G16_B16_A16 = 0x03, |
| 141 | Size_32_32 = 0x04, | 564 | Size_R32_G32 = 0x04, |
| 142 | Size_16_16_16 = 0x05, | 565 | Size_R16_G16_B16 = 0x05, |
| 143 | Size_8_8_8_8 = 0x0a, | 566 | Size_R8_G8_B8_A8 = 0x0A, |
| 144 | Size_16_16 = 0x0f, | 567 | Size_R16_G16 = 0x0F, |
| 145 | Size_32 = 0x12, | 568 | Size_R32 = 0x12, |
| 146 | Size_8_8_8 = 0x13, | 569 | Size_R8_G8_B8 = 0x13, |
| 147 | Size_8_8 = 0x18, | 570 | Size_R8_G8 = 0x18, |
| 148 | Size_16 = 0x1b, | 571 | Size_R16 = 0x1B, |
| 149 | Size_8 = 0x1d, | 572 | Size_R8 = 0x1D, |
| 150 | Size_10_10_10_2 = 0x30, | 573 | Size_A2_B10_G10_R10 = 0x30, |
| 151 | Size_11_11_10 = 0x31, | 574 | Size_B10_G11_R11 = 0x31, |
| 575 | Size_G8_R8 = 0x32, | ||
| 576 | Size_X8_B8_G8_R8 = 0x33, | ||
| 577 | Size_A8 = 0x34, | ||
| 152 | }; | 578 | }; |
| 153 | 579 | ||
| 154 | enum class Type : u32 { | 580 | enum class Type : u32 { |
| 155 | SignedNorm = 1, | 581 | UnusedEnumDoNotUseBecauseItWillGoAway = 0, |
| 156 | UnsignedNorm = 2, | 582 | SNorm = 1, |
| 157 | SignedInt = 3, | 583 | UNorm = 2, |
| 158 | UnsignedInt = 4, | 584 | SInt = 3, |
| 159 | UnsignedScaled = 5, | 585 | UInt = 4, |
| 160 | SignedScaled = 6, | 586 | UScaled = 5, |
| 587 | SScaled = 6, | ||
| 161 | Float = 7, | 588 | Float = 7, |
| 162 | }; | 589 | }; |
| 163 | 590 | ||
| @@ -173,33 +600,36 @@ public: | |||
| 173 | 600 | ||
| 174 | u32 ComponentCount() const { | 601 | u32 ComponentCount() const { |
| 175 | switch (size) { | 602 | switch (size) { |
| 176 | case Size::Size_32_32_32_32: | 603 | case Size::Size_R32_G32_B32_A32: |
| 177 | return 4; | 604 | return 4; |
| 178 | case Size::Size_32_32_32: | 605 | case Size::Size_R32_G32_B32: |
| 179 | return 3; | 606 | return 3; |
| 180 | case Size::Size_16_16_16_16: | 607 | case Size::Size_R16_G16_B16_A16: |
| 181 | return 4; | 608 | return 4; |
| 182 | case Size::Size_32_32: | 609 | case Size::Size_R32_G32: |
| 183 | return 2; | 610 | return 2; |
| 184 | case Size::Size_16_16_16: | 611 | case Size::Size_R16_G16_B16: |
| 185 | return 3; | 612 | return 3; |
| 186 | case Size::Size_8_8_8_8: | 613 | case Size::Size_R8_G8_B8_A8: |
| 614 | case Size::Size_X8_B8_G8_R8: | ||
| 187 | return 4; | 615 | return 4; |
| 188 | case Size::Size_16_16: | 616 | case Size::Size_R16_G16: |
| 189 | return 2; | 617 | return 2; |
| 190 | case Size::Size_32: | 618 | case Size::Size_R32: |
| 191 | return 1; | 619 | return 1; |
| 192 | case Size::Size_8_8_8: | 620 | case Size::Size_R8_G8_B8: |
| 193 | return 3; | 621 | return 3; |
| 194 | case Size::Size_8_8: | 622 | case Size::Size_R8_G8: |
| 623 | case Size::Size_G8_R8: | ||
| 195 | return 2; | 624 | return 2; |
| 196 | case Size::Size_16: | 625 | case Size::Size_R16: |
| 197 | return 1; | 626 | return 1; |
| 198 | case Size::Size_8: | 627 | case Size::Size_R8: |
| 628 | case Size::Size_A8: | ||
| 199 | return 1; | 629 | return 1; |
| 200 | case Size::Size_10_10_10_2: | 630 | case Size::Size_A2_B10_G10_R10: |
| 201 | return 4; | 631 | return 4; |
| 202 | case Size::Size_11_11_10: | 632 | case Size::Size_B10_G11_R11: |
| 203 | return 3; | 633 | return 3; |
| 204 | default: | 634 | default: |
| 205 | ASSERT(false); | 635 | ASSERT(false); |
| @@ -209,33 +639,36 @@ public: | |||
| 209 | 639 | ||
| 210 | u32 SizeInBytes() const { | 640 | u32 SizeInBytes() const { |
| 211 | switch (size) { | 641 | switch (size) { |
| 212 | case Size::Size_32_32_32_32: | 642 | case Size::Size_R32_G32_B32_A32: |
| 213 | return 16; | 643 | return 16; |
| 214 | case Size::Size_32_32_32: | 644 | case Size::Size_R32_G32_B32: |
| 215 | return 12; | 645 | return 12; |
| 216 | case Size::Size_16_16_16_16: | 646 | case Size::Size_R16_G16_B16_A16: |
| 217 | return 8; | 647 | return 8; |
| 218 | case Size::Size_32_32: | 648 | case Size::Size_R32_G32: |
| 219 | return 8; | 649 | return 8; |
| 220 | case Size::Size_16_16_16: | 650 | case Size::Size_R16_G16_B16: |
| 221 | return 6; | 651 | return 6; |
| 222 | case Size::Size_8_8_8_8: | 652 | case Size::Size_R8_G8_B8_A8: |
| 653 | case Size::Size_X8_B8_G8_R8: | ||
| 223 | return 4; | 654 | return 4; |
| 224 | case Size::Size_16_16: | 655 | case Size::Size_R16_G16: |
| 225 | return 4; | 656 | return 4; |
| 226 | case Size::Size_32: | 657 | case Size::Size_R32: |
| 227 | return 4; | 658 | return 4; |
| 228 | case Size::Size_8_8_8: | 659 | case Size::Size_R8_G8_B8: |
| 229 | return 3; | 660 | return 3; |
| 230 | case Size::Size_8_8: | 661 | case Size::Size_R8_G8: |
| 662 | case Size::Size_G8_R8: | ||
| 231 | return 2; | 663 | return 2; |
| 232 | case Size::Size_16: | 664 | case Size::Size_R16: |
| 233 | return 2; | 665 | return 2; |
| 234 | case Size::Size_8: | 666 | case Size::Size_R8: |
| 667 | case Size::Size_A8: | ||
| 235 | return 1; | 668 | return 1; |
| 236 | case Size::Size_10_10_10_2: | 669 | case Size::Size_A2_B10_G10_R10: |
| 237 | return 4; | 670 | return 4; |
| 238 | case Size::Size_11_11_10: | 671 | case Size::Size_B10_G11_R11: |
| 239 | return 4; | 672 | return 4; |
| 240 | default: | 673 | default: |
| 241 | ASSERT(false); | 674 | ASSERT(false); |
| @@ -245,34 +678,36 @@ public: | |||
| 245 | 678 | ||
| 246 | std::string SizeString() const { | 679 | std::string SizeString() const { |
| 247 | switch (size) { | 680 | switch (size) { |
| 248 | case Size::Size_32_32_32_32: | 681 | case Size::Size_R32_G32_B32_A32: |
| 249 | return "32_32_32_32"; | 682 | return "32_32_32_32"; |
| 250 | case Size::Size_32_32_32: | 683 | case Size::Size_R32_G32_B32: |
| 251 | return "32_32_32"; | 684 | return "32_32_32"; |
| 252 | case Size::Size_16_16_16_16: | 685 | case Size::Size_R16_G16_B16_A16: |
| 253 | return "16_16_16_16"; | 686 | return "16_16_16_16"; |
| 254 | case Size::Size_32_32: | 687 | case Size::Size_R32_G32: |
| 255 | return "32_32"; | 688 | return "32_32"; |
| 256 | case Size::Size_16_16_16: | 689 | case Size::Size_R16_G16_B16: |
| 257 | return "16_16_16"; | 690 | return "16_16_16"; |
| 258 | case Size::Size_8_8_8_8: | 691 | case Size::Size_R8_G8_B8_A8: |
| 259 | return "8_8_8_8"; | 692 | return "8_8_8_8"; |
| 260 | case Size::Size_16_16: | 693 | case Size::Size_R16_G16: |
| 261 | return "16_16"; | 694 | return "16_16"; |
| 262 | case Size::Size_32: | 695 | case Size::Size_R32: |
| 263 | return "32"; | 696 | return "32"; |
| 264 | case Size::Size_8_8_8: | 697 | case Size::Size_R8_G8_B8: |
| 265 | return "8_8_8"; | 698 | return "8_8_8"; |
| 266 | case Size::Size_8_8: | 699 | case Size::Size_R8_G8: |
| 700 | case Size::Size_G8_R8: | ||
| 267 | return "8_8"; | 701 | return "8_8"; |
| 268 | case Size::Size_16: | 702 | case Size::Size_R16: |
| 269 | return "16"; | 703 | return "16"; |
| 270 | case Size::Size_8: | 704 | case Size::Size_R8: |
| 705 | case Size::Size_A8: | ||
| 271 | return "8"; | 706 | return "8"; |
| 272 | case Size::Size_10_10_10_2: | 707 | case Size::Size_A2_B10_G10_R10: |
| 273 | return "10_10_10_2"; | 708 | return "2_10_10_10"; |
| 274 | case Size::Size_11_11_10: | 709 | case Size::Size_B10_G11_R11: |
| 275 | return "11_11_10"; | 710 | return "10_11_12"; |
| 276 | default: | 711 | default: |
| 277 | ASSERT(false); | 712 | ASSERT(false); |
| 278 | return {}; | 713 | return {}; |
| @@ -281,17 +716,19 @@ public: | |||
| 281 | 716 | ||
| 282 | std::string TypeString() const { | 717 | std::string TypeString() const { |
| 283 | switch (type) { | 718 | switch (type) { |
| 284 | case Type::SignedNorm: | 719 | case Type::UnusedEnumDoNotUseBecauseItWillGoAway: |
| 720 | return "Unused"; | ||
| 721 | case Type::SNorm: | ||
| 285 | return "SNORM"; | 722 | return "SNORM"; |
| 286 | case Type::UnsignedNorm: | 723 | case Type::UNorm: |
| 287 | return "UNORM"; | 724 | return "UNORM"; |
| 288 | case Type::SignedInt: | 725 | case Type::SInt: |
| 289 | return "SINT"; | 726 | return "SINT"; |
| 290 | case Type::UnsignedInt: | 727 | case Type::UInt: |
| 291 | return "UINT"; | 728 | return "UINT"; |
| 292 | case Type::UnsignedScaled: | 729 | case Type::UScaled: |
| 293 | return "USCALED"; | 730 | return "USCALED"; |
| 294 | case Type::SignedScaled: | 731 | case Type::SScaled: |
| 295 | return "SSCALED"; | 732 | return "SSCALED"; |
| 296 | case Type::Float: | 733 | case Type::Float: |
| 297 | return "FLOAT"; | 734 | return "FLOAT"; |
| @@ -301,7 +738,7 @@ public: | |||
| 301 | } | 738 | } |
| 302 | 739 | ||
| 303 | bool IsNormalized() const { | 740 | bool IsNormalized() const { |
| 304 | return (type == Type::SignedNorm) || (type == Type::UnsignedNorm); | 741 | return (type == Type::SNorm) || (type == Type::UNorm); |
| 305 | } | 742 | } |
| 306 | 743 | ||
| 307 | bool IsValid() const { | 744 | bool IsValid() const { |
| @@ -312,6 +749,7 @@ public: | |||
| 312 | return hex < other.hex; | 749 | return hex < other.hex; |
| 313 | } | 750 | } |
| 314 | }; | 751 | }; |
| 752 | static_assert(sizeof(VertexAttribute) == 0x4); | ||
| 315 | 753 | ||
| 316 | struct MsaaSampleLocation { | 754 | struct MsaaSampleLocation { |
| 317 | union { | 755 | union { |
| @@ -342,9 +780,96 @@ public: | |||
| 342 | } | 780 | } |
| 343 | }; | 781 | }; |
| 344 | 782 | ||
| 345 | enum class DepthMode : u32 { | 783 | struct MultisampleCoverageToColor { |
| 346 | MinusOneToOne = 0, | 784 | union { |
| 347 | ZeroToOne = 1, | 785 | BitField<0, 1, u32> enable; |
| 786 | BitField<4, 3, u32> target; | ||
| 787 | }; | ||
| 788 | }; | ||
| 789 | |||
| 790 | struct DecompressZetaSurface { | ||
| 791 | union { | ||
| 792 | BitField<0, 1, u32> z_enable; | ||
| 793 | BitField<4, 1, u32> stencil_enable; | ||
| 794 | }; | ||
| 795 | }; | ||
| 796 | |||
| 797 | struct ZetaSparse { | ||
| 798 | enum class UnmappedCompare : u32 { | ||
| 799 | Unmapped = 0, | ||
| 800 | FailAlways = 1, | ||
| 801 | }; | ||
| 802 | union { | ||
| 803 | BitField<0, 1, u32> enable; | ||
| 804 | BitField<1, 1, UnmappedCompare> unmapped_compare; | ||
| 805 | }; | ||
| 806 | }; | ||
| 807 | |||
| 808 | struct RtControl { | ||
| 809 | union { | ||
| 810 | BitField<0, 4, u32> count; | ||
| 811 | BitField<4, 3, u32> target0; | ||
| 812 | BitField<7, 3, u32> target1; | ||
| 813 | BitField<10, 3, u32> target2; | ||
| 814 | BitField<13, 3, u32> target3; | ||
| 815 | BitField<16, 3, u32> target4; | ||
| 816 | BitField<19, 3, u32> target5; | ||
| 817 | BitField<22, 3, u32> target6; | ||
| 818 | BitField<25, 3, u32> target7; | ||
| 819 | }; | ||
| 820 | |||
| 821 | u32 Map(std::size_t index) const { | ||
| 822 | const std::array<u32, NumRenderTargets> maps{target0, target1, target2, target3, | ||
| 823 | target4, target5, target6, target7}; | ||
| 824 | ASSERT(index < maps.size()); | ||
| 825 | return maps[index]; | ||
| 826 | } | ||
| 827 | }; | ||
| 828 | |||
| 829 | struct CompressionThresholdSamples { | ||
| 830 | u32 samples; | ||
| 831 | |||
| 832 | u32 Samples() { | ||
| 833 | if (samples == 0) { | ||
| 834 | return 0; | ||
| 835 | } | ||
| 836 | return 1 << (samples - 1); | ||
| 837 | } | ||
| 838 | }; | ||
| 839 | |||
| 840 | struct PixelShaderInterlockControl { | ||
| 841 | enum class TileMode : u32 { | ||
| 842 | NoConflictDetect = 0, | ||
| 843 | DetectSampleConflict = 1, | ||
| 844 | DetectPixelConflict = 2, | ||
| 845 | }; | ||
| 846 | enum class TileSize : u32 { | ||
| 847 | Size_16x16 = 0, | ||
| 848 | Size_8x8 = 1, | ||
| 849 | }; | ||
| 850 | enum class FragmentOrder : u32 { | ||
| 851 | FragmentOrdered = 0, | ||
| 852 | FragmentUnordered = 1, | ||
| 853 | }; | ||
| 854 | union { | ||
| 855 | BitField<0, 2, TileMode> tile_mode; | ||
| 856 | BitField<2, 1, TileSize> tile_size; | ||
| 857 | BitField<3, 1, FragmentOrder> fragment_order; | ||
| 858 | }; | ||
| 859 | }; | ||
| 860 | |||
| 861 | struct ZetaSize { | ||
| 862 | enum class DimensionControl : u32 { | ||
| 863 | DepthDefinesArray = 0, | ||
| 864 | ArraySizeOne = 1, | ||
| 865 | }; | ||
| 866 | |||
| 867 | u32 width; | ||
| 868 | u32 height; | ||
| 869 | union { | ||
| 870 | BitField<0, 16, u32> depth; | ||
| 871 | BitField<16, 1, DimensionControl> dim_control; | ||
| 872 | }; | ||
| 348 | }; | 873 | }; |
| 349 | 874 | ||
| 350 | enum class PrimitiveTopology : u32 { | 875 | enum class PrimitiveTopology : u32 { |
| @@ -358,15 +883,21 @@ public: | |||
| 358 | Quads = 0x7, | 883 | Quads = 0x7, |
| 359 | QuadStrip = 0x8, | 884 | QuadStrip = 0x8, |
| 360 | Polygon = 0x9, | 885 | Polygon = 0x9, |
| 361 | LinesAdjacency = 0xa, | 886 | LinesAdjacency = 0xA, |
| 362 | LineStripAdjacency = 0xb, | 887 | LineStripAdjacency = 0xB, |
| 363 | TrianglesAdjacency = 0xc, | 888 | TrianglesAdjacency = 0xC, |
| 364 | TriangleStripAdjacency = 0xd, | 889 | TriangleStripAdjacency = 0xD, |
| 365 | Patches = 0xe, | 890 | Patches = 0xE, |
| 891 | }; | ||
| 892 | |||
| 893 | struct VertexArray { | ||
| 894 | union { | ||
| 895 | BitField<0, 16, u32> start; | ||
| 896 | BitField<16, 12, u32> count; | ||
| 897 | BitField<28, 3, PrimitiveTopology> topology; | ||
| 898 | }; | ||
| 366 | }; | 899 | }; |
| 367 | 900 | ||
| 368 | // Constants as from NVC0_3D_UNK1970_D3D | ||
| 369 | // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h#L1598 | ||
| 370 | enum class PrimitiveTopologyOverride : u32 { | 901 | enum class PrimitiveTopologyOverride : u32 { |
| 371 | None = 0x0, | 902 | None = 0x0, |
| 372 | Points = 0x1, | 903 | Points = 0x1, |
| @@ -374,11 +905,32 @@ public: | |||
| 374 | LineStrip = 0x3, | 905 | LineStrip = 0x3, |
| 375 | Triangles = 0x4, | 906 | Triangles = 0x4, |
| 376 | TriangleStrip = 0x5, | 907 | TriangleStrip = 0x5, |
| 377 | LinesAdjacency = 0xa, | 908 | LinesAdjacency = 0xA, |
| 378 | LineStripAdjacency = 0xb, | 909 | LineStripAdjacency = 0xB, |
| 379 | TrianglesAdjacency = 0xc, | 910 | TrianglesAdjacency = 0xC, |
| 380 | TriangleStripAdjacency = 0xd, | 911 | TriangleStripAdjacency = 0xD, |
| 381 | Patches = 0xe, | 912 | Patches = 0xE, |
| 913 | |||
| 914 | LegacyPoints = 0x1001, | ||
| 915 | LegacyIndexedLines = 0x1002, | ||
| 916 | LegacyIndexedTriangles = 0x1003, | ||
| 917 | LegacyLines = 0x100F, | ||
| 918 | LegacyLineStrip = 0x1010, | ||
| 919 | LegacyIndexedLineStrip = 0x1011, | ||
| 920 | LegacyTriangles = 0x1012, | ||
| 921 | LegacyTriangleStrip = 0x1013, | ||
| 922 | LegacyIndexedTriangleStrip = 0x1014, | ||
| 923 | LegacyTriangleFan = 0x1015, | ||
| 924 | LegacyIndexedTriangleFan = 0x1016, | ||
| 925 | LegacyTriangleFanImm = 0x1017, | ||
| 926 | LegacyLinesImm = 0x1018, | ||
| 927 | LegacyIndexedTriangles2 = 0x101A, | ||
| 928 | LegacyIndexedLines2 = 0x101B, | ||
| 929 | }; | ||
| 930 | |||
| 931 | enum class DepthMode : u32 { | ||
| 932 | MinusOneToOne = 0, | ||
| 933 | ZeroToOne = 1, | ||
| 382 | }; | 934 | }; |
| 383 | 935 | ||
| 384 | enum class IndexFormat : u32 { | 936 | enum class IndexFormat : u32 { |
| @@ -388,183 +940,143 @@ public: | |||
| 388 | }; | 940 | }; |
| 389 | 941 | ||
| 390 | enum class ComparisonOp : u32 { | 942 | enum class ComparisonOp : u32 { |
| 391 | // These values are used by Nouveau and most games, they correspond to the OpenGL token | 943 | Never_D3D = 1, |
| 392 | // values for these operations. | 944 | Less_D3D = 2, |
| 393 | Never = 0x200, | 945 | Equal_D3D = 3, |
| 394 | Less = 0x201, | 946 | LessEqual_D3D = 4, |
| 395 | Equal = 0x202, | 947 | Greater_D3D = 5, |
| 396 | LessEqual = 0x203, | 948 | NotEqual_D3D = 6, |
| 397 | Greater = 0x204, | 949 | GreaterEqual_D3D = 7, |
| 398 | NotEqual = 0x205, | 950 | Always_D3D = 8, |
| 399 | GreaterEqual = 0x206, | 951 | |
| 400 | Always = 0x207, | 952 | Never_GL = 0x200, |
| 401 | 953 | Less_GL = 0x201, | |
| 402 | // These values are used by some games, they seem to be NV04 values. | 954 | Equal_GL = 0x202, |
| 403 | NeverOld = 1, | 955 | LessEqual_GL = 0x203, |
| 404 | LessOld = 2, | 956 | Greater_GL = 0x204, |
| 405 | EqualOld = 3, | 957 | NotEqual_GL = 0x205, |
| 406 | LessEqualOld = 4, | 958 | GreaterEqual_GL = 0x206, |
| 407 | GreaterOld = 5, | 959 | Always_GL = 0x207, |
| 408 | NotEqualOld = 6, | 960 | }; |
| 409 | GreaterEqualOld = 7, | 961 | |
| 410 | AlwaysOld = 8, | 962 | enum class ClearReport : u32 { |
| 411 | }; | 963 | ZPassPixelCount = 0x01, |
| 412 | 964 | ZCullStats = 0x02, | |
| 413 | enum class LogicOperation : u32 { | 965 | StreamingPrimitvesNeededMinusSucceeded = 0x03, |
| 414 | Clear = 0x1500, | 966 | AlphaBetaClocks = 0x04, |
| 415 | And = 0x1501, | 967 | StreamingPrimitivesSucceeded = 0x10, |
| 416 | AndReverse = 0x1502, | 968 | StreamingPrimitivesNeeded = 0x11, |
| 417 | Copy = 0x1503, | 969 | VerticesGenerated = 0x12, |
| 418 | AndInverted = 0x1504, | 970 | PrimitivesGenerated = 0x13, |
| 419 | NoOp = 0x1505, | 971 | VertexShaderInvocations = 0x15, |
| 420 | Xor = 0x1506, | 972 | TessellationInitInvocations = 0x16, |
| 421 | Or = 0x1507, | 973 | TessellationShaderInvocations = 0x17, |
| 422 | Nor = 0x1508, | 974 | TessellationShaderPrimitivesGenerated = 0x18, |
| 423 | Equiv = 0x1509, | 975 | GeometryShaderInvocations = 0x1A, |
| 424 | Invert = 0x150A, | 976 | GeometryShaderPrimitivesGenerated = 0x1B, |
| 425 | OrReverse = 0x150B, | 977 | ClipperInvocations = 0x1C, |
| 426 | CopyInverted = 0x150C, | 978 | ClipperPrimitivesGenerated = 0x1D, |
| 427 | OrInverted = 0x150D, | 979 | PixelShaderInvocations = 0x1E, |
| 428 | Nand = 0x150E, | 980 | VtgPrimitivesOut = 0x1F, |
| 429 | Set = 0x150F, | ||
| 430 | }; | ||
| 431 | |||
| 432 | enum class StencilOp : u32 { | ||
| 433 | Keep = 1, | ||
| 434 | Zero = 2, | ||
| 435 | Replace = 3, | ||
| 436 | Incr = 4, | ||
| 437 | Decr = 5, | ||
| 438 | Invert = 6, | ||
| 439 | IncrWrap = 7, | ||
| 440 | DecrWrap = 8, | ||
| 441 | KeepOGL = 0x1E00, | ||
| 442 | ZeroOGL = 0, | ||
| 443 | ReplaceOGL = 0x1E01, | ||
| 444 | IncrOGL = 0x1E02, | ||
| 445 | DecrOGL = 0x1E03, | ||
| 446 | InvertOGL = 0x150A, | ||
| 447 | IncrWrapOGL = 0x8507, | ||
| 448 | DecrWrapOGL = 0x8508, | ||
| 449 | }; | ||
| 450 | |||
| 451 | enum class CounterReset : u32 { | ||
| 452 | SampleCnt = 0x01, | ||
| 453 | Unk02 = 0x02, | ||
| 454 | Unk03 = 0x03, | ||
| 455 | Unk04 = 0x04, | ||
| 456 | EmittedPrimitives = 0x10, // Not tested | ||
| 457 | Unk11 = 0x11, | ||
| 458 | Unk12 = 0x12, | ||
| 459 | Unk13 = 0x13, | ||
| 460 | Unk15 = 0x15, | ||
| 461 | Unk16 = 0x16, | ||
| 462 | Unk17 = 0x17, | ||
| 463 | Unk18 = 0x18, | ||
| 464 | Unk1A = 0x1A, | ||
| 465 | Unk1B = 0x1B, | ||
| 466 | Unk1C = 0x1C, | ||
| 467 | Unk1D = 0x1D, | ||
| 468 | Unk1E = 0x1E, | ||
| 469 | GeneratedPrimitives = 0x1F, | ||
| 470 | }; | 981 | }; |
| 471 | 982 | ||
| 472 | enum class FrontFace : u32 { | 983 | enum class FrontFace : u32 { |
| 473 | ClockWise = 0x0900, | 984 | ClockWise = 0x900, |
| 474 | CounterClockWise = 0x0901, | 985 | CounterClockWise = 0x901, |
| 475 | }; | 986 | }; |
| 476 | 987 | ||
| 477 | enum class CullFace : u32 { | 988 | enum class CullFace : u32 { |
| 478 | Front = 0x0404, | 989 | Front = 0x404, |
| 479 | Back = 0x0405, | 990 | Back = 0x405, |
| 480 | FrontAndBack = 0x0408, | 991 | FrontAndBack = 0x408, |
| 481 | }; | 992 | }; |
| 482 | 993 | ||
| 483 | struct Blend { | 994 | struct Blend { |
| 484 | enum class Equation : u32 { | 995 | enum class Equation : u32 { |
| 485 | Add = 1, | 996 | Add_D3D = 1, |
| 486 | Subtract = 2, | 997 | Subtract_D3D = 2, |
| 487 | ReverseSubtract = 3, | 998 | ReverseSubtract_D3D = 3, |
| 488 | Min = 4, | 999 | Min_D3D = 4, |
| 489 | Max = 5, | 1000 | Max_D3D = 5, |
| 490 | 1001 | ||
| 491 | // These values are used by Nouveau and some games. | 1002 | Add_GL = 0x8006, |
| 492 | AddGL = 0x8006, | 1003 | Min_GL = 0x8007, |
| 493 | MinGL = 0x8007, | 1004 | Max_GL = 0x8008, |
| 494 | MaxGL = 0x8008, | 1005 | Subtract_GL = 0x800A, |
| 495 | SubtractGL = 0x800a, | 1006 | ReverseSubtract_GL = 0x800B |
| 496 | ReverseSubtractGL = 0x800b | ||
| 497 | }; | 1007 | }; |
| 498 | 1008 | ||
| 499 | enum class Factor : u32 { | 1009 | enum class Factor : u32 { |
| 500 | Zero = 0x1, | 1010 | Zero_D3D = 0x1, |
| 501 | One = 0x2, | 1011 | One_D3D = 0x2, |
| 502 | SourceColor = 0x3, | 1012 | SourceColor_D3D = 0x3, |
| 503 | OneMinusSourceColor = 0x4, | 1013 | OneMinusSourceColor_D3D = 0x4, |
| 504 | SourceAlpha = 0x5, | 1014 | SourceAlpha_D3D = 0x5, |
| 505 | OneMinusSourceAlpha = 0x6, | 1015 | OneMinusSourceAlpha_D3D = 0x6, |
| 506 | DestAlpha = 0x7, | 1016 | DestAlpha_D3D = 0x7, |
| 507 | OneMinusDestAlpha = 0x8, | 1017 | OneMinusDestAlpha_D3D = 0x8, |
| 508 | DestColor = 0x9, | 1018 | DestColor_D3D = 0x9, |
| 509 | OneMinusDestColor = 0xa, | 1019 | OneMinusDestColor_D3D = 0xA, |
| 510 | SourceAlphaSaturate = 0xb, | 1020 | SourceAlphaSaturate_D3D = 0xB, |
| 511 | Source1Color = 0x10, | 1021 | BothSourceAlpha_D3D = 0xC, |
| 512 | OneMinusSource1Color = 0x11, | 1022 | OneMinusBothSourceAlpha_D3D = 0xD, |
| 513 | Source1Alpha = 0x12, | 1023 | BlendFactor_D3D = 0xE, |
| 514 | OneMinusSource1Alpha = 0x13, | 1024 | OneMinusBlendFactor_D3D = 0xF, |
| 515 | ConstantColor = 0x61, | 1025 | Source1Color_D3D = 0x10, |
| 516 | OneMinusConstantColor = 0x62, | 1026 | OneMinusSource1Color_D3D = 0x11, |
| 517 | ConstantAlpha = 0x63, | 1027 | Source1Alpha_D3D = 0x12, |
| 518 | OneMinusConstantAlpha = 0x64, | 1028 | OneMinusSource1Alpha_D3D = 0x13, |
| 519 | 1029 | ||
| 520 | // These values are used by Nouveau and some games. | 1030 | Zero_GL = 0x4000, |
| 521 | ZeroGL = 0x4000, | 1031 | One_GL = 0x4001, |
| 522 | OneGL = 0x4001, | 1032 | SourceColor_GL = 0x4300, |
| 523 | SourceColorGL = 0x4300, | 1033 | OneMinusSourceColor_GL = 0x4301, |
| 524 | OneMinusSourceColorGL = 0x4301, | 1034 | SourceAlpha_GL = 0x4302, |
| 525 | SourceAlphaGL = 0x4302, | 1035 | OneMinusSourceAlpha_GL = 0x4303, |
| 526 | OneMinusSourceAlphaGL = 0x4303, | 1036 | DestAlpha_GL = 0x4304, |
| 527 | DestAlphaGL = 0x4304, | 1037 | OneMinusDestAlpha_GL = 0x4305, |
| 528 | OneMinusDestAlphaGL = 0x4305, | 1038 | DestColor_GL = 0x4306, |
| 529 | DestColorGL = 0x4306, | 1039 | OneMinusDestColor_GL = 0x4307, |
| 530 | OneMinusDestColorGL = 0x4307, | 1040 | SourceAlphaSaturate_GL = 0x4308, |
| 531 | SourceAlphaSaturateGL = 0x4308, | 1041 | ConstantColor_GL = 0xC001, |
| 532 | ConstantColorGL = 0xc001, | 1042 | OneMinusConstantColor_GL = 0xC002, |
| 533 | OneMinusConstantColorGL = 0xc002, | 1043 | ConstantAlpha_GL = 0xC003, |
| 534 | ConstantAlphaGL = 0xc003, | 1044 | OneMinusConstantAlpha_GL = 0xC004, |
| 535 | OneMinusConstantAlphaGL = 0xc004, | 1045 | Source1Color_GL = 0xC900, |
| 536 | Source1ColorGL = 0xc900, | 1046 | OneMinusSource1Color_GL = 0xC901, |
| 537 | OneMinusSource1ColorGL = 0xc901, | 1047 | Source1Alpha_GL = 0xC902, |
| 538 | Source1AlphaGL = 0xc902, | 1048 | OneMinusSource1Alpha_GL = 0xC903, |
| 539 | OneMinusSource1AlphaGL = 0xc903, | ||
| 540 | }; | 1049 | }; |
| 541 | 1050 | ||
| 542 | u32 separate_alpha; | 1051 | u32 separate_alpha; |
| 543 | Equation equation_rgb; | 1052 | Equation color_op; |
| 544 | Factor factor_source_rgb; | 1053 | Factor color_source; |
| 545 | Factor factor_dest_rgb; | 1054 | Factor color_dest; |
| 546 | Equation equation_a; | 1055 | Equation alpha_op; |
| 547 | Factor factor_source_a; | 1056 | Factor alpha_source; |
| 548 | Factor factor_dest_a; | 1057 | u32 enable_global_color_key; |
| 549 | INSERT_PADDING_WORDS_NOINIT(1); | 1058 | Factor alpha_dest; |
| 550 | }; | 1059 | |
| 551 | 1060 | u32 single_rop_control_enable; | |
| 552 | enum class TessellationPrimitive : u32 { | 1061 | u32 enable[NumRenderTargets]; |
| 553 | Isolines = 0, | ||
| 554 | Triangles = 1, | ||
| 555 | Quads = 2, | ||
| 556 | }; | 1062 | }; |
| 557 | 1063 | ||
| 558 | enum class TessellationSpacing : u32 { | 1064 | struct BlendPerTarget { |
| 559 | Equal = 0, | 1065 | u32 separate_alpha; |
| 560 | FractionalOdd = 1, | 1066 | Blend::Equation color_op; |
| 561 | FractionalEven = 2, | 1067 | Blend::Factor color_source; |
| 1068 | Blend::Factor color_dest; | ||
| 1069 | Blend::Equation alpha_op; | ||
| 1070 | Blend::Factor alpha_source; | ||
| 1071 | Blend::Factor alpha_dest; | ||
| 1072 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 562 | }; | 1073 | }; |
| 1074 | static_assert(sizeof(BlendPerTarget) == 0x20); | ||
| 563 | 1075 | ||
| 564 | enum class PolygonMode : u32 { | 1076 | enum class PolygonMode : u32 { |
| 565 | Point = 0x1b00, | 1077 | Point = 0x1B00, |
| 566 | Line = 0x1b01, | 1078 | Line = 0x1B01, |
| 567 | Fill = 0x1b02, | 1079 | Fill = 0x1B02, |
| 568 | }; | 1080 | }; |
| 569 | 1081 | ||
| 570 | enum class ShadowRamControl : u32 { | 1082 | enum class ShadowRamControl : u32 { |
| @@ -589,18 +1101,22 @@ public: | |||
| 589 | NegativeW = 7, | 1101 | NegativeW = 7, |
| 590 | }; | 1102 | }; |
| 591 | 1103 | ||
| 592 | enum class SamplerIndex : u32 { | 1104 | enum class SamplerBinding : u32 { |
| 593 | Independently = 0, | 1105 | Independently = 0, |
| 594 | ViaHeaderIndex = 1, | 1106 | ViaHeaderBinding = 1, |
| 595 | }; | 1107 | }; |
| 596 | 1108 | ||
| 597 | struct TileMode { | 1109 | struct TileMode { |
| 1110 | enum class DimensionControl : u32 { | ||
| 1111 | DepthDefinesArray = 0, | ||
| 1112 | DepthDefinesDepth = 1, | ||
| 1113 | }; | ||
| 598 | union { | 1114 | union { |
| 599 | BitField<0, 4, u32> block_width; | 1115 | BitField<0, 4, u32> block_width; |
| 600 | BitField<4, 4, u32> block_height; | 1116 | BitField<4, 4, u32> block_height; |
| 601 | BitField<8, 4, u32> block_depth; | 1117 | BitField<8, 4, u32> block_depth; |
| 602 | BitField<12, 1, u32> is_pitch_linear; | 1118 | BitField<12, 1, u32> is_pitch_linear; |
| 603 | BitField<16, 1, u32> is_3d; | 1119 | BitField<16, 1, DimensionControl> dim_control; |
| 604 | }; | 1120 | }; |
| 605 | }; | 1121 | }; |
| 606 | static_assert(sizeof(TileMode) == 4); | 1122 | static_assert(sizeof(TileMode) == 4); |
| @@ -616,23 +1132,25 @@ public: | |||
| 616 | BitField<0, 16, u32> depth; | 1132 | BitField<0, 16, u32> depth; |
| 617 | BitField<16, 1, u32> volume; | 1133 | BitField<16, 1, u32> volume; |
| 618 | }; | 1134 | }; |
| 619 | u32 layer_stride; | 1135 | u32 array_pitch; |
| 620 | u32 base_layer; | 1136 | u32 base_layer; |
| 621 | INSERT_PADDING_WORDS_NOINIT(7); | 1137 | u32 mark_ieee_clean; |
| 1138 | INSERT_PADDING_BYTES_NOINIT(0x18); | ||
| 622 | 1139 | ||
| 623 | GPUVAddr Address() const { | 1140 | GPUVAddr Address() const { |
| 624 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 1141 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 625 | address_low); | 1142 | address_low); |
| 626 | } | 1143 | } |
| 627 | }; | 1144 | }; |
| 1145 | static_assert(sizeof(RenderTargetConfig) == 0x40); | ||
| 628 | 1146 | ||
| 629 | struct ColorMask { | 1147 | struct ColorMask { |
| 630 | union { | 1148 | union { |
| 631 | u32 raw; | 1149 | u32 raw; |
| 632 | BitField<0, 4, u32> R; | 1150 | BitField<0, 1, u32> R; |
| 633 | BitField<4, 4, u32> G; | 1151 | BitField<4, 1, u32> G; |
| 634 | BitField<8, 4, u32> B; | 1152 | BitField<8, 1, u32> B; |
| 635 | BitField<12, 4, u32> A; | 1153 | BitField<12, 1, u32> A; |
| 636 | }; | 1154 | }; |
| 637 | }; | 1155 | }; |
| 638 | 1156 | ||
| @@ -643,6 +1161,7 @@ public: | |||
| 643 | f32 translate_x; | 1161 | f32 translate_x; |
| 644 | f32 translate_y; | 1162 | f32 translate_y; |
| 645 | f32 translate_z; | 1163 | f32 translate_z; |
| 1164 | |||
| 646 | union { | 1165 | union { |
| 647 | u32 raw; | 1166 | u32 raw; |
| 648 | BitField<0, 3, ViewportSwizzle> x; | 1167 | BitField<0, 3, ViewportSwizzle> x; |
| @@ -650,7 +1169,11 @@ public: | |||
| 650 | BitField<8, 3, ViewportSwizzle> z; | 1169 | BitField<8, 3, ViewportSwizzle> z; |
| 651 | BitField<12, 3, ViewportSwizzle> w; | 1170 | BitField<12, 3, ViewportSwizzle> w; |
| 652 | } swizzle; | 1171 | } swizzle; |
| 653 | INSERT_PADDING_WORDS_NOINIT(1); | 1172 | |
| 1173 | union { | ||
| 1174 | BitField<0, 5, u32> x; | ||
| 1175 | BitField<8, 5, u32> y; | ||
| 1176 | } snap_grid_precision; | ||
| 654 | 1177 | ||
| 655 | Common::Rectangle<f32> GetRect() const { | 1178 | Common::Rectangle<f32> GetRect() const { |
| 656 | return { | 1179 | return { |
| @@ -677,21 +1200,14 @@ public: | |||
| 677 | return translate_y + std::fabs(scale_y) - GetY(); | 1200 | return translate_y + std::fabs(scale_y) - GetY(); |
| 678 | } | 1201 | } |
| 679 | }; | 1202 | }; |
| 1203 | static_assert(sizeof(ViewportTransform) == 0x20); | ||
| 680 | 1204 | ||
| 681 | struct ScissorTest { | 1205 | struct Viewport { |
| 682 | u32 enable; | 1206 | enum class PixelCenter : u32 { |
| 683 | union { | 1207 | HalfIntegers = 0, |
| 684 | BitField<0, 16, u32> min_x; | 1208 | Integers = 1, |
| 685 | BitField<16, 16, u32> max_x; | ||
| 686 | }; | 1209 | }; |
| 687 | union { | ||
| 688 | BitField<0, 16, u32> min_y; | ||
| 689 | BitField<16, 16, u32> max_y; | ||
| 690 | }; | ||
| 691 | u32 fill; | ||
| 692 | }; | ||
| 693 | 1210 | ||
| 694 | struct ViewPort { | ||
| 695 | union { | 1211 | union { |
| 696 | BitField<0, 16, u32> x; | 1212 | BitField<0, 16, u32> x; |
| 697 | BitField<16, 16, u32> width; | 1213 | BitField<16, 16, u32> width; |
| @@ -703,726 +1219,1822 @@ public: | |||
| 703 | float depth_range_near; | 1219 | float depth_range_near; |
| 704 | float depth_range_far; | 1220 | float depth_range_far; |
| 705 | }; | 1221 | }; |
| 1222 | static_assert(sizeof(Viewport) == 0x10); | ||
| 706 | 1223 | ||
| 707 | struct TransformFeedbackBinding { | 1224 | struct Window { |
| 708 | u32 buffer_enable; | 1225 | union { |
| 709 | u32 address_high; | 1226 | BitField<0, 16, u32> x_min; |
| 710 | u32 address_low; | 1227 | BitField<16, 16, u32> x_max; |
| 711 | s32 buffer_size; | 1228 | }; |
| 712 | s32 buffer_offset; | 1229 | union { |
| 713 | INSERT_PADDING_WORDS_NOINIT(3); | 1230 | BitField<0, 16, u32> y_min; |
| 714 | 1231 | BitField<16, 16, u32> y_max; | |
| 715 | GPUVAddr Address() const { | 1232 | }; |
| 716 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 717 | address_low); | ||
| 718 | } | ||
| 719 | }; | 1233 | }; |
| 720 | static_assert(sizeof(TransformFeedbackBinding) == 32); | 1234 | static_assert(sizeof(Window) == 0x8); |
| 721 | 1235 | ||
| 722 | struct TransformFeedbackLayout { | 1236 | struct ClipIdExtent { |
| 723 | u32 stream; | 1237 | union { |
| 724 | u32 varying_count; | 1238 | BitField<0, 16, u32> x; |
| 725 | u32 stride; | 1239 | BitField<16, 16, u32> width; |
| 726 | INSERT_PADDING_WORDS_NOINIT(1); | 1240 | }; |
| 1241 | union { | ||
| 1242 | BitField<0, 16, u32> y; | ||
| 1243 | BitField<16, 16, u32> height; | ||
| 1244 | }; | ||
| 1245 | }; | ||
| 1246 | static_assert(sizeof(ClipIdExtent) == 0x8); | ||
| 1247 | |||
| 1248 | enum class VisibleCallLimit : u32 { | ||
| 1249 | Limit0 = 0, | ||
| 1250 | Limit1 = 1, | ||
| 1251 | Limit2 = 2, | ||
| 1252 | Limit4 = 3, | ||
| 1253 | Limit8 = 4, | ||
| 1254 | Limit16 = 5, | ||
| 1255 | Limit32 = 6, | ||
| 1256 | Limit64 = 7, | ||
| 1257 | Limit128 = 8, | ||
| 1258 | None = 15, | ||
| 727 | }; | 1259 | }; |
| 728 | static_assert(sizeof(TransformFeedbackLayout) == 16); | ||
| 729 | |||
| 730 | bool IsShaderConfigEnabled(std::size_t index) const { | ||
| 731 | // The VertexB is always enabled. | ||
| 732 | if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) { | ||
| 733 | return true; | ||
| 734 | } | ||
| 735 | return shader_config[index].enable != 0; | ||
| 736 | } | ||
| 737 | |||
| 738 | bool IsShaderConfigEnabled(Regs::ShaderProgram type) const { | ||
| 739 | return IsShaderConfigEnabled(static_cast<std::size_t>(type)); | ||
| 740 | } | ||
| 741 | 1260 | ||
| 742 | union { | 1261 | struct StatisticsCounter { |
| 743 | struct { | 1262 | union { |
| 744 | INSERT_PADDING_WORDS_NOINIT(0x44); | 1263 | BitField<0, 1, u32> da_vertices; |
| 1264 | BitField<1, 1, u32> da_primitives; | ||
| 1265 | BitField<2, 1, u32> vs_invocations; | ||
| 1266 | BitField<3, 1, u32> gs_invocations; | ||
| 1267 | BitField<4, 1, u32> gs_primitives; | ||
| 1268 | BitField<5, 1, u32> streaming_primitives_succeeded; | ||
| 1269 | BitField<6, 1, u32> streaming_primitives_needed; | ||
| 1270 | BitField<7, 1, u32> clipper_invocations; | ||
| 1271 | BitField<8, 1, u32> clipper_primitives; | ||
| 1272 | BitField<9, 1, u32> ps_invocations; | ||
| 1273 | BitField<11, 1, u32> ti_invocations; | ||
| 1274 | BitField<12, 1, u32> ts_invocations; | ||
| 1275 | BitField<13, 1, u32> ts_primitives; | ||
| 1276 | BitField<14, 1, u32> total_streaming_primitives_needed_succeeded; | ||
| 1277 | BitField<10, 1, u32> vtg_primitives_out; | ||
| 1278 | BitField<15, 1, u32> alpha_beta_clocks; | ||
| 1279 | }; | ||
| 1280 | }; | ||
| 745 | 1281 | ||
| 746 | u32 wait_for_idle; | 1282 | struct ClearRect { |
| 1283 | union { | ||
| 1284 | BitField<0, 16, u32> x_min; | ||
| 1285 | BitField<16, 16, u32> x_max; | ||
| 1286 | }; | ||
| 1287 | union { | ||
| 1288 | BitField<0, 16, u32> y_min; | ||
| 1289 | BitField<16, 16, u32> y_max; | ||
| 1290 | }; | ||
| 1291 | }; | ||
| 747 | 1292 | ||
| 748 | struct { | 1293 | struct VertexBuffer { |
| 749 | u32 upload_address; | 1294 | u32 first; |
| 750 | u32 data; | 1295 | u32 count; |
| 751 | u32 entry; | 1296 | }; |
| 752 | u32 bind; | ||
| 753 | } macros; | ||
| 754 | 1297 | ||
| 755 | ShadowRamControl shadow_ram_control; | 1298 | struct InvalidateShaderCacheNoWFI { |
| 1299 | union { | ||
| 1300 | BitField<0, 1, u32> instruction; | ||
| 1301 | BitField<4, 1, u32> global_data; | ||
| 1302 | BitField<12, 1, u32> constant; | ||
| 1303 | }; | ||
| 1304 | }; | ||
| 756 | 1305 | ||
| 757 | INSERT_PADDING_WORDS_NOINIT(0x16); | 1306 | struct ZCullSerialization { |
| 1307 | enum class Applied : u32 { | ||
| 1308 | Always = 0, | ||
| 1309 | LateZ = 1, | ||
| 1310 | OutOfGamutZ = 2, | ||
| 1311 | LateZOrOutOfGamutZ = 3, | ||
| 1312 | }; | ||
| 1313 | union { | ||
| 1314 | BitField<0, 1, u32> enable; | ||
| 1315 | BitField<4, 2, Applied> applied; | ||
| 1316 | }; | ||
| 1317 | }; | ||
| 758 | 1318 | ||
| 759 | Upload::Registers upload; | 1319 | struct ZCullDirFormat { |
| 760 | struct { | 1320 | enum class Zdir : u32 { |
| 761 | union { | 1321 | Less = 0, |
| 762 | BitField<0, 1, u32> linear; | 1322 | Greater = 1, |
| 763 | }; | 1323 | }; |
| 764 | } exec_upload; | 1324 | enum class Zformat : u32 { |
| 1325 | MSB = 0, | ||
| 1326 | FP = 1, | ||
| 1327 | Ztrick = 2, | ||
| 1328 | Zf32 = 3, | ||
| 1329 | }; | ||
| 765 | 1330 | ||
| 766 | u32 data_upload; | 1331 | union { |
| 1332 | BitField<0, 16, Zdir> dir; | ||
| 1333 | BitField<16, 16, Zformat> format; | ||
| 1334 | }; | ||
| 1335 | }; | ||
| 767 | 1336 | ||
| 768 | INSERT_PADDING_WORDS_NOINIT(0x16); | 1337 | struct IteratedBlend { |
| 1338 | union { | ||
| 1339 | BitField<0, 1, u32> enable; | ||
| 1340 | BitField<1, 1, u32> enable_alpha; | ||
| 1341 | }; | ||
| 1342 | u32 pass_count; | ||
| 1343 | }; | ||
| 769 | 1344 | ||
| 770 | u32 force_early_fragment_tests; | 1345 | struct ZCullCriterion { |
| 1346 | enum class Sfunc : u32 { | ||
| 1347 | Never = 0, | ||
| 1348 | Less = 1, | ||
| 1349 | Equal = 2, | ||
| 1350 | LessOrEqual = 3, | ||
| 1351 | Greater = 4, | ||
| 1352 | NotEqual = 5, | ||
| 1353 | GreaterOrEqual = 6, | ||
| 1354 | Always = 7, | ||
| 1355 | }; | ||
| 771 | 1356 | ||
| 772 | INSERT_PADDING_WORDS_NOINIT(0x2D); | 1357 | union { |
| 1358 | BitField<0, 8, Sfunc> sfunc; | ||
| 1359 | BitField<8, 1, u32> no_invalidate; | ||
| 1360 | BitField<9, 1, u32> force_match; | ||
| 1361 | BitField<16, 8, u32> sref; | ||
| 1362 | BitField<24, 8, u32> smask; | ||
| 1363 | }; | ||
| 1364 | }; | ||
| 773 | 1365 | ||
| 774 | struct { | 1366 | struct LoadIteratedBlend { |
| 775 | union { | 1367 | enum class Test : u32 { |
| 776 | BitField<0, 16, u32> sync_point; | 1368 | False = 0, |
| 777 | BitField<16, 1, u32> unknown; | 1369 | True = 1, |
| 778 | BitField<20, 1, u32> increment; | 1370 | Equal = 2, |
| 779 | }; | 1371 | NotEqual = 3, |
| 780 | } sync_info; | 1372 | LessThan = 4, |
| 1373 | LessOrEqual = 5, | ||
| 1374 | Greater = 6, | ||
| 1375 | GreaterOrEqual = 7, | ||
| 1376 | }; | ||
| 1377 | enum class Operation : u32 { | ||
| 1378 | AddProducts = 0, | ||
| 1379 | SubProducts = 1, | ||
| 1380 | Min = 2, | ||
| 1381 | Max = 3, | ||
| 1382 | Reciprocal = 4, | ||
| 1383 | Add = 5, | ||
| 1384 | Sub = 6, | ||
| 1385 | }; | ||
| 1386 | enum class OperandA : u32 { | ||
| 1387 | SrcRGB = 0, | ||
| 1388 | DstRGB = 1, | ||
| 1389 | SrcAAA = 2, | ||
| 1390 | DstAAA = 3, | ||
| 1391 | Temp0_RGB = 4, | ||
| 1392 | Temp1_RGB = 5, | ||
| 1393 | Temp2_RGB = 6, | ||
| 1394 | PBR_RGB = 7, | ||
| 1395 | }; | ||
| 1396 | enum class OperandB : u32 { | ||
| 1397 | Zero = 0, | ||
| 1398 | One = 1, | ||
| 1399 | SrcRGB = 2, | ||
| 1400 | SrcAAA = 3, | ||
| 1401 | OneMinusSrcAAA = 4, | ||
| 1402 | DstRGB = 5, | ||
| 1403 | DstAAA = 6, | ||
| 1404 | OneMinusDstAAA = 7, | ||
| 1405 | Temp0_RGB = 9, | ||
| 1406 | Temp1_RGB = 10, | ||
| 1407 | Temp2_RGB = 11, | ||
| 1408 | PBR_RGB = 12, | ||
| 1409 | ConstRGB = 13, | ||
| 1410 | ZeroATimesB = 14, | ||
| 1411 | }; | ||
| 1412 | enum class Swizzle : u32 { | ||
| 1413 | RGB = 0, | ||
| 1414 | GBR = 1, | ||
| 1415 | RRR = 2, | ||
| 1416 | GGG = 3, | ||
| 1417 | BBB = 4, | ||
| 1418 | RToA = 5, | ||
| 1419 | }; | ||
| 1420 | enum class WriteMask : u32 { | ||
| 1421 | RGB = 0, | ||
| 1422 | ROnly = 1, | ||
| 1423 | GOnly = 2, | ||
| 1424 | BOnly = 3, | ||
| 1425 | }; | ||
| 1426 | enum class Pass : u32 { | ||
| 1427 | Temp0 = 0, | ||
| 1428 | Temp1 = 1, | ||
| 1429 | Temp2 = 2, | ||
| 1430 | None = 3, | ||
| 1431 | }; | ||
| 781 | 1432 | ||
| 782 | INSERT_PADDING_WORDS_NOINIT(0x15); | 1433 | u32 instruction_ptr; |
| 1434 | union { | ||
| 1435 | BitField<0, 3, Test> test; | ||
| 1436 | BitField<3, 3, Operation> operation; | ||
| 1437 | BitField<6, 3, u32> const_input; | ||
| 1438 | BitField<9, 3, OperandA> operand_a; | ||
| 1439 | BitField<12, 4, OperandB> operand_b; | ||
| 1440 | BitField<16, 3, OperandA> operand_c; | ||
| 1441 | BitField<19, 4, OperandB> operand_d; | ||
| 1442 | BitField<23, 3, Swizzle> output_swizzle; | ||
| 1443 | BitField<26, 2, WriteMask> output_mask; | ||
| 1444 | BitField<28, 2, Pass> output_pass; | ||
| 1445 | BitField<31, 1, u32> test_enabled; | ||
| 1446 | }; | ||
| 1447 | }; | ||
| 783 | 1448 | ||
| 784 | union { | 1449 | struct ScissorTest { |
| 785 | BitField<0, 2, TessellationPrimitive> prim; | 1450 | u32 enable; |
| 786 | BitField<4, 2, TessellationSpacing> spacing; | 1451 | union { |
| 787 | BitField<8, 1, u32> cw; | 1452 | BitField<0, 16, u32> min_x; |
| 788 | BitField<9, 1, u32> connected; | 1453 | BitField<16, 16, u32> max_x; |
| 789 | } tess_mode; | 1454 | }; |
| 1455 | union { | ||
| 1456 | BitField<0, 16, u32> min_y; | ||
| 1457 | BitField<16, 16, u32> max_y; | ||
| 1458 | }; | ||
| 1459 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 1460 | }; | ||
| 1461 | static_assert(sizeof(ScissorTest) == 0x10); | ||
| 790 | 1462 | ||
| 791 | std::array<f32, 4> tess_level_outer; | 1463 | struct VPCPerf { |
| 792 | std::array<f32, 2> tess_level_inner; | 1464 | union { |
| 1465 | BitField<0, 8, u32> culled_small_lines; | ||
| 1466 | BitField<8, 8, u32> culled_small_triangles; | ||
| 1467 | BitField<16, 8, u32> nonculled_lines_and_points; | ||
| 1468 | BitField<24, 8, u32> nonculled_triangles; | ||
| 1469 | }; | ||
| 1470 | }; | ||
| 793 | 1471 | ||
| 794 | INSERT_PADDING_WORDS_NOINIT(0x10); | 1472 | struct ConstantColorRendering { |
| 1473 | u32 enabled; | ||
| 1474 | u32 red; | ||
| 1475 | u32 green; | ||
| 1476 | u32 blue; | ||
| 1477 | u32 alpha; | ||
| 1478 | }; | ||
| 795 | 1479 | ||
| 796 | u32 rasterize_enable; | 1480 | struct VertexStreamSubstitute { |
| 1481 | u32 address_high; | ||
| 1482 | u32 address_low; | ||
| 797 | 1483 | ||
| 798 | std::array<TransformFeedbackBinding, NumTransformFeedbackBuffers> tfb_bindings; | 1484 | GPUVAddr Address() const { |
| 1485 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 1486 | address_low); | ||
| 1487 | } | ||
| 1488 | }; | ||
| 799 | 1489 | ||
| 800 | INSERT_PADDING_WORDS_NOINIT(0xC0); | 1490 | struct VTGWarpWatermarks { |
| 1491 | union { | ||
| 1492 | BitField<0, 16, u32> low; | ||
| 1493 | BitField<16, 16, u32> high; | ||
| 1494 | }; | ||
| 1495 | }; | ||
| 801 | 1496 | ||
| 802 | std::array<TransformFeedbackLayout, NumTransformFeedbackBuffers> tfb_layouts; | 1497 | struct SampleMask { |
| 1498 | struct Target { | ||
| 1499 | union { | ||
| 1500 | BitField<0, 1, u32> raster_out; | ||
| 1501 | BitField<4, 1, u32> color_target; | ||
| 1502 | }; | ||
| 1503 | u32 target; | ||
| 1504 | }; | ||
| 1505 | struct Pos { | ||
| 1506 | u32 x0_y0; | ||
| 1507 | u32 x1_y0; | ||
| 1508 | u32 x0_y1; | ||
| 1509 | u32 x1_y1; | ||
| 1510 | }; | ||
| 1511 | }; | ||
| 803 | 1512 | ||
| 804 | INSERT_PADDING_WORDS_NOINIT(0x1); | 1513 | enum class NonMultisampledZ : u32 { |
| 1514 | PerSample = 0, | ||
| 1515 | PixelCenter = 1, | ||
| 1516 | }; | ||
| 805 | 1517 | ||
| 806 | u32 tfb_enabled; | 1518 | enum class TIRMode : u32 { |
| 1519 | Disabled = 0, | ||
| 1520 | RasterNTargetM = 1, | ||
| 1521 | }; | ||
| 807 | 1522 | ||
| 808 | INSERT_PADDING_WORDS_NOINIT(0x2E); | 1523 | enum class AntiAliasRaster : u32 { |
| 1524 | Mode1x1 = 0, | ||
| 1525 | Mode2x2 = 2, | ||
| 1526 | Mode4x2_D3D = 4, | ||
| 1527 | Mode2x1_D3D = 5, | ||
| 1528 | Mode4x4 = 6, | ||
| 1529 | }; | ||
| 809 | 1530 | ||
| 810 | std::array<RenderTargetConfig, NumRenderTargets> rt; | 1531 | struct SurfaceClipIDMemory { |
| 1532 | u32 address_high; | ||
| 1533 | u32 address_low; | ||
| 811 | 1534 | ||
| 812 | std::array<ViewportTransform, NumViewports> viewport_transform; | 1535 | GPUVAddr Address() const { |
| 1536 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 1537 | address_low); | ||
| 1538 | } | ||
| 1539 | }; | ||
| 813 | 1540 | ||
| 814 | std::array<ViewPort, NumViewports> viewports; | 1541 | struct TIRModulation { |
| 1542 | enum class Component : u32 { | ||
| 1543 | None = 0, | ||
| 1544 | RGB = 1, | ||
| 1545 | AlphaOnly = 2, | ||
| 1546 | RGBA = 3, | ||
| 1547 | }; | ||
| 1548 | enum class Function : u32 { | ||
| 1549 | Linear = 0, | ||
| 1550 | Table = 1, | ||
| 1551 | }; | ||
| 1552 | Component component; | ||
| 1553 | Function function; | ||
| 1554 | }; | ||
| 815 | 1555 | ||
| 816 | INSERT_PADDING_WORDS_NOINIT(0x1D); | 1556 | struct Zeta { |
| 1557 | u32 address_high; | ||
| 1558 | u32 address_low; | ||
| 1559 | Tegra::DepthFormat format; | ||
| 1560 | TileMode tile_mode; | ||
| 1561 | u32 array_pitch; | ||
| 817 | 1562 | ||
| 818 | struct { | 1563 | GPUVAddr Address() const { |
| 819 | u32 first; | 1564 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 820 | u32 count; | 1565 | address_low); |
| 821 | } vertex_buffer; | 1566 | } |
| 1567 | }; | ||
| 822 | 1568 | ||
| 823 | DepthMode depth_mode; | 1569 | struct SurfaceClip { |
| 1570 | union { | ||
| 1571 | BitField<0, 16, u32> x; | ||
| 1572 | BitField<16, 16, u32> width; | ||
| 1573 | }; | ||
| 1574 | union { | ||
| 1575 | BitField<0, 16, u32> y; | ||
| 1576 | BitField<16, 16, u32> height; | ||
| 1577 | }; | ||
| 1578 | }; | ||
| 824 | 1579 | ||
| 825 | float clear_color[4]; | 1580 | enum class L2CacheControlPolicy : u32 { |
| 826 | float clear_depth; | 1581 | First = 0, |
| 1582 | Normal = 1, | ||
| 1583 | Last = 2, | ||
| 1584 | }; | ||
| 827 | 1585 | ||
| 828 | INSERT_PADDING_WORDS_NOINIT(0x3); | 1586 | struct L2CacheVAFRequests { |
| 1587 | union { | ||
| 1588 | BitField<0, 1, u32> system_memory_volatile; | ||
| 1589 | BitField<4, 2, L2CacheControlPolicy> policy; | ||
| 1590 | }; | ||
| 1591 | }; | ||
| 829 | 1592 | ||
| 830 | s32 clear_stencil; | 1593 | enum class ViewportMulticast : u32 { |
| 1594 | ViewportOrder = 0, | ||
| 1595 | PrimitiveOrder = 1, | ||
| 1596 | }; | ||
| 831 | 1597 | ||
| 832 | INSERT_PADDING_WORDS_NOINIT(0x2); | 1598 | struct TIRModulationCoeff { |
| 1599 | union { | ||
| 1600 | BitField<0, 8, u32> table_v0; | ||
| 1601 | BitField<8, 8, u32> table_v1; | ||
| 1602 | BitField<16, 8, u32> table_v2; | ||
| 1603 | BitField<24, 8, u32> table_v3; | ||
| 1604 | }; | ||
| 1605 | }; | ||
| 1606 | static_assert(sizeof(TIRModulationCoeff) == 0x4); | ||
| 833 | 1607 | ||
| 834 | PolygonMode polygon_mode_front; | 1608 | struct ReduceColorThreshold { |
| 835 | PolygonMode polygon_mode_back; | 1609 | union { |
| 1610 | BitField<0, 8, u32> all_hit_once; | ||
| 1611 | BitField<16, 8, u32> all_covered; | ||
| 1612 | }; | ||
| 1613 | }; | ||
| 836 | 1614 | ||
| 837 | INSERT_PADDING_WORDS_NOINIT(0x3); | 1615 | struct ClearControl { |
| 1616 | union { | ||
| 1617 | BitField<0, 1, u32> respect_stencil_mask; | ||
| 1618 | BitField<4, 1, u32> use_clear_rect; | ||
| 1619 | BitField<8, 1, u32> use_scissor; | ||
| 1620 | BitField<12, 1, u32> use_viewport_clip0; | ||
| 1621 | }; | ||
| 1622 | }; | ||
| 838 | 1623 | ||
| 839 | u32 polygon_offset_point_enable; | 1624 | struct L2CacheRopNonInterlockedReads { |
| 840 | u32 polygon_offset_line_enable; | 1625 | union { |
| 841 | u32 polygon_offset_fill_enable; | 1626 | BitField<4, 2, L2CacheControlPolicy> policy; |
| 1627 | }; | ||
| 1628 | }; | ||
| 842 | 1629 | ||
| 843 | u32 patch_vertices; | 1630 | struct VertexOutputAttributeSkipMasks { |
| 1631 | struct Attributes { | ||
| 1632 | union { | ||
| 1633 | BitField<0, 1, u32> attribute0_comp0; | ||
| 1634 | BitField<1, 1, u32> attribute0_comp1; | ||
| 1635 | BitField<2, 1, u32> attribute0_comp2; | ||
| 1636 | BitField<3, 1, u32> attribute0_comp3; | ||
| 1637 | BitField<4, 1, u32> attribute1_comp0; | ||
| 1638 | BitField<5, 1, u32> attribute1_comp1; | ||
| 1639 | BitField<6, 1, u32> attribute1_comp2; | ||
| 1640 | BitField<7, 1, u32> attribute1_comp3; | ||
| 1641 | BitField<8, 1, u32> attribute2_comp0; | ||
| 1642 | BitField<9, 1, u32> attribute2_comp1; | ||
| 1643 | BitField<10, 1, u32> attribute2_comp2; | ||
| 1644 | BitField<11, 1, u32> attribute2_comp3; | ||
| 1645 | BitField<12, 1, u32> attribute3_comp0; | ||
| 1646 | BitField<13, 1, u32> attribute3_comp1; | ||
| 1647 | BitField<14, 1, u32> attribute3_comp2; | ||
| 1648 | BitField<15, 1, u32> attribute3_comp3; | ||
| 1649 | BitField<16, 1, u32> attribute4_comp0; | ||
| 1650 | BitField<17, 1, u32> attribute4_comp1; | ||
| 1651 | BitField<18, 1, u32> attribute4_comp2; | ||
| 1652 | BitField<19, 1, u32> attribute4_comp3; | ||
| 1653 | BitField<20, 1, u32> attribute5_comp0; | ||
| 1654 | BitField<21, 1, u32> attribute5_comp1; | ||
| 1655 | BitField<22, 1, u32> attribute5_comp2; | ||
| 1656 | BitField<23, 1, u32> attribute5_comp3; | ||
| 1657 | BitField<24, 1, u32> attribute6_comp0; | ||
| 1658 | BitField<25, 1, u32> attribute6_comp1; | ||
| 1659 | BitField<26, 1, u32> attribute6_comp2; | ||
| 1660 | BitField<27, 1, u32> attribute6_comp3; | ||
| 1661 | BitField<28, 1, u32> attribute7_comp0; | ||
| 1662 | BitField<29, 1, u32> attribute7_comp1; | ||
| 1663 | BitField<30, 1, u32> attribute7_comp2; | ||
| 1664 | BitField<31, 1, u32> attribute7_comp3; | ||
| 1665 | }; | ||
| 1666 | }; | ||
| 844 | 1667 | ||
| 845 | INSERT_PADDING_WORDS_NOINIT(0x4); | 1668 | std::array<Attributes, 2> a; |
| 1669 | std::array<Attributes, 2> b; | ||
| 1670 | }; | ||
| 846 | 1671 | ||
| 847 | u32 fragment_barrier; | 1672 | struct TIRControl { |
| 1673 | union { | ||
| 1674 | BitField<0, 1, u32> z_pass_pixel_count_use_raster_samples; | ||
| 1675 | BitField<4, 1, u32> alpha_coverage_use_raster_samples; | ||
| 1676 | BitField<1, 1, u32> reduce_coverage; | ||
| 1677 | }; | ||
| 1678 | }; | ||
| 848 | 1679 | ||
| 849 | INSERT_PADDING_WORDS_NOINIT(0x7); | 1680 | enum class FillViaTriangleMode : u32 { |
| 1681 | Disabled = 0, | ||
| 1682 | FillAll = 1, | ||
| 1683 | FillBoundingBox = 2, | ||
| 1684 | }; | ||
| 850 | 1685 | ||
| 851 | std::array<ScissorTest, NumViewports> scissor_test; | 1686 | struct PsTicketDispenserValue { |
| 1687 | union { | ||
| 1688 | BitField<0, 8, u32> index; | ||
| 1689 | BitField<8, 16, u32> value; | ||
| 1690 | }; | ||
| 1691 | }; | ||
| 852 | 1692 | ||
| 853 | INSERT_PADDING_WORDS_NOINIT(0x15); | 1693 | struct RegisterWatermarks { |
| 1694 | union { | ||
| 1695 | BitField<0, 16, u32> low; | ||
| 1696 | BitField<16, 16, u32> high; | ||
| 1697 | }; | ||
| 1698 | }; | ||
| 854 | 1699 | ||
| 855 | s32 stencil_back_func_ref; | 1700 | enum class InvalidateCacheLines : u32 { |
| 856 | u32 stencil_back_mask; | 1701 | All = 0, |
| 857 | u32 stencil_back_func_mask; | 1702 | One = 1, |
| 1703 | }; | ||
| 858 | 1704 | ||
| 859 | INSERT_PADDING_WORDS_NOINIT(0x5); | 1705 | struct InvalidateTextureDataCacheNoWfi { |
| 1706 | union { | ||
| 1707 | BitField<0, 1, InvalidateCacheLines> lines; | ||
| 1708 | BitField<4, 22, u32> tag; | ||
| 1709 | }; | ||
| 1710 | }; | ||
| 860 | 1711 | ||
| 861 | u32 invalidate_texture_data_cache; | 1712 | struct ZCullRegionEnable { |
| 1713 | union { | ||
| 1714 | BitField<0, 1, u32> enable_z; | ||
| 1715 | BitField<4, 1, u32> enable_stencil; | ||
| 1716 | BitField<1, 1, u32> rect_clear; | ||
| 1717 | BitField<2, 1, u32> use_rt_array_index; | ||
| 1718 | BitField<5, 16, u32> rt_array_index; | ||
| 1719 | BitField<3, 1, u32> make_conservative; | ||
| 1720 | }; | ||
| 1721 | }; | ||
| 862 | 1722 | ||
| 863 | INSERT_PADDING_WORDS_NOINIT(0x1); | 1723 | enum class FillMode : u32 { |
| 1724 | Point = 1, | ||
| 1725 | Wireframe = 2, | ||
| 1726 | Solid = 3, | ||
| 1727 | }; | ||
| 864 | 1728 | ||
| 865 | u32 tiled_cache_barrier; | 1729 | enum class ShadeMode : u32 { |
| 1730 | Flat = 0x1, | ||
| 1731 | Gouraud = 0x2, | ||
| 1732 | GL_Flat = 0x1D00, | ||
| 1733 | GL_Smooth = 0x1D01, | ||
| 1734 | }; | ||
| 866 | 1735 | ||
| 867 | INSERT_PADDING_WORDS_NOINIT(0x4); | 1736 | enum class AlphaToCoverageDither : u32 { |
| 1737 | Footprint_1x1 = 0, | ||
| 1738 | Footprint_2x2 = 1, | ||
| 1739 | Footprint_1x1_Virtual = 2, | ||
| 1740 | }; | ||
| 868 | 1741 | ||
| 869 | u32 color_mask_common; | 1742 | struct InlineIndex4x8Align { |
| 1743 | union { | ||
| 1744 | BitField<0, 30, u32> count; | ||
| 1745 | BitField<30, 2, u32> start; | ||
| 1746 | }; | ||
| 1747 | }; | ||
| 870 | 1748 | ||
| 871 | INSERT_PADDING_WORDS_NOINIT(0x2); | 1749 | struct InlineIndex4x8Index { |
| 1750 | union { | ||
| 1751 | BitField<0, 8, u32> index0; | ||
| 1752 | BitField<8, 8, u32> index1; | ||
| 1753 | BitField<16, 8, u32> index2; | ||
| 1754 | BitField<24, 8, u32> index3; | ||
| 1755 | }; | ||
| 1756 | }; | ||
| 872 | 1757 | ||
| 873 | f32 depth_bounds[2]; | 1758 | enum class D3DCullMode : u32 { |
| 1759 | None = 0, | ||
| 1760 | CW = 1, | ||
| 1761 | CCW = 2, | ||
| 1762 | }; | ||
| 874 | 1763 | ||
| 875 | INSERT_PADDING_WORDS_NOINIT(0x2); | 1764 | struct BlendColor { |
| 1765 | f32 r; | ||
| 1766 | f32 g; | ||
| 1767 | f32 b; | ||
| 1768 | f32 a; | ||
| 1769 | }; | ||
| 876 | 1770 | ||
| 877 | u32 rt_separate_frag_data; | 1771 | struct StencilOp { |
| 1772 | enum class Op : u32 { | ||
| 1773 | Keep_D3D = 1, | ||
| 1774 | Zero_D3D = 2, | ||
| 1775 | Replace_D3D = 3, | ||
| 1776 | IncrSaturate_D3D = 4, | ||
| 1777 | DecrSaturate_D3D = 5, | ||
| 1778 | Invert_D3D = 6, | ||
| 1779 | Incr_D3D = 7, | ||
| 1780 | Decr_D3D = 8, | ||
| 1781 | |||
| 1782 | Keep_GL = 0x1E00, | ||
| 1783 | Zero_GL = 0, | ||
| 1784 | Replace_GL = 0x1E01, | ||
| 1785 | IncrSaturate_GL = 0x1E02, | ||
| 1786 | DecrSaturate_GL = 0x1E03, | ||
| 1787 | Invert_GL = 0x150A, | ||
| 1788 | Incr_GL = 0x8507, | ||
| 1789 | Decr_GL = 0x8508, | ||
| 1790 | }; | ||
| 878 | 1791 | ||
| 879 | INSERT_PADDING_WORDS_NOINIT(0x1); | 1792 | Op fail; |
| 1793 | Op zfail; | ||
| 1794 | Op zpass; | ||
| 1795 | ComparisonOp func; | ||
| 1796 | }; | ||
| 880 | 1797 | ||
| 881 | u32 multisample_raster_enable; | 1798 | struct StencilFunc { |
| 882 | u32 multisample_raster_samples; | 1799 | s32 ref; |
| 883 | std::array<u32, 4> multisample_sample_mask; | 1800 | u32 func_mask; |
| 1801 | u32 mask; | ||
| 1802 | }; | ||
| 884 | 1803 | ||
| 885 | INSERT_PADDING_WORDS_NOINIT(0x5); | 1804 | struct PsSaturate { |
| 1805 | // Opposite of DepthMode | ||
| 1806 | enum class Depth : u32 { | ||
| 1807 | ZeroToOne = 0, | ||
| 1808 | MinusOneToOne = 1, | ||
| 1809 | }; | ||
| 886 | 1810 | ||
| 887 | struct { | 1811 | union { |
| 888 | u32 address_high; | 1812 | BitField<0, 1, u32> output0_enable; |
| 889 | u32 address_low; | 1813 | BitField<1, 1, Depth> output0_range; |
| 890 | Tegra::DepthFormat format; | 1814 | BitField<4, 1, u32> output1_enable; |
| 891 | TileMode tile_mode; | 1815 | BitField<5, 1, Depth> output1_range; |
| 892 | u32 layer_stride; | 1816 | BitField<8, 1, u32> output2_enable; |
| 1817 | BitField<9, 1, Depth> output2_range; | ||
| 1818 | BitField<12, 1, u32> output3_enable; | ||
| 1819 | BitField<13, 1, Depth> output3_range; | ||
| 1820 | BitField<16, 1, u32> output4_enable; | ||
| 1821 | BitField<17, 1, Depth> output4_range; | ||
| 1822 | BitField<20, 1, u32> output5_enable; | ||
| 1823 | BitField<21, 1, Depth> output5_range; | ||
| 1824 | BitField<24, 1, u32> output6_enable; | ||
| 1825 | BitField<25, 1, Depth> output6_range; | ||
| 1826 | BitField<28, 1, u32> output7_enable; | ||
| 1827 | BitField<29, 1, Depth> output7_range; | ||
| 1828 | }; | ||
| 893 | 1829 | ||
| 894 | GPUVAddr Address() const { | 1830 | bool AnyEnabled() const { |
| 895 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 1831 | return output0_enable || output1_enable || output2_enable || output3_enable || |
| 896 | address_low); | 1832 | output4_enable || output5_enable || output6_enable || output7_enable; |
| 897 | } | 1833 | } |
| 898 | } zeta; | 1834 | }; |
| 899 | 1835 | ||
| 900 | struct { | 1836 | struct WindowOrigin { |
| 901 | union { | 1837 | enum class Mode : u32 { |
| 902 | BitField<0, 16, u32> x; | 1838 | UpperLeft = 0, |
| 903 | BitField<16, 16, u32> width; | 1839 | LowerLeft = 1, |
| 904 | }; | 1840 | }; |
| 905 | union { | 1841 | union { |
| 906 | BitField<0, 16, u32> y; | 1842 | BitField<0, 1, Mode> mode; |
| 907 | BitField<16, 16, u32> height; | 1843 | BitField<4, 1, u32> flip_y; |
| 908 | }; | 1844 | }; |
| 909 | } render_area; | 1845 | }; |
| 910 | 1846 | ||
| 911 | INSERT_PADDING_WORDS_NOINIT(0x3F); | 1847 | struct IteratedBlendConstants { |
| 1848 | u32 r; | ||
| 1849 | u32 g; | ||
| 1850 | u32 b; | ||
| 1851 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 1852 | }; | ||
| 1853 | static_assert(sizeof(IteratedBlendConstants) == 0x10); | ||
| 912 | 1854 | ||
| 1855 | struct UserClip { | ||
| 1856 | struct Enable { | ||
| 913 | union { | 1857 | union { |
| 914 | BitField<0, 4, u32> stencil; | 1858 | u32 raw; |
| 915 | BitField<4, 4, u32> unknown; | 1859 | BitField<0, 1, u32> plane0; |
| 916 | BitField<8, 4, u32> scissor; | 1860 | BitField<1, 1, u32> plane1; |
| 917 | BitField<12, 4, u32> viewport; | 1861 | BitField<2, 1, u32> plane2; |
| 918 | } clear_flags; | 1862 | BitField<3, 1, u32> plane3; |
| 919 | 1863 | BitField<4, 1, u32> plane4; | |
| 920 | INSERT_PADDING_WORDS_NOINIT(0x10); | 1864 | BitField<5, 1, u32> plane5; |
| 921 | 1865 | BitField<6, 1, u32> plane6; | |
| 922 | u32 fill_rectangle; | 1866 | BitField<7, 1, u32> plane7; |
| 923 | 1867 | }; | |
| 924 | INSERT_PADDING_WORDS_NOINIT(0x2); | ||
| 925 | |||
| 926 | u32 conservative_raster_enable; | ||
| 927 | |||
| 928 | INSERT_PADDING_WORDS_NOINIT(0x5); | ||
| 929 | |||
| 930 | std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; | ||
| 931 | 1868 | ||
| 932 | std::array<MsaaSampleLocation, 4> multisample_sample_locations; | 1869 | bool AnyEnabled() const { |
| 1870 | return plane0 || plane1 || plane2 || plane3 || plane4 || plane5 || plane6 || | ||
| 1871 | plane7; | ||
| 1872 | } | ||
| 1873 | }; | ||
| 933 | 1874 | ||
| 934 | INSERT_PADDING_WORDS_NOINIT(0x2); | 1875 | struct Op { |
| 1876 | enum class ClipOrCull : u32 { | ||
| 1877 | Clip = 0, | ||
| 1878 | Cull = 1, | ||
| 1879 | }; | ||
| 935 | 1880 | ||
| 936 | union { | 1881 | union { |
| 937 | BitField<0, 1, u32> enable; | 1882 | u32 raw; |
| 938 | BitField<4, 3, u32> target; | 1883 | BitField<0, 1, ClipOrCull> plane0; |
| 939 | } multisample_coverage_to_color; | 1884 | BitField<4, 1, ClipOrCull> plane1; |
| 940 | 1885 | BitField<8, 1, ClipOrCull> plane2; | |
| 941 | INSERT_PADDING_WORDS_NOINIT(0x8); | 1886 | BitField<12, 1, ClipOrCull> plane3; |
| 942 | 1887 | BitField<16, 1, ClipOrCull> plane4; | |
| 943 | struct { | 1888 | BitField<20, 1, ClipOrCull> plane5; |
| 944 | union { | 1889 | BitField<24, 1, ClipOrCull> plane6; |
| 945 | BitField<0, 4, u32> count; | 1890 | BitField<28, 1, ClipOrCull> plane7; |
| 946 | BitField<4, 3, u32> map_0; | ||
| 947 | BitField<7, 3, u32> map_1; | ||
| 948 | BitField<10, 3, u32> map_2; | ||
| 949 | BitField<13, 3, u32> map_3; | ||
| 950 | BitField<16, 3, u32> map_4; | ||
| 951 | BitField<19, 3, u32> map_5; | ||
| 952 | BitField<22, 3, u32> map_6; | ||
| 953 | BitField<25, 3, u32> map_7; | ||
| 954 | }; | ||
| 955 | |||
| 956 | u32 Map(std::size_t index) const { | ||
| 957 | const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3, | ||
| 958 | map_4, map_5, map_6, map_7}; | ||
| 959 | ASSERT(index < maps.size()); | ||
| 960 | return maps[index]; | ||
| 961 | } | ||
| 962 | } rt_control; | ||
| 963 | |||
| 964 | INSERT_PADDING_WORDS_NOINIT(0x2); | ||
| 965 | |||
| 966 | u32 zeta_width; | ||
| 967 | u32 zeta_height; | ||
| 968 | union { | ||
| 969 | BitField<0, 16, u32> zeta_depth; | ||
| 970 | BitField<16, 1, u32> zeta_volume; | ||
| 971 | }; | 1891 | }; |
| 1892 | }; | ||
| 1893 | }; | ||
| 972 | 1894 | ||
| 973 | SamplerIndex sampler_index; | 1895 | struct AntiAliasAlphaControl { |
| 1896 | union { | ||
| 1897 | BitField<0, 1, u32> alpha_to_coverage; | ||
| 1898 | BitField<4, 1, u32> alpha_to_one; | ||
| 1899 | }; | ||
| 1900 | }; | ||
| 974 | 1901 | ||
| 975 | INSERT_PADDING_WORDS_NOINIT(0x2); | 1902 | struct RenderEnable { |
| 1903 | enum class Override : u32 { | ||
| 1904 | UseRenderEnable = 0, | ||
| 1905 | AlwaysRender = 1, | ||
| 1906 | NeverRender = 2, | ||
| 1907 | }; | ||
| 976 | 1908 | ||
| 977 | std::array<u32, 8> gp_passthrough_mask; | 1909 | enum class Mode : u32 { |
| 1910 | False = 0, | ||
| 1911 | True = 1, | ||
| 1912 | Conditional = 2, | ||
| 1913 | IfEqual = 3, | ||
| 1914 | IfNotEqual = 4, | ||
| 1915 | }; | ||
| 978 | 1916 | ||
| 979 | INSERT_PADDING_WORDS_NOINIT(0x1B); | 1917 | u32 address_high; |
| 1918 | u32 address_low; | ||
| 1919 | Mode mode; | ||
| 980 | 1920 | ||
| 981 | u32 depth_test_enable; | 1921 | GPUVAddr Address() const { |
| 1922 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 1923 | address_low); | ||
| 1924 | } | ||
| 1925 | }; | ||
| 982 | 1926 | ||
| 983 | INSERT_PADDING_WORDS_NOINIT(0x5); | 1927 | struct TexSampler { |
| 1928 | u32 address_high; | ||
| 1929 | u32 address_low; | ||
| 1930 | u32 limit; | ||
| 984 | 1931 | ||
| 985 | u32 independent_blend_enable; | 1932 | GPUVAddr Address() const { |
| 1933 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 1934 | address_low); | ||
| 1935 | } | ||
| 1936 | }; | ||
| 986 | 1937 | ||
| 987 | u32 depth_write_enabled; | 1938 | struct TexHeader { |
| 1939 | u32 address_high; | ||
| 1940 | u32 address_low; | ||
| 1941 | u32 limit; | ||
| 988 | 1942 | ||
| 989 | u32 alpha_test_enabled; | 1943 | GPUVAddr Address() const { |
| 1944 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 1945 | address_low); | ||
| 1946 | } | ||
| 1947 | }; | ||
| 990 | 1948 | ||
| 991 | INSERT_PADDING_WORDS_NOINIT(0x6); | 1949 | enum class ZCullRegionFormat : u32 { |
| 1950 | Z_4x4 = 0, | ||
| 1951 | ZS_4x4 = 1, | ||
| 1952 | Z_4x2 = 2, | ||
| 1953 | Z_2x4 = 3, | ||
| 1954 | Z_16x8_4x4 = 4, | ||
| 1955 | Z_8x8_4x2 = 5, | ||
| 1956 | Z_8x8_2x4 = 6, | ||
| 1957 | Z_16x16_4x8 = 7, | ||
| 1958 | Z_4x8_2x2 = 8, | ||
| 1959 | ZS_16x8_4x2 = 9, | ||
| 1960 | ZS_16x8_2x4 = 10, | ||
| 1961 | ZS_8x8_2x2 = 11, | ||
| 1962 | Z_4x8_1x1 = 12, | ||
| 1963 | }; | ||
| 992 | 1964 | ||
| 993 | u32 d3d_cull_mode; | 1965 | struct RtLayer { |
| 1966 | enum class Control { | ||
| 1967 | LayerSelectsLayer = 0, | ||
| 1968 | GeometryShaderSelectsLayer = 1, | ||
| 1969 | }; | ||
| 994 | 1970 | ||
| 995 | ComparisonOp depth_test_func; | 1971 | union { |
| 996 | float alpha_test_ref; | 1972 | BitField<0, 16, u32> layer; |
| 997 | ComparisonOp alpha_test_func; | 1973 | BitField<16, 1, u32> control; |
| 998 | u32 draw_tfb_stride; | 1974 | }; |
| 999 | struct { | 1975 | }; |
| 1000 | float r; | ||
| 1001 | float g; | ||
| 1002 | float b; | ||
| 1003 | float a; | ||
| 1004 | } blend_color; | ||
| 1005 | 1976 | ||
| 1006 | INSERT_PADDING_WORDS_NOINIT(0x4); | 1977 | struct InlineIndex2x16 { |
| 1978 | union { | ||
| 1979 | BitField<0, 31, u32> count; | ||
| 1980 | BitField<31, 1, u32> start_odd; | ||
| 1981 | }; | ||
| 1982 | union { | ||
| 1983 | BitField<0, 16, u32> even; | ||
| 1984 | BitField<16, 16, u32> odd; | ||
| 1985 | }; | ||
| 1986 | }; | ||
| 1007 | 1987 | ||
| 1008 | struct { | 1988 | struct VertexGlobalBaseOffset { |
| 1009 | u32 separate_alpha; | 1989 | u32 address_high; |
| 1010 | Blend::Equation equation_rgb; | 1990 | u32 address_low; |
| 1011 | Blend::Factor factor_source_rgb; | ||
| 1012 | Blend::Factor factor_dest_rgb; | ||
| 1013 | Blend::Equation equation_a; | ||
| 1014 | Blend::Factor factor_source_a; | ||
| 1015 | INSERT_PADDING_WORDS_NOINIT(1); | ||
| 1016 | Blend::Factor factor_dest_a; | ||
| 1017 | 1991 | ||
| 1018 | u32 enable_common; | 1992 | GPUVAddr Address() const { |
| 1019 | u32 enable[NumRenderTargets]; | 1993 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 1020 | } blend; | 1994 | address_low); |
| 1995 | } | ||
| 1996 | }; | ||
| 1021 | 1997 | ||
| 1022 | u32 stencil_enable; | 1998 | struct ZCullRegionPixelOffset { |
| 1023 | StencilOp stencil_front_op_fail; | 1999 | u32 width; |
| 1024 | StencilOp stencil_front_op_zfail; | 2000 | u32 height; |
| 1025 | StencilOp stencil_front_op_zpass; | 2001 | }; |
| 1026 | ComparisonOp stencil_front_func_func; | ||
| 1027 | s32 stencil_front_func_ref; | ||
| 1028 | u32 stencil_front_func_mask; | ||
| 1029 | u32 stencil_front_mask; | ||
| 1030 | 2002 | ||
| 1031 | INSERT_PADDING_WORDS_NOINIT(0x2); | 2003 | struct PointSprite { |
| 2004 | enum class RMode : u32 { | ||
| 2005 | Zero = 0, | ||
| 2006 | FromR = 1, | ||
| 2007 | FromS = 2, | ||
| 2008 | }; | ||
| 2009 | enum class Origin : u32 { | ||
| 2010 | Bottom = 0, | ||
| 2011 | Top = 1, | ||
| 2012 | }; | ||
| 2013 | enum class Texture : u32 { | ||
| 2014 | Passthrough = 0, | ||
| 2015 | Generate = 1, | ||
| 2016 | }; | ||
| 2017 | |||
| 2018 | union { | ||
| 2019 | BitField<0, 2, RMode> rmode; | ||
| 2020 | BitField<2, 1, Origin> origin; | ||
| 2021 | BitField<3, 1, Texture> texture0; | ||
| 2022 | BitField<4, 1, Texture> texture1; | ||
| 2023 | BitField<5, 1, Texture> texture2; | ||
| 2024 | BitField<6, 1, Texture> texture3; | ||
| 2025 | BitField<7, 1, Texture> texture4; | ||
| 2026 | BitField<8, 1, Texture> texture5; | ||
| 2027 | BitField<9, 1, Texture> texture6; | ||
| 2028 | BitField<10, 1, Texture> texture7; | ||
| 2029 | BitField<11, 1, Texture> texture8; | ||
| 2030 | BitField<12, 1, Texture> texture9; | ||
| 2031 | }; | ||
| 2032 | }; | ||
| 1032 | 2033 | ||
| 1033 | u32 frag_color_clamp; | 2034 | struct ProgramRegion { |
| 2035 | u32 address_high; | ||
| 2036 | u32 address_low; | ||
| 1034 | 2037 | ||
| 1035 | union { | 2038 | GPUVAddr Address() const { |
| 1036 | BitField<0, 1, u32> y_negate; | 2039 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 1037 | BitField<4, 1, u32> triangle_rast_flip; | 2040 | address_low); |
| 1038 | } screen_y_control; | 2041 | } |
| 2042 | }; | ||
| 1039 | 2043 | ||
| 1040 | float line_width_smooth; | 2044 | struct DefaultAttributes { |
| 1041 | float line_width_aliased; | 2045 | enum class Diffuse : u32 { |
| 2046 | Vector_0001 = 0, | ||
| 2047 | Vector_1111 = 1, | ||
| 2048 | }; | ||
| 2049 | enum class Specular : u32 { | ||
| 2050 | Vector_0000 = 0, | ||
| 2051 | Vector_0001 = 1, | ||
| 2052 | }; | ||
| 2053 | enum class Vector : u32 { | ||
| 2054 | Vector_0000 = 0, | ||
| 2055 | Vector_0001 = 1, | ||
| 2056 | }; | ||
| 2057 | enum class FixedFncTexture : u32 { | ||
| 2058 | Vector_0000 = 0, | ||
| 2059 | Vector_0001 = 1, | ||
| 2060 | }; | ||
| 2061 | enum class DX9Color0 : u32 { | ||
| 2062 | Vector_0000 = 0, | ||
| 2063 | Vector_1111 = 1, | ||
| 2064 | }; | ||
| 2065 | enum class DX9Color1To15 : u32 { | ||
| 2066 | Vector_0000 = 0, | ||
| 2067 | Vector_0001 = 1, | ||
| 2068 | }; | ||
| 1042 | 2069 | ||
| 1043 | INSERT_PADDING_WORDS_NOINIT(0x1B); | 2070 | union { |
| 2071 | BitField<0, 1, Diffuse> color_front_diffuse; | ||
| 2072 | BitField<1, 1, Specular> color_front_specular; | ||
| 2073 | BitField<2, 1, Vector> generic_vector; | ||
| 2074 | BitField<3, 1, FixedFncTexture> fixed_fnc_texture; | ||
| 2075 | BitField<4, 1, DX9Color0> dx9_color0; | ||
| 2076 | BitField<5, 1, DX9Color1To15> dx9_color1_to_15; | ||
| 2077 | }; | ||
| 2078 | }; | ||
| 1044 | 2079 | ||
| 1045 | u32 invalidate_sampler_cache_no_wfi; | 2080 | struct Draw { |
| 1046 | u32 invalidate_texture_header_cache_no_wfi; | 2081 | enum class PrimitiveId : u32 { |
| 2082 | First = 0, | ||
| 2083 | Unchanged = 1, | ||
| 2084 | }; | ||
| 2085 | enum class InstanceId : u32 { | ||
| 2086 | First = 0, | ||
| 2087 | Subsequent = 1, | ||
| 2088 | Unchanged = 2, | ||
| 2089 | }; | ||
| 2090 | enum class SplitMode : u32 { | ||
| 2091 | NormalBeginNormal = 0, | ||
| 2092 | NormalBeginOpen = 1, | ||
| 2093 | OpenBeginOpen = 2, | ||
| 2094 | OpenBeginNormal = 3, | ||
| 2095 | }; | ||
| 1047 | 2096 | ||
| 1048 | INSERT_PADDING_WORDS_NOINIT(0x2); | 2097 | u32 end; |
| 2098 | union { | ||
| 2099 | u32 begin; | ||
| 2100 | BitField<0, 16, PrimitiveTopology> topology; | ||
| 2101 | BitField<24, 1, PrimitiveId> primitive_id; | ||
| 2102 | BitField<26, 2, InstanceId> instance_id; | ||
| 2103 | BitField<29, 2, SplitMode> split_mode; | ||
| 2104 | }; | ||
| 2105 | }; | ||
| 1049 | 2106 | ||
| 1050 | u32 vb_element_base; | 2107 | struct VertexIdCopy { |
| 1051 | u32 vb_base_instance; | 2108 | union { |
| 2109 | BitField<0, 1, u32> enable; | ||
| 2110 | BitField<4, 8, u32> attribute_slot; | ||
| 2111 | }; | ||
| 2112 | }; | ||
| 1052 | 2113 | ||
| 1053 | INSERT_PADDING_WORDS_NOINIT(0x35); | 2114 | struct ShaderBasedCull { |
| 2115 | union { | ||
| 2116 | BitField<1, 1, u32> batch_cull_enable; | ||
| 2117 | BitField<0, 1, u32> before_fetch_enable; | ||
| 2118 | }; | ||
| 2119 | }; | ||
| 1054 | 2120 | ||
| 1055 | u32 clip_distance_enabled; | 2121 | struct ClassVersion { |
| 2122 | union { | ||
| 2123 | BitField<0, 16, u32> current; | ||
| 2124 | BitField<16, 16, u32> oldest_supported; | ||
| 2125 | }; | ||
| 2126 | }; | ||
| 1056 | 2127 | ||
| 1057 | u32 samplecnt_enable; | 2128 | struct PrimitiveRestart { |
| 2129 | u32 enabled; | ||
| 2130 | u32 index; | ||
| 2131 | }; | ||
| 1058 | 2132 | ||
| 1059 | float point_size; | 2133 | struct OutputVertexId { |
| 2134 | union { | ||
| 2135 | BitField<12, 1, u32> uses_array_start; | ||
| 2136 | }; | ||
| 2137 | }; | ||
| 1060 | 2138 | ||
| 1061 | INSERT_PADDING_WORDS_NOINIT(0x1); | 2139 | enum class PointCenterMode : u32 { |
| 2140 | GL = 0, | ||
| 2141 | D3D = 1, | ||
| 2142 | }; | ||
| 1062 | 2143 | ||
| 1063 | u32 point_sprite_enable; | 2144 | enum class LineSmoothParams : u32 { |
| 2145 | Falloff_1_00 = 0, | ||
| 2146 | Falloff_1_33 = 1, | ||
| 2147 | Falloff_1_66 = 2, | ||
| 2148 | }; | ||
| 1064 | 2149 | ||
| 1065 | INSERT_PADDING_WORDS_NOINIT(0x3); | 2150 | struct LineSmoothEdgeTable { |
| 2151 | union { | ||
| 2152 | BitField<0, 8, u32> v0; | ||
| 2153 | BitField<8, 8, u32> v1; | ||
| 2154 | BitField<16, 8, u32> v2; | ||
| 2155 | BitField<24, 8, u32> v3; | ||
| 2156 | }; | ||
| 2157 | }; | ||
| 1066 | 2158 | ||
| 1067 | CounterReset counter_reset; | 2159 | struct LineStippleParams { |
| 2160 | union { | ||
| 2161 | BitField<0, 8, u32> factor; | ||
| 2162 | BitField<8, 16, u32> pattern; | ||
| 2163 | }; | ||
| 2164 | }; | ||
| 1068 | 2165 | ||
| 1069 | u32 multisample_enable; | 2166 | enum class ProvokingVertex : u32 { |
| 2167 | First = 0, | ||
| 2168 | Last = 1, | ||
| 2169 | }; | ||
| 1070 | 2170 | ||
| 1071 | u32 zeta_enable; | 2171 | struct ShaderControl { |
| 2172 | enum class Partial : u32 { | ||
| 2173 | Zero = 0, | ||
| 2174 | Infinity = 1, | ||
| 2175 | }; | ||
| 2176 | enum class FP32NanBehavior : u32 { | ||
| 2177 | Legacy = 0, | ||
| 2178 | FP64Compatible = 1, | ||
| 2179 | }; | ||
| 2180 | enum class FP32F2INanBehavior : u32 { | ||
| 2181 | PassZero = 0, | ||
| 2182 | PassIndefinite = 1, | ||
| 2183 | }; | ||
| 1072 | 2184 | ||
| 1073 | union { | 2185 | union { |
| 1074 | BitField<0, 1, u32> alpha_to_coverage; | 2186 | BitField<0, 1, Partial> default_partial; |
| 1075 | BitField<4, 1, u32> alpha_to_one; | 2187 | BitField<1, 1, FP32NanBehavior> fp32_nan_behavior; |
| 1076 | } multisample_control; | 2188 | BitField<2, 1, FP32F2INanBehavior> fp32_f2i_nan_behavior; |
| 2189 | }; | ||
| 2190 | }; | ||
| 1077 | 2191 | ||
| 1078 | INSERT_PADDING_WORDS_NOINIT(0x4); | 2192 | struct SphVersion { |
| 2193 | union { | ||
| 2194 | BitField<0, 16, u32> current; | ||
| 2195 | BitField<16, 16, u32> oldest_supported; | ||
| 2196 | }; | ||
| 2197 | }; | ||
| 1079 | 2198 | ||
| 1080 | struct { | 2199 | struct AlphaToCoverageOverride { |
| 1081 | u32 address_high; | 2200 | union { |
| 1082 | u32 address_low; | 2201 | BitField<0, 1, u32> qualify_by_anti_alias_enable; |
| 1083 | ConditionMode mode; | 2202 | BitField<1, 1, u32> qualify_by_ps_sample_mask_enable; |
| 2203 | }; | ||
| 2204 | }; | ||
| 1084 | 2205 | ||
| 1085 | GPUVAddr Address() const { | 2206 | struct AamVersion { |
| 1086 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 2207 | union { |
| 1087 | address_low); | 2208 | BitField<0, 16, u32> current; |
| 1088 | } | 2209 | BitField<16, 16, u32> oldest_supported; |
| 1089 | } condition; | 2210 | }; |
| 2211 | }; | ||
| 1090 | 2212 | ||
| 1091 | struct { | 2213 | struct IndexBuffer { |
| 1092 | u32 address_high; | 2214 | u32 start_addr_high; |
| 1093 | u32 address_low; | 2215 | u32 start_addr_low; |
| 1094 | u32 limit; | 2216 | u32 limit_addr_high; |
| 2217 | u32 limit_addr_low; | ||
| 2218 | IndexFormat format; | ||
| 2219 | u32 first; | ||
| 2220 | u32 count; | ||
| 2221 | |||
| 2222 | unsigned FormatSizeInBytes() const { | ||
| 2223 | switch (format) { | ||
| 2224 | case IndexFormat::UnsignedByte: | ||
| 2225 | return 1; | ||
| 2226 | case IndexFormat::UnsignedShort: | ||
| 2227 | return 2; | ||
| 2228 | case IndexFormat::UnsignedInt: | ||
| 2229 | return 4; | ||
| 2230 | } | ||
| 2231 | ASSERT(false); | ||
| 2232 | return 1; | ||
| 2233 | } | ||
| 1095 | 2234 | ||
| 1096 | GPUVAddr Address() const { | 2235 | GPUVAddr StartAddress() const { |
| 1097 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 2236 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_addr_high) << 32) | |
| 1098 | address_low); | 2237 | start_addr_low); |
| 1099 | } | 2238 | } |
| 1100 | } tsc; | ||
| 1101 | 2239 | ||
| 1102 | INSERT_PADDING_WORDS_NOINIT(0x1); | 2240 | GPUVAddr EndAddress() const { |
| 2241 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_addr_high) << 32) | | ||
| 2242 | limit_addr_low); | ||
| 2243 | } | ||
| 1103 | 2244 | ||
| 1104 | float polygon_offset_factor; | 2245 | /// Adjust the index buffer offset so it points to the first desired index. |
| 2246 | GPUVAddr IndexStart() const { | ||
| 2247 | return StartAddress() + | ||
| 2248 | static_cast<size_t>(first) * static_cast<size_t>(FormatSizeInBytes()); | ||
| 2249 | } | ||
| 2250 | }; | ||
| 1105 | 2251 | ||
| 1106 | u32 line_smooth_enable; | 2252 | struct IndexBufferSmall { |
| 2253 | union { | ||
| 2254 | BitField<0, 16, u32> first; | ||
| 2255 | BitField<16, 12, u32> count; | ||
| 2256 | BitField<28, 4, PrimitiveTopology> topology; | ||
| 2257 | }; | ||
| 2258 | }; | ||
| 1107 | 2259 | ||
| 1108 | struct { | 2260 | struct VertexStreamInstances { |
| 1109 | u32 address_high; | 2261 | std::array<u32, NumVertexArrays> is_instanced; |
| 1110 | u32 address_low; | ||
| 1111 | u32 limit; | ||
| 1112 | 2262 | ||
| 1113 | GPUVAddr Address() const { | 2263 | /// Returns whether the vertex array specified by index is supposed to be |
| 1114 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 2264 | /// accessed per instance or not. |
| 1115 | address_low); | 2265 | bool IsInstancingEnabled(std::size_t index) const { |
| 1116 | } | 2266 | return is_instanced[index]; |
| 1117 | } tic; | 2267 | } |
| 2268 | }; | ||
| 1118 | 2269 | ||
| 1119 | INSERT_PADDING_WORDS_NOINIT(0x5); | 2270 | struct AttributePointSize { |
| 2271 | union { | ||
| 2272 | BitField<0, 1, u32> enabled; | ||
| 2273 | BitField<4, 8, u32> slot; | ||
| 2274 | }; | ||
| 2275 | }; | ||
| 1120 | 2276 | ||
| 1121 | u32 stencil_two_side_enable; | 2277 | struct ViewportClipControl { |
| 1122 | StencilOp stencil_back_op_fail; | 2278 | enum class GeometryGuardband : u32 { |
| 1123 | StencilOp stencil_back_op_zfail; | 2279 | Scale256 = 0, |
| 1124 | StencilOp stencil_back_op_zpass; | 2280 | Scale1 = 1, |
| 1125 | ComparisonOp stencil_back_func_func; | 2281 | }; |
| 2282 | enum class GeometryClip : u32 { | ||
| 2283 | WZero = 0, | ||
| 2284 | Passthrough = 1, | ||
| 2285 | FrustumXY = 2, | ||
| 2286 | FrustumXYZ = 3, | ||
| 2287 | WZeroNoZCull = 4, | ||
| 2288 | FrustumZ = 5, | ||
| 2289 | WZeroTriFillOrClip = 6, | ||
| 2290 | }; | ||
| 2291 | enum class GeometryGuardbandZ : u32 { | ||
| 2292 | SameAsXY = 0, | ||
| 2293 | Scale256 = 1, | ||
| 2294 | Scale1 = 2, | ||
| 2295 | }; | ||
| 1126 | 2296 | ||
| 1127 | INSERT_PADDING_WORDS_NOINIT(0x4); | 2297 | union { |
| 2298 | BitField<0, 1, u32> depth_0_to_1; | ||
| 2299 | BitField<3, 1, u32> pixel_min_z; | ||
| 2300 | BitField<4, 1, u32> pixel_max_z; | ||
| 2301 | BitField<7, 1, GeometryGuardband> geometry_guardband; | ||
| 2302 | BitField<11, 3, GeometryClip> geometry_clip; | ||
| 2303 | BitField<1, 2, GeometryGuardbandZ> geometry_guardband_z; | ||
| 2304 | }; | ||
| 2305 | }; | ||
| 1128 | 2306 | ||
| 1129 | u32 framebuffer_srgb; | 2307 | enum class PrimitiveTopologyControl : u32 { |
| 2308 | UseInBeginMethods = 0, | ||
| 2309 | UseSeparateState = 1, | ||
| 2310 | }; | ||
| 1130 | 2311 | ||
| 1131 | float polygon_offset_units; | 2312 | struct WindowClip { |
| 2313 | enum class Type : u32 { | ||
| 2314 | Inclusive = 0, | ||
| 2315 | Exclusive = 1, | ||
| 2316 | ClipAll = 2, | ||
| 2317 | }; | ||
| 1132 | 2318 | ||
| 1133 | INSERT_PADDING_WORDS_NOINIT(0x4); | 2319 | u32 enable; |
| 2320 | Type type; | ||
| 2321 | }; | ||
| 1134 | 2322 | ||
| 1135 | Tegra::Texture::MsaaMode multisample_mode; | 2323 | enum class InvalidateZCull : u32 { |
| 2324 | Invalidate = 0, | ||
| 2325 | }; | ||
| 1136 | 2326 | ||
| 1137 | INSERT_PADDING_WORDS_NOINIT(0xC); | 2327 | struct ZCull { |
| 2328 | union { | ||
| 2329 | BitField<0, 1, u32> z_enable; | ||
| 2330 | BitField<1, 1, u32> stencil_enable; | ||
| 2331 | }; | ||
| 2332 | union { | ||
| 2333 | BitField<0, 1, u32> z_min_enbounded; | ||
| 2334 | BitField<1, 1, u32> z_max_unbounded; | ||
| 2335 | }; | ||
| 2336 | }; | ||
| 1138 | 2337 | ||
| 1139 | union { | 2338 | struct LogicOp { |
| 1140 | BitField<2, 1, u32> coord_origin; | 2339 | enum class Op : u32 { |
| 1141 | BitField<3, 10, u32> enable; | 2340 | Clear = 0x1500, |
| 1142 | } point_coord_replace; | 2341 | And = 0x1501, |
| 1143 | 2342 | AndReverse = 0x1502, | |
| 1144 | struct { | 2343 | Copy = 0x1503, |
| 1145 | u32 code_address_high; | 2344 | AndInverted = 0x1504, |
| 1146 | u32 code_address_low; | 2345 | NoOp = 0x1505, |
| 1147 | 2346 | Xor = 0x1506, | |
| 1148 | GPUVAddr CodeAddress() const { | 2347 | Or = 0x1507, |
| 1149 | return static_cast<GPUVAddr>( | 2348 | Nor = 0x1508, |
| 1150 | (static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low); | 2349 | Equiv = 0x1509, |
| 1151 | } | 2350 | Invert = 0x150A, |
| 1152 | } code_address; | 2351 | OrReverse = 0x150B, |
| 1153 | INSERT_PADDING_WORDS_NOINIT(1); | 2352 | CopyInverted = 0x150C, |
| 1154 | 2353 | OrInverted = 0x150D, | |
| 1155 | struct { | 2354 | Nand = 0x150E, |
| 1156 | u32 vertex_end_gl; | 2355 | Set = 0x150F, |
| 1157 | union { | 2356 | }; |
| 1158 | u32 vertex_begin_gl; | ||
| 1159 | BitField<0, 16, PrimitiveTopology> topology; | ||
| 1160 | BitField<26, 1, u32> instance_next; | ||
| 1161 | BitField<27, 1, u32> instance_cont; | ||
| 1162 | }; | ||
| 1163 | } draw; | ||
| 1164 | |||
| 1165 | INSERT_PADDING_WORDS_NOINIT(0xA); | ||
| 1166 | |||
| 1167 | struct { | ||
| 1168 | u32 enabled; | ||
| 1169 | u32 index; | ||
| 1170 | } primitive_restart; | ||
| 1171 | |||
| 1172 | INSERT_PADDING_WORDS_NOINIT(0xE); | ||
| 1173 | |||
| 1174 | u32 provoking_vertex_last; | ||
| 1175 | |||
| 1176 | INSERT_PADDING_WORDS_NOINIT(0x50); | ||
| 1177 | |||
| 1178 | struct { | ||
| 1179 | u32 start_addr_high; | ||
| 1180 | u32 start_addr_low; | ||
| 1181 | u32 end_addr_high; | ||
| 1182 | u32 end_addr_low; | ||
| 1183 | IndexFormat format; | ||
| 1184 | u32 first; | ||
| 1185 | u32 count; | ||
| 1186 | |||
| 1187 | unsigned FormatSizeInBytes() const { | ||
| 1188 | switch (format) { | ||
| 1189 | case IndexFormat::UnsignedByte: | ||
| 1190 | return 1; | ||
| 1191 | case IndexFormat::UnsignedShort: | ||
| 1192 | return 2; | ||
| 1193 | case IndexFormat::UnsignedInt: | ||
| 1194 | return 4; | ||
| 1195 | } | ||
| 1196 | ASSERT(false); | ||
| 1197 | return 1; | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | GPUVAddr StartAddress() const { | ||
| 1201 | return static_cast<GPUVAddr>( | ||
| 1202 | (static_cast<GPUVAddr>(start_addr_high) << 32) | start_addr_low); | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | GPUVAddr EndAddress() const { | ||
| 1206 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(end_addr_high) << 32) | | ||
| 1207 | end_addr_low); | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | /// Adjust the index buffer offset so it points to the first desired index. | ||
| 1211 | GPUVAddr IndexStart() const { | ||
| 1212 | return StartAddress() + static_cast<size_t>(first) * | ||
| 1213 | static_cast<size_t>(FormatSizeInBytes()); | ||
| 1214 | } | ||
| 1215 | } index_array; | ||
| 1216 | 2357 | ||
| 1217 | union { | 2358 | u32 enable; |
| 1218 | BitField<0, 16, u32> first; | 2359 | Op op; |
| 1219 | BitField<16, 16, u32> count; | 2360 | }; |
| 1220 | } small_index; | ||
| 1221 | 2361 | ||
| 1222 | union { | 2362 | struct ClearSurface { |
| 1223 | BitField<0, 16, u32> first; | 2363 | union { |
| 1224 | BitField<16, 16, u32> count; | 2364 | u32 raw; |
| 1225 | } small_index_2; | 2365 | BitField<0, 1, u32> Z; |
| 2366 | BitField<1, 1, u32> S; | ||
| 2367 | BitField<2, 1, u32> R; | ||
| 2368 | BitField<3, 1, u32> G; | ||
| 2369 | BitField<4, 1, u32> B; | ||
| 2370 | BitField<5, 1, u32> A; | ||
| 2371 | BitField<6, 4, u32> RT; | ||
| 2372 | BitField<10, 16, u32> layer; | ||
| 2373 | }; | ||
| 2374 | }; | ||
| 1226 | 2375 | ||
| 1227 | INSERT_PADDING_WORDS_NOINIT(0x5); | 2376 | struct ReportSemaphore { |
| 2377 | struct Compare { | ||
| 2378 | u32 initial_sequence; | ||
| 2379 | u32 initial_mode; | ||
| 2380 | u32 unknown1; | ||
| 2381 | u32 unknown2; | ||
| 2382 | u32 current_sequence; | ||
| 2383 | u32 current_mode; | ||
| 2384 | }; | ||
| 1228 | 2385 | ||
| 1229 | INSERT_PADDING_WORDS_NOINIT(0x1F); | 2386 | enum class Operation : u32 { |
| 2387 | Release = 0, | ||
| 2388 | Acquire = 1, | ||
| 2389 | ReportOnly = 2, | ||
| 2390 | Trap = 3, | ||
| 2391 | }; | ||
| 1230 | 2392 | ||
| 1231 | float polygon_offset_clamp; | 2393 | enum class Release : u32 { |
| 2394 | AfterAllPreceedingReads = 0, | ||
| 2395 | AfterAllPreceedingWrites = 1, | ||
| 2396 | }; | ||
| 1232 | 2397 | ||
| 1233 | struct { | 2398 | enum class Acquire : u32 { |
| 1234 | u32 is_instanced[NumVertexArrays]; | 2399 | BeforeAnyFollowingWrites = 0, |
| 2400 | BeforeAnyFollowingReads = 1, | ||
| 2401 | }; | ||
| 1235 | 2402 | ||
| 1236 | /// Returns whether the vertex array specified by index is supposed to be | 2403 | enum class Location : u32 { |
| 1237 | /// accessed per instance or not. | 2404 | None = 0, |
| 1238 | bool IsInstancingEnabled(std::size_t index) const { | 2405 | VertexFetch = 1, |
| 1239 | return is_instanced[index]; | 2406 | VertexShader = 2, |
| 1240 | } | 2407 | VPC = 4, |
| 1241 | } instanced_arrays; | 2408 | StreamingOutput = 5, |
| 2409 | GeometryShader = 6, | ||
| 2410 | ZCull = 7, | ||
| 2411 | TessellationInit = 8, | ||
| 2412 | TessellationShader = 9, | ||
| 2413 | PixelShader = 10, | ||
| 2414 | DepthTest = 12, | ||
| 2415 | All = 15, | ||
| 2416 | }; | ||
| 1242 | 2417 | ||
| 1243 | INSERT_PADDING_WORDS_NOINIT(0x4); | 2418 | enum class Comparison : u32 { |
| 2419 | NotEqual = 0, | ||
| 2420 | GreaterOrEqual = 1, | ||
| 2421 | }; | ||
| 1244 | 2422 | ||
| 1245 | union { | 2423 | enum class Report : u32 { |
| 1246 | BitField<0, 1, u32> enable; | 2424 | Payload = 0, // "None" in docs, but confirmed via hardware to return the payload |
| 1247 | BitField<4, 8, u32> unk4; | 2425 | VerticesGenerated = 1, |
| 1248 | } vp_point_size; | 2426 | ZPassPixelCount = 2, |
| 2427 | PrimitivesGenerated = 3, | ||
| 2428 | AlphaBetaClocks = 4, | ||
| 2429 | VertexShaderInvocations = 5, | ||
| 2430 | StreamingPrimitivesNeededMinusSucceeded = 6, | ||
| 2431 | GeometryShaderInvocations = 7, | ||
| 2432 | GeometryShaderPrimitivesGenerated = 9, | ||
| 2433 | ZCullStats0 = 10, | ||
| 2434 | StreamingPrimitivesSucceeded = 11, | ||
| 2435 | ZCullStats1 = 12, | ||
| 2436 | StreamingPrimitivesNeeded = 13, | ||
| 2437 | ZCullStats2 = 14, | ||
| 2438 | ClipperInvocations = 15, | ||
| 2439 | ZCullStats3 = 16, | ||
| 2440 | ClipperPrimitivesGenerated = 17, | ||
| 2441 | VtgPrimitivesOut = 18, | ||
| 2442 | PixelShaderInvocations = 19, | ||
| 2443 | ZPassPixelCount64 = 21, | ||
| 2444 | IEEECleanColorTarget = 24, | ||
| 2445 | IEEECleanZetaTarget = 25, | ||
| 2446 | StreamingByteCount = 26, | ||
| 2447 | TessellationInitInvocations = 27, | ||
| 2448 | BoundingRectangle = 28, | ||
| 2449 | TessellationShaderInvocations = 29, | ||
| 2450 | TotalStreamingPrimitivesNeededMinusSucceeded = 30, | ||
| 2451 | TessellationShaderPrimitivesGenerated = 31, | ||
| 2452 | }; | ||
| 1249 | 2453 | ||
| 1250 | INSERT_PADDING_WORDS_NOINIT(1); | 2454 | u32 address_high; |
| 2455 | u32 address_low; | ||
| 2456 | u32 payload; | ||
| 2457 | union { | ||
| 2458 | u32 raw; | ||
| 2459 | BitField<0, 2, Operation> operation; | ||
| 2460 | BitField<4, 1, Release> release; | ||
| 2461 | BitField<8, 1, Acquire> acquire; | ||
| 2462 | BitField<12, 4, Location> location; | ||
| 2463 | BitField<16, 1, Comparison> comparison; | ||
| 2464 | BitField<20, 1, u32> awaken_enable; | ||
| 2465 | BitField<23, 5, Report> report; | ||
| 2466 | BitField<28, 1, u32> short_query; | ||
| 2467 | BitField<5, 3, u32> sub_report; | ||
| 2468 | BitField<21, 1, u32> dword_number; | ||
| 2469 | BitField<2, 1, u32> disable_flush; | ||
| 2470 | BitField<3, 1, u32> reduction_enable; | ||
| 2471 | BitField<9, 3, ReductionOp> reduction_op; | ||
| 2472 | BitField<17, 2, u32> format_signed; | ||
| 2473 | } query; | ||
| 1251 | 2474 | ||
| 1252 | u32 cull_test_enabled; | 2475 | GPUVAddr Address() const { |
| 1253 | FrontFace front_face; | 2476 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 1254 | CullFace cull_face; | 2477 | address_low); |
| 2478 | } | ||
| 2479 | }; | ||
| 1255 | 2480 | ||
| 1256 | u32 pixel_center_integer; | 2481 | struct VertexStream { |
| 2482 | union { | ||
| 2483 | BitField<0, 12, u32> stride; | ||
| 2484 | BitField<12, 1, u32> enable; | ||
| 2485 | }; | ||
| 2486 | u32 address_high; | ||
| 2487 | u32 address_low; | ||
| 2488 | u32 frequency; | ||
| 1257 | 2489 | ||
| 1258 | INSERT_PADDING_WORDS_NOINIT(0x1); | 2490 | GPUVAddr Address() const { |
| 2491 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 2492 | address_low); | ||
| 2493 | } | ||
| 1259 | 2494 | ||
| 1260 | u32 viewport_transform_enabled; | 2495 | bool IsEnabled() const { |
| 2496 | return enable != 0 && Address() != 0; | ||
| 2497 | } | ||
| 2498 | }; | ||
| 2499 | static_assert(sizeof(VertexStream) == 0x10); | ||
| 1261 | 2500 | ||
| 1262 | INSERT_PADDING_WORDS_NOINIT(0x3); | 2501 | struct VertexStreamLimit { |
| 2502 | u32 address_high; | ||
| 2503 | u32 address_low; | ||
| 1263 | 2504 | ||
| 1264 | union { | 2505 | GPUVAddr Address() const { |
| 1265 | BitField<0, 1, u32> depth_range_0_1; | 2506 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 1266 | BitField<3, 1, u32> depth_clamp_near; | 2507 | address_low); |
| 1267 | BitField<4, 1, u32> depth_clamp_far; | 2508 | } |
| 1268 | BitField<11, 1, u32> depth_clamp_disabled; | 2509 | }; |
| 1269 | } view_volume_clip_control; | 2510 | static_assert(sizeof(VertexStreamLimit) == 0x8); |
| 1270 | 2511 | ||
| 1271 | INSERT_PADDING_WORDS_NOINIT(0xC); | 2512 | enum class ShaderType : u32 { |
| 2513 | VertexA = 0, | ||
| 2514 | VertexB = 1, | ||
| 2515 | TessellationInit = 2, | ||
| 2516 | Tessellation = 3, | ||
| 2517 | Geometry = 4, | ||
| 2518 | Pixel = 5, | ||
| 2519 | }; | ||
| 1272 | 2520 | ||
| 1273 | PrimitiveTopologyOverride topology_override; | 2521 | struct Pipeline { |
| 2522 | union { | ||
| 2523 | BitField<0, 1, u32> enable; | ||
| 2524 | BitField<4, 4, ShaderType> program; | ||
| 2525 | }; | ||
| 2526 | u32 offset; | ||
| 2527 | u32 reservedA; | ||
| 2528 | u32 register_count; | ||
| 2529 | u32 binding_group; | ||
| 2530 | std::array<u32, 4> reserved; | ||
| 2531 | INSERT_PADDING_BYTES_NOINIT(0x1C); | ||
| 2532 | }; | ||
| 2533 | static_assert(sizeof(Pipeline) == 0x40); | ||
| 1274 | 2534 | ||
| 1275 | INSERT_PADDING_WORDS_NOINIT(0x12); | 2535 | bool IsShaderConfigEnabled(std::size_t index) const { |
| 2536 | // The VertexB is always enabled. | ||
| 2537 | if (index == static_cast<std::size_t>(ShaderType::VertexB)) { | ||
| 2538 | return true; | ||
| 2539 | } | ||
| 2540 | return pipelines[index].enable != 0; | ||
| 2541 | } | ||
| 1276 | 2542 | ||
| 1277 | u32 depth_bounds_enable; | 2543 | bool IsShaderConfigEnabled(ShaderType type) const { |
| 2544 | return IsShaderConfigEnabled(static_cast<std::size_t>(type)); | ||
| 2545 | } | ||
| 1278 | 2546 | ||
| 1279 | INSERT_PADDING_WORDS_NOINIT(1); | 2547 | struct ConstantBuffer { |
| 2548 | u32 size; | ||
| 2549 | u32 address_high; | ||
| 2550 | u32 address_low; | ||
| 2551 | u32 offset; | ||
| 2552 | std::array<u32, NumCBData> buffer; | ||
| 1280 | 2553 | ||
| 1281 | struct { | 2554 | GPUVAddr Address() const { |
| 1282 | u32 enable; | 2555 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| 1283 | LogicOperation operation; | 2556 | address_low); |
| 1284 | } logic_op; | 2557 | } |
| 2558 | }; | ||
| 1285 | 2559 | ||
| 1286 | INSERT_PADDING_WORDS_NOINIT(0x1); | 2560 | struct BindGroup { |
| 2561 | std::array<u32, 4> reserved; | ||
| 2562 | union { | ||
| 2563 | u32 raw_config; | ||
| 2564 | BitField<0, 1, u32> valid; | ||
| 2565 | BitField<4, 5, u32> shader_slot; | ||
| 2566 | }; | ||
| 2567 | INSERT_PADDING_BYTES_NOINIT(0xC); | ||
| 2568 | }; | ||
| 2569 | static_assert(sizeof(BindGroup) == 0x20); | ||
| 1287 | 2570 | ||
| 2571 | struct StreamOutLayout { | ||
| 2572 | union { | ||
| 2573 | BitField<0, 8, u32> attribute0; | ||
| 2574 | BitField<8, 8, u32> attribute1; | ||
| 2575 | BitField<16, 8, u32> attribute2; | ||
| 2576 | BitField<24, 8, u32> attribute3; | ||
| 2577 | }; | ||
| 2578 | }; | ||
| 2579 | |||
| 2580 | struct ShaderPerformance { | ||
| 2581 | struct ControlA { | ||
| 1288 | union { | 2582 | union { |
| 1289 | u32 raw; | 2583 | BitField<0, 2, u32> event0; |
| 1290 | BitField<0, 1, u32> Z; | 2584 | BitField<2, 3, u32> bit0; |
| 1291 | BitField<1, 1, u32> S; | 2585 | BitField<5, 2, u32> event1; |
| 1292 | BitField<2, 1, u32> R; | 2586 | BitField<7, 3, u32> bit1; |
| 1293 | BitField<3, 1, u32> G; | 2587 | BitField<10, 2, u32> event2; |
| 1294 | BitField<4, 1, u32> B; | 2588 | BitField<12, 3, u32> bit2; |
| 1295 | BitField<5, 1, u32> A; | 2589 | BitField<15, 2, u32> event3; |
| 1296 | BitField<6, 4, u32> RT; | 2590 | BitField<17, 3, u32> bit3; |
| 1297 | BitField<10, 11, u32> layer; | 2591 | BitField<20, 2, u32> event4; |
| 1298 | } clear_buffers; | 2592 | BitField<22, 3, u32> bit4; |
| 1299 | INSERT_PADDING_WORDS_NOINIT(0xB); | 2593 | BitField<25, 2, u32> event5; |
| 1300 | std::array<ColorMask, NumRenderTargets> color_mask; | 2594 | BitField<27, 3, u32> bit5; |
| 1301 | INSERT_PADDING_WORDS_NOINIT(0x38); | 2595 | BitField<30, 2, u32> spare; |
| 1302 | 2596 | }; | |
| 1303 | struct { | 2597 | }; |
| 1304 | u32 query_address_high; | ||
| 1305 | u32 query_address_low; | ||
| 1306 | u32 query_sequence; | ||
| 1307 | union { | ||
| 1308 | u32 raw; | ||
| 1309 | BitField<0, 2, QueryOperation> operation; | ||
| 1310 | BitField<4, 1, u32> fence; | ||
| 1311 | BitField<12, 4, QueryUnit> unit; | ||
| 1312 | BitField<16, 1, QuerySyncCondition> sync_cond; | ||
| 1313 | BitField<23, 5, QuerySelect> select; | ||
| 1314 | BitField<28, 1, u32> short_query; | ||
| 1315 | } query_get; | ||
| 1316 | |||
| 1317 | GPUVAddr QueryAddress() const { | ||
| 1318 | return static_cast<GPUVAddr>( | ||
| 1319 | (static_cast<GPUVAddr>(query_address_high) << 32) | query_address_low); | ||
| 1320 | } | ||
| 1321 | } query; | ||
| 1322 | |||
| 1323 | INSERT_PADDING_WORDS_NOINIT(0x3C); | ||
| 1324 | |||
| 1325 | struct { | ||
| 1326 | union { | ||
| 1327 | BitField<0, 12, u32> stride; | ||
| 1328 | BitField<12, 1, u32> enable; | ||
| 1329 | }; | ||
| 1330 | u32 start_high; | ||
| 1331 | u32 start_low; | ||
| 1332 | u32 divisor; | ||
| 1333 | |||
| 1334 | GPUVAddr StartAddress() const { | ||
| 1335 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_high) << 32) | | ||
| 1336 | start_low); | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | bool IsEnabled() const { | ||
| 1340 | return enable != 0 && StartAddress() != 0; | ||
| 1341 | } | ||
| 1342 | |||
| 1343 | } vertex_array[NumVertexArrays]; | ||
| 1344 | |||
| 1345 | Blend independent_blend[NumRenderTargets]; | ||
| 1346 | |||
| 1347 | struct { | ||
| 1348 | u32 limit_high; | ||
| 1349 | u32 limit_low; | ||
| 1350 | |||
| 1351 | GPUVAddr LimitAddress() const { | ||
| 1352 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) | | ||
| 1353 | limit_low); | ||
| 1354 | } | ||
| 1355 | } vertex_array_limit[NumVertexArrays]; | ||
| 1356 | |||
| 1357 | struct { | ||
| 1358 | union { | ||
| 1359 | BitField<0, 1, u32> enable; | ||
| 1360 | BitField<4, 4, ShaderProgram> program; | ||
| 1361 | }; | ||
| 1362 | u32 offset; | ||
| 1363 | INSERT_PADDING_WORDS_NOINIT(14); | ||
| 1364 | } shader_config[MaxShaderProgram]; | ||
| 1365 | |||
| 1366 | INSERT_PADDING_WORDS_NOINIT(0x60); | ||
| 1367 | |||
| 1368 | u32 firmware[0x20]; | ||
| 1369 | |||
| 1370 | struct { | ||
| 1371 | u32 cb_size; | ||
| 1372 | u32 cb_address_high; | ||
| 1373 | u32 cb_address_low; | ||
| 1374 | u32 cb_pos; | ||
| 1375 | std::array<u32, NumCBData> cb_data; | ||
| 1376 | |||
| 1377 | GPUVAddr BufferAddress() const { | ||
| 1378 | return static_cast<GPUVAddr>( | ||
| 1379 | (static_cast<GPUVAddr>(cb_address_high) << 32) | cb_address_low); | ||
| 1380 | } | ||
| 1381 | } const_buffer; | ||
| 1382 | |||
| 1383 | INSERT_PADDING_WORDS_NOINIT(0x10); | ||
| 1384 | |||
| 1385 | struct { | ||
| 1386 | union { | ||
| 1387 | u32 raw_config; | ||
| 1388 | BitField<0, 1, u32> valid; | ||
| 1389 | BitField<4, 5, u32> index; | ||
| 1390 | }; | ||
| 1391 | INSERT_PADDING_WORDS_NOINIT(7); | ||
| 1392 | } cb_bind[MaxShaderStage]; | ||
| 1393 | |||
| 1394 | INSERT_PADDING_WORDS_NOINIT(0x56); | ||
| 1395 | |||
| 1396 | u32 tex_cb_index; | ||
| 1397 | |||
| 1398 | INSERT_PADDING_WORDS_NOINIT(0x7D); | ||
| 1399 | |||
| 1400 | std::array<std::array<u8, 128>, NumTransformFeedbackBuffers> tfb_varying_locs; | ||
| 1401 | |||
| 1402 | INSERT_PADDING_WORDS_NOINIT(0x298); | ||
| 1403 | |||
| 1404 | struct { | ||
| 1405 | /// Compressed address of a buffer that holds information about bound SSBOs. | ||
| 1406 | /// This address is usually bound to c0 in the shaders. | ||
| 1407 | u32 buffer_address; | ||
| 1408 | |||
| 1409 | GPUVAddr BufferAddress() const { | ||
| 1410 | return static_cast<GPUVAddr>(buffer_address) << 8; | ||
| 1411 | } | ||
| 1412 | } ssbo_info; | ||
| 1413 | 2598 | ||
| 1414 | INSERT_PADDING_WORDS_NOINIT(0x11); | 2599 | struct ControlB { |
| 2600 | union { | ||
| 2601 | BitField<0, 1, u32> edge; | ||
| 2602 | BitField<1, 2, u32> mode; | ||
| 2603 | BitField<3, 1, u32> windowed; | ||
| 2604 | BitField<4, 16, u32> func; | ||
| 2605 | }; | ||
| 2606 | }; | ||
| 1415 | 2607 | ||
| 1416 | struct { | 2608 | std::array<u32, 8> values_upper; |
| 1417 | u32 address[MaxShaderStage]; | 2609 | std::array<u32, 8> values; |
| 1418 | u32 size[MaxShaderStage]; | 2610 | std::array<u32, 8> events; |
| 1419 | } tex_info_buffers; | 2611 | std::array<ControlA, 8> control_a; |
| 2612 | std::array<ControlB, 8> control_b; | ||
| 2613 | u32 trap_control_mask; | ||
| 2614 | u32 start_shader_mask; | ||
| 2615 | u32 stop_shader_mask; | ||
| 2616 | }; | ||
| 1420 | 2617 | ||
| 1421 | INSERT_PADDING_WORDS_NOINIT(0xCC); | 2618 | // clang-format off |
| 2619 | union { | ||
| 2620 | struct { | ||
| 2621 | ID object_id; ///< 0x0000 | ||
| 2622 | INSERT_PADDING_BYTES_NOINIT(0xFC); | ||
| 2623 | u32 nop; ///< 0x0100 | ||
| 2624 | Notify notify; ///< 0x0104 | ||
| 2625 | u32 wait_for_idle; ///< 0x0110 | ||
| 2626 | LoadMME load_mme; ///< 0x0114 | ||
| 2627 | ShadowRamControl shadow_ram_control; ///< 0x0124 | ||
| 2628 | PeerSemaphore peer; ///< 0x0128 | ||
| 2629 | GlobalRender global_render; ///< 0x0130 | ||
| 2630 | u32 go_idle; ///< 0x013C | ||
| 2631 | u32 trigger; ///< 0x0140 | ||
| 2632 | u32 trigger_wfi; ///< 0x0144 | ||
| 2633 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2634 | u32 instrumentation_method_header; ///< 0x0150 | ||
| 2635 | u32 instrumentation_method_data; ///< 0x0154 | ||
| 2636 | INSERT_PADDING_BYTES_NOINIT(0x28); | ||
| 2637 | Upload::Registers upload; ///< 0x0180 | ||
| 2638 | LaunchDMA launch_dma; ///< 0x01B0 | ||
| 2639 | u32 inline_data; ///< 0x01B4 | ||
| 2640 | INSERT_PADDING_BYTES_NOINIT(0x24); | ||
| 2641 | I2M i2m; ///< 0x01DC | ||
| 2642 | u32 run_ds_now; ///< 0x0200 | ||
| 2643 | OpportunisticEarlyZ opportunistic_early_z; ///< 0x0204 | ||
| 2644 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2645 | u32 aliased_line_width_enabled; ///< 0x020C | ||
| 2646 | u32 mandated_early_z; ///< 0x0210 | ||
| 2647 | GeometryShaderDmFifo gs_dm_fifo; ///< 0x0214 | ||
| 2648 | L2CacheControl l2_cache_control; ///< 0x0218 | ||
| 2649 | InvalidateShaderCache invalidate_shader_cache; ///< 0x021C | ||
| 2650 | INSERT_PADDING_BYTES_NOINIT(0xA8); | ||
| 2651 | SyncInfo sync_info; ///< 0x02C8 | ||
| 2652 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2653 | u32 prim_circular_buffer_throttle; ///< 0x02D0 | ||
| 2654 | u32 flush_invalidate_rop_mini_cache; ///< 0x02D4 | ||
| 2655 | SurfaceClipBlockId surface_clip_block_id; ///< 0x02D8 | ||
| 2656 | u32 alpha_circular_buffer_size; ///< 0x02DC | ||
| 2657 | DecompressSurface decompress_surface; ///< 0x02E0 | ||
| 2658 | ZCullRopBypass zcull_rop_bypass; ///< 0x02E4 | ||
| 2659 | ZCullSubregion zcull_subregion; ///< 0x02E8 | ||
| 2660 | RasterBoundingBox raster_bounding_box; ///< 0x02EC | ||
| 2661 | u32 peer_semaphore_release; ///< 0x02F0 | ||
| 2662 | u32 iterated_blend_optimization; ///< 0x02F4 | ||
| 2663 | ZCullSubregionAllocation zcull_subregion_allocation; ///< 0x02F8 | ||
| 2664 | ZCullSubregionAlgorithm zcull_subregion_algorithm; ///< 0x02FC | ||
| 2665 | PixelShaderOutputSampleMaskUsage ps_output_sample_mask_usage; ///< 0x0300 | ||
| 2666 | u32 draw_zero_index; ///< 0x0304 | ||
| 2667 | L1Configuration l1_configuration; ///< 0x0308 | ||
| 2668 | u32 render_enable_control_load_const_buffer; ///< 0x030C | ||
| 2669 | SPAVersion spa_version; ///< 0x0310 | ||
| 2670 | u32 ieee_clean_update; ///< 0x0314 | ||
| 2671 | SnapGrid snap_grid; ///< 0x0318 | ||
| 2672 | Tessellation tessellation; ///< 0x0320 | ||
| 2673 | SubTilingPerf sub_tiling_perf; ///< 0x0360 | ||
| 2674 | ZCullSubregionReport zcull_subregion_report; ///< 0x036C | ||
| 2675 | BalancedPrimitiveWorkload balanced_primitive_workload; ///< 0x0374 | ||
| 2676 | u32 max_patches_per_batch; ///< 0x0378 | ||
| 2677 | u32 rasterize_enable; ///< 0x037C | ||
| 2678 | TransformFeedback transform_feedback; ///< 0x0380 | ||
| 2679 | u32 raster_input; ///< 0x0740 | ||
| 2680 | u32 transform_feedback_enabled; ///< 0x0744 | ||
| 2681 | u32 primitive_restart_topology_change_enable; ///< 0x0748 | ||
| 2682 | u32 alpha_fraction; ///< 0x074C | ||
| 2683 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2684 | HybridAntiAliasControl hybrid_aa_control; ///< 0x0754 | ||
| 2685 | INSERT_PADDING_BYTES_NOINIT(0x24); | ||
| 2686 | ShaderLocalMemory shader_local_memory; ///< 0x077C | ||
| 2687 | u32 color_zero_bandwidth_clear; ///< 0x07A4 | ||
| 2688 | u32 z_zero_bandwidth_clear; ///< 0x07A8 | ||
| 2689 | u32 isbe_save_restore_program_offset; ///< 0x07AC | ||
| 2690 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2691 | ZCullRegion zcull_region; ///< 0x07C0 | ||
| 2692 | ZetaReadOnly zeta_read_only; ///< 0x07F8 | ||
| 2693 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2694 | std::array<RenderTargetConfig, NumRenderTargets> rt; ///< 0x0800 | ||
| 2695 | std::array<ViewportTransform, NumViewports> viewport_transform; ///< 0x0A00 | ||
| 2696 | std::array<Viewport, NumViewports> viewports; ///< 0x0C00 | ||
| 2697 | std::array<Window, 8> windows; ///< 0x0D00 | ||
| 2698 | std::array<ClipIdExtent, 4> clip_id_extent; ///< 0x0D40 | ||
| 2699 | u32 max_geometry_instances_per_task; ///< 0x0D60 | ||
| 2700 | VisibleCallLimit visible_call_limit; ///< 0x0D64 | ||
| 2701 | StatisticsCounter statistics_count; ///< 0x0D68 | ||
| 2702 | ClearRect clear_rect; ///< 0x0D6C | ||
| 2703 | VertexBuffer vertex_buffer; ///< 0x0D74 | ||
| 2704 | DepthMode depth_mode; ///< 0x0D7C | ||
| 2705 | std::array<f32, 4> clear_color; ///< 0x0D80 | ||
| 2706 | f32 clear_depth; ///< 0x0D90 | ||
| 2707 | u32 shader_cache_icache_prefetch; ///< 0x0D94 | ||
| 2708 | u32 force_transition_to_beta; ///< 0x0D98 | ||
| 2709 | u32 reduce_colour_thresholds; ///< 0x0D9C | ||
| 2710 | s32 clear_stencil; ///< 0x0DA0 | ||
| 2711 | InvalidateShaderCacheNoWFI invalidate_shader_cache_no_wfi; ///< 0x0DA4 | ||
| 2712 | ZCullSerialization zcull_serialization; ///< 0x0DA8 | ||
| 2713 | PolygonMode polygon_mode_front; ///< 0x0DAC | ||
| 2714 | PolygonMode polygon_mode_back; ///< 0x0DB0 | ||
| 2715 | u32 polygon_smooth; ///< 0x0DB4 | ||
| 2716 | u32 zeta_mark_clean_ieee; ///< 0x0DB8 | ||
| 2717 | ZCullDirFormat zcull_dir_format; ///< 0x0DBC | ||
| 2718 | u32 polygon_offset_point_enable; ///< 0x0DC0 | ||
| 2719 | u32 polygon_offset_line_enable; ///< 0x0DC4 | ||
| 2720 | u32 polygon_offset_fill_enable; ///< 0x0DC8 | ||
| 2721 | u32 patch_vertices; ///< 0x0DCC | ||
| 2722 | IteratedBlend iterated_blend; ///< 0x0DD0 | ||
| 2723 | ZCullCriterion zcull_criteria; ///< 0x0DD8 | ||
| 2724 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2725 | u32 fragment_barrier; ///< 0x0DE0 | ||
| 2726 | u32 sm_timeout; ///< 0x0DE4 | ||
| 2727 | u32 primitive_restart_array; ///< 0x0DE8 | ||
| 2728 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2729 | LoadIteratedBlend load_iterated_blend; ///< 0x0DF0 | ||
| 2730 | u32 window_offset_x; ///< 0x0DF8 | ||
| 2731 | u32 window_offset_y; ///< 0x0DFC | ||
| 2732 | std::array<ScissorTest, NumViewports> scissor_test; ///< 0x0E00 | ||
| 2733 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2734 | u32 select_texture_headers; ///< 0x0F10 | ||
| 2735 | VPCPerf vpc_perf; ///< 0x0F14 | ||
| 2736 | u32 pm_local_trigger; ///< 0x0F18 | ||
| 2737 | u32 post_z_pixel_imask; ///< 0x0F1C | ||
| 2738 | INSERT_PADDING_BYTES_NOINIT(0x20); | ||
| 2739 | ConstantColorRendering const_color_rendering; ///< 0x0F40 | ||
| 2740 | StencilFunc stencil_back_func; ///< 0x0F54 | ||
| 2741 | INSERT_PADDING_BYTES_NOINIT(0x24); | ||
| 2742 | VertexStreamSubstitute vertex_stream_substitute; ///< 0x0F84 | ||
| 2743 | u32 line_mode_clip_generated_edge_do_not_draw; ///< 0x0F8C | ||
| 2744 | u32 color_mask_common; ///< 0x0F90 | ||
| 2745 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2746 | VTGWarpWatermarks vtg_warp_watermarks; ///< 0x0F98 | ||
| 2747 | f32 depth_bounds[2]; ///< 0x0F9C | ||
| 2748 | SampleMask::Target sample_mask_target; ///< 0x0FA4 | ||
| 2749 | u32 color_target_mrt_enable; ///< 0x0FAC | ||
| 2750 | NonMultisampledZ non_multisampled_z; ///< 0x0FB0 | ||
| 2751 | TIRMode tir_mode; ///< 0x0FB4 | ||
| 2752 | AntiAliasRaster anti_alias_raster; ///< 0x0FB8 | ||
| 2753 | SampleMask::Pos sample_mask_pos; ///< 0x0FBC | ||
| 2754 | SurfaceClipIDMemory surface_clip_id_memory; ///< 0x0FCC | ||
| 2755 | TIRModulation tir_modulation; ///< 0x0FD4 | ||
| 2756 | u32 blend_control_allow_float_pixel_kills; ///< 0x0FDC | ||
| 2757 | Zeta zeta; ///< 0x0FE0 | ||
| 2758 | SurfaceClip surface_clip; ///< 0x0FF4 | ||
| 2759 | u32 tiled_cache_treat_heavy_as_light; ///< 0x0FFC | ||
| 2760 | L2CacheVAFRequests l2_cache_vaf; ///< 0x1000 | ||
| 2761 | ViewportMulticast viewport_multicast; ///< 0x1004 | ||
| 2762 | u32 tessellation_cut_height; ///< 0x1008 | ||
| 2763 | u32 max_gs_instances_per_task; ///< 0x100C | ||
| 2764 | u32 max_gs_output_vertices_per_task; ///< 0x1010 | ||
| 2765 | u32 reserved_sw_method0; ///< 0x1014 | ||
| 2766 | u32 gs_output_cb_storage_multiplier; ///< 0x1018 | ||
| 2767 | u32 beta_cb_storage_constant; ///< 0x101C | ||
| 2768 | u32 ti_output_cb_storage_multiplier; ///< 0x1020 | ||
| 2769 | u32 alpha_cb_storage_constraint; ///< 0x1024 | ||
| 2770 | u32 reserved_sw_method1; ///< 0x1028 | ||
| 2771 | u32 reserved_sw_method2; ///< 0x102C | ||
| 2772 | std::array<TIRModulationCoeff, 5> tir_modulation_coeff; ///< 0x1030 | ||
| 2773 | std::array<u32, 15> spare_nop; ///< 0x1044 | ||
| 2774 | INSERT_PADDING_BYTES_NOINIT(0x30); | ||
| 2775 | std::array<u32, 7> reserved_sw_method3_to_7; ///< 0x10B0 | ||
| 2776 | ReduceColorThreshold reduce_color_thresholds_unorm8; ///< 0x10CC | ||
| 2777 | std::array<u32, 4> reserved_sw_method10_to_13; ///< 0x10D0 | ||
| 2778 | ReduceColorThreshold reduce_color_thresholds_unorm10; ///< 0x10E0 | ||
| 2779 | ReduceColorThreshold reduce_color_thresholds_unorm16; ///< 0x10E4 | ||
| 2780 | ReduceColorThreshold reduce_color_thresholds_fp11; ///< 0x10E8 | ||
| 2781 | ReduceColorThreshold reduce_color_thresholds_fp16; ///< 0x10EC | ||
| 2782 | ReduceColorThreshold reduce_color_thresholds_srgb8; ///< 0x10F0 | ||
| 2783 | u32 unbind_all_constant_buffers; ///< 0x10F4 | ||
| 2784 | ClearControl clear_control; ///< 0x10F8 | ||
| 2785 | L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_reads; ///< 0x10FC | ||
| 2786 | u32 reserved_sw_method14; ///< 0x1100 | ||
| 2787 | u32 reserved_sw_method15; ///< 0x1104 | ||
| 2788 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2789 | u32 no_operation_data_high; ///< 0x110C | ||
| 2790 | u32 depth_bias_control; ///< 0x1110 | ||
| 2791 | u32 pm_trigger_end; ///< 0x1114 | ||
| 2792 | u32 vertex_id_base; ///< 0x1118 | ||
| 2793 | u32 stencil_compression_enabled; ///< 0x111C | ||
| 2794 | VertexOutputAttributeSkipMasks vertex_output_attribute_skip_masks; ///< 0x1120 | ||
| 2795 | TIRControl tir_control; ///< 0x1130 | ||
| 2796 | u32 mutable_method_treat_mutable_as_heavy; ///< 0x1134 | ||
| 2797 | u32 post_ps_use_pre_ps_coverage; ///< 0x1138 | ||
| 2798 | FillViaTriangleMode fill_via_triangle_mode; ///< 0x113C | ||
| 2799 | u32 blend_per_format_snorm8_unorm16_snorm16_enabled; ///< 0x1140 | ||
| 2800 | u32 flush_pending_writes_sm_gloal_store; ///< 0x1144 | ||
| 2801 | INSERT_PADDING_BYTES_NOINIT(0x18); | ||
| 2802 | std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; ///< 0x1160 | ||
| 2803 | std::array<MsaaSampleLocation, 4> multisample_sample_locations; ///< 0x11E0 | ||
| 2804 | u32 offset_render_target_index_by_viewport_index; ///< 0x11F0 | ||
| 2805 | u32 force_heavy_method_sync; ///< 0x11F4 | ||
| 2806 | MultisampleCoverageToColor multisample_coverage_to_color; ///< 0x11F8 | ||
| 2807 | DecompressZetaSurface decompress_zeta_surface; ///< 0x11FC | ||
| 2808 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2809 | ZetaSparse zeta_sparse; ///< 0x1208 | ||
| 2810 | u32 invalidate_sampler_cache; ///< 0x120C | ||
| 2811 | u32 invalidate_texture_header_cache; ///< 0x1210 | ||
| 2812 | VertexArray vertex_array_instance_first; ///< 0x1214 | ||
| 2813 | VertexArray vertex_array_instance_subsequent; ///< 0x1218 | ||
| 2814 | RtControl rt_control; ///< 0x121C | ||
| 2815 | CompressionThresholdSamples compression_threshold_samples; ///< 0x1220 | ||
| 2816 | PixelShaderInterlockControl ps_interlock_control; ///< 0x1224 | ||
| 2817 | ZetaSize zeta_size; ///< 0x1228 | ||
| 2818 | SamplerBinding sampler_binding; ///< 0x1234 | ||
| 2819 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2820 | u32 draw_auto_byte_count; ///< 0x123C | ||
| 2821 | std::array<u32, 8> post_vtg_shader_attrib_skip_mask; ///< 0x1240 | ||
| 2822 | PsTicketDispenserValue ps_ticket_dispenser_value; ///< 0x1260 | ||
| 2823 | INSERT_PADDING_BYTES_NOINIT(0x1C); | ||
| 2824 | u32 circular_buffer_size; ///< 0x1280 | ||
| 2825 | RegisterWatermarks vtg_register_watermarks; ///< 0x1284 | ||
| 2826 | InvalidateTextureDataCacheNoWfi invalidate_texture_cache_no_wfi; ///< 0x1288 | ||
| 2827 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2828 | L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_reads; ///< 0x1290 | ||
| 2829 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2830 | u32 primitive_restart_topology_change_index; ///< 0x12A4 | ||
| 2831 | INSERT_PADDING_BYTES_NOINIT(0x20); | ||
| 2832 | ZCullRegionEnable zcull_region_enable; ///< 0x12C8 | ||
| 2833 | u32 depth_test_enable; ///< 0x12CC | ||
| 2834 | FillMode fill_mode; ///< 0x12D0 | ||
| 2835 | ShadeMode shade_mode; ///< 0x12D4 | ||
| 2836 | L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_writes; ///< 0x12D8 | ||
| 2837 | L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_writes; ///< 0x12DC | ||
| 2838 | AlphaToCoverageDither alpha_to_coverage_dither; ///< 0x12E0 | ||
| 2839 | u32 blend_per_target_enabled; ///< 0x12E4 | ||
| 2840 | u32 depth_write_enabled; ///< 0x12E8 | ||
| 2841 | u32 alpha_test_enabled; ///< 0x12EC | ||
| 2842 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2843 | InlineIndex4x8Align inline_index_4x8_align; ///< 0x1300 | ||
| 2844 | InlineIndex4x8Index inline_index_4x8_index; ///< 0x1304 | ||
| 2845 | D3DCullMode d3d_cull_mode; ///< 0x1308 | ||
| 2846 | ComparisonOp depth_test_func; ///< 0x130C | ||
| 2847 | f32 alpha_test_ref; ///< 0x1310 | ||
| 2848 | ComparisonOp alpha_test_func; ///< 0x1314 | ||
| 2849 | u32 draw_auto_stride; ///< 0x1318 | ||
| 2850 | BlendColor blend_color; ///< 0x131C | ||
| 2851 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2852 | InvalidateCacheLines invalidate_sampler_cache_lines; ///< 0x1330 | ||
| 2853 | InvalidateCacheLines invalidate_texture_header_cache_lines; ///< 0x1334 | ||
| 2854 | InvalidateCacheLines invalidate_texture_data_cache_lines; ///< 0x1338 | ||
| 2855 | Blend blend; ///< 0x133C | ||
| 2856 | u32 stencil_enable; ///< 0x1380 | ||
| 2857 | StencilOp stencil_front_op; ///< 0x1384 | ||
| 2858 | StencilFunc stencil_front_func; ///< 0x1394 | ||
| 2859 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2860 | u32 draw_auto_start_byte_count; ///< 0x13A4 | ||
| 2861 | PsSaturate frag_color_clamp; ///< 0x13A8 | ||
| 2862 | WindowOrigin window_origin; ///< 0x13AC | ||
| 2863 | f32 line_width_smooth; ///< 0x13B0 | ||
| 2864 | f32 line_width_aliased; ///< 0x13B4 | ||
| 2865 | INSERT_PADDING_BYTES_NOINIT(0x60); | ||
| 2866 | u32 line_override_multisample; ///< 0x1418 | ||
| 2867 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2868 | u32 alpha_hysteresis_rounds; ///< 0x1420 | ||
| 2869 | InvalidateCacheLines invalidate_sampler_cache_no_wfi; ///< 0x1424 | ||
| 2870 | InvalidateCacheLines invalidate_texture_header_cache_no_wfi; ///< 0x1428 | ||
| 2871 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2872 | u32 global_base_vertex_index; ///< 0x1434 | ||
| 2873 | u32 global_base_instance_index; ///< 0x1438 | ||
| 2874 | INSERT_PADDING_BYTES_NOINIT(0x14); | ||
| 2875 | RegisterWatermarks ps_warp_watermarks; ///< 0x1450 | ||
| 2876 | RegisterWatermarks ps_regster_watermarks; ///< 0x1454 | ||
| 2877 | INSERT_PADDING_BYTES_NOINIT(0xC); | ||
| 2878 | u32 store_zcull; ///< 0x1464 | ||
| 2879 | INSERT_PADDING_BYTES_NOINIT(0x18); | ||
| 2880 | std::array<IteratedBlendConstants, NumRenderTargets> | ||
| 2881 | iterated_blend_constants; ///< 0x1480 | ||
| 2882 | u32 load_zcull; ///< 0x1500 | ||
| 2883 | u32 surface_clip_id_height; ///< 0x1504 | ||
| 2884 | Window surface_clip_id_clear_rect; ///< 0x1508 | ||
| 2885 | UserClip::Enable user_clip_enable; ///< 0x1510 | ||
| 2886 | u32 zpass_pixel_count_enable; ///< 0x1514 | ||
| 2887 | f32 point_size; ///< 0x1518 | ||
| 2888 | u32 zcull_stats_enable; ///< 0x151C | ||
| 2889 | u32 point_sprite_enable; ///< 0x1520 | ||
| 2890 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2891 | u32 shader_exceptions_enable; ///< 0x1528 | ||
| 2892 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2893 | ClearReport clear_report_value; ///< 0x1530 | ||
| 2894 | u32 anti_alias_enable; ///< 0x1534 | ||
| 2895 | u32 zeta_enable; ///< 0x1538 | ||
| 2896 | AntiAliasAlphaControl anti_alias_alpha_control; ///< 0x153C | ||
| 2897 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2898 | RenderEnable render_enable; ///< 0x1550 | ||
| 2899 | TexSampler tex_sampler; ///< 0x155C | ||
| 2900 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2901 | f32 slope_scale_depth_bias; ///< 0x156C | ||
| 2902 | u32 line_anti_alias_enable; ///< 0x1570 | ||
| 2903 | TexHeader tex_header; ///< 0x1574 | ||
| 2904 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2905 | u32 active_zcull_region_id; ///< 0x1590 | ||
| 2906 | u32 stencil_two_side_enable; ///< 0x1594 | ||
| 2907 | StencilOp stencil_back_op; ///< 0x1598 | ||
| 2908 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2909 | u32 framebuffer_srgb; ///< 0x15B8 | ||
| 2910 | f32 depth_bias; ///< 0x15BC | ||
| 2911 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2912 | ZCullRegionFormat zcull_region_format; ///< 0x15C8 | ||
| 2913 | RtLayer rt_layer; ///< 0x15CC | ||
| 2914 | Tegra::Texture::MsaaMode anti_alias_samples_mode; ///< 0x15D0 | ||
| 2915 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2916 | u32 edge_flag; ///< 0x15E4 | ||
| 2917 | u32 draw_inline_index; ///< 0x15E8 | ||
| 2918 | InlineIndex2x16 inline_index_2x16; ///< 0x15EC | ||
| 2919 | VertexGlobalBaseOffset vertex_global_base_offset; ///< 0x15F4 | ||
| 2920 | ZCullRegionPixelOffset zcull_region_pixel_offset; ///< 0x15FC | ||
| 2921 | PointSprite point_sprite; ///< 0x1604 | ||
| 2922 | ProgramRegion program_region; ///< 0x1608 | ||
| 2923 | DefaultAttributes default_attributes; ///< 0x1610 | ||
| 2924 | Draw draw; ///< 0x1614 | ||
| 2925 | VertexIdCopy vertex_id_copy; ///< 0x161C | ||
| 2926 | u32 add_to_primitive_id; ///< 0x1620 | ||
| 2927 | u32 load_to_primitive_id; ///< 0x1624 | ||
| 2928 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2929 | ShaderBasedCull shader_based_cull; ///< 0x162C | ||
| 2930 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2931 | ClassVersion class_version; ///< 0x1638 | ||
| 2932 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2933 | PrimitiveRestart primitive_restart; ///< 0x1644 | ||
| 2934 | OutputVertexId output_vertex_id; ///< 0x164C | ||
| 2935 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2936 | u32 anti_alias_point_enable; ///< 0x1658 | ||
| 2937 | PointCenterMode point_center_mode; ///< 0x165C | ||
| 2938 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2939 | LineSmoothParams line_smooth_params; ///< 0x1668 | ||
| 2940 | u32 line_stipple_enable; ///< 0x166C | ||
| 2941 | std::array<LineSmoothEdgeTable, 4> line_smooth_edge_table; ///< 0x1670 | ||
| 2942 | LineStippleParams line_stipple_params; ///< 0x1680 | ||
| 2943 | ProvokingVertex provoking_vertex; ///< 0x1684 | ||
| 2944 | u32 two_sided_light_enabled; ///< 0x1688 | ||
| 2945 | u32 polygon_stipple_enabled; ///< 0x168C | ||
| 2946 | ShaderControl shader_control; ///< 0x1690 | ||
| 2947 | INSERT_PADDING_BYTES_NOINIT(0xC); | ||
| 2948 | ClassVersion class_version_check; ///< 0x16A0 | ||
| 2949 | SphVersion sph_version; ///< 0x16A4 | ||
| 2950 | SphVersion sph_version_check; ///< 0x16A8 | ||
| 2951 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 2952 | AlphaToCoverageOverride alpha_to_coverage_override; ///< 0x16B4 | ||
| 2953 | INSERT_PADDING_BYTES_NOINIT(0x48); | ||
| 2954 | std::array<u32, 32> polygon_stipple_pattern; ///< 0x1700 | ||
| 2955 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2956 | AamVersion aam_version; ///< 0x1790 | ||
| 2957 | AamVersion aam_version_check; ///< 0x1794 | ||
| 2958 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2959 | u32 zeta_layer_offset; ///< 0x179C | ||
| 2960 | INSERT_PADDING_BYTES_NOINIT(0x28); | ||
| 2961 | IndexBuffer index_buffer; ///< 0x17C8 | ||
| 2962 | IndexBufferSmall index_buffer32_first; ///< 0x17E4 | ||
| 2963 | IndexBufferSmall index_buffer16_first; ///< 0x17E8 | ||
| 2964 | IndexBufferSmall index_buffer8_first; ///< 0x17EC | ||
| 2965 | IndexBufferSmall index_buffer32_subsequent; ///< 0x17F0 | ||
| 2966 | IndexBufferSmall index_buffer16_subsequent; ///< 0x17F4 | ||
| 2967 | IndexBufferSmall index_buffer8_subsequent; ///< 0x17F8 | ||
| 2968 | INSERT_PADDING_BYTES_NOINIT(0x80); | ||
| 2969 | f32 depth_bias_clamp; ///< 0x187C | ||
| 2970 | VertexStreamInstances vertex_stream_instances; ///< 0x1880 | ||
| 2971 | INSERT_PADDING_BYTES_NOINIT(0x10); | ||
| 2972 | AttributePointSize point_size_attribute; ///< 0x1910 | ||
| 2973 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2974 | u32 gl_cull_test_enabled; ///< 0x1918 | ||
| 2975 | FrontFace gl_front_face; ///< 0x191C | ||
| 2976 | CullFace gl_cull_face; ///< 0x1920 | ||
| 2977 | Viewport::PixelCenter viewport_pixel_center; ///< 0x1924 | ||
| 2978 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2979 | u32 viewport_scale_offset_enbled; ///< 0x192C | ||
| 2980 | INSERT_PADDING_BYTES_NOINIT(0xC); | ||
| 2981 | ViewportClipControl viewport_clip_control; ///< 0x193C | ||
| 2982 | UserClip::Op user_clip_op; ///< 0x1940 | ||
| 2983 | RenderEnable::Override render_enable_override; ///< 0x1944 | ||
| 2984 | PrimitiveTopologyControl primitive_topology_control; ///< 0x1948 | ||
| 2985 | WindowClip window_clip_enable; ///< 0x194C | ||
| 2986 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2987 | InvalidateZCull invalidate_zcull; ///< 0x1958 | ||
| 2988 | INSERT_PADDING_BYTES_NOINIT(0xC); | ||
| 2989 | ZCull zcull; ///< 0x1968 | ||
| 2990 | PrimitiveTopologyOverride topology_override; ///< 0x1970 | ||
| 2991 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 2992 | u32 zcull_sync; ///< 0x1978 | ||
| 2993 | u32 clip_id_test_enable; ///< 0x197C | ||
| 2994 | u32 surface_clip_id_width; ///< 0x1980 | ||
| 2995 | u32 clip_id; ///< 0x1984 | ||
| 2996 | INSERT_PADDING_BYTES_NOINIT(0x34); | ||
| 2997 | u32 depth_bounds_enable; ///< 0x19BC | ||
| 2998 | u32 blend_float_zero_times_anything_is_zero; ///< 0x19C0 | ||
| 2999 | LogicOp logic_op; ///< 0x19C4 | ||
| 3000 | u32 z_compression_enable; ///< 0x19CC | ||
| 3001 | ClearSurface clear_surface; ///< 0x19D0 | ||
| 3002 | u32 clear_clip_id_surface; ///< 0x19D4 | ||
| 3003 | INSERT_PADDING_BYTES_NOINIT(0x8); | ||
| 3004 | std::array<u32, NumRenderTargets> color_compression_enable; ///< 0x19E0 | ||
| 3005 | std::array<ColorMask, NumRenderTargets> color_mask; ///< 0x1A00 | ||
| 3006 | INSERT_PADDING_BYTES_NOINIT(0xC); | ||
| 3007 | u32 pipe_nop; ///< 0x1A2C | ||
| 3008 | std::array<u32, 4> spare; ///< 0x1A30 | ||
| 3009 | INSERT_PADDING_BYTES_NOINIT(0xC0); | ||
| 3010 | ReportSemaphore report_semaphore; ///< 0x1B00 | ||
| 3011 | INSERT_PADDING_BYTES_NOINIT(0xF0); | ||
| 3012 | std::array<VertexStream, NumVertexArrays> vertex_streams; ///< 0x1C00 | ||
| 3013 | BlendPerTarget blend_per_target[NumRenderTargets]; ///< 0x1E00 | ||
| 3014 | std::array<VertexStreamLimit, NumVertexArrays> vertex_stream_limits; ///< 0x1F00 | ||
| 3015 | std::array<Pipeline, MaxShaderProgram> pipelines; ///< 0x2000 | ||
| 3016 | INSERT_PADDING_BYTES_NOINIT(0x180); | ||
| 3017 | u32 falcon[32]; ///< 0x2300 | ||
| 3018 | ConstantBuffer const_buffer; ///< 0x2380 | ||
| 3019 | INSERT_PADDING_BYTES_NOINIT(0x30); | ||
| 3020 | BindGroup bind_groups[MaxShaderStage]; ///< 0x2400 | ||
| 3021 | INSERT_PADDING_BYTES_NOINIT(0x160); | ||
| 3022 | u32 color_clamp_enable; ///< 0x2600 | ||
| 3023 | INSERT_PADDING_BYTES_NOINIT(0x4); | ||
| 3024 | u32 bindless_texture_const_buffer_slot; ///< 0x2608 | ||
| 3025 | u32 trap_handler; ///< 0x260C | ||
| 3026 | INSERT_PADDING_BYTES_NOINIT(0x1F0); | ||
| 3027 | std::array<std::array<StreamOutLayout, 32>, NumTransformFeedbackBuffers> | ||
| 3028 | stream_out_layout; ///< 0x2800 | ||
| 3029 | INSERT_PADDING_BYTES_NOINIT(0x93C); | ||
| 3030 | ShaderPerformance shader_performance; ///< 0x333C | ||
| 3031 | INSERT_PADDING_BYTES_NOINIT(0x18); | ||
| 3032 | std::array<u32, 0x100> shadow_scratch; ///< 0x3400 | ||
| 1422 | }; | 3033 | }; |
| 1423 | std::array<u32, NUM_REGS> reg_array; | 3034 | std::array<u32, NUM_REGS> reg_array; |
| 1424 | }; | 3035 | }; |
| 1425 | }; | 3036 | }; |
| 3037 | // clang-format on | ||
| 1426 | 3038 | ||
| 1427 | Regs regs{}; | 3039 | Regs regs{}; |
| 1428 | 3040 | ||
| @@ -1591,147 +3203,346 @@ private: | |||
| 1591 | }; | 3203 | }; |
| 1592 | 3204 | ||
| 1593 | #define ASSERT_REG_POSITION(field_name, position) \ | 3205 | #define ASSERT_REG_POSITION(field_name, position) \ |
| 1594 | static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ | 3206 | static_assert(offsetof(Maxwell3D::Regs, field_name) == position, \ |
| 1595 | "Field " #field_name " has invalid position") | 3207 | "Field " #field_name " has invalid position") |
| 1596 | 3208 | ||
| 1597 | ASSERT_REG_POSITION(wait_for_idle, 0x44); | 3209 | ASSERT_REG_POSITION(object_id, 0x0000); |
| 1598 | ASSERT_REG_POSITION(macros, 0x45); | 3210 | ASSERT_REG_POSITION(nop, 0x0100); |
| 1599 | ASSERT_REG_POSITION(shadow_ram_control, 0x49); | 3211 | ASSERT_REG_POSITION(notify, 0x0104); |
| 1600 | ASSERT_REG_POSITION(upload, 0x60); | 3212 | ASSERT_REG_POSITION(wait_for_idle, 0x0110); |
| 1601 | ASSERT_REG_POSITION(exec_upload, 0x6C); | 3213 | ASSERT_REG_POSITION(load_mme, 0x0114); |
| 1602 | ASSERT_REG_POSITION(data_upload, 0x6D); | 3214 | ASSERT_REG_POSITION(shadow_ram_control, 0x0124); |
| 1603 | ASSERT_REG_POSITION(force_early_fragment_tests, 0x84); | 3215 | ASSERT_REG_POSITION(peer, 0x0128); |
| 1604 | ASSERT_REG_POSITION(sync_info, 0xB2); | 3216 | ASSERT_REG_POSITION(global_render, 0x0130); |
| 1605 | ASSERT_REG_POSITION(tess_mode, 0xC8); | 3217 | ASSERT_REG_POSITION(go_idle, 0x013C); |
| 1606 | ASSERT_REG_POSITION(tess_level_outer, 0xC9); | 3218 | ASSERT_REG_POSITION(trigger, 0x0140); |
| 1607 | ASSERT_REG_POSITION(tess_level_inner, 0xCD); | 3219 | ASSERT_REG_POSITION(trigger_wfi, 0x0144); |
| 1608 | ASSERT_REG_POSITION(rasterize_enable, 0xDF); | 3220 | ASSERT_REG_POSITION(instrumentation_method_header, 0x0150); |
| 1609 | ASSERT_REG_POSITION(tfb_bindings, 0xE0); | 3221 | ASSERT_REG_POSITION(instrumentation_method_data, 0x0154); |
| 1610 | ASSERT_REG_POSITION(tfb_layouts, 0x1C0); | 3222 | ASSERT_REG_POSITION(upload, 0x0180); |
| 1611 | ASSERT_REG_POSITION(tfb_enabled, 0x1D1); | 3223 | ASSERT_REG_POSITION(launch_dma, 0x01B0); |
| 1612 | ASSERT_REG_POSITION(rt, 0x200); | 3224 | ASSERT_REG_POSITION(inline_data, 0x01B4); |
| 1613 | ASSERT_REG_POSITION(viewport_transform, 0x280); | 3225 | ASSERT_REG_POSITION(i2m, 0x01DC); |
| 1614 | ASSERT_REG_POSITION(viewports, 0x300); | 3226 | ASSERT_REG_POSITION(run_ds_now, 0x0200); |
| 1615 | ASSERT_REG_POSITION(vertex_buffer, 0x35D); | 3227 | ASSERT_REG_POSITION(opportunistic_early_z, 0x0204); |
| 1616 | ASSERT_REG_POSITION(depth_mode, 0x35F); | 3228 | ASSERT_REG_POSITION(aliased_line_width_enabled, 0x020C); |
| 1617 | ASSERT_REG_POSITION(clear_color[0], 0x360); | 3229 | ASSERT_REG_POSITION(mandated_early_z, 0x0210); |
| 1618 | ASSERT_REG_POSITION(clear_depth, 0x364); | 3230 | ASSERT_REG_POSITION(gs_dm_fifo, 0x0214); |
| 1619 | ASSERT_REG_POSITION(clear_stencil, 0x368); | 3231 | ASSERT_REG_POSITION(l2_cache_control, 0x0218); |
| 1620 | ASSERT_REG_POSITION(polygon_mode_front, 0x36B); | 3232 | ASSERT_REG_POSITION(invalidate_shader_cache, 0x021C); |
| 1621 | ASSERT_REG_POSITION(polygon_mode_back, 0x36C); | 3233 | ASSERT_REG_POSITION(sync_info, 0x02C8); |
| 1622 | ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370); | 3234 | ASSERT_REG_POSITION(prim_circular_buffer_throttle, 0x02D0); |
| 1623 | ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371); | 3235 | ASSERT_REG_POSITION(flush_invalidate_rop_mini_cache, 0x02D4); |
| 1624 | ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); | 3236 | ASSERT_REG_POSITION(surface_clip_block_id, 0x02D8); |
| 1625 | ASSERT_REG_POSITION(patch_vertices, 0x373); | 3237 | ASSERT_REG_POSITION(alpha_circular_buffer_size, 0x02DC); |
| 1626 | ASSERT_REG_POSITION(fragment_barrier, 0x378); | 3238 | ASSERT_REG_POSITION(decompress_surface, 0x02E0); |
| 1627 | ASSERT_REG_POSITION(scissor_test, 0x380); | 3239 | ASSERT_REG_POSITION(zcull_rop_bypass, 0x02E4); |
| 1628 | ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); | 3240 | ASSERT_REG_POSITION(zcull_subregion, 0x02E8); |
| 1629 | ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); | 3241 | ASSERT_REG_POSITION(raster_bounding_box, 0x02EC); |
| 1630 | ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); | 3242 | ASSERT_REG_POSITION(peer_semaphore_release, 0x02F0); |
| 1631 | ASSERT_REG_POSITION(invalidate_texture_data_cache, 0x3DD); | 3243 | ASSERT_REG_POSITION(iterated_blend_optimization, 0x02F4); |
| 1632 | ASSERT_REG_POSITION(tiled_cache_barrier, 0x3DF); | 3244 | ASSERT_REG_POSITION(zcull_subregion_allocation, 0x02F8); |
| 1633 | ASSERT_REG_POSITION(color_mask_common, 0x3E4); | 3245 | ASSERT_REG_POSITION(zcull_subregion_algorithm, 0x02FC); |
| 1634 | ASSERT_REG_POSITION(depth_bounds, 0x3E7); | 3246 | ASSERT_REG_POSITION(ps_output_sample_mask_usage, 0x0300); |
| 1635 | ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); | 3247 | ASSERT_REG_POSITION(draw_zero_index, 0x0304); |
| 1636 | ASSERT_REG_POSITION(multisample_raster_enable, 0x3ED); | 3248 | ASSERT_REG_POSITION(l1_configuration, 0x0308); |
| 1637 | ASSERT_REG_POSITION(multisample_raster_samples, 0x3EE); | 3249 | ASSERT_REG_POSITION(render_enable_control_load_const_buffer, 0x030C); |
| 1638 | ASSERT_REG_POSITION(multisample_sample_mask, 0x3EF); | 3250 | ASSERT_REG_POSITION(spa_version, 0x0310); |
| 1639 | ASSERT_REG_POSITION(zeta, 0x3F8); | 3251 | ASSERT_REG_POSITION(ieee_clean_update, 0x0314); |
| 1640 | ASSERT_REG_POSITION(render_area, 0x3FD); | 3252 | ASSERT_REG_POSITION(snap_grid, 0x0318); |
| 1641 | ASSERT_REG_POSITION(clear_flags, 0x43E); | 3253 | ASSERT_REG_POSITION(tessellation, 0x0320); |
| 1642 | ASSERT_REG_POSITION(fill_rectangle, 0x44F); | 3254 | ASSERT_REG_POSITION(sub_tiling_perf, 0x0360); |
| 1643 | ASSERT_REG_POSITION(conservative_raster_enable, 0x452); | 3255 | ASSERT_REG_POSITION(zcull_subregion_report, 0x036C); |
| 1644 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); | 3256 | ASSERT_REG_POSITION(balanced_primitive_workload, 0x0374); |
| 1645 | ASSERT_REG_POSITION(multisample_sample_locations, 0x478); | 3257 | ASSERT_REG_POSITION(max_patches_per_batch, 0x0378); |
| 1646 | ASSERT_REG_POSITION(multisample_coverage_to_color, 0x47E); | 3258 | ASSERT_REG_POSITION(rasterize_enable, 0x037C); |
| 1647 | ASSERT_REG_POSITION(rt_control, 0x487); | 3259 | ASSERT_REG_POSITION(transform_feedback, 0x0380); |
| 1648 | ASSERT_REG_POSITION(zeta_width, 0x48a); | 3260 | ASSERT_REG_POSITION(transform_feedback.controls, 0x0700); |
| 1649 | ASSERT_REG_POSITION(zeta_height, 0x48b); | 3261 | ASSERT_REG_POSITION(raster_input, 0x0740); |
| 1650 | ASSERT_REG_POSITION(zeta_depth, 0x48c); | 3262 | ASSERT_REG_POSITION(transform_feedback_enabled, 0x0744); |
| 1651 | ASSERT_REG_POSITION(sampler_index, 0x48D); | 3263 | ASSERT_REG_POSITION(primitive_restart_topology_change_enable, 0x0748); |
| 1652 | ASSERT_REG_POSITION(gp_passthrough_mask, 0x490); | 3264 | ASSERT_REG_POSITION(alpha_fraction, 0x074C); |
| 1653 | ASSERT_REG_POSITION(depth_test_enable, 0x4B3); | 3265 | ASSERT_REG_POSITION(hybrid_aa_control, 0x0754); |
| 1654 | ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); | 3266 | ASSERT_REG_POSITION(shader_local_memory, 0x077C); |
| 1655 | ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); | 3267 | ASSERT_REG_POSITION(color_zero_bandwidth_clear, 0x07A4); |
| 1656 | ASSERT_REG_POSITION(alpha_test_enabled, 0x4BB); | 3268 | ASSERT_REG_POSITION(z_zero_bandwidth_clear, 0x07A8); |
| 1657 | ASSERT_REG_POSITION(d3d_cull_mode, 0x4C2); | 3269 | ASSERT_REG_POSITION(isbe_save_restore_program_offset, 0x07AC); |
| 1658 | ASSERT_REG_POSITION(depth_test_func, 0x4C3); | 3270 | ASSERT_REG_POSITION(zcull_region, 0x07C0); |
| 1659 | ASSERT_REG_POSITION(alpha_test_ref, 0x4C4); | 3271 | ASSERT_REG_POSITION(zeta_read_only, 0x07F8); |
| 1660 | ASSERT_REG_POSITION(alpha_test_func, 0x4C5); | 3272 | ASSERT_REG_POSITION(rt, 0x0800); |
| 1661 | ASSERT_REG_POSITION(draw_tfb_stride, 0x4C6); | 3273 | ASSERT_REG_POSITION(viewport_transform, 0x0A00); |
| 1662 | ASSERT_REG_POSITION(blend_color, 0x4C7); | 3274 | ASSERT_REG_POSITION(viewports, 0x0C00); |
| 1663 | ASSERT_REG_POSITION(blend, 0x4CF); | 3275 | ASSERT_REG_POSITION(windows, 0x0D00); |
| 1664 | ASSERT_REG_POSITION(stencil_enable, 0x4E0); | 3276 | ASSERT_REG_POSITION(clip_id_extent, 0x0D40); |
| 1665 | ASSERT_REG_POSITION(stencil_front_op_fail, 0x4E1); | 3277 | ASSERT_REG_POSITION(max_geometry_instances_per_task, 0x0D60); |
| 1666 | ASSERT_REG_POSITION(stencil_front_op_zfail, 0x4E2); | 3278 | ASSERT_REG_POSITION(visible_call_limit, 0x0D64); |
| 1667 | ASSERT_REG_POSITION(stencil_front_op_zpass, 0x4E3); | 3279 | ASSERT_REG_POSITION(statistics_count, 0x0D68); |
| 1668 | ASSERT_REG_POSITION(stencil_front_func_func, 0x4E4); | 3280 | ASSERT_REG_POSITION(clear_rect, 0x0D6C); |
| 1669 | ASSERT_REG_POSITION(stencil_front_func_ref, 0x4E5); | 3281 | ASSERT_REG_POSITION(vertex_buffer, 0x0D74); |
| 1670 | ASSERT_REG_POSITION(stencil_front_func_mask, 0x4E6); | 3282 | ASSERT_REG_POSITION(depth_mode, 0x0D7C); |
| 1671 | ASSERT_REG_POSITION(stencil_front_mask, 0x4E7); | 3283 | ASSERT_REG_POSITION(clear_color, 0x0D80); |
| 1672 | ASSERT_REG_POSITION(frag_color_clamp, 0x4EA); | 3284 | ASSERT_REG_POSITION(clear_depth, 0x0D90); |
| 1673 | ASSERT_REG_POSITION(screen_y_control, 0x4EB); | 3285 | ASSERT_REG_POSITION(shader_cache_icache_prefetch, 0x0D94); |
| 1674 | ASSERT_REG_POSITION(line_width_smooth, 0x4EC); | 3286 | ASSERT_REG_POSITION(force_transition_to_beta, 0x0D98); |
| 1675 | ASSERT_REG_POSITION(line_width_aliased, 0x4ED); | 3287 | ASSERT_REG_POSITION(reduce_colour_thresholds, 0x0D9C); |
| 1676 | ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x509); | 3288 | ASSERT_REG_POSITION(clear_stencil, 0x0DA0); |
| 1677 | ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x50A); | 3289 | ASSERT_REG_POSITION(invalidate_shader_cache_no_wfi, 0x0DA4); |
| 1678 | ASSERT_REG_POSITION(vb_element_base, 0x50D); | 3290 | ASSERT_REG_POSITION(zcull_serialization, 0x0DA8); |
| 1679 | ASSERT_REG_POSITION(vb_base_instance, 0x50E); | 3291 | ASSERT_REG_POSITION(polygon_mode_front, 0x0DAC); |
| 1680 | ASSERT_REG_POSITION(clip_distance_enabled, 0x544); | 3292 | ASSERT_REG_POSITION(polygon_mode_back, 0x0DB0); |
| 1681 | ASSERT_REG_POSITION(samplecnt_enable, 0x545); | 3293 | ASSERT_REG_POSITION(polygon_smooth, 0x0DB4); |
| 1682 | ASSERT_REG_POSITION(point_size, 0x546); | 3294 | ASSERT_REG_POSITION(zeta_mark_clean_ieee, 0x0DB8); |
| 1683 | ASSERT_REG_POSITION(point_sprite_enable, 0x548); | 3295 | ASSERT_REG_POSITION(zcull_dir_format, 0x0DBC); |
| 1684 | ASSERT_REG_POSITION(counter_reset, 0x54C); | 3296 | ASSERT_REG_POSITION(polygon_offset_point_enable, 0x0DC0); |
| 1685 | ASSERT_REG_POSITION(multisample_enable, 0x54D); | 3297 | ASSERT_REG_POSITION(polygon_offset_line_enable, 0x0DC4); |
| 1686 | ASSERT_REG_POSITION(zeta_enable, 0x54E); | 3298 | ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x0DC8); |
| 1687 | ASSERT_REG_POSITION(multisample_control, 0x54F); | 3299 | ASSERT_REG_POSITION(patch_vertices, 0x0DCC); |
| 1688 | ASSERT_REG_POSITION(condition, 0x554); | 3300 | ASSERT_REG_POSITION(iterated_blend, 0x0DD0); |
| 1689 | ASSERT_REG_POSITION(tsc, 0x557); | 3301 | ASSERT_REG_POSITION(zcull_criteria, 0x0DD8); |
| 1690 | ASSERT_REG_POSITION(polygon_offset_factor, 0x55B); | 3302 | ASSERT_REG_POSITION(fragment_barrier, 0x0DE0); |
| 1691 | ASSERT_REG_POSITION(line_smooth_enable, 0x55C); | 3303 | ASSERT_REG_POSITION(sm_timeout, 0x0DE4); |
| 1692 | ASSERT_REG_POSITION(tic, 0x55D); | 3304 | ASSERT_REG_POSITION(primitive_restart_array, 0x0DE8); |
| 1693 | ASSERT_REG_POSITION(stencil_two_side_enable, 0x565); | 3305 | ASSERT_REG_POSITION(load_iterated_blend, 0x0DF0); |
| 1694 | ASSERT_REG_POSITION(stencil_back_op_fail, 0x566); | 3306 | ASSERT_REG_POSITION(window_offset_x, 0x0DF8); |
| 1695 | ASSERT_REG_POSITION(stencil_back_op_zfail, 0x567); | 3307 | ASSERT_REG_POSITION(window_offset_y, 0x0DFC); |
| 1696 | ASSERT_REG_POSITION(stencil_back_op_zpass, 0x568); | 3308 | ASSERT_REG_POSITION(scissor_test, 0x0E00); |
| 1697 | ASSERT_REG_POSITION(stencil_back_func_func, 0x569); | 3309 | ASSERT_REG_POSITION(select_texture_headers, 0x0F10); |
| 1698 | ASSERT_REG_POSITION(framebuffer_srgb, 0x56E); | 3310 | ASSERT_REG_POSITION(vpc_perf, 0x0F14); |
| 1699 | ASSERT_REG_POSITION(polygon_offset_units, 0x56F); | 3311 | ASSERT_REG_POSITION(pm_local_trigger, 0x0F18); |
| 1700 | ASSERT_REG_POSITION(multisample_mode, 0x574); | 3312 | ASSERT_REG_POSITION(post_z_pixel_imask, 0x0F1C); |
| 1701 | ASSERT_REG_POSITION(point_coord_replace, 0x581); | 3313 | ASSERT_REG_POSITION(const_color_rendering, 0x0F40); |
| 1702 | ASSERT_REG_POSITION(code_address, 0x582); | 3314 | ASSERT_REG_POSITION(stencil_back_func, 0x0F54); |
| 1703 | ASSERT_REG_POSITION(draw, 0x585); | 3315 | ASSERT_REG_POSITION(vertex_stream_substitute, 0x0F84); |
| 1704 | ASSERT_REG_POSITION(primitive_restart, 0x591); | 3316 | ASSERT_REG_POSITION(line_mode_clip_generated_edge_do_not_draw, 0x0F8C); |
| 1705 | ASSERT_REG_POSITION(provoking_vertex_last, 0x5A1); | 3317 | ASSERT_REG_POSITION(color_mask_common, 0x0F90); |
| 1706 | ASSERT_REG_POSITION(index_array, 0x5F2); | 3318 | ASSERT_REG_POSITION(vtg_warp_watermarks, 0x0F98); |
| 1707 | ASSERT_REG_POSITION(small_index, 0x5F9); | 3319 | ASSERT_REG_POSITION(depth_bounds, 0x0F9C); |
| 1708 | ASSERT_REG_POSITION(polygon_offset_clamp, 0x61F); | 3320 | ASSERT_REG_POSITION(sample_mask_target, 0x0FA4); |
| 1709 | ASSERT_REG_POSITION(instanced_arrays, 0x620); | 3321 | ASSERT_REG_POSITION(color_target_mrt_enable, 0x0FAC); |
| 1710 | ASSERT_REG_POSITION(vp_point_size, 0x644); | 3322 | ASSERT_REG_POSITION(non_multisampled_z, 0x0FB0); |
| 1711 | ASSERT_REG_POSITION(cull_test_enabled, 0x646); | 3323 | ASSERT_REG_POSITION(tir_mode, 0x0FB4); |
| 1712 | ASSERT_REG_POSITION(front_face, 0x647); | 3324 | ASSERT_REG_POSITION(anti_alias_raster, 0x0FB8); |
| 1713 | ASSERT_REG_POSITION(cull_face, 0x648); | 3325 | ASSERT_REG_POSITION(sample_mask_pos, 0x0FBC); |
| 1714 | ASSERT_REG_POSITION(pixel_center_integer, 0x649); | 3326 | ASSERT_REG_POSITION(surface_clip_id_memory, 0x0FCC); |
| 1715 | ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B); | 3327 | ASSERT_REG_POSITION(tir_modulation, 0x0FD4); |
| 1716 | ASSERT_REG_POSITION(view_volume_clip_control, 0x64F); | 3328 | ASSERT_REG_POSITION(blend_control_allow_float_pixel_kills, 0x0FDC); |
| 1717 | ASSERT_REG_POSITION(topology_override, 0x65C); | 3329 | ASSERT_REG_POSITION(zeta, 0x0FE0); |
| 1718 | ASSERT_REG_POSITION(depth_bounds_enable, 0x66F); | 3330 | ASSERT_REG_POSITION(surface_clip, 0x0FF4); |
| 1719 | ASSERT_REG_POSITION(logic_op, 0x671); | 3331 | ASSERT_REG_POSITION(tiled_cache_treat_heavy_as_light, 0x0FFC); |
| 1720 | ASSERT_REG_POSITION(clear_buffers, 0x674); | 3332 | ASSERT_REG_POSITION(l2_cache_vaf, 0x1000); |
| 1721 | ASSERT_REG_POSITION(color_mask, 0x680); | 3333 | ASSERT_REG_POSITION(viewport_multicast, 0x1004); |
| 1722 | ASSERT_REG_POSITION(query, 0x6C0); | 3334 | ASSERT_REG_POSITION(tessellation_cut_height, 0x1008); |
| 1723 | ASSERT_REG_POSITION(vertex_array[0], 0x700); | 3335 | ASSERT_REG_POSITION(max_gs_instances_per_task, 0x100C); |
| 1724 | ASSERT_REG_POSITION(independent_blend, 0x780); | 3336 | ASSERT_REG_POSITION(max_gs_output_vertices_per_task, 0x1010); |
| 1725 | ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0); | 3337 | ASSERT_REG_POSITION(reserved_sw_method0, 0x1014); |
| 1726 | ASSERT_REG_POSITION(shader_config[0], 0x800); | 3338 | ASSERT_REG_POSITION(gs_output_cb_storage_multiplier, 0x1018); |
| 1727 | ASSERT_REG_POSITION(firmware, 0x8C0); | 3339 | ASSERT_REG_POSITION(beta_cb_storage_constant, 0x101C); |
| 1728 | ASSERT_REG_POSITION(const_buffer, 0x8E0); | 3340 | ASSERT_REG_POSITION(ti_output_cb_storage_multiplier, 0x1020); |
| 1729 | ASSERT_REG_POSITION(cb_bind[0], 0x904); | 3341 | ASSERT_REG_POSITION(alpha_cb_storage_constraint, 0x1024); |
| 1730 | ASSERT_REG_POSITION(tex_cb_index, 0x982); | 3342 | ASSERT_REG_POSITION(reserved_sw_method1, 0x1028); |
| 1731 | ASSERT_REG_POSITION(tfb_varying_locs, 0xA00); | 3343 | ASSERT_REG_POSITION(reserved_sw_method2, 0x102C); |
| 1732 | ASSERT_REG_POSITION(ssbo_info, 0xD18); | 3344 | ASSERT_REG_POSITION(tir_modulation_coeff, 0x1030); |
| 1733 | ASSERT_REG_POSITION(tex_info_buffers.address[0], 0xD2A); | 3345 | ASSERT_REG_POSITION(spare_nop, 0x1044); |
| 1734 | ASSERT_REG_POSITION(tex_info_buffers.size[0], 0xD2F); | 3346 | ASSERT_REG_POSITION(reserved_sw_method3_to_7, 0x10B0); |
| 3347 | ASSERT_REG_POSITION(reduce_color_thresholds_unorm8, 0x10CC); | ||
| 3348 | ASSERT_REG_POSITION(reserved_sw_method10_to_13, 0x10D0); | ||
| 3349 | ASSERT_REG_POSITION(reduce_color_thresholds_unorm10, 0x10E0); | ||
| 3350 | ASSERT_REG_POSITION(reduce_color_thresholds_unorm16, 0x10E4); | ||
| 3351 | ASSERT_REG_POSITION(reduce_color_thresholds_fp11, 0x10E8); | ||
| 3352 | ASSERT_REG_POSITION(reduce_color_thresholds_fp16, 0x10EC); | ||
| 3353 | ASSERT_REG_POSITION(reduce_color_thresholds_srgb8, 0x10F0); | ||
| 3354 | ASSERT_REG_POSITION(unbind_all_constant_buffers, 0x10F4); | ||
| 3355 | ASSERT_REG_POSITION(clear_control, 0x10F8); | ||
| 3356 | ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_reads, 0x10FC); | ||
| 3357 | ASSERT_REG_POSITION(reserved_sw_method14, 0x1100); | ||
| 3358 | ASSERT_REG_POSITION(reserved_sw_method15, 0x1104); | ||
| 3359 | ASSERT_REG_POSITION(no_operation_data_high, 0x110C); | ||
| 3360 | ASSERT_REG_POSITION(depth_bias_control, 0x1110); | ||
| 3361 | ASSERT_REG_POSITION(pm_trigger_end, 0x1114); | ||
| 3362 | ASSERT_REG_POSITION(vertex_id_base, 0x1118); | ||
| 3363 | ASSERT_REG_POSITION(stencil_compression_enabled, 0x111C); | ||
| 3364 | ASSERT_REG_POSITION(vertex_output_attribute_skip_masks, 0x1120); | ||
| 3365 | ASSERT_REG_POSITION(tir_control, 0x1130); | ||
| 3366 | ASSERT_REG_POSITION(mutable_method_treat_mutable_as_heavy, 0x1134); | ||
| 3367 | ASSERT_REG_POSITION(post_ps_use_pre_ps_coverage, 0x1138); | ||
| 3368 | ASSERT_REG_POSITION(fill_via_triangle_mode, 0x113C); | ||
| 3369 | ASSERT_REG_POSITION(blend_per_format_snorm8_unorm16_snorm16_enabled, 0x1140); | ||
| 3370 | ASSERT_REG_POSITION(flush_pending_writes_sm_gloal_store, 0x1144); | ||
| 3371 | ASSERT_REG_POSITION(vertex_attrib_format, 0x1160); | ||
| 3372 | ASSERT_REG_POSITION(multisample_sample_locations, 0x11E0); | ||
| 3373 | ASSERT_REG_POSITION(offset_render_target_index_by_viewport_index, 0x11F0); | ||
| 3374 | ASSERT_REG_POSITION(force_heavy_method_sync, 0x11F4); | ||
| 3375 | ASSERT_REG_POSITION(multisample_coverage_to_color, 0x11F8); | ||
| 3376 | ASSERT_REG_POSITION(decompress_zeta_surface, 0x11FC); | ||
| 3377 | ASSERT_REG_POSITION(zeta_sparse, 0x1208); | ||
| 3378 | ASSERT_REG_POSITION(invalidate_sampler_cache, 0x120C); | ||
| 3379 | ASSERT_REG_POSITION(invalidate_texture_header_cache, 0x1210); | ||
| 3380 | ASSERT_REG_POSITION(vertex_array_instance_first, 0x1214); | ||
| 3381 | ASSERT_REG_POSITION(vertex_array_instance_subsequent, 0x1218); | ||
| 3382 | ASSERT_REG_POSITION(rt_control, 0x121C); | ||
| 3383 | ASSERT_REG_POSITION(compression_threshold_samples, 0x1220); | ||
| 3384 | ASSERT_REG_POSITION(ps_interlock_control, 0x1224); | ||
| 3385 | ASSERT_REG_POSITION(zeta_size, 0x1228); | ||
| 3386 | ASSERT_REG_POSITION(sampler_binding, 0x1234); | ||
| 3387 | ASSERT_REG_POSITION(draw_auto_byte_count, 0x123C); | ||
| 3388 | ASSERT_REG_POSITION(post_vtg_shader_attrib_skip_mask, 0x1240); | ||
| 3389 | ASSERT_REG_POSITION(ps_ticket_dispenser_value, 0x1260); | ||
| 3390 | ASSERT_REG_POSITION(circular_buffer_size, 0x1280); | ||
| 3391 | ASSERT_REG_POSITION(vtg_register_watermarks, 0x1284); | ||
| 3392 | ASSERT_REG_POSITION(invalidate_texture_cache_no_wfi, 0x1288); | ||
| 3393 | ASSERT_REG_POSITION(l2_cache_rop_interlocked_reads, 0x1290); | ||
| 3394 | ASSERT_REG_POSITION(primitive_restart_topology_change_index, 0x12A4); | ||
| 3395 | ASSERT_REG_POSITION(zcull_region_enable, 0x12C8); | ||
| 3396 | ASSERT_REG_POSITION(depth_test_enable, 0x12CC); | ||
| 3397 | ASSERT_REG_POSITION(fill_mode, 0x12D0); | ||
| 3398 | ASSERT_REG_POSITION(shade_mode, 0x12D4); | ||
| 3399 | ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_writes, 0x12D8); | ||
| 3400 | ASSERT_REG_POSITION(l2_cache_rop_interlocked_writes, 0x12DC); | ||
| 3401 | ASSERT_REG_POSITION(alpha_to_coverage_dither, 0x12E0); | ||
| 3402 | ASSERT_REG_POSITION(blend_per_target_enabled, 0x12E4); | ||
| 3403 | ASSERT_REG_POSITION(depth_write_enabled, 0x12E8); | ||
| 3404 | ASSERT_REG_POSITION(alpha_test_enabled, 0x12EC); | ||
| 3405 | ASSERT_REG_POSITION(inline_index_4x8_align, 0x1300); | ||
| 3406 | ASSERT_REG_POSITION(inline_index_4x8_index, 0x1304); | ||
| 3407 | ASSERT_REG_POSITION(d3d_cull_mode, 0x1308); | ||
| 3408 | ASSERT_REG_POSITION(depth_test_func, 0x130C); | ||
| 3409 | ASSERT_REG_POSITION(alpha_test_ref, 0x1310); | ||
| 3410 | ASSERT_REG_POSITION(alpha_test_func, 0x1314); | ||
| 3411 | ASSERT_REG_POSITION(draw_auto_stride, 0x1318); | ||
| 3412 | ASSERT_REG_POSITION(blend_color, 0x131C); | ||
| 3413 | ASSERT_REG_POSITION(invalidate_sampler_cache_lines, 0x1330); | ||
| 3414 | ASSERT_REG_POSITION(invalidate_texture_header_cache_lines, 0x1334); | ||
| 3415 | ASSERT_REG_POSITION(invalidate_texture_data_cache_lines, 0x1338); | ||
| 3416 | ASSERT_REG_POSITION(blend, 0x133C); | ||
| 3417 | ASSERT_REG_POSITION(stencil_enable, 0x1380); | ||
| 3418 | ASSERT_REG_POSITION(stencil_front_op, 0x1384); | ||
| 3419 | ASSERT_REG_POSITION(stencil_front_func, 0x1394); | ||
| 3420 | ASSERT_REG_POSITION(draw_auto_start_byte_count, 0x13A4); | ||
| 3421 | ASSERT_REG_POSITION(frag_color_clamp, 0x13A8); | ||
| 3422 | ASSERT_REG_POSITION(window_origin, 0x13AC); | ||
| 3423 | ASSERT_REG_POSITION(line_width_smooth, 0x13B0); | ||
| 3424 | ASSERT_REG_POSITION(line_width_aliased, 0x13B4); | ||
| 3425 | ASSERT_REG_POSITION(line_override_multisample, 0x1418); | ||
| 3426 | ASSERT_REG_POSITION(alpha_hysteresis_rounds, 0x1420); | ||
| 3427 | ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x1424); | ||
| 3428 | ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x1428); | ||
| 3429 | ASSERT_REG_POSITION(global_base_vertex_index, 0x1434); | ||
| 3430 | ASSERT_REG_POSITION(global_base_instance_index, 0x1438); | ||
| 3431 | ASSERT_REG_POSITION(ps_warp_watermarks, 0x1450); | ||
| 3432 | ASSERT_REG_POSITION(ps_regster_watermarks, 0x1454); | ||
| 3433 | ASSERT_REG_POSITION(store_zcull, 0x1464); | ||
| 3434 | ASSERT_REG_POSITION(iterated_blend_constants, 0x1480); | ||
| 3435 | ASSERT_REG_POSITION(load_zcull, 0x1500); | ||
| 3436 | ASSERT_REG_POSITION(surface_clip_id_height, 0x1504); | ||
| 3437 | ASSERT_REG_POSITION(surface_clip_id_clear_rect, 0x1508); | ||
| 3438 | ASSERT_REG_POSITION(user_clip_enable, 0x1510); | ||
| 3439 | ASSERT_REG_POSITION(zpass_pixel_count_enable, 0x1514); | ||
| 3440 | ASSERT_REG_POSITION(point_size, 0x1518); | ||
| 3441 | ASSERT_REG_POSITION(zcull_stats_enable, 0x151C); | ||
| 3442 | ASSERT_REG_POSITION(point_sprite_enable, 0x1520); | ||
| 3443 | ASSERT_REG_POSITION(shader_exceptions_enable, 0x1528); | ||
| 3444 | ASSERT_REG_POSITION(clear_report_value, 0x1530); | ||
| 3445 | ASSERT_REG_POSITION(anti_alias_enable, 0x1534); | ||
| 3446 | ASSERT_REG_POSITION(zeta_enable, 0x1538); | ||
| 3447 | ASSERT_REG_POSITION(anti_alias_alpha_control, 0x153C); | ||
| 3448 | ASSERT_REG_POSITION(render_enable, 0x1550); | ||
| 3449 | ASSERT_REG_POSITION(tex_sampler, 0x155C); | ||
| 3450 | ASSERT_REG_POSITION(slope_scale_depth_bias, 0x156C); | ||
| 3451 | ASSERT_REG_POSITION(line_anti_alias_enable, 0x1570); | ||
| 3452 | ASSERT_REG_POSITION(tex_header, 0x1574); | ||
| 3453 | ASSERT_REG_POSITION(active_zcull_region_id, 0x1590); | ||
| 3454 | ASSERT_REG_POSITION(stencil_two_side_enable, 0x1594); | ||
| 3455 | ASSERT_REG_POSITION(stencil_back_op, 0x1598); | ||
| 3456 | ASSERT_REG_POSITION(framebuffer_srgb, 0x15B8); | ||
| 3457 | ASSERT_REG_POSITION(depth_bias, 0x15BC); | ||
| 3458 | ASSERT_REG_POSITION(zcull_region_format, 0x15C8); | ||
| 3459 | ASSERT_REG_POSITION(rt_layer, 0x15CC); | ||
| 3460 | ASSERT_REG_POSITION(anti_alias_samples_mode, 0x15D0); | ||
| 3461 | ASSERT_REG_POSITION(edge_flag, 0x15E4); | ||
| 3462 | ASSERT_REG_POSITION(draw_inline_index, 0x15E8); | ||
| 3463 | ASSERT_REG_POSITION(inline_index_2x16, 0x15EC); | ||
| 3464 | ASSERT_REG_POSITION(vertex_global_base_offset, 0x15F4); | ||
| 3465 | ASSERT_REG_POSITION(zcull_region_pixel_offset, 0x15FC); | ||
| 3466 | ASSERT_REG_POSITION(point_sprite, 0x1604); | ||
| 3467 | ASSERT_REG_POSITION(program_region, 0x1608); | ||
| 3468 | ASSERT_REG_POSITION(default_attributes, 0x1610); | ||
| 3469 | ASSERT_REG_POSITION(draw, 0x1614); | ||
| 3470 | ASSERT_REG_POSITION(vertex_id_copy, 0x161C); | ||
| 3471 | ASSERT_REG_POSITION(add_to_primitive_id, 0x1620); | ||
| 3472 | ASSERT_REG_POSITION(load_to_primitive_id, 0x1624); | ||
| 3473 | ASSERT_REG_POSITION(shader_based_cull, 0x162C); | ||
| 3474 | ASSERT_REG_POSITION(class_version, 0x1638); | ||
| 3475 | ASSERT_REG_POSITION(primitive_restart, 0x1644); | ||
| 3476 | ASSERT_REG_POSITION(output_vertex_id, 0x164C); | ||
| 3477 | ASSERT_REG_POSITION(anti_alias_point_enable, 0x1658); | ||
| 3478 | ASSERT_REG_POSITION(point_center_mode, 0x165C); | ||
| 3479 | ASSERT_REG_POSITION(line_smooth_params, 0x1668); | ||
| 3480 | ASSERT_REG_POSITION(line_stipple_enable, 0x166C); | ||
| 3481 | ASSERT_REG_POSITION(line_smooth_edge_table, 0x1670); | ||
| 3482 | ASSERT_REG_POSITION(line_stipple_params, 0x1680); | ||
| 3483 | ASSERT_REG_POSITION(provoking_vertex, 0x1684); | ||
| 3484 | ASSERT_REG_POSITION(two_sided_light_enabled, 0x1688); | ||
| 3485 | ASSERT_REG_POSITION(polygon_stipple_enabled, 0x168C); | ||
| 3486 | ASSERT_REG_POSITION(shader_control, 0x1690); | ||
| 3487 | ASSERT_REG_POSITION(class_version_check, 0x16A0); | ||
| 3488 | ASSERT_REG_POSITION(sph_version, 0x16A4); | ||
| 3489 | ASSERT_REG_POSITION(sph_version_check, 0x16A8); | ||
| 3490 | ASSERT_REG_POSITION(alpha_to_coverage_override, 0x16B4); | ||
| 3491 | ASSERT_REG_POSITION(polygon_stipple_pattern, 0x1700); | ||
| 3492 | ASSERT_REG_POSITION(aam_version, 0x1790); | ||
| 3493 | ASSERT_REG_POSITION(aam_version_check, 0x1794); | ||
| 3494 | ASSERT_REG_POSITION(zeta_layer_offset, 0x179C); | ||
| 3495 | ASSERT_REG_POSITION(index_buffer, 0x17C8); | ||
| 3496 | ASSERT_REG_POSITION(index_buffer32_first, 0x17E4); | ||
| 3497 | ASSERT_REG_POSITION(index_buffer16_first, 0x17E8); | ||
| 3498 | ASSERT_REG_POSITION(index_buffer8_first, 0x17EC); | ||
| 3499 | ASSERT_REG_POSITION(index_buffer32_subsequent, 0x17F0); | ||
| 3500 | ASSERT_REG_POSITION(index_buffer16_subsequent, 0x17F4); | ||
| 3501 | ASSERT_REG_POSITION(index_buffer8_subsequent, 0x17F8); | ||
| 3502 | ASSERT_REG_POSITION(depth_bias_clamp, 0x187C); | ||
| 3503 | ASSERT_REG_POSITION(vertex_stream_instances, 0x1880); | ||
| 3504 | ASSERT_REG_POSITION(point_size_attribute, 0x1910); | ||
| 3505 | ASSERT_REG_POSITION(gl_cull_test_enabled, 0x1918); | ||
| 3506 | ASSERT_REG_POSITION(gl_front_face, 0x191C); | ||
| 3507 | ASSERT_REG_POSITION(gl_cull_face, 0x1920); | ||
| 3508 | ASSERT_REG_POSITION(viewport_pixel_center, 0x1924); | ||
| 3509 | ASSERT_REG_POSITION(viewport_scale_offset_enbled, 0x192C); | ||
| 3510 | ASSERT_REG_POSITION(viewport_clip_control, 0x193C); | ||
| 3511 | ASSERT_REG_POSITION(user_clip_op, 0x1940); | ||
| 3512 | ASSERT_REG_POSITION(render_enable_override, 0x1944); | ||
| 3513 | ASSERT_REG_POSITION(primitive_topology_control, 0x1948); | ||
| 3514 | ASSERT_REG_POSITION(window_clip_enable, 0x194C); | ||
| 3515 | ASSERT_REG_POSITION(invalidate_zcull, 0x1958); | ||
| 3516 | ASSERT_REG_POSITION(zcull, 0x1968); | ||
| 3517 | ASSERT_REG_POSITION(topology_override, 0x1970); | ||
| 3518 | ASSERT_REG_POSITION(zcull_sync, 0x1978); | ||
| 3519 | ASSERT_REG_POSITION(clip_id_test_enable, 0x197C); | ||
| 3520 | ASSERT_REG_POSITION(surface_clip_id_width, 0x1980); | ||
| 3521 | ASSERT_REG_POSITION(clip_id, 0x1984); | ||
| 3522 | ASSERT_REG_POSITION(depth_bounds_enable, 0x19BC); | ||
| 3523 | ASSERT_REG_POSITION(blend_float_zero_times_anything_is_zero, 0x19C0); | ||
| 3524 | ASSERT_REG_POSITION(logic_op, 0x19C4); | ||
| 3525 | ASSERT_REG_POSITION(z_compression_enable, 0x19CC); | ||
| 3526 | ASSERT_REG_POSITION(clear_surface, 0x19D0); | ||
| 3527 | ASSERT_REG_POSITION(clear_clip_id_surface, 0x19D4); | ||
| 3528 | ASSERT_REG_POSITION(color_compression_enable, 0x19E0); | ||
| 3529 | ASSERT_REG_POSITION(color_mask, 0x1A00); | ||
| 3530 | ASSERT_REG_POSITION(pipe_nop, 0x1A2C); | ||
| 3531 | ASSERT_REG_POSITION(spare, 0x1A30); | ||
| 3532 | ASSERT_REG_POSITION(report_semaphore, 0x1B00); | ||
| 3533 | ASSERT_REG_POSITION(vertex_streams, 0x1C00); | ||
| 3534 | ASSERT_REG_POSITION(blend_per_target, 0x1E00); | ||
| 3535 | ASSERT_REG_POSITION(vertex_stream_limits, 0x1F00); | ||
| 3536 | ASSERT_REG_POSITION(pipelines, 0x2000); | ||
| 3537 | ASSERT_REG_POSITION(falcon, 0x2300); | ||
| 3538 | ASSERT_REG_POSITION(const_buffer, 0x2380); | ||
| 3539 | ASSERT_REG_POSITION(bind_groups, 0x2400); | ||
| 3540 | ASSERT_REG_POSITION(color_clamp_enable, 0x2600); | ||
| 3541 | ASSERT_REG_POSITION(bindless_texture_const_buffer_slot, 0x2608); | ||
| 3542 | ASSERT_REG_POSITION(trap_handler, 0x260C); | ||
| 3543 | ASSERT_REG_POSITION(stream_out_layout, 0x2800); | ||
| 3544 | ASSERT_REG_POSITION(shader_performance, 0x333C); | ||
| 3545 | ASSERT_REG_POSITION(shadow_scratch, 0x3400); | ||
| 1735 | 3546 | ||
| 1736 | #undef ASSERT_REG_POSITION | 3547 | #undef ASSERT_REG_POSITION |
| 1737 | 3548 | ||
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 0a4a8b14f..d0709dc69 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -24,11 +24,15 @@ namespace Tegra { | |||
| 24 | class DmaPusher; | 24 | class DmaPusher; |
| 25 | struct CommandList; | 25 | struct CommandList; |
| 26 | 26 | ||
| 27 | // TODO: Implement the commented ones | ||
| 27 | enum class RenderTargetFormat : u32 { | 28 | enum class RenderTargetFormat : u32 { |
| 28 | NONE = 0x0, | 29 | NONE = 0x0, |
| 29 | R32B32G32A32_FLOAT = 0xC0, | 30 | R32B32G32A32_FLOAT = 0xC0, |
| 30 | R32G32B32A32_SINT = 0xC1, | 31 | R32G32B32A32_SINT = 0xC1, |
| 31 | R32G32B32A32_UINT = 0xC2, | 32 | R32G32B32A32_UINT = 0xC2, |
| 33 | // R32G32B32X32_FLOAT = 0xC3, | ||
| 34 | // R32G32B32X32_SINT = 0xC4, | ||
| 35 | // R32G32B32X32_UINT = 0xC5, | ||
| 32 | R16G16B16A16_UNORM = 0xC6, | 36 | R16G16B16A16_UNORM = 0xC6, |
| 33 | R16G16B16A16_SNORM = 0xC7, | 37 | R16G16B16A16_SNORM = 0xC7, |
| 34 | R16G16B16A16_SINT = 0xC8, | 38 | R16G16B16A16_SINT = 0xC8, |
| @@ -38,8 +42,8 @@ enum class RenderTargetFormat : u32 { | |||
| 38 | R32G32_SINT = 0xCC, | 42 | R32G32_SINT = 0xCC, |
| 39 | R32G32_UINT = 0xCD, | 43 | R32G32_UINT = 0xCD, |
| 40 | R16G16B16X16_FLOAT = 0xCE, | 44 | R16G16B16X16_FLOAT = 0xCE, |
| 41 | B8G8R8A8_UNORM = 0xCF, | 45 | A8R8G8B8_UNORM = 0xCF, |
| 42 | B8G8R8A8_SRGB = 0xD0, | 46 | A8R8G8B8_SRGB = 0xD0, |
| 43 | A2B10G10R10_UNORM = 0xD1, | 47 | A2B10G10R10_UNORM = 0xD1, |
| 44 | A2B10G10R10_UINT = 0xD2, | 48 | A2B10G10R10_UINT = 0xD2, |
| 45 | A8B8G8R8_UNORM = 0xD5, | 49 | A8B8G8R8_UNORM = 0xD5, |
| @@ -52,10 +56,13 @@ enum class RenderTargetFormat : u32 { | |||
| 52 | R16G16_SINT = 0xDC, | 56 | R16G16_SINT = 0xDC, |
| 53 | R16G16_UINT = 0xDD, | 57 | R16G16_UINT = 0xDD, |
| 54 | R16G16_FLOAT = 0xDE, | 58 | R16G16_FLOAT = 0xDE, |
| 59 | // A2R10G10B10_UNORM = 0xDF, | ||
| 55 | B10G11R11_FLOAT = 0xE0, | 60 | B10G11R11_FLOAT = 0xE0, |
| 56 | R32_SINT = 0xE3, | 61 | R32_SINT = 0xE3, |
| 57 | R32_UINT = 0xE4, | 62 | R32_UINT = 0xE4, |
| 58 | R32_FLOAT = 0xE5, | 63 | R32_FLOAT = 0xE5, |
| 64 | // X8R8G8B8_UNORM = 0xE6, | ||
| 65 | // X8R8G8B8_SRGB = 0xE7, | ||
| 59 | R5G6B5_UNORM = 0xE8, | 66 | R5G6B5_UNORM = 0xE8, |
| 60 | A1R5G5B5_UNORM = 0xE9, | 67 | A1R5G5B5_UNORM = 0xE9, |
| 61 | R8G8_UNORM = 0xEA, | 68 | R8G8_UNORM = 0xEA, |
| @@ -71,17 +78,42 @@ enum class RenderTargetFormat : u32 { | |||
| 71 | R8_SNORM = 0xF4, | 78 | R8_SNORM = 0xF4, |
| 72 | R8_SINT = 0xF5, | 79 | R8_SINT = 0xF5, |
| 73 | R8_UINT = 0xF6, | 80 | R8_UINT = 0xF6, |
| 81 | |||
| 82 | /* | ||
| 83 | A8_UNORM = 0xF7, | ||
| 84 | X1R5G5B5_UNORM = 0xF8, | ||
| 85 | X8B8G8R8_UNORM = 0xF9, | ||
| 86 | X8B8G8R8_SRGB = 0xFA, | ||
| 87 | Z1R5G5B5_UNORM = 0xFB, | ||
| 88 | O1R5G5B5_UNORM = 0xFC, | ||
| 89 | Z8R8G8B8_UNORM = 0xFD, | ||
| 90 | O8R8G8B8_UNORM = 0xFE, | ||
| 91 | R32_UNORM = 0xFF, | ||
| 92 | A16_UNORM = 0x40, | ||
| 93 | A16_FLOAT = 0x41, | ||
| 94 | A32_FLOAT = 0x42, | ||
| 95 | A8R8_UNORM = 0x43, | ||
| 96 | R16A16_UNORM = 0x44, | ||
| 97 | R16A16_FLOAT = 0x45, | ||
| 98 | R32A32_FLOAT = 0x46, | ||
| 99 | B8G8R8A8_UNORM = 0x47, | ||
| 100 | */ | ||
| 74 | }; | 101 | }; |
| 75 | 102 | ||
| 76 | enum class DepthFormat : u32 { | 103 | enum class DepthFormat : u32 { |
| 77 | D32_FLOAT = 0xA, | 104 | Z32_FLOAT = 0xA, |
| 78 | D16_UNORM = 0x13, | 105 | Z16_UNORM = 0x13, |
| 79 | S8_UINT_Z24_UNORM = 0x14, | 106 | Z24_UNORM_S8_UINT = 0x14, |
| 80 | D24X8_UNORM = 0x15, | 107 | X8Z24_UNORM = 0x15, |
| 81 | D24S8_UNORM = 0x16, | 108 | S8Z24_UNORM = 0x16, |
| 82 | S8_UINT = 0x17, | 109 | S8_UINT = 0x17, |
| 83 | D24C8_UNORM = 0x18, | 110 | V8Z24_UNORM = 0x18, |
| 84 | D32_FLOAT_S8X24_UINT = 0x19, | 111 | Z32_FLOAT_X24S8_UINT = 0x19, |
| 112 | /* | ||
| 113 | X8Z24_UNORM_X16V8S8_UINT = 0x1D, | ||
| 114 | Z32_FLOAT_X16V8X8_UINT = 0x1E, | ||
| 115 | Z32_FLOAT_X16V8S8_UINT = 0x1F, | ||
| 116 | */ | ||
| 85 | }; | 117 | }; |
| 86 | 118 | ||
| 87 | namespace Engines { | 119 | namespace Engines { |
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp index cabe8dcbf..8a8adbb42 100644 --- a/src/video_core/macro/macro_hle.cpp +++ b/src/video_core/macro/macro_hle.cpp | |||
| @@ -21,16 +21,16 @@ void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 21 | 21 | ||
| 22 | maxwell3d.regs.draw.topology.Assign( | 22 | maxwell3d.regs.draw.topology.Assign( |
| 23 | static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0x3ffffff)); | 23 | static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0x3ffffff)); |
| 24 | maxwell3d.regs.vb_base_instance = parameters[5]; | 24 | maxwell3d.regs.global_base_instance_index = parameters[5]; |
| 25 | maxwell3d.mme_draw.instance_count = instance_count; | 25 | maxwell3d.mme_draw.instance_count = instance_count; |
| 26 | maxwell3d.regs.vb_element_base = parameters[3]; | 26 | maxwell3d.regs.global_base_vertex_index = parameters[3]; |
| 27 | maxwell3d.regs.index_array.count = parameters[1]; | 27 | maxwell3d.regs.index_buffer.count = parameters[1]; |
| 28 | maxwell3d.regs.index_array.first = parameters[4]; | 28 | maxwell3d.regs.index_buffer.first = parameters[4]; |
| 29 | 29 | ||
| 30 | if (maxwell3d.ShouldExecute()) { | 30 | if (maxwell3d.ShouldExecute()) { |
| 31 | maxwell3d.Rasterizer().Draw(true, true); | 31 | maxwell3d.Rasterizer().Draw(true, true); |
| 32 | } | 32 | } |
| 33 | maxwell3d.regs.index_array.count = 0; | 33 | maxwell3d.regs.index_buffer.count = 0; |
| 34 | maxwell3d.mme_draw.instance_count = 0; | 34 | maxwell3d.mme_draw.instance_count = 0; |
| 35 | maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; | 35 | maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; |
| 36 | } | 36 | } |
| @@ -40,7 +40,7 @@ void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 40 | 40 | ||
| 41 | maxwell3d.regs.vertex_buffer.first = parameters[3]; | 41 | maxwell3d.regs.vertex_buffer.first = parameters[3]; |
| 42 | maxwell3d.regs.vertex_buffer.count = parameters[1]; | 42 | maxwell3d.regs.vertex_buffer.count = parameters[1]; |
| 43 | maxwell3d.regs.vb_base_instance = parameters[4]; | 43 | maxwell3d.regs.global_base_instance_index = parameters[4]; |
| 44 | maxwell3d.regs.draw.topology.Assign( | 44 | maxwell3d.regs.draw.topology.Assign( |
| 45 | static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0])); | 45 | static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0])); |
| 46 | maxwell3d.mme_draw.instance_count = count; | 46 | maxwell3d.mme_draw.instance_count = count; |
| @@ -57,12 +57,12 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 57 | const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); | 57 | const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); |
| 58 | const u32 element_base = parameters[4]; | 58 | const u32 element_base = parameters[4]; |
| 59 | const u32 base_instance = parameters[5]; | 59 | const u32 base_instance = parameters[5]; |
| 60 | maxwell3d.regs.index_array.first = parameters[3]; | 60 | maxwell3d.regs.index_buffer.first = parameters[3]; |
| 61 | maxwell3d.regs.reg_array[0x446] = element_base; // vertex id base? | 61 | maxwell3d.regs.vertex_id_base = element_base; |
| 62 | maxwell3d.regs.index_array.count = parameters[1]; | 62 | maxwell3d.regs.index_buffer.count = parameters[1]; |
| 63 | maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; | 63 | maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; |
| 64 | maxwell3d.regs.vb_element_base = element_base; | 64 | maxwell3d.regs.global_base_vertex_index = element_base; |
| 65 | maxwell3d.regs.vb_base_instance = base_instance; | 65 | maxwell3d.regs.global_base_instance_index = base_instance; |
| 66 | maxwell3d.mme_draw.instance_count = instance_count; | 66 | maxwell3d.mme_draw.instance_count = instance_count; |
| 67 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); | 67 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); |
| 68 | maxwell3d.CallMethodFromMME(0x8e4, element_base); | 68 | maxwell3d.CallMethodFromMME(0x8e4, element_base); |
| @@ -72,10 +72,10 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 72 | if (maxwell3d.ShouldExecute()) { | 72 | if (maxwell3d.ShouldExecute()) { |
| 73 | maxwell3d.Rasterizer().Draw(true, true); | 73 | maxwell3d.Rasterizer().Draw(true, true); |
| 74 | } | 74 | } |
| 75 | maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? | 75 | maxwell3d.regs.vertex_id_base = 0x0; |
| 76 | maxwell3d.regs.index_array.count = 0; | 76 | maxwell3d.regs.index_buffer.count = 0; |
| 77 | maxwell3d.regs.vb_element_base = 0x0; | 77 | maxwell3d.regs.global_base_vertex_index = 0x0; |
| 78 | maxwell3d.regs.vb_base_instance = 0x0; | 78 | maxwell3d.regs.global_base_instance_index = 0x0; |
| 79 | maxwell3d.mme_draw.instance_count = 0; | 79 | maxwell3d.mme_draw.instance_count = 0; |
| 80 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); | 80 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); |
| 81 | maxwell3d.CallMethodFromMME(0x8e4, 0x0); | 81 | maxwell3d.CallMethodFromMME(0x8e4, 0x0); |
| @@ -87,10 +87,10 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 87 | void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) { | 87 | void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) { |
| 88 | SCOPE_EXIT({ | 88 | SCOPE_EXIT({ |
| 89 | // Clean everything. | 89 | // Clean everything. |
| 90 | maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? | 90 | maxwell3d.regs.vertex_id_base = 0x0; |
| 91 | maxwell3d.regs.index_array.count = 0; | 91 | maxwell3d.regs.index_buffer.count = 0; |
| 92 | maxwell3d.regs.vb_element_base = 0x0; | 92 | maxwell3d.regs.global_base_vertex_index = 0x0; |
| 93 | maxwell3d.regs.vb_base_instance = 0x0; | 93 | maxwell3d.regs.global_base_instance_index = 0x0; |
| 94 | maxwell3d.mme_draw.instance_count = 0; | 94 | maxwell3d.mme_draw.instance_count = 0; |
| 95 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); | 95 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); |
| 96 | maxwell3d.CallMethodFromMME(0x8e4, 0x0); | 96 | maxwell3d.CallMethodFromMME(0x8e4, 0x0); |
| @@ -122,11 +122,11 @@ void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& | |||
| 122 | const u32 first_index = parameters[base + 2]; | 122 | const u32 first_index = parameters[base + 2]; |
| 123 | const u32 base_vertex = parameters[base + 3]; | 123 | const u32 base_vertex = parameters[base + 3]; |
| 124 | const u32 base_instance = parameters[base + 4]; | 124 | const u32 base_instance = parameters[base + 4]; |
| 125 | maxwell3d.regs.index_array.first = first_index; | 125 | maxwell3d.regs.index_buffer.first = first_index; |
| 126 | maxwell3d.regs.reg_array[0x446] = base_vertex; | 126 | maxwell3d.regs.vertex_id_base = base_vertex; |
| 127 | maxwell3d.regs.index_array.count = num_vertices; | 127 | maxwell3d.regs.index_buffer.count = num_vertices; |
| 128 | maxwell3d.regs.vb_element_base = base_vertex; | 128 | maxwell3d.regs.global_base_vertex_index = base_vertex; |
| 129 | maxwell3d.regs.vb_base_instance = base_instance; | 129 | maxwell3d.regs.global_base_instance_index = base_instance; |
| 130 | maxwell3d.mme_draw.instance_count = instance_count; | 130 | maxwell3d.mme_draw.instance_count = instance_count; |
| 131 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); | 131 | maxwell3d.CallMethodFromMME(0x8e3, 0x640); |
| 132 | maxwell3d.CallMethodFromMME(0x8e4, base_vertex); | 132 | maxwell3d.CallMethodFromMME(0x8e4, base_vertex); |
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h index b0ebe71b7..00ce53e3e 100644 --- a/src/video_core/query_cache.h +++ b/src/video_core/query_cache.h | |||
| @@ -137,7 +137,7 @@ public: | |||
| 137 | std::unique_lock lock{mutex}; | 137 | std::unique_lock lock{mutex}; |
| 138 | if (maxwell3d) { | 138 | if (maxwell3d) { |
| 139 | const auto& regs = maxwell3d->regs; | 139 | const auto& regs = maxwell3d->regs; |
| 140 | Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable); | 140 | Stream(VideoCore::QueryType::SamplesPassed).Update(regs.zpass_pixel_count_enable); |
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | 143 | ||
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 41493a7da..1d20a79ec 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | |||
| @@ -73,8 +73,8 @@ GLenum AssemblyStage(size_t stage_index) { | |||
| 73 | /// @param location Hardware location | 73 | /// @param location Hardware location |
| 74 | /// @return Pair of ARB_transform_feedback3 token stream first and third arguments | 74 | /// @return Pair of ARB_transform_feedback3 token stream first and third arguments |
| 75 | /// @note Read https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_transform_feedback3.txt | 75 | /// @note Read https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_transform_feedback3.txt |
| 76 | std::pair<GLint, GLint> TransformFeedbackEnum(u8 location) { | 76 | std::pair<GLint, GLint> TransformFeedbackEnum(u32 location) { |
| 77 | const u8 index = location / 4; | 77 | const auto index = location / 4; |
| 78 | if (index >= 8 && index <= 39) { | 78 | if (index >= 8 && index <= 39) { |
| 79 | return {GL_GENERIC_ATTRIB_NV, index - 8}; | 79 | return {GL_GENERIC_ATTRIB_NV, index - 8}; |
| 80 | } | 80 | } |
| @@ -286,7 +286,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 286 | buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers); | 286 | buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers); |
| 287 | 287 | ||
| 288 | const auto& regs{maxwell3d->regs}; | 288 | const auto& regs{maxwell3d->regs}; |
| 289 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; | 289 | const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding}; |
| 290 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { | 290 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 291 | const Shader::Info& info{stage_infos[stage]}; | 291 | const Shader::Info& info{stage_infos[stage]}; |
| 292 | buffer_cache.UnbindGraphicsStorageBuffers(stage); | 292 | buffer_cache.UnbindGraphicsStorageBuffers(stage); |
| @@ -557,10 +557,25 @@ void GraphicsPipeline::GenerateTransformFeedbackState() { | |||
| 557 | ++current_stream; | 557 | ++current_stream; |
| 558 | 558 | ||
| 559 | const auto& locations = key.xfb_state.varyings[feedback]; | 559 | const auto& locations = key.xfb_state.varyings[feedback]; |
| 560 | std::optional<u8> current_index; | 560 | std::optional<u32> current_index; |
| 561 | for (u32 offset = 0; offset < layout.varying_count; ++offset) { | 561 | for (u32 offset = 0; offset < layout.varying_count; ++offset) { |
| 562 | const u8 location = locations[offset]; | 562 | const auto get_attribute = [&locations](u32 index) -> u32 { |
| 563 | const u8 index = location / 4; | 563 | switch (index % 4) { |
| 564 | case 0: | ||
| 565 | return locations[index / 4].attribute0.Value(); | ||
| 566 | case 1: | ||
| 567 | return locations[index / 4].attribute1.Value(); | ||
| 568 | case 2: | ||
| 569 | return locations[index / 4].attribute2.Value(); | ||
| 570 | case 3: | ||
| 571 | return locations[index / 4].attribute3.Value(); | ||
| 572 | } | ||
| 573 | UNREACHABLE(); | ||
| 574 | return 0; | ||
| 575 | }; | ||
| 576 | |||
| 577 | const auto attribute{get_attribute(offset)}; | ||
| 578 | const auto index = attribute / 4U; | ||
| 564 | 579 | ||
| 565 | if (current_index == index) { | 580 | if (current_index == index) { |
| 566 | // Increase number of components of the previous attachment | 581 | // Increase number of components of the previous attachment |
| @@ -569,7 +584,7 @@ void GraphicsPipeline::GenerateTransformFeedbackState() { | |||
| 569 | } | 584 | } |
| 570 | current_index = index; | 585 | current_index = index; |
| 571 | 586 | ||
| 572 | std::tie(cursor[0], cursor[2]) = TransformFeedbackEnum(location); | 587 | std::tie(cursor[0], cursor[2]) = TransformFeedbackEnum(attribute); |
| 573 | cursor[1] = 1; | 588 | cursor[1] = 1; |
| 574 | cursor += XFB_ENTRY_STRIDE; | 589 | cursor += XFB_ENTRY_STRIDE; |
| 575 | } | 590 | } |
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h index a0f0e63cb..ea53ddb46 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h | |||
| @@ -37,8 +37,8 @@ struct GraphicsPipelineKey { | |||
| 37 | BitField<0, 1, u32> xfb_enabled; | 37 | BitField<0, 1, u32> xfb_enabled; |
| 38 | BitField<1, 1, u32> early_z; | 38 | BitField<1, 1, u32> early_z; |
| 39 | BitField<2, 4, Maxwell::PrimitiveTopology> gs_input_topology; | 39 | BitField<2, 4, Maxwell::PrimitiveTopology> gs_input_topology; |
| 40 | BitField<6, 2, Maxwell::TessellationPrimitive> tessellation_primitive; | 40 | BitField<6, 2, Maxwell::Tessellation::DomainType> tessellation_primitive; |
| 41 | BitField<8, 2, Maxwell::TessellationSpacing> tessellation_spacing; | 41 | BitField<8, 2, Maxwell::Tessellation::Spacing> tessellation_spacing; |
| 42 | BitField<10, 1, u32> tessellation_clockwise; | 42 | BitField<10, 1, u32> tessellation_clockwise; |
| 43 | }; | 43 | }; |
| 44 | std::array<u32, 3> padding; | 44 | std::array<u32, 3> padding; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index c2d80605d..cce00cea8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -87,7 +87,7 @@ void RasterizerOpenGL::SyncVertexFormats() { | |||
| 87 | } | 87 | } |
| 88 | flags[Dirty::VertexFormat0 + index] = false; | 88 | flags[Dirty::VertexFormat0 + index] = false; |
| 89 | 89 | ||
| 90 | const auto attrib = maxwell3d->regs.vertex_attrib_format[index]; | 90 | const auto& attrib = maxwell3d->regs.vertex_attrib_format[index]; |
| 91 | const auto gl_index = static_cast<GLuint>(index); | 91 | const auto gl_index = static_cast<GLuint>(index); |
| 92 | 92 | ||
| 93 | // Disable constant attributes. | 93 | // Disable constant attributes. |
| @@ -97,8 +97,8 @@ void RasterizerOpenGL::SyncVertexFormats() { | |||
| 97 | } | 97 | } |
| 98 | glEnableVertexAttribArray(gl_index); | 98 | glEnableVertexAttribArray(gl_index); |
| 99 | 99 | ||
| 100 | if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt || | 100 | if (attrib.type == Maxwell::VertexAttribute::Type::SInt || |
| 101 | attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) { | 101 | attrib.type == Maxwell::VertexAttribute::Type::UInt) { |
| 102 | glVertexAttribIFormat(gl_index, attrib.ComponentCount(), | 102 | glVertexAttribIFormat(gl_index, attrib.ComponentCount(), |
| 103 | MaxwellToGL::VertexFormat(attrib), attrib.offset); | 103 | MaxwellToGL::VertexFormat(attrib), attrib.offset); |
| 104 | } else { | 104 | } else { |
| @@ -125,8 +125,8 @@ void RasterizerOpenGL::SyncVertexInstances() { | |||
| 125 | flags[Dirty::VertexInstance0 + index] = false; | 125 | flags[Dirty::VertexInstance0 + index] = false; |
| 126 | 126 | ||
| 127 | const auto gl_index = static_cast<GLuint>(index); | 127 | const auto gl_index = static_cast<GLuint>(index); |
| 128 | const bool instancing_enabled = regs.instanced_arrays.IsInstancingEnabled(gl_index); | 128 | const bool instancing_enabled = regs.vertex_stream_instances.IsInstancingEnabled(gl_index); |
| 129 | const GLuint divisor = instancing_enabled ? regs.vertex_array[index].divisor : 0; | 129 | const GLuint divisor = instancing_enabled ? regs.vertex_streams[index].frequency : 0; |
| 130 | glVertexBindingDivisor(gl_index, divisor); | 130 | glVertexBindingDivisor(gl_index, divisor); |
| 131 | } | 131 | } |
| 132 | } | 132 | } |
| @@ -147,27 +147,27 @@ void RasterizerOpenGL::Clear() { | |||
| 147 | bool use_depth{}; | 147 | bool use_depth{}; |
| 148 | bool use_stencil{}; | 148 | bool use_stencil{}; |
| 149 | 149 | ||
| 150 | if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || | 150 | if (regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B || |
| 151 | regs.clear_buffers.A) { | 151 | regs.clear_surface.A) { |
| 152 | use_color = true; | 152 | use_color = true; |
| 153 | 153 | ||
| 154 | const GLuint index = regs.clear_buffers.RT; | 154 | const GLuint index = regs.clear_surface.RT; |
| 155 | state_tracker.NotifyColorMask(index); | 155 | state_tracker.NotifyColorMask(index); |
| 156 | glColorMaski(index, regs.clear_buffers.R != 0, regs.clear_buffers.G != 0, | 156 | glColorMaski(index, regs.clear_surface.R != 0, regs.clear_surface.G != 0, |
| 157 | regs.clear_buffers.B != 0, regs.clear_buffers.A != 0); | 157 | regs.clear_surface.B != 0, regs.clear_surface.A != 0); |
| 158 | 158 | ||
| 159 | // TODO(Rodrigo): Determine if clamping is used on clears | 159 | // TODO(Rodrigo): Determine if clamping is used on clears |
| 160 | SyncFragmentColorClampState(); | 160 | SyncFragmentColorClampState(); |
| 161 | SyncFramebufferSRGB(); | 161 | SyncFramebufferSRGB(); |
| 162 | } | 162 | } |
| 163 | if (regs.clear_buffers.Z) { | 163 | if (regs.clear_surface.Z) { |
| 164 | ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); | 164 | ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); |
| 165 | use_depth = true; | 165 | use_depth = true; |
| 166 | 166 | ||
| 167 | state_tracker.NotifyDepthMask(); | 167 | state_tracker.NotifyDepthMask(); |
| 168 | glDepthMask(GL_TRUE); | 168 | glDepthMask(GL_TRUE); |
| 169 | } | 169 | } |
| 170 | if (regs.clear_buffers.S) { | 170 | if (regs.clear_surface.S) { |
| 171 | ASSERT_MSG(regs.zeta_enable, "Tried to clear stencil but buffer is not enabled!"); | 171 | ASSERT_MSG(regs.zeta_enable, "Tried to clear stencil but buffer is not enabled!"); |
| 172 | use_stencil = true; | 172 | use_stencil = true; |
| 173 | } | 173 | } |
| @@ -184,16 +184,16 @@ void RasterizerOpenGL::Clear() { | |||
| 184 | texture_cache.UpdateRenderTargets(true); | 184 | texture_cache.UpdateRenderTargets(true); |
| 185 | state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); | 185 | state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); |
| 186 | SyncViewport(); | 186 | SyncViewport(); |
| 187 | if (regs.clear_flags.scissor) { | 187 | if (regs.clear_control.use_scissor) { |
| 188 | SyncScissorTest(); | 188 | SyncScissorTest(); |
| 189 | } else { | 189 | } else { |
| 190 | state_tracker.NotifyScissor0(); | 190 | state_tracker.NotifyScissor0(); |
| 191 | glDisablei(GL_SCISSOR_TEST, 0); | 191 | glDisablei(GL_SCISSOR_TEST, 0); |
| 192 | } | 192 | } |
| 193 | UNIMPLEMENTED_IF(regs.clear_flags.viewport); | 193 | UNIMPLEMENTED_IF(regs.clear_control.use_viewport_clip0); |
| 194 | 194 | ||
| 195 | if (use_color) { | 195 | if (use_color) { |
| 196 | glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color); | 196 | glClearBufferfv(GL_COLOR, regs.clear_surface.RT, regs.clear_color.data()); |
| 197 | } | 197 | } |
| 198 | if (use_depth && use_stencil) { | 198 | if (use_depth && use_stencil) { |
| 199 | glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil); | 199 | glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil); |
| @@ -227,14 +227,14 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 227 | const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology); | 227 | const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology); |
| 228 | BeginTransformFeedback(pipeline, primitive_mode); | 228 | BeginTransformFeedback(pipeline, primitive_mode); |
| 229 | 229 | ||
| 230 | const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.vb_base_instance); | 230 | const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.global_base_instance_index); |
| 231 | const GLsizei num_instances = | 231 | const GLsizei num_instances = |
| 232 | static_cast<GLsizei>(is_instanced ? maxwell3d->mme_draw.instance_count : 1); | 232 | static_cast<GLsizei>(is_instanced ? maxwell3d->mme_draw.instance_count : 1); |
| 233 | if (is_indexed) { | 233 | if (is_indexed) { |
| 234 | const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vb_element_base); | 234 | const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.global_base_vertex_index); |
| 235 | const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_array.count); | 235 | const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_buffer.count); |
| 236 | const GLvoid* const offset = buffer_cache_runtime.IndexOffset(); | 236 | const GLvoid* const offset = buffer_cache_runtime.IndexOffset(); |
| 237 | const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_array.format); | 237 | const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format); |
| 238 | if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { | 238 | if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { |
| 239 | glDrawElements(primitive_mode, num_vertices, format, offset); | 239 | glDrawElements(primitive_mode, num_vertices, format, offset); |
| 240 | } else if (num_instances == 1 && base_instance == 0) { | 240 | } else if (num_instances == 1 && base_instance == 0) { |
| @@ -555,9 +555,9 @@ void RasterizerOpenGL::SyncViewport() { | |||
| 555 | if (dirty_viewport || dirty_clip_control || flags[Dirty::FrontFace]) { | 555 | if (dirty_viewport || dirty_clip_control || flags[Dirty::FrontFace]) { |
| 556 | flags[Dirty::FrontFace] = false; | 556 | flags[Dirty::FrontFace] = false; |
| 557 | 557 | ||
| 558 | GLenum mode = MaxwellToGL::FrontFace(regs.front_face); | 558 | GLenum mode = MaxwellToGL::FrontFace(regs.gl_front_face); |
| 559 | bool flip_faces = true; | 559 | bool flip_faces = true; |
| 560 | if (regs.screen_y_control.triangle_rast_flip != 0) { | 560 | if (regs.window_origin.flip_y != 0) { |
| 561 | flip_faces = !flip_faces; | 561 | flip_faces = !flip_faces; |
| 562 | } | 562 | } |
| 563 | if (regs.viewport_transform[0].scale_y < 0.0f) { | 563 | if (regs.viewport_transform[0].scale_y < 0.0f) { |
| @@ -582,14 +582,15 @@ void RasterizerOpenGL::SyncViewport() { | |||
| 582 | if (regs.viewport_transform[0].scale_y < 0.0f) { | 582 | if (regs.viewport_transform[0].scale_y < 0.0f) { |
| 583 | flip_y = !flip_y; | 583 | flip_y = !flip_y; |
| 584 | } | 584 | } |
| 585 | if (regs.screen_y_control.y_negate != 0) { | 585 | const bool lower_left{regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft}; |
| 586 | if (lower_left) { | ||
| 586 | flip_y = !flip_y; | 587 | flip_y = !flip_y; |
| 587 | } | 588 | } |
| 588 | const bool is_zero_to_one = regs.depth_mode == Maxwell::DepthMode::ZeroToOne; | 589 | const bool is_zero_to_one = regs.depth_mode == Maxwell::DepthMode::ZeroToOne; |
| 589 | const GLenum origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT; | 590 | const GLenum origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT; |
| 590 | const GLenum depth = is_zero_to_one ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE; | 591 | const GLenum depth = is_zero_to_one ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE; |
| 591 | state_tracker.ClipControl(origin, depth); | 592 | state_tracker.ClipControl(origin, depth); |
| 592 | state_tracker.SetYNegate(regs.screen_y_control.y_negate != 0); | 593 | state_tracker.SetYNegate(lower_left); |
| 593 | } | 594 | } |
| 594 | const bool is_rescaling{texture_cache.IsRescaling()}; | 595 | const bool is_rescaling{texture_cache.IsRescaling()}; |
| 595 | const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; | 596 | const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; |
| @@ -657,7 +658,8 @@ void RasterizerOpenGL::SyncDepthClamp() { | |||
| 657 | } | 658 | } |
| 658 | flags[Dirty::DepthClampEnabled] = false; | 659 | flags[Dirty::DepthClampEnabled] = false; |
| 659 | 660 | ||
| 660 | oglEnable(GL_DEPTH_CLAMP, maxwell3d->regs.view_volume_clip_control.depth_clamp_disabled == 0); | 661 | oglEnable(GL_DEPTH_CLAMP, maxwell3d->regs.viewport_clip_control.geometry_clip != |
| 662 | Maxwell::ViewportClipControl::GeometryClip::Passthrough); | ||
| 661 | } | 663 | } |
| 662 | 664 | ||
| 663 | void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { | 665 | void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { |
| @@ -667,7 +669,7 @@ void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { | |||
| 667 | } | 669 | } |
| 668 | flags[Dirty::ClipDistances] = false; | 670 | flags[Dirty::ClipDistances] = false; |
| 669 | 671 | ||
| 670 | clip_mask &= maxwell3d->regs.clip_distance_enabled; | 672 | clip_mask &= maxwell3d->regs.user_clip_enable.raw; |
| 671 | if (clip_mask == last_clip_distance_mask) { | 673 | if (clip_mask == last_clip_distance_mask) { |
| 672 | return; | 674 | return; |
| 673 | } | 675 | } |
| @@ -689,9 +691,9 @@ void RasterizerOpenGL::SyncCullMode() { | |||
| 689 | if (flags[Dirty::CullTest]) { | 691 | if (flags[Dirty::CullTest]) { |
| 690 | flags[Dirty::CullTest] = false; | 692 | flags[Dirty::CullTest] = false; |
| 691 | 693 | ||
| 692 | if (regs.cull_test_enabled) { | 694 | if (regs.gl_cull_test_enabled) { |
| 693 | glEnable(GL_CULL_FACE); | 695 | glEnable(GL_CULL_FACE); |
| 694 | glCullFace(MaxwellToGL::CullFace(regs.cull_face)); | 696 | glCullFace(MaxwellToGL::CullFace(regs.gl_cull_face)); |
| 695 | } else { | 697 | } else { |
| 696 | glDisable(GL_CULL_FACE); | 698 | glDisable(GL_CULL_FACE); |
| 697 | } | 699 | } |
| @@ -743,20 +745,20 @@ void RasterizerOpenGL::SyncStencilTestState() { | |||
| 743 | const auto& regs = maxwell3d->regs; | 745 | const auto& regs = maxwell3d->regs; |
| 744 | oglEnable(GL_STENCIL_TEST, regs.stencil_enable); | 746 | oglEnable(GL_STENCIL_TEST, regs.stencil_enable); |
| 745 | 747 | ||
| 746 | glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), | 748 | glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_op.func), |
| 747 | regs.stencil_front_func_ref, regs.stencil_front_func_mask); | 749 | regs.stencil_front_func.ref, regs.stencil_front_func.func_mask); |
| 748 | glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail), | 750 | glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op.fail), |
| 749 | MaxwellToGL::StencilOp(regs.stencil_front_op_zfail), | 751 | MaxwellToGL::StencilOp(regs.stencil_front_op.zfail), |
| 750 | MaxwellToGL::StencilOp(regs.stencil_front_op_zpass)); | 752 | MaxwellToGL::StencilOp(regs.stencil_front_op.zpass)); |
| 751 | glStencilMaskSeparate(GL_FRONT, regs.stencil_front_mask); | 753 | glStencilMaskSeparate(GL_FRONT, regs.stencil_front_func.mask); |
| 752 | 754 | ||
| 753 | if (regs.stencil_two_side_enable) { | 755 | if (regs.stencil_two_side_enable) { |
| 754 | glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_func_func), | 756 | glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_op.func), |
| 755 | regs.stencil_back_func_ref, regs.stencil_back_func_mask); | 757 | regs.stencil_back_func.ref, regs.stencil_back_func.mask); |
| 756 | glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op_fail), | 758 | glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op.fail), |
| 757 | MaxwellToGL::StencilOp(regs.stencil_back_op_zfail), | 759 | MaxwellToGL::StencilOp(regs.stencil_back_op.zfail), |
| 758 | MaxwellToGL::StencilOp(regs.stencil_back_op_zpass)); | 760 | MaxwellToGL::StencilOp(regs.stencil_back_op.zpass)); |
| 759 | glStencilMaskSeparate(GL_BACK, regs.stencil_back_mask); | 761 | glStencilMaskSeparate(GL_BACK, regs.stencil_back_func.mask); |
| 760 | } else { | 762 | } else { |
| 761 | glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 0xFFFFFFFF); | 763 | glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 0xFFFFFFFF); |
| 762 | glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP); | 764 | glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP); |
| @@ -782,7 +784,7 @@ void RasterizerOpenGL::SyncPolygonModes() { | |||
| 782 | flags[Dirty::PolygonModes] = false; | 784 | flags[Dirty::PolygonModes] = false; |
| 783 | 785 | ||
| 784 | const auto& regs = maxwell3d->regs; | 786 | const auto& regs = maxwell3d->regs; |
| 785 | if (regs.fill_rectangle) { | 787 | if (regs.fill_via_triangle_mode != Maxwell::FillViaTriangleMode::Disabled) { |
| 786 | if (!GLAD_GL_NV_fill_rectangle) { | 788 | if (!GLAD_GL_NV_fill_rectangle) { |
| 787 | LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); | 789 | LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); |
| 788 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | 790 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
| @@ -855,8 +857,8 @@ void RasterizerOpenGL::SyncMultiSampleState() { | |||
| 855 | flags[Dirty::MultisampleControl] = false; | 857 | flags[Dirty::MultisampleControl] = false; |
| 856 | 858 | ||
| 857 | const auto& regs = maxwell3d->regs; | 859 | const auto& regs = maxwell3d->regs; |
| 858 | oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage); | 860 | oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.anti_alias_alpha_control.alpha_to_coverage); |
| 859 | oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one); | 861 | oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.anti_alias_alpha_control.alpha_to_one); |
| 860 | } | 862 | } |
| 861 | 863 | ||
| 862 | void RasterizerOpenGL::SyncFragmentColorClampState() { | 864 | void RasterizerOpenGL::SyncFragmentColorClampState() { |
| @@ -866,7 +868,8 @@ void RasterizerOpenGL::SyncFragmentColorClampState() { | |||
| 866 | } | 868 | } |
| 867 | flags[Dirty::FragmentClampColor] = false; | 869 | flags[Dirty::FragmentClampColor] = false; |
| 868 | 870 | ||
| 869 | glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d->regs.frag_color_clamp ? GL_TRUE : GL_FALSE); | 871 | glClampColor(GL_CLAMP_FRAGMENT_COLOR, |
| 872 | maxwell3d->regs.frag_color_clamp.AnyEnabled() ? GL_TRUE : GL_FALSE); | ||
| 870 | } | 873 | } |
| 871 | 874 | ||
| 872 | void RasterizerOpenGL::SyncBlendState() { | 875 | void RasterizerOpenGL::SyncBlendState() { |
| @@ -886,18 +889,18 @@ void RasterizerOpenGL::SyncBlendState() { | |||
| 886 | } | 889 | } |
| 887 | flags[Dirty::BlendStates] = false; | 890 | flags[Dirty::BlendStates] = false; |
| 888 | 891 | ||
| 889 | if (!regs.independent_blend_enable) { | 892 | if (!regs.blend_per_target_enabled) { |
| 890 | if (!regs.blend.enable[0]) { | 893 | if (!regs.blend.enable[0]) { |
| 891 | glDisable(GL_BLEND); | 894 | glDisable(GL_BLEND); |
| 892 | return; | 895 | return; |
| 893 | } | 896 | } |
| 894 | glEnable(GL_BLEND); | 897 | glEnable(GL_BLEND); |
| 895 | glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb), | 898 | glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.color_source), |
| 896 | MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb), | 899 | MaxwellToGL::BlendFunc(regs.blend.color_dest), |
| 897 | MaxwellToGL::BlendFunc(regs.blend.factor_source_a), | 900 | MaxwellToGL::BlendFunc(regs.blend.alpha_source), |
| 898 | MaxwellToGL::BlendFunc(regs.blend.factor_dest_a)); | 901 | MaxwellToGL::BlendFunc(regs.blend.alpha_dest)); |
| 899 | glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb), | 902 | glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.color_op), |
| 900 | MaxwellToGL::BlendEquation(regs.blend.equation_a)); | 903 | MaxwellToGL::BlendEquation(regs.blend.alpha_op)); |
| 901 | return; | 904 | return; |
| 902 | } | 905 | } |
| 903 | 906 | ||
| @@ -916,14 +919,13 @@ void RasterizerOpenGL::SyncBlendState() { | |||
| 916 | } | 919 | } |
| 917 | glEnablei(GL_BLEND, static_cast<GLuint>(i)); | 920 | glEnablei(GL_BLEND, static_cast<GLuint>(i)); |
| 918 | 921 | ||
| 919 | const auto& src = regs.independent_blend[i]; | 922 | const auto& src = regs.blend_per_target[i]; |
| 920 | glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb), | 923 | glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.color_source), |
| 921 | MaxwellToGL::BlendFunc(src.factor_dest_rgb), | 924 | MaxwellToGL::BlendFunc(src.color_dest), |
| 922 | MaxwellToGL::BlendFunc(src.factor_source_a), | 925 | MaxwellToGL::BlendFunc(src.alpha_source), |
| 923 | MaxwellToGL::BlendFunc(src.factor_dest_a)); | 926 | MaxwellToGL::BlendFunc(src.alpha_dest)); |
| 924 | glBlendEquationSeparatei(static_cast<GLuint>(i), | 927 | glBlendEquationSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendEquation(src.color_op), |
| 925 | MaxwellToGL::BlendEquation(src.equation_rgb), | 928 | MaxwellToGL::BlendEquation(src.alpha_op)); |
| 926 | MaxwellToGL::BlendEquation(src.equation_a)); | ||
| 927 | } | 929 | } |
| 928 | } | 930 | } |
| 929 | 931 | ||
| @@ -937,7 +939,7 @@ void RasterizerOpenGL::SyncLogicOpState() { | |||
| 937 | const auto& regs = maxwell3d->regs; | 939 | const auto& regs = maxwell3d->regs; |
| 938 | if (regs.logic_op.enable) { | 940 | if (regs.logic_op.enable) { |
| 939 | glEnable(GL_COLOR_LOGIC_OP); | 941 | glEnable(GL_COLOR_LOGIC_OP); |
| 940 | glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); | 942 | glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.op)); |
| 941 | } else { | 943 | } else { |
| 942 | glDisable(GL_COLOR_LOGIC_OP); | 944 | glDisable(GL_COLOR_LOGIC_OP); |
| 943 | } | 945 | } |
| @@ -996,7 +998,7 @@ void RasterizerOpenGL::SyncPointState() { | |||
| 996 | flags[Dirty::PointSize] = false; | 998 | flags[Dirty::PointSize] = false; |
| 997 | 999 | ||
| 998 | oglEnable(GL_POINT_SPRITE, maxwell3d->regs.point_sprite_enable); | 1000 | oglEnable(GL_POINT_SPRITE, maxwell3d->regs.point_sprite_enable); |
| 999 | oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.vp_point_size.enable); | 1001 | oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.point_size_attribute.enabled); |
| 1000 | const bool is_rescaling{texture_cache.IsRescaling()}; | 1002 | const bool is_rescaling{texture_cache.IsRescaling()}; |
| 1001 | const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; | 1003 | const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; |
| 1002 | glPointSize(std::max(1.0f, maxwell3d->regs.point_size * scale)); | 1004 | glPointSize(std::max(1.0f, maxwell3d->regs.point_size * scale)); |
| @@ -1010,8 +1012,8 @@ void RasterizerOpenGL::SyncLineState() { | |||
| 1010 | flags[Dirty::LineWidth] = false; | 1012 | flags[Dirty::LineWidth] = false; |
| 1011 | 1013 | ||
| 1012 | const auto& regs = maxwell3d->regs; | 1014 | const auto& regs = maxwell3d->regs; |
| 1013 | oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable); | 1015 | oglEnable(GL_LINE_SMOOTH, regs.line_anti_alias_enable); |
| 1014 | glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased); | 1016 | glLineWidth(regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased); |
| 1015 | } | 1017 | } |
| 1016 | 1018 | ||
| 1017 | void RasterizerOpenGL::SyncPolygonOffset() { | 1019 | void RasterizerOpenGL::SyncPolygonOffset() { |
| @@ -1029,8 +1031,8 @@ void RasterizerOpenGL::SyncPolygonOffset() { | |||
| 1029 | if (regs.polygon_offset_fill_enable || regs.polygon_offset_line_enable || | 1031 | if (regs.polygon_offset_fill_enable || regs.polygon_offset_line_enable || |
| 1030 | regs.polygon_offset_point_enable) { | 1032 | regs.polygon_offset_point_enable) { |
| 1031 | // Hardware divides polygon offset units by two | 1033 | // Hardware divides polygon offset units by two |
| 1032 | glPolygonOffsetClamp(regs.polygon_offset_factor, regs.polygon_offset_units / 2.0f, | 1034 | glPolygonOffsetClamp(regs.slope_scale_depth_bias, regs.depth_bias / 2.0f, |
| 1033 | regs.polygon_offset_clamp); | 1035 | regs.depth_bias_clamp); |
| 1034 | } | 1036 | } |
| 1035 | } | 1037 | } |
| 1036 | 1038 | ||
| @@ -1062,14 +1064,14 @@ void RasterizerOpenGL::SyncFramebufferSRGB() { | |||
| 1062 | 1064 | ||
| 1063 | void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) { | 1065 | void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) { |
| 1064 | const auto& regs = maxwell3d->regs; | 1066 | const auto& regs = maxwell3d->regs; |
| 1065 | if (regs.tfb_enabled == 0) { | 1067 | if (regs.transform_feedback_enabled == 0) { |
| 1066 | return; | 1068 | return; |
| 1067 | } | 1069 | } |
| 1068 | program->ConfigureTransformFeedback(); | 1070 | program->ConfigureTransformFeedback(); |
| 1069 | 1071 | ||
| 1070 | UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationControl) || | 1072 | UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) || |
| 1071 | regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationEval) || | 1073 | regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) || |
| 1072 | regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::Geometry)); | 1074 | regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry)); |
| 1073 | UNIMPLEMENTED_IF(primitive_mode != GL_POINTS); | 1075 | UNIMPLEMENTED_IF(primitive_mode != GL_POINTS); |
| 1074 | 1076 | ||
| 1075 | // We may have to call BeginTransformFeedbackNV here since they seem to call different | 1077 | // We may have to call BeginTransformFeedbackNV here since they seem to call different |
| @@ -1080,7 +1082,7 @@ void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum | |||
| 1080 | } | 1082 | } |
| 1081 | 1083 | ||
| 1082 | void RasterizerOpenGL::EndTransformFeedback() { | 1084 | void RasterizerOpenGL::EndTransformFeedback() { |
| 1083 | if (maxwell3d->regs.tfb_enabled != 0) { | 1085 | if (maxwell3d->regs.transform_feedback_enabled != 0) { |
| 1084 | glEndTransformFeedback(); | 1086 | glEndTransformFeedback(); |
| 1085 | } | 1087 | } |
| 1086 | } | 1088 | } |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 5a29a41d2..6bdb0b645 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -78,11 +78,11 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | |||
| 78 | info.tess_clockwise = key.tessellation_clockwise != 0; | 78 | info.tess_clockwise = key.tessellation_clockwise != 0; |
| 79 | info.tess_primitive = [&key] { | 79 | info.tess_primitive = [&key] { |
| 80 | switch (key.tessellation_primitive) { | 80 | switch (key.tessellation_primitive) { |
| 81 | case Maxwell::TessellationPrimitive::Isolines: | 81 | case Maxwell::Tessellation::DomainType::Isolines: |
| 82 | return Shader::TessPrimitive::Isolines; | 82 | return Shader::TessPrimitive::Isolines; |
| 83 | case Maxwell::TessellationPrimitive::Triangles: | 83 | case Maxwell::Tessellation::DomainType::Triangles: |
| 84 | return Shader::TessPrimitive::Triangles; | 84 | return Shader::TessPrimitive::Triangles; |
| 85 | case Maxwell::TessellationPrimitive::Quads: | 85 | case Maxwell::Tessellation::DomainType::Quads: |
| 86 | return Shader::TessPrimitive::Quads; | 86 | return Shader::TessPrimitive::Quads; |
| 87 | } | 87 | } |
| 88 | ASSERT(false); | 88 | ASSERT(false); |
| @@ -90,11 +90,11 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | |||
| 90 | }(); | 90 | }(); |
| 91 | info.tess_spacing = [&] { | 91 | info.tess_spacing = [&] { |
| 92 | switch (key.tessellation_spacing) { | 92 | switch (key.tessellation_spacing) { |
| 93 | case Maxwell::TessellationSpacing::Equal: | 93 | case Maxwell::Tessellation::Spacing::Integer: |
| 94 | return Shader::TessSpacing::Equal; | 94 | return Shader::TessSpacing::Equal; |
| 95 | case Maxwell::TessellationSpacing::FractionalOdd: | 95 | case Maxwell::Tessellation::Spacing::FractionalOdd: |
| 96 | return Shader::TessSpacing::FractionalOdd; | 96 | return Shader::TessSpacing::FractionalOdd; |
| 97 | case Maxwell::TessellationSpacing::FractionalEven: | 97 | case Maxwell::Tessellation::Spacing::FractionalEven: |
| 98 | return Shader::TessSpacing::FractionalEven; | 98 | return Shader::TessSpacing::FractionalEven; |
| 99 | } | 99 | } |
| 100 | ASSERT(false); | 100 | ASSERT(false); |
| @@ -139,14 +139,15 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | |||
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | void SetXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) { | 141 | void SetXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) { |
| 142 | std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) { | 142 | std::ranges::transform(regs.transform_feedback.controls, state.layouts.begin(), |
| 143 | return VideoCommon::TransformFeedbackState::Layout{ | 143 | [](const auto& layout) { |
| 144 | .stream = layout.stream, | 144 | return VideoCommon::TransformFeedbackState::Layout{ |
| 145 | .varying_count = layout.varying_count, | 145 | .stream = layout.stream, |
| 146 | .stride = layout.stride, | 146 | .varying_count = layout.varying_count, |
| 147 | }; | 147 | .stride = layout.stride, |
| 148 | }); | 148 | }; |
| 149 | state.varyings = regs.tfb_varying_locs; | 149 | }); |
| 150 | state.varyings = regs.stream_out_layout; | ||
| 150 | } | 151 | } |
| 151 | } // Anonymous namespace | 152 | } // Anonymous namespace |
| 152 | 153 | ||
| @@ -309,14 +310,16 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() { | |||
| 309 | } | 310 | } |
| 310 | const auto& regs{maxwell3d->regs}; | 311 | const auto& regs{maxwell3d->regs}; |
| 311 | graphics_key.raw = 0; | 312 | graphics_key.raw = 0; |
| 312 | graphics_key.early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0); | 313 | graphics_key.early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0); |
| 313 | graphics_key.gs_input_topology.Assign(graphics_key.unique_hashes[4] != 0 | 314 | graphics_key.gs_input_topology.Assign(graphics_key.unique_hashes[4] != 0 |
| 314 | ? regs.draw.topology.Value() | 315 | ? regs.draw.topology.Value() |
| 315 | : Maxwell::PrimitiveTopology{}); | 316 | : Maxwell::PrimitiveTopology{}); |
| 316 | graphics_key.tessellation_primitive.Assign(regs.tess_mode.prim.Value()); | 317 | graphics_key.tessellation_primitive.Assign(regs.tessellation.params.domain_type.Value()); |
| 317 | graphics_key.tessellation_spacing.Assign(regs.tess_mode.spacing.Value()); | 318 | graphics_key.tessellation_spacing.Assign(regs.tessellation.params.spacing.Value()); |
| 318 | graphics_key.tessellation_clockwise.Assign(regs.tess_mode.cw.Value()); | 319 | graphics_key.tessellation_clockwise.Assign( |
| 319 | graphics_key.xfb_enabled.Assign(regs.tfb_enabled != 0 ? 1 : 0); | 320 | regs.tessellation.params.output_primitives.Value() != |
| 321 | Maxwell::Tessellation::OutputPrimitves::Triangles_CCW); | ||
| 322 | graphics_key.xfb_enabled.Assign(regs.transform_feedback_enabled != 0 ? 1 : 0); | ||
| 320 | if (graphics_key.xfb_enabled) { | 323 | if (graphics_key.xfb_enabled) { |
| 321 | SetXfbState(graphics_key.xfb_state, regs); | 324 | SetXfbState(graphics_key.xfb_state, regs); |
| 322 | } | 325 | } |
| @@ -354,7 +357,7 @@ GraphicsPipeline* ShaderCache::BuiltPipeline(GraphicsPipeline* pipeline) const n | |||
| 354 | // If games are using a small index count, we can assume these are full screen quads. | 357 | // If games are using a small index count, we can assume these are full screen quads. |
| 355 | // Usually these shaders are only used once for building textures so we can assume they | 358 | // Usually these shaders are only used once for building textures so we can assume they |
| 356 | // can't be built async | 359 | // can't be built async |
| 357 | if (maxwell3d->regs.index_array.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) { | 360 | if (maxwell3d->regs.index_buffer.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) { |
| 358 | return pipeline; | 361 | return pipeline; |
| 359 | } | 362 | } |
| 360 | return nullptr; | 363 | return nullptr; |
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index a8f3a0f57..e2c709aac 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp | |||
| @@ -38,12 +38,12 @@ void SetupDirtyColorMasks(Tables& tables) { | |||
| 38 | void SetupDirtyVertexInstances(Tables& tables) { | 38 | void SetupDirtyVertexInstances(Tables& tables) { |
| 39 | static constexpr std::size_t instance_base_offset = 3; | 39 | static constexpr std::size_t instance_base_offset = 3; |
| 40 | for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) { | 40 | for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) { |
| 41 | const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]); | 41 | const std::size_t array_offset = OFF(vertex_streams) + i * NUM(vertex_streams[0]); |
| 42 | const std::size_t instance_array_offset = array_offset + instance_base_offset; | 42 | const std::size_t instance_array_offset = array_offset + instance_base_offset; |
| 43 | tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i); | 43 | tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i); |
| 44 | tables[1][instance_array_offset] = VertexInstances; | 44 | tables[1][instance_array_offset] = VertexInstances; |
| 45 | 45 | ||
| 46 | const std::size_t instance_offset = OFF(instanced_arrays) + i; | 46 | const std::size_t instance_offset = OFF(vertex_stream_instances) + i; |
| 47 | tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i); | 47 | tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i); |
| 48 | tables[1][instance_offset] = VertexInstances; | 48 | tables[1][instance_offset] = VertexInstances; |
| 49 | } | 49 | } |
| @@ -70,8 +70,8 @@ void SetupDirtyViewports(Tables& tables) { | |||
| 70 | FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports); | 70 | FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports); |
| 71 | FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports); | 71 | FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports); |
| 72 | 72 | ||
| 73 | tables[0][OFF(viewport_transform_enabled)] = ViewportTransform; | 73 | tables[0][OFF(viewport_scale_offset_enbled)] = ViewportTransform; |
| 74 | tables[1][OFF(viewport_transform_enabled)] = Viewports; | 74 | tables[1][OFF(viewport_scale_offset_enbled)] = Viewports; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | void SetupDirtyScissors(Tables& tables) { | 77 | void SetupDirtyScissors(Tables& tables) { |
| @@ -88,7 +88,7 @@ void SetupDirtyPolygonModes(Tables& tables) { | |||
| 88 | 88 | ||
| 89 | tables[1][OFF(polygon_mode_front)] = PolygonModes; | 89 | tables[1][OFF(polygon_mode_front)] = PolygonModes; |
| 90 | tables[1][OFF(polygon_mode_back)] = PolygonModes; | 90 | tables[1][OFF(polygon_mode_back)] = PolygonModes; |
| 91 | tables[0][OFF(fill_rectangle)] = PolygonModes; | 91 | tables[0][OFF(fill_via_triangle_mode)] = PolygonModes; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | void SetupDirtyDepthTest(Tables& tables) { | 94 | void SetupDirtyDepthTest(Tables& tables) { |
| @@ -100,12 +100,14 @@ void SetupDirtyDepthTest(Tables& tables) { | |||
| 100 | 100 | ||
| 101 | void SetupDirtyStencilTest(Tables& tables) { | 101 | void SetupDirtyStencilTest(Tables& tables) { |
| 102 | static constexpr std::array offsets = { | 102 | static constexpr std::array offsets = { |
| 103 | OFF(stencil_enable), OFF(stencil_front_func_func), OFF(stencil_front_func_ref), | 103 | OFF(stencil_enable), OFF(stencil_front_op.func), |
| 104 | OFF(stencil_front_func_mask), OFF(stencil_front_op_fail), OFF(stencil_front_op_zfail), | 104 | OFF(stencil_front_func.ref), OFF(stencil_front_func.func_mask), |
| 105 | OFF(stencil_front_op_zpass), OFF(stencil_front_mask), OFF(stencil_two_side_enable), | 105 | OFF(stencil_front_op.fail), OFF(stencil_front_op.zfail), |
| 106 | OFF(stencil_back_func_func), OFF(stencil_back_func_ref), OFF(stencil_back_func_mask), | 106 | OFF(stencil_front_op.zpass), OFF(stencil_front_func.mask), |
| 107 | OFF(stencil_back_op_fail), OFF(stencil_back_op_zfail), OFF(stencil_back_op_zpass), | 107 | OFF(stencil_two_side_enable), OFF(stencil_back_op.func), |
| 108 | OFF(stencil_back_mask)}; | 108 | OFF(stencil_back_func.ref), OFF(stencil_back_func.func_mask), |
| 109 | OFF(stencil_back_op.fail), OFF(stencil_back_op.zfail), | ||
| 110 | OFF(stencil_back_op.zpass), OFF(stencil_back_func.mask)}; | ||
| 109 | for (const auto offset : offsets) { | 111 | for (const auto offset : offsets) { |
| 110 | tables[0][offset] = StencilTest; | 112 | tables[0][offset] = StencilTest; |
| 111 | } | 113 | } |
| @@ -121,15 +123,15 @@ void SetupDirtyAlphaTest(Tables& tables) { | |||
| 121 | void SetupDirtyBlend(Tables& tables) { | 123 | void SetupDirtyBlend(Tables& tables) { |
| 122 | FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor); | 124 | FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor); |
| 123 | 125 | ||
| 124 | tables[0][OFF(independent_blend_enable)] = BlendIndependentEnabled; | 126 | tables[0][OFF(blend_per_target_enabled)] = BlendIndependentEnabled; |
| 125 | 127 | ||
| 126 | for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) { | 128 | for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) { |
| 127 | const std::size_t offset = OFF(independent_blend) + i * NUM(independent_blend[0]); | 129 | const std::size_t offset = OFF(blend_per_target) + i * NUM(blend_per_target[0]); |
| 128 | FillBlock(tables[0], offset, NUM(independent_blend[0]), BlendState0 + i); | 130 | FillBlock(tables[0], offset, NUM(blend_per_target[0]), BlendState0 + i); |
| 129 | 131 | ||
| 130 | tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i); | 132 | tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i); |
| 131 | } | 133 | } |
| 132 | FillBlock(tables[1], OFF(independent_blend), NUM(independent_blend), BlendStates); | 134 | FillBlock(tables[1], OFF(blend_per_target), NUM(blend_per_target), BlendStates); |
| 133 | FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates); | 135 | FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates); |
| 134 | } | 136 | } |
| 135 | 137 | ||
| @@ -142,13 +144,14 @@ void SetupDirtyPolygonOffset(Tables& tables) { | |||
| 142 | table[OFF(polygon_offset_fill_enable)] = PolygonOffset; | 144 | table[OFF(polygon_offset_fill_enable)] = PolygonOffset; |
| 143 | table[OFF(polygon_offset_line_enable)] = PolygonOffset; | 145 | table[OFF(polygon_offset_line_enable)] = PolygonOffset; |
| 144 | table[OFF(polygon_offset_point_enable)] = PolygonOffset; | 146 | table[OFF(polygon_offset_point_enable)] = PolygonOffset; |
| 145 | table[OFF(polygon_offset_factor)] = PolygonOffset; | 147 | table[OFF(slope_scale_depth_bias)] = PolygonOffset; |
| 146 | table[OFF(polygon_offset_units)] = PolygonOffset; | 148 | table[OFF(depth_bias)] = PolygonOffset; |
| 147 | table[OFF(polygon_offset_clamp)] = PolygonOffset; | 149 | table[OFF(depth_bias_clamp)] = PolygonOffset; |
| 148 | } | 150 | } |
| 149 | 151 | ||
| 150 | void SetupDirtyMultisampleControl(Tables& tables) { | 152 | void SetupDirtyMultisampleControl(Tables& tables) { |
| 151 | FillBlock(tables[0], OFF(multisample_control), NUM(multisample_control), MultisampleControl); | 153 | FillBlock(tables[0], OFF(anti_alias_alpha_control), NUM(anti_alias_alpha_control), |
| 154 | MultisampleControl); | ||
| 152 | } | 155 | } |
| 153 | 156 | ||
| 154 | void SetupDirtyRasterizeEnable(Tables& tables) { | 157 | void SetupDirtyRasterizeEnable(Tables& tables) { |
| @@ -168,7 +171,7 @@ void SetupDirtyFragmentClampColor(Tables& tables) { | |||
| 168 | } | 171 | } |
| 169 | 172 | ||
| 170 | void SetupDirtyPointSize(Tables& tables) { | 173 | void SetupDirtyPointSize(Tables& tables) { |
| 171 | tables[0][OFF(vp_point_size)] = PointSize; | 174 | tables[0][OFF(point_size_attribute)] = PointSize; |
| 172 | tables[0][OFF(point_size)] = PointSize; | 175 | tables[0][OFF(point_size)] = PointSize; |
| 173 | tables[0][OFF(point_sprite_enable)] = PointSize; | 176 | tables[0][OFF(point_sprite_enable)] = PointSize; |
| 174 | } | 177 | } |
| @@ -176,28 +179,28 @@ void SetupDirtyPointSize(Tables& tables) { | |||
| 176 | void SetupDirtyLineWidth(Tables& tables) { | 179 | void SetupDirtyLineWidth(Tables& tables) { |
| 177 | tables[0][OFF(line_width_smooth)] = LineWidth; | 180 | tables[0][OFF(line_width_smooth)] = LineWidth; |
| 178 | tables[0][OFF(line_width_aliased)] = LineWidth; | 181 | tables[0][OFF(line_width_aliased)] = LineWidth; |
| 179 | tables[0][OFF(line_smooth_enable)] = LineWidth; | 182 | tables[0][OFF(line_anti_alias_enable)] = LineWidth; |
| 180 | } | 183 | } |
| 181 | 184 | ||
| 182 | void SetupDirtyClipControl(Tables& tables) { | 185 | void SetupDirtyClipControl(Tables& tables) { |
| 183 | auto& table = tables[0]; | 186 | auto& table = tables[0]; |
| 184 | table[OFF(screen_y_control)] = ClipControl; | 187 | table[OFF(window_origin)] = ClipControl; |
| 185 | table[OFF(depth_mode)] = ClipControl; | 188 | table[OFF(depth_mode)] = ClipControl; |
| 186 | } | 189 | } |
| 187 | 190 | ||
| 188 | void SetupDirtyDepthClampEnabled(Tables& tables) { | 191 | void SetupDirtyDepthClampEnabled(Tables& tables) { |
| 189 | tables[0][OFF(view_volume_clip_control)] = DepthClampEnabled; | 192 | tables[0][OFF(viewport_clip_control)] = DepthClampEnabled; |
| 190 | } | 193 | } |
| 191 | 194 | ||
| 192 | void SetupDirtyMisc(Tables& tables) { | 195 | void SetupDirtyMisc(Tables& tables) { |
| 193 | auto& table = tables[0]; | 196 | auto& table = tables[0]; |
| 194 | 197 | ||
| 195 | table[OFF(clip_distance_enabled)] = ClipDistances; | 198 | table[OFF(user_clip_enable)] = ClipDistances; |
| 196 | 199 | ||
| 197 | table[OFF(front_face)] = FrontFace; | 200 | table[OFF(gl_front_face)] = FrontFace; |
| 198 | 201 | ||
| 199 | table[OFF(cull_test_enabled)] = CullTest; | 202 | table[OFF(gl_cull_test_enabled)] = CullTest; |
| 200 | table[OFF(cull_face)] = CullTest; | 203 | table[OFF(gl_cull_face)] = CullTest; |
| 201 | } | 204 | } |
| 202 | 205 | ||
| 203 | } // Anonymous namespace | 206 | } // Anonymous namespace |
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 004421236..e14f9b2db 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -126,51 +126,60 @@ inline const FormatTuple& GetFormatTuple(VideoCore::Surface::PixelFormat pixel_f | |||
| 126 | 126 | ||
| 127 | inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) { | 127 | inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) { |
| 128 | switch (attrib.type) { | 128 | switch (attrib.type) { |
| 129 | case Maxwell::VertexAttribute::Type::UnsignedNorm: | 129 | case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway: |
| 130 | case Maxwell::VertexAttribute::Type::UnsignedScaled: | 130 | ASSERT_MSG(false, "Invalid vertex attribute type!"); |
| 131 | case Maxwell::VertexAttribute::Type::UnsignedInt: | 131 | break; |
| 132 | case Maxwell::VertexAttribute::Type::UNorm: | ||
| 133 | case Maxwell::VertexAttribute::Type::UScaled: | ||
| 134 | case Maxwell::VertexAttribute::Type::UInt: | ||
| 132 | switch (attrib.size) { | 135 | switch (attrib.size) { |
| 133 | case Maxwell::VertexAttribute::Size::Size_8: | 136 | case Maxwell::VertexAttribute::Size::Size_R8: |
| 134 | case Maxwell::VertexAttribute::Size::Size_8_8: | 137 | case Maxwell::VertexAttribute::Size::Size_A8: |
| 135 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | 138 | case Maxwell::VertexAttribute::Size::Size_R8_G8: |
| 136 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 139 | case Maxwell::VertexAttribute::Size::Size_G8_R8: |
| 140 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8: | ||
| 141 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8: | ||
| 142 | case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8: | ||
| 137 | return GL_UNSIGNED_BYTE; | 143 | return GL_UNSIGNED_BYTE; |
| 138 | case Maxwell::VertexAttribute::Size::Size_16: | 144 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 139 | case Maxwell::VertexAttribute::Size::Size_16_16: | 145 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 140 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 146 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 141 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 147 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 142 | return GL_UNSIGNED_SHORT; | 148 | return GL_UNSIGNED_SHORT; |
| 143 | case Maxwell::VertexAttribute::Size::Size_32: | 149 | case Maxwell::VertexAttribute::Size::Size_R32: |
| 144 | case Maxwell::VertexAttribute::Size::Size_32_32: | 150 | case Maxwell::VertexAttribute::Size::Size_R32_G32: |
| 145 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | 151 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32: |
| 146 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | 152 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32: |
| 147 | return GL_UNSIGNED_INT; | 153 | return GL_UNSIGNED_INT; |
| 148 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 154 | case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10: |
| 149 | return GL_UNSIGNED_INT_2_10_10_10_REV; | 155 | return GL_UNSIGNED_INT_2_10_10_10_REV; |
| 150 | default: | 156 | default: |
| 151 | break; | 157 | break; |
| 152 | } | 158 | } |
| 153 | break; | 159 | break; |
| 154 | case Maxwell::VertexAttribute::Type::SignedNorm: | 160 | case Maxwell::VertexAttribute::Type::SNorm: |
| 155 | case Maxwell::VertexAttribute::Type::SignedScaled: | 161 | case Maxwell::VertexAttribute::Type::SScaled: |
| 156 | case Maxwell::VertexAttribute::Type::SignedInt: | 162 | case Maxwell::VertexAttribute::Type::SInt: |
| 157 | switch (attrib.size) { | 163 | switch (attrib.size) { |
| 158 | case Maxwell::VertexAttribute::Size::Size_8: | 164 | case Maxwell::VertexAttribute::Size::Size_R8: |
| 159 | case Maxwell::VertexAttribute::Size::Size_8_8: | 165 | case Maxwell::VertexAttribute::Size::Size_A8: |
| 160 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | 166 | case Maxwell::VertexAttribute::Size::Size_R8_G8: |
| 161 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 167 | case Maxwell::VertexAttribute::Size::Size_G8_R8: |
| 168 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8: | ||
| 169 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8: | ||
| 170 | case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8: | ||
| 162 | return GL_BYTE; | 171 | return GL_BYTE; |
| 163 | case Maxwell::VertexAttribute::Size::Size_16: | 172 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 164 | case Maxwell::VertexAttribute::Size::Size_16_16: | 173 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 165 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 174 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 166 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 175 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 167 | return GL_SHORT; | 176 | return GL_SHORT; |
| 168 | case Maxwell::VertexAttribute::Size::Size_32: | 177 | case Maxwell::VertexAttribute::Size::Size_R32: |
| 169 | case Maxwell::VertexAttribute::Size::Size_32_32: | 178 | case Maxwell::VertexAttribute::Size::Size_R32_G32: |
| 170 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | 179 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32: |
| 171 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | 180 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32: |
| 172 | return GL_INT; | 181 | return GL_INT; |
| 173 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 182 | case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10: |
| 174 | return GL_INT_2_10_10_10_REV; | 183 | return GL_INT_2_10_10_10_REV; |
| 175 | default: | 184 | default: |
| 176 | break; | 185 | break; |
| @@ -178,17 +187,17 @@ inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) { | |||
| 178 | break; | 187 | break; |
| 179 | case Maxwell::VertexAttribute::Type::Float: | 188 | case Maxwell::VertexAttribute::Type::Float: |
| 180 | switch (attrib.size) { | 189 | switch (attrib.size) { |
| 181 | case Maxwell::VertexAttribute::Size::Size_16: | 190 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 182 | case Maxwell::VertexAttribute::Size::Size_16_16: | 191 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 183 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 192 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 184 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 193 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 185 | return GL_HALF_FLOAT; | 194 | return GL_HALF_FLOAT; |
| 186 | case Maxwell::VertexAttribute::Size::Size_32: | 195 | case Maxwell::VertexAttribute::Size::Size_R32: |
| 187 | case Maxwell::VertexAttribute::Size::Size_32_32: | 196 | case Maxwell::VertexAttribute::Size::Size_R32_G32: |
| 188 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | 197 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32: |
| 189 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | 198 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32: |
| 190 | return GL_FLOAT; | 199 | return GL_FLOAT; |
| 191 | case Maxwell::VertexAttribute::Size::Size_11_11_10: | 200 | case Maxwell::VertexAttribute::Size::Size_B10_G11_R11: |
| 192 | return GL_UNSIGNED_INT_10F_11F_11F_REV; | 201 | return GL_UNSIGNED_INT_10F_11F_11F_REV; |
| 193 | default: | 202 | default: |
| 194 | break; | 203 | break; |
| @@ -335,20 +344,20 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) { | |||
| 335 | 344 | ||
| 336 | inline GLenum BlendEquation(Maxwell::Blend::Equation equation) { | 345 | inline GLenum BlendEquation(Maxwell::Blend::Equation equation) { |
| 337 | switch (equation) { | 346 | switch (equation) { |
| 338 | case Maxwell::Blend::Equation::Add: | 347 | case Maxwell::Blend::Equation::Add_D3D: |
| 339 | case Maxwell::Blend::Equation::AddGL: | 348 | case Maxwell::Blend::Equation::Add_GL: |
| 340 | return GL_FUNC_ADD; | 349 | return GL_FUNC_ADD; |
| 341 | case Maxwell::Blend::Equation::Subtract: | 350 | case Maxwell::Blend::Equation::Subtract_D3D: |
| 342 | case Maxwell::Blend::Equation::SubtractGL: | 351 | case Maxwell::Blend::Equation::Subtract_GL: |
| 343 | return GL_FUNC_SUBTRACT; | 352 | return GL_FUNC_SUBTRACT; |
| 344 | case Maxwell::Blend::Equation::ReverseSubtract: | 353 | case Maxwell::Blend::Equation::ReverseSubtract_D3D: |
| 345 | case Maxwell::Blend::Equation::ReverseSubtractGL: | 354 | case Maxwell::Blend::Equation::ReverseSubtract_GL: |
| 346 | return GL_FUNC_REVERSE_SUBTRACT; | 355 | return GL_FUNC_REVERSE_SUBTRACT; |
| 347 | case Maxwell::Blend::Equation::Min: | 356 | case Maxwell::Blend::Equation::Min_D3D: |
| 348 | case Maxwell::Blend::Equation::MinGL: | 357 | case Maxwell::Blend::Equation::Min_GL: |
| 349 | return GL_MIN; | 358 | return GL_MIN; |
| 350 | case Maxwell::Blend::Equation::Max: | 359 | case Maxwell::Blend::Equation::Max_D3D: |
| 351 | case Maxwell::Blend::Equation::MaxGL: | 360 | case Maxwell::Blend::Equation::Max_GL: |
| 352 | return GL_MAX; | 361 | return GL_MAX; |
| 353 | } | 362 | } |
| 354 | UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation); | 363 | UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation); |
| @@ -357,62 +366,62 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) { | |||
| 357 | 366 | ||
| 358 | inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { | 367 | inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { |
| 359 | switch (factor) { | 368 | switch (factor) { |
| 360 | case Maxwell::Blend::Factor::Zero: | 369 | case Maxwell::Blend::Factor::Zero_D3D: |
| 361 | case Maxwell::Blend::Factor::ZeroGL: | 370 | case Maxwell::Blend::Factor::Zero_GL: |
| 362 | return GL_ZERO; | 371 | return GL_ZERO; |
| 363 | case Maxwell::Blend::Factor::One: | 372 | case Maxwell::Blend::Factor::One_D3D: |
| 364 | case Maxwell::Blend::Factor::OneGL: | 373 | case Maxwell::Blend::Factor::One_GL: |
| 365 | return GL_ONE; | 374 | return GL_ONE; |
| 366 | case Maxwell::Blend::Factor::SourceColor: | 375 | case Maxwell::Blend::Factor::SourceColor_D3D: |
| 367 | case Maxwell::Blend::Factor::SourceColorGL: | 376 | case Maxwell::Blend::Factor::SourceColor_GL: |
| 368 | return GL_SRC_COLOR; | 377 | return GL_SRC_COLOR; |
| 369 | case Maxwell::Blend::Factor::OneMinusSourceColor: | 378 | case Maxwell::Blend::Factor::OneMinusSourceColor_D3D: |
| 370 | case Maxwell::Blend::Factor::OneMinusSourceColorGL: | 379 | case Maxwell::Blend::Factor::OneMinusSourceColor_GL: |
| 371 | return GL_ONE_MINUS_SRC_COLOR; | 380 | return GL_ONE_MINUS_SRC_COLOR; |
| 372 | case Maxwell::Blend::Factor::SourceAlpha: | 381 | case Maxwell::Blend::Factor::SourceAlpha_D3D: |
| 373 | case Maxwell::Blend::Factor::SourceAlphaGL: | 382 | case Maxwell::Blend::Factor::SourceAlpha_GL: |
| 374 | return GL_SRC_ALPHA; | 383 | return GL_SRC_ALPHA; |
| 375 | case Maxwell::Blend::Factor::OneMinusSourceAlpha: | 384 | case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D: |
| 376 | case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: | 385 | case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL: |
| 377 | return GL_ONE_MINUS_SRC_ALPHA; | 386 | return GL_ONE_MINUS_SRC_ALPHA; |
| 378 | case Maxwell::Blend::Factor::DestAlpha: | 387 | case Maxwell::Blend::Factor::DestAlpha_D3D: |
| 379 | case Maxwell::Blend::Factor::DestAlphaGL: | 388 | case Maxwell::Blend::Factor::DestAlpha_GL: |
| 380 | return GL_DST_ALPHA; | 389 | return GL_DST_ALPHA; |
| 381 | case Maxwell::Blend::Factor::OneMinusDestAlpha: | 390 | case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D: |
| 382 | case Maxwell::Blend::Factor::OneMinusDestAlphaGL: | 391 | case Maxwell::Blend::Factor::OneMinusDestAlpha_GL: |
| 383 | return GL_ONE_MINUS_DST_ALPHA; | 392 | return GL_ONE_MINUS_DST_ALPHA; |
| 384 | case Maxwell::Blend::Factor::DestColor: | 393 | case Maxwell::Blend::Factor::DestColor_D3D: |
| 385 | case Maxwell::Blend::Factor::DestColorGL: | 394 | case Maxwell::Blend::Factor::DestColor_GL: |
| 386 | return GL_DST_COLOR; | 395 | return GL_DST_COLOR; |
| 387 | case Maxwell::Blend::Factor::OneMinusDestColor: | 396 | case Maxwell::Blend::Factor::OneMinusDestColor_D3D: |
| 388 | case Maxwell::Blend::Factor::OneMinusDestColorGL: | 397 | case Maxwell::Blend::Factor::OneMinusDestColor_GL: |
| 389 | return GL_ONE_MINUS_DST_COLOR; | 398 | return GL_ONE_MINUS_DST_COLOR; |
| 390 | case Maxwell::Blend::Factor::SourceAlphaSaturate: | 399 | case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D: |
| 391 | case Maxwell::Blend::Factor::SourceAlphaSaturateGL: | 400 | case Maxwell::Blend::Factor::SourceAlphaSaturate_GL: |
| 392 | return GL_SRC_ALPHA_SATURATE; | 401 | return GL_SRC_ALPHA_SATURATE; |
| 393 | case Maxwell::Blend::Factor::Source1Color: | 402 | case Maxwell::Blend::Factor::Source1Color_D3D: |
| 394 | case Maxwell::Blend::Factor::Source1ColorGL: | 403 | case Maxwell::Blend::Factor::Source1Color_GL: |
| 395 | return GL_SRC1_COLOR; | 404 | return GL_SRC1_COLOR; |
| 396 | case Maxwell::Blend::Factor::OneMinusSource1Color: | 405 | case Maxwell::Blend::Factor::OneMinusSource1Color_D3D: |
| 397 | case Maxwell::Blend::Factor::OneMinusSource1ColorGL: | 406 | case Maxwell::Blend::Factor::OneMinusSource1Color_GL: |
| 398 | return GL_ONE_MINUS_SRC1_COLOR; | 407 | return GL_ONE_MINUS_SRC1_COLOR; |
| 399 | case Maxwell::Blend::Factor::Source1Alpha: | 408 | case Maxwell::Blend::Factor::Source1Alpha_D3D: |
| 400 | case Maxwell::Blend::Factor::Source1AlphaGL: | 409 | case Maxwell::Blend::Factor::Source1Alpha_GL: |
| 401 | return GL_SRC1_ALPHA; | 410 | return GL_SRC1_ALPHA; |
| 402 | case Maxwell::Blend::Factor::OneMinusSource1Alpha: | 411 | case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D: |
| 403 | case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: | 412 | case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL: |
| 404 | return GL_ONE_MINUS_SRC1_ALPHA; | 413 | return GL_ONE_MINUS_SRC1_ALPHA; |
| 405 | case Maxwell::Blend::Factor::ConstantColor: | 414 | case Maxwell::Blend::Factor::BlendFactor_D3D: |
| 406 | case Maxwell::Blend::Factor::ConstantColorGL: | 415 | case Maxwell::Blend::Factor::ConstantColor_GL: |
| 407 | return GL_CONSTANT_COLOR; | 416 | return GL_CONSTANT_COLOR; |
| 408 | case Maxwell::Blend::Factor::OneMinusConstantColor: | 417 | case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D: |
| 409 | case Maxwell::Blend::Factor::OneMinusConstantColorGL: | 418 | case Maxwell::Blend::Factor::OneMinusConstantColor_GL: |
| 410 | return GL_ONE_MINUS_CONSTANT_COLOR; | 419 | return GL_ONE_MINUS_CONSTANT_COLOR; |
| 411 | case Maxwell::Blend::Factor::ConstantAlpha: | 420 | case Maxwell::Blend::Factor::BothSourceAlpha_D3D: |
| 412 | case Maxwell::Blend::Factor::ConstantAlphaGL: | 421 | case Maxwell::Blend::Factor::ConstantAlpha_GL: |
| 413 | return GL_CONSTANT_ALPHA; | 422 | return GL_CONSTANT_ALPHA; |
| 414 | case Maxwell::Blend::Factor::OneMinusConstantAlpha: | 423 | case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D: |
| 415 | case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: | 424 | case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL: |
| 416 | return GL_ONE_MINUS_CONSTANT_ALPHA; | 425 | return GL_ONE_MINUS_CONSTANT_ALPHA; |
| 417 | } | 426 | } |
| 418 | UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor); | 427 | UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor); |
| @@ -421,60 +430,60 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { | |||
| 421 | 430 | ||
| 422 | inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) { | 431 | inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) { |
| 423 | switch (comparison) { | 432 | switch (comparison) { |
| 424 | case Maxwell::ComparisonOp::Never: | 433 | case Maxwell::ComparisonOp::Never_D3D: |
| 425 | case Maxwell::ComparisonOp::NeverOld: | 434 | case Maxwell::ComparisonOp::Never_GL: |
| 426 | return GL_NEVER; | 435 | return GL_NEVER; |
| 427 | case Maxwell::ComparisonOp::Less: | 436 | case Maxwell::ComparisonOp::Less_D3D: |
| 428 | case Maxwell::ComparisonOp::LessOld: | 437 | case Maxwell::ComparisonOp::Less_GL: |
| 429 | return GL_LESS; | 438 | return GL_LESS; |
| 430 | case Maxwell::ComparisonOp::Equal: | 439 | case Maxwell::ComparisonOp::Equal_D3D: |
| 431 | case Maxwell::ComparisonOp::EqualOld: | 440 | case Maxwell::ComparisonOp::Equal_GL: |
| 432 | return GL_EQUAL; | 441 | return GL_EQUAL; |
| 433 | case Maxwell::ComparisonOp::LessEqual: | 442 | case Maxwell::ComparisonOp::LessEqual_D3D: |
| 434 | case Maxwell::ComparisonOp::LessEqualOld: | 443 | case Maxwell::ComparisonOp::LessEqual_GL: |
| 435 | return GL_LEQUAL; | 444 | return GL_LEQUAL; |
| 436 | case Maxwell::ComparisonOp::Greater: | 445 | case Maxwell::ComparisonOp::Greater_D3D: |
| 437 | case Maxwell::ComparisonOp::GreaterOld: | 446 | case Maxwell::ComparisonOp::Greater_GL: |
| 438 | return GL_GREATER; | 447 | return GL_GREATER; |
| 439 | case Maxwell::ComparisonOp::NotEqual: | 448 | case Maxwell::ComparisonOp::NotEqual_D3D: |
| 440 | case Maxwell::ComparisonOp::NotEqualOld: | 449 | case Maxwell::ComparisonOp::NotEqual_GL: |
| 441 | return GL_NOTEQUAL; | 450 | return GL_NOTEQUAL; |
| 442 | case Maxwell::ComparisonOp::GreaterEqual: | 451 | case Maxwell::ComparisonOp::GreaterEqual_D3D: |
| 443 | case Maxwell::ComparisonOp::GreaterEqualOld: | 452 | case Maxwell::ComparisonOp::GreaterEqual_GL: |
| 444 | return GL_GEQUAL; | 453 | return GL_GEQUAL; |
| 445 | case Maxwell::ComparisonOp::Always: | 454 | case Maxwell::ComparisonOp::Always_D3D: |
| 446 | case Maxwell::ComparisonOp::AlwaysOld: | 455 | case Maxwell::ComparisonOp::Always_GL: |
| 447 | return GL_ALWAYS; | 456 | return GL_ALWAYS; |
| 448 | } | 457 | } |
| 449 | UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); | 458 | UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); |
| 450 | return GL_ALWAYS; | 459 | return GL_ALWAYS; |
| 451 | } | 460 | } |
| 452 | 461 | ||
| 453 | inline GLenum StencilOp(Maxwell::StencilOp stencil) { | 462 | inline GLenum StencilOp(Maxwell::StencilOp::Op stencil) { |
| 454 | switch (stencil) { | 463 | switch (stencil) { |
| 455 | case Maxwell::StencilOp::Keep: | 464 | case Maxwell::StencilOp::Op::Keep_D3D: |
| 456 | case Maxwell::StencilOp::KeepOGL: | 465 | case Maxwell::StencilOp::Op::Keep_GL: |
| 457 | return GL_KEEP; | 466 | return GL_KEEP; |
| 458 | case Maxwell::StencilOp::Zero: | 467 | case Maxwell::StencilOp::Op::Zero_D3D: |
| 459 | case Maxwell::StencilOp::ZeroOGL: | 468 | case Maxwell::StencilOp::Op::Zero_GL: |
| 460 | return GL_ZERO; | 469 | return GL_ZERO; |
| 461 | case Maxwell::StencilOp::Replace: | 470 | case Maxwell::StencilOp::Op::Replace_D3D: |
| 462 | case Maxwell::StencilOp::ReplaceOGL: | 471 | case Maxwell::StencilOp::Op::Replace_GL: |
| 463 | return GL_REPLACE; | 472 | return GL_REPLACE; |
| 464 | case Maxwell::StencilOp::Incr: | 473 | case Maxwell::StencilOp::Op::IncrSaturate_D3D: |
| 465 | case Maxwell::StencilOp::IncrOGL: | 474 | case Maxwell::StencilOp::Op::IncrSaturate_GL: |
| 466 | return GL_INCR; | 475 | return GL_INCR; |
| 467 | case Maxwell::StencilOp::Decr: | 476 | case Maxwell::StencilOp::Op::DecrSaturate_D3D: |
| 468 | case Maxwell::StencilOp::DecrOGL: | 477 | case Maxwell::StencilOp::Op::DecrSaturate_GL: |
| 469 | return GL_DECR; | 478 | return GL_DECR; |
| 470 | case Maxwell::StencilOp::Invert: | 479 | case Maxwell::StencilOp::Op::Invert_D3D: |
| 471 | case Maxwell::StencilOp::InvertOGL: | 480 | case Maxwell::StencilOp::Op::Invert_GL: |
| 472 | return GL_INVERT; | 481 | return GL_INVERT; |
| 473 | case Maxwell::StencilOp::IncrWrap: | 482 | case Maxwell::StencilOp::Op::Incr_D3D: |
| 474 | case Maxwell::StencilOp::IncrWrapOGL: | 483 | case Maxwell::StencilOp::Op::Incr_GL: |
| 475 | return GL_INCR_WRAP; | 484 | return GL_INCR_WRAP; |
| 476 | case Maxwell::StencilOp::DecrWrap: | 485 | case Maxwell::StencilOp::Op::Decr_D3D: |
| 477 | case Maxwell::StencilOp::DecrWrapOGL: | 486 | case Maxwell::StencilOp::Op::Decr_GL: |
| 478 | return GL_DECR_WRAP; | 487 | return GL_DECR_WRAP; |
| 479 | } | 488 | } |
| 480 | UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil); | 489 | UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil); |
| @@ -505,39 +514,39 @@ inline GLenum CullFace(Maxwell::CullFace cull_face) { | |||
| 505 | return GL_BACK; | 514 | return GL_BACK; |
| 506 | } | 515 | } |
| 507 | 516 | ||
| 508 | inline GLenum LogicOp(Maxwell::LogicOperation operation) { | 517 | inline GLenum LogicOp(Maxwell::LogicOp::Op operation) { |
| 509 | switch (operation) { | 518 | switch (operation) { |
| 510 | case Maxwell::LogicOperation::Clear: | 519 | case Maxwell::LogicOp::Op::Clear: |
| 511 | return GL_CLEAR; | 520 | return GL_CLEAR; |
| 512 | case Maxwell::LogicOperation::And: | 521 | case Maxwell::LogicOp::Op::And: |
| 513 | return GL_AND; | 522 | return GL_AND; |
| 514 | case Maxwell::LogicOperation::AndReverse: | 523 | case Maxwell::LogicOp::Op::AndReverse: |
| 515 | return GL_AND_REVERSE; | 524 | return GL_AND_REVERSE; |
| 516 | case Maxwell::LogicOperation::Copy: | 525 | case Maxwell::LogicOp::Op::Copy: |
| 517 | return GL_COPY; | 526 | return GL_COPY; |
| 518 | case Maxwell::LogicOperation::AndInverted: | 527 | case Maxwell::LogicOp::Op::AndInverted: |
| 519 | return GL_AND_INVERTED; | 528 | return GL_AND_INVERTED; |
| 520 | case Maxwell::LogicOperation::NoOp: | 529 | case Maxwell::LogicOp::Op::NoOp: |
| 521 | return GL_NOOP; | 530 | return GL_NOOP; |
| 522 | case Maxwell::LogicOperation::Xor: | 531 | case Maxwell::LogicOp::Op::Xor: |
| 523 | return GL_XOR; | 532 | return GL_XOR; |
| 524 | case Maxwell::LogicOperation::Or: | 533 | case Maxwell::LogicOp::Op::Or: |
| 525 | return GL_OR; | 534 | return GL_OR; |
| 526 | case Maxwell::LogicOperation::Nor: | 535 | case Maxwell::LogicOp::Op::Nor: |
| 527 | return GL_NOR; | 536 | return GL_NOR; |
| 528 | case Maxwell::LogicOperation::Equiv: | 537 | case Maxwell::LogicOp::Op::Equiv: |
| 529 | return GL_EQUIV; | 538 | return GL_EQUIV; |
| 530 | case Maxwell::LogicOperation::Invert: | 539 | case Maxwell::LogicOp::Op::Invert: |
| 531 | return GL_INVERT; | 540 | return GL_INVERT; |
| 532 | case Maxwell::LogicOperation::OrReverse: | 541 | case Maxwell::LogicOp::Op::OrReverse: |
| 533 | return GL_OR_REVERSE; | 542 | return GL_OR_REVERSE; |
| 534 | case Maxwell::LogicOperation::CopyInverted: | 543 | case Maxwell::LogicOp::Op::CopyInverted: |
| 535 | return GL_COPY_INVERTED; | 544 | return GL_COPY_INVERTED; |
| 536 | case Maxwell::LogicOperation::OrInverted: | 545 | case Maxwell::LogicOp::Op::OrInverted: |
| 537 | return GL_OR_INVERTED; | 546 | return GL_OR_INVERTED; |
| 538 | case Maxwell::LogicOperation::Nand: | 547 | case Maxwell::LogicOp::Op::Nand: |
| 539 | return GL_NAND; | 548 | return GL_NAND; |
| 540 | case Maxwell::LogicOperation::Set: | 549 | case Maxwell::LogicOp::Op::Set: |
| 541 | return GL_SET; | 550 | return GL_SET; |
| 542 | } | 551 | } |
| 543 | UNIMPLEMENTED_MSG("Unimplemented logic operation={}", operation); | 552 | UNIMPLEMENTED_MSG("Unimplemented logic operation={}", operation); |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 733b454de..eb7c22fd5 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | |||
| @@ -34,14 +34,15 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = { | |||
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) { | 36 | void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) { |
| 37 | std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) { | 37 | std::ranges::transform(regs.transform_feedback.controls, state.layouts.begin(), |
| 38 | return VideoCommon::TransformFeedbackState::Layout{ | 38 | [](const auto& layout) { |
| 39 | .stream = layout.stream, | 39 | return VideoCommon::TransformFeedbackState::Layout{ |
| 40 | .varying_count = layout.varying_count, | 40 | .stream = layout.stream, |
| 41 | .stride = layout.stride, | 41 | .varying_count = layout.varying_count, |
| 42 | }; | 42 | .stride = layout.stride, |
| 43 | }); | 43 | }; |
| 44 | state.varyings = regs.tfb_varying_locs; | 44 | }); |
| 45 | state.varyings = regs.stream_out_layout; | ||
| 45 | } | 46 | } |
| 46 | } // Anonymous namespace | 47 | } // Anonymous namespace |
| 47 | 48 | ||
| @@ -58,33 +59,34 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | |||
| 58 | raw1 = 0; | 59 | raw1 = 0; |
| 59 | extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0); | 60 | extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0); |
| 60 | dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0); | 61 | dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0); |
| 61 | xfb_enabled.Assign(regs.tfb_enabled != 0); | 62 | xfb_enabled.Assign(regs.transform_feedback_enabled != 0); |
| 62 | primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); | 63 | primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); |
| 63 | depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); | 64 | depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); |
| 64 | depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value()); | 65 | depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip == |
| 66 | Maxwell::ViewportClipControl::GeometryClip::Passthrough); | ||
| 65 | ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0); | 67 | ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0); |
| 66 | polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front)); | 68 | polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front)); |
| 67 | patch_control_points_minus_one.Assign(regs.patch_vertices - 1); | 69 | patch_control_points_minus_one.Assign(regs.patch_vertices - 1); |
| 68 | tessellation_primitive.Assign(static_cast<u32>(regs.tess_mode.prim.Value())); | 70 | tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value())); |
| 69 | tessellation_spacing.Assign(static_cast<u32>(regs.tess_mode.spacing.Value())); | 71 | tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value())); |
| 70 | tessellation_clockwise.Assign(regs.tess_mode.cw.Value()); | 72 | tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() != |
| 73 | Maxwell::Tessellation::OutputPrimitves::Triangles_CCW); | ||
| 71 | logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); | 74 | logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); |
| 72 | logic_op.Assign(PackLogicOp(regs.logic_op.operation)); | 75 | logic_op.Assign(PackLogicOp(regs.logic_op.op)); |
| 73 | topology.Assign(regs.draw.topology); | 76 | topology.Assign(regs.draw.topology); |
| 74 | msaa_mode.Assign(regs.multisample_mode); | 77 | msaa_mode.Assign(regs.anti_alias_samples_mode); |
| 75 | 78 | ||
| 76 | raw2 = 0; | 79 | raw2 = 0; |
| 77 | rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); | 80 | rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); |
| 78 | const auto test_func = | 81 | const auto test_func = |
| 79 | regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always; | 82 | regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always_GL; |
| 80 | alpha_test_func.Assign(PackComparisonOp(test_func)); | 83 | alpha_test_func.Assign(PackComparisonOp(test_func)); |
| 81 | early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0); | 84 | early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0); |
| 82 | depth_enabled.Assign(regs.zeta_enable != 0 ? 1 : 0); | 85 | depth_enabled.Assign(regs.zeta_enable != 0 ? 1 : 0); |
| 83 | depth_format.Assign(static_cast<u32>(regs.zeta.format)); | 86 | depth_format.Assign(static_cast<u32>(regs.zeta.format)); |
| 84 | y_negate.Assign(regs.screen_y_control.y_negate != 0 ? 1 : 0); | 87 | y_negate.Assign(regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft ? 1 : 0); |
| 85 | provoking_vertex_last.Assign(regs.provoking_vertex_last != 0 ? 1 : 0); | 88 | provoking_vertex_last.Assign(regs.provoking_vertex == Maxwell::ProvokingVertex::Last ? 1 : 0); |
| 86 | conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0); | 89 | smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0); |
| 87 | smooth_lines.Assign(regs.line_smooth_enable != 0 ? 1 : 0); | ||
| 88 | 90 | ||
| 89 | for (size_t i = 0; i < regs.rt.size(); ++i) { | 91 | for (size_t i = 0; i < regs.rt.size(); ++i) { |
| 90 | color_formats[i] = static_cast<u8>(regs.rt[i].format); | 92 | color_formats[i] = static_cast<u8>(regs.rt[i].format); |
| @@ -116,8 +118,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | |||
| 116 | maxwell3d.dirty.flags[Dirty::VertexInput] = false; | 118 | maxwell3d.dirty.flags[Dirty::VertexInput] = false; |
| 117 | enabled_divisors = 0; | 119 | enabled_divisors = 0; |
| 118 | for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | 120 | for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 119 | const bool is_enabled = regs.instanced_arrays.IsInstancingEnabled(index); | 121 | const bool is_enabled = regs.vertex_stream_instances.IsInstancingEnabled(index); |
| 120 | binding_divisors[index] = is_enabled ? regs.vertex_array[index].divisor : 0; | 122 | binding_divisors[index] = is_enabled ? regs.vertex_streams[index].frequency : 0; |
| 121 | enabled_divisors |= (is_enabled ? u64{1} : 0) << index; | 123 | enabled_divisors |= (is_enabled ? u64{1} : 0) << index; |
| 122 | } | 124 | } |
| 123 | for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { | 125 | for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { |
| @@ -164,17 +166,17 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t | |||
| 164 | 166 | ||
| 165 | // TODO: C++20 Use templated lambda to deduplicate code | 167 | // TODO: C++20 Use templated lambda to deduplicate code |
| 166 | 168 | ||
| 167 | if (!regs.independent_blend_enable) { | 169 | if (!regs.blend_per_target_enabled) { |
| 168 | const auto& src = regs.blend; | 170 | if (!regs.blend.enable[index]) { |
| 169 | if (!src.enable[index]) { | ||
| 170 | return; | 171 | return; |
| 171 | } | 172 | } |
| 172 | equation_rgb.Assign(PackBlendEquation(src.equation_rgb)); | 173 | const auto& src = regs.blend; |
| 173 | equation_a.Assign(PackBlendEquation(src.equation_a)); | 174 | equation_rgb.Assign(PackBlendEquation(src.color_op)); |
| 174 | factor_source_rgb.Assign(PackBlendFactor(src.factor_source_rgb)); | 175 | equation_a.Assign(PackBlendEquation(src.alpha_op)); |
| 175 | factor_dest_rgb.Assign(PackBlendFactor(src.factor_dest_rgb)); | 176 | factor_source_rgb.Assign(PackBlendFactor(src.color_source)); |
| 176 | factor_source_a.Assign(PackBlendFactor(src.factor_source_a)); | 177 | factor_dest_rgb.Assign(PackBlendFactor(src.color_dest)); |
| 177 | factor_dest_a.Assign(PackBlendFactor(src.factor_dest_a)); | 178 | factor_source_a.Assign(PackBlendFactor(src.alpha_source)); |
| 179 | factor_dest_a.Assign(PackBlendFactor(src.alpha_dest)); | ||
| 178 | enable.Assign(1); | 180 | enable.Assign(1); |
| 179 | return; | 181 | return; |
| 180 | } | 182 | } |
| @@ -182,34 +184,34 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t | |||
| 182 | if (!regs.blend.enable[index]) { | 184 | if (!regs.blend.enable[index]) { |
| 183 | return; | 185 | return; |
| 184 | } | 186 | } |
| 185 | const auto& src = regs.independent_blend[index]; | 187 | const auto& src = regs.blend_per_target[index]; |
| 186 | equation_rgb.Assign(PackBlendEquation(src.equation_rgb)); | 188 | equation_rgb.Assign(PackBlendEquation(src.color_op)); |
| 187 | equation_a.Assign(PackBlendEquation(src.equation_a)); | 189 | equation_a.Assign(PackBlendEquation(src.alpha_op)); |
| 188 | factor_source_rgb.Assign(PackBlendFactor(src.factor_source_rgb)); | 190 | factor_source_rgb.Assign(PackBlendFactor(src.color_source)); |
| 189 | factor_dest_rgb.Assign(PackBlendFactor(src.factor_dest_rgb)); | 191 | factor_dest_rgb.Assign(PackBlendFactor(src.color_dest)); |
| 190 | factor_source_a.Assign(PackBlendFactor(src.factor_source_a)); | 192 | factor_source_a.Assign(PackBlendFactor(src.alpha_source)); |
| 191 | factor_dest_a.Assign(PackBlendFactor(src.factor_dest_a)); | 193 | factor_dest_a.Assign(PackBlendFactor(src.alpha_dest)); |
| 192 | enable.Assign(1); | 194 | enable.Assign(1); |
| 193 | } | 195 | } |
| 194 | 196 | ||
| 195 | void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { | 197 | void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { |
| 196 | u32 packed_front_face = PackFrontFace(regs.front_face); | 198 | u32 packed_front_face = PackFrontFace(regs.gl_front_face); |
| 197 | if (regs.screen_y_control.triangle_rast_flip != 0) { | 199 | if (regs.window_origin.flip_y != 0) { |
| 198 | // Flip front face | 200 | // Flip front face |
| 199 | packed_front_face = 1 - packed_front_face; | 201 | packed_front_face = 1 - packed_front_face; |
| 200 | } | 202 | } |
| 201 | 203 | ||
| 202 | raw1 = 0; | 204 | raw1 = 0; |
| 203 | raw2 = 0; | 205 | raw2 = 0; |
| 204 | front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op_fail)); | 206 | front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op.fail)); |
| 205 | front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op_zfail)); | 207 | front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op.zfail)); |
| 206 | front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op_zpass)); | 208 | front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op.zpass)); |
| 207 | front.test_func.Assign(PackComparisonOp(regs.stencil_front_func_func)); | 209 | front.test_func.Assign(PackComparisonOp(regs.stencil_front_op.func)); |
| 208 | if (regs.stencil_two_side_enable) { | 210 | if (regs.stencil_two_side_enable) { |
| 209 | back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op_fail)); | 211 | back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op.fail)); |
| 210 | back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op_zfail)); | 212 | back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op.zfail)); |
| 211 | back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op_zpass)); | 213 | back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op.zpass)); |
| 212 | back.test_func.Assign(PackComparisonOp(regs.stencil_back_func_func)); | 214 | back.test_func.Assign(PackComparisonOp(regs.stencil_back_op.func)); |
| 213 | } else { | 215 | } else { |
| 214 | back.action_stencil_fail.Assign(front.action_stencil_fail); | 216 | back.action_stencil_fail.Assign(front.action_stencil_fail); |
| 215 | back.action_depth_fail.Assign(front.action_depth_fail); | 217 | back.action_depth_fail.Assign(front.action_depth_fail); |
| @@ -222,9 +224,9 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { | |||
| 222 | depth_test_enable.Assign(regs.depth_test_enable); | 224 | depth_test_enable.Assign(regs.depth_test_enable); |
| 223 | front_face.Assign(packed_front_face); | 225 | front_face.Assign(packed_front_face); |
| 224 | depth_test_func.Assign(PackComparisonOp(regs.depth_test_func)); | 226 | depth_test_func.Assign(PackComparisonOp(regs.depth_test_func)); |
| 225 | cull_face.Assign(PackCullFace(regs.cull_face)); | 227 | cull_face.Assign(PackCullFace(regs.gl_cull_face)); |
| 226 | cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0); | 228 | cull_enable.Assign(regs.gl_cull_test_enabled != 0 ? 1 : 0); |
| 227 | std::ranges::transform(regs.vertex_array, vertex_strides.begin(), [](const auto& array) { | 229 | std::ranges::transform(regs.vertex_streams, vertex_strides.begin(), [](const auto& array) { |
| 228 | return static_cast<u16>(array.stride.Value()); | 230 | return static_cast<u16>(array.stride.Value()); |
| 229 | }); | 231 | }); |
| 230 | } | 232 | } |
| @@ -251,41 +253,42 @@ Maxwell::ComparisonOp FixedPipelineState::UnpackComparisonOp(u32 packed) noexcep | |||
| 251 | return static_cast<Maxwell::ComparisonOp>(packed + 1); | 253 | return static_cast<Maxwell::ComparisonOp>(packed + 1); |
| 252 | } | 254 | } |
| 253 | 255 | ||
| 254 | u32 FixedPipelineState::PackStencilOp(Maxwell::StencilOp op) noexcept { | 256 | u32 FixedPipelineState::PackStencilOp(Maxwell::StencilOp::Op op) noexcept { |
| 255 | switch (op) { | 257 | switch (op) { |
| 256 | case Maxwell::StencilOp::Keep: | 258 | case Maxwell::StencilOp::Op::Keep_D3D: |
| 257 | case Maxwell::StencilOp::KeepOGL: | 259 | case Maxwell::StencilOp::Op::Keep_GL: |
| 258 | return 0; | 260 | return 0; |
| 259 | case Maxwell::StencilOp::Zero: | 261 | case Maxwell::StencilOp::Op::Zero_D3D: |
| 260 | case Maxwell::StencilOp::ZeroOGL: | 262 | case Maxwell::StencilOp::Op::Zero_GL: |
| 261 | return 1; | 263 | return 1; |
| 262 | case Maxwell::StencilOp::Replace: | 264 | case Maxwell::StencilOp::Op::Replace_D3D: |
| 263 | case Maxwell::StencilOp::ReplaceOGL: | 265 | case Maxwell::StencilOp::Op::Replace_GL: |
| 264 | return 2; | 266 | return 2; |
| 265 | case Maxwell::StencilOp::Incr: | 267 | case Maxwell::StencilOp::Op::IncrSaturate_D3D: |
| 266 | case Maxwell::StencilOp::IncrOGL: | 268 | case Maxwell::StencilOp::Op::IncrSaturate_GL: |
| 267 | return 3; | 269 | return 3; |
| 268 | case Maxwell::StencilOp::Decr: | 270 | case Maxwell::StencilOp::Op::DecrSaturate_D3D: |
| 269 | case Maxwell::StencilOp::DecrOGL: | 271 | case Maxwell::StencilOp::Op::DecrSaturate_GL: |
| 270 | return 4; | 272 | return 4; |
| 271 | case Maxwell::StencilOp::Invert: | 273 | case Maxwell::StencilOp::Op::Invert_D3D: |
| 272 | case Maxwell::StencilOp::InvertOGL: | 274 | case Maxwell::StencilOp::Op::Invert_GL: |
| 273 | return 5; | 275 | return 5; |
| 274 | case Maxwell::StencilOp::IncrWrap: | 276 | case Maxwell::StencilOp::Op::Incr_D3D: |
| 275 | case Maxwell::StencilOp::IncrWrapOGL: | 277 | case Maxwell::StencilOp::Op::Incr_GL: |
| 276 | return 6; | 278 | return 6; |
| 277 | case Maxwell::StencilOp::DecrWrap: | 279 | case Maxwell::StencilOp::Op::Decr_D3D: |
| 278 | case Maxwell::StencilOp::DecrWrapOGL: | 280 | case Maxwell::StencilOp::Op::Decr_GL: |
| 279 | return 7; | 281 | return 7; |
| 280 | } | 282 | } |
| 281 | return 0; | 283 | return 0; |
| 282 | } | 284 | } |
| 283 | 285 | ||
| 284 | Maxwell::StencilOp FixedPipelineState::UnpackStencilOp(u32 packed) noexcept { | 286 | Maxwell::StencilOp::Op FixedPipelineState::UnpackStencilOp(u32 packed) noexcept { |
| 285 | static constexpr std::array LUT = {Maxwell::StencilOp::Keep, Maxwell::StencilOp::Zero, | 287 | static constexpr std::array LUT = { |
| 286 | Maxwell::StencilOp::Replace, Maxwell::StencilOp::Incr, | 288 | Maxwell::StencilOp::Op::Keep_D3D, Maxwell::StencilOp::Op::Zero_D3D, |
| 287 | Maxwell::StencilOp::Decr, Maxwell::StencilOp::Invert, | 289 | Maxwell::StencilOp::Op::Replace_D3D, Maxwell::StencilOp::Op::IncrSaturate_D3D, |
| 288 | Maxwell::StencilOp::IncrWrap, Maxwell::StencilOp::DecrWrap}; | 290 | Maxwell::StencilOp::Op::DecrSaturate_D3D, Maxwell::StencilOp::Op::Invert_D3D, |
| 291 | Maxwell::StencilOp::Op::Incr_D3D, Maxwell::StencilOp::Op::Decr_D3D}; | ||
| 289 | return LUT[packed]; | 292 | return LUT[packed]; |
| 290 | } | 293 | } |
| 291 | 294 | ||
| @@ -318,30 +321,30 @@ Maxwell::PolygonMode FixedPipelineState::UnpackPolygonMode(u32 packed) noexcept | |||
| 318 | return static_cast<Maxwell::PolygonMode>(packed + 0x1B00); | 321 | return static_cast<Maxwell::PolygonMode>(packed + 0x1B00); |
| 319 | } | 322 | } |
| 320 | 323 | ||
| 321 | u32 FixedPipelineState::PackLogicOp(Maxwell::LogicOperation op) noexcept { | 324 | u32 FixedPipelineState::PackLogicOp(Maxwell::LogicOp::Op op) noexcept { |
| 322 | return static_cast<u32>(op) - 0x1500; | 325 | return static_cast<u32>(op) - 0x1500; |
| 323 | } | 326 | } |
| 324 | 327 | ||
| 325 | Maxwell::LogicOperation FixedPipelineState::UnpackLogicOp(u32 packed) noexcept { | 328 | Maxwell::LogicOp::Op FixedPipelineState::UnpackLogicOp(u32 packed) noexcept { |
| 326 | return static_cast<Maxwell::LogicOperation>(packed + 0x1500); | 329 | return static_cast<Maxwell::LogicOp::Op>(packed + 0x1500); |
| 327 | } | 330 | } |
| 328 | 331 | ||
| 329 | u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noexcept { | 332 | u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noexcept { |
| 330 | switch (equation) { | 333 | switch (equation) { |
| 331 | case Maxwell::Blend::Equation::Add: | 334 | case Maxwell::Blend::Equation::Add_D3D: |
| 332 | case Maxwell::Blend::Equation::AddGL: | 335 | case Maxwell::Blend::Equation::Add_GL: |
| 333 | return 0; | 336 | return 0; |
| 334 | case Maxwell::Blend::Equation::Subtract: | 337 | case Maxwell::Blend::Equation::Subtract_D3D: |
| 335 | case Maxwell::Blend::Equation::SubtractGL: | 338 | case Maxwell::Blend::Equation::Subtract_GL: |
| 336 | return 1; | 339 | return 1; |
| 337 | case Maxwell::Blend::Equation::ReverseSubtract: | 340 | case Maxwell::Blend::Equation::ReverseSubtract_D3D: |
| 338 | case Maxwell::Blend::Equation::ReverseSubtractGL: | 341 | case Maxwell::Blend::Equation::ReverseSubtract_GL: |
| 339 | return 2; | 342 | return 2; |
| 340 | case Maxwell::Blend::Equation::Min: | 343 | case Maxwell::Blend::Equation::Min_D3D: |
| 341 | case Maxwell::Blend::Equation::MinGL: | 344 | case Maxwell::Blend::Equation::Min_GL: |
| 342 | return 3; | 345 | return 3; |
| 343 | case Maxwell::Blend::Equation::Max: | 346 | case Maxwell::Blend::Equation::Max_D3D: |
| 344 | case Maxwell::Blend::Equation::MaxGL: | 347 | case Maxwell::Blend::Equation::Max_GL: |
| 345 | return 4; | 348 | return 4; |
| 346 | } | 349 | } |
| 347 | return 0; | 350 | return 0; |
| @@ -349,97 +352,99 @@ u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noe | |||
| 349 | 352 | ||
| 350 | Maxwell::Blend::Equation FixedPipelineState::UnpackBlendEquation(u32 packed) noexcept { | 353 | Maxwell::Blend::Equation FixedPipelineState::UnpackBlendEquation(u32 packed) noexcept { |
| 351 | static constexpr std::array LUT = { | 354 | static constexpr std::array LUT = { |
| 352 | Maxwell::Blend::Equation::Add, Maxwell::Blend::Equation::Subtract, | 355 | Maxwell::Blend::Equation::Add_D3D, Maxwell::Blend::Equation::Subtract_D3D, |
| 353 | Maxwell::Blend::Equation::ReverseSubtract, Maxwell::Blend::Equation::Min, | 356 | Maxwell::Blend::Equation::ReverseSubtract_D3D, Maxwell::Blend::Equation::Min_D3D, |
| 354 | Maxwell::Blend::Equation::Max}; | 357 | Maxwell::Blend::Equation::Max_D3D}; |
| 355 | return LUT[packed]; | 358 | return LUT[packed]; |
| 356 | } | 359 | } |
| 357 | 360 | ||
| 358 | u32 FixedPipelineState::PackBlendFactor(Maxwell::Blend::Factor factor) noexcept { | 361 | u32 FixedPipelineState::PackBlendFactor(Maxwell::Blend::Factor factor) noexcept { |
| 359 | switch (factor) { | 362 | switch (factor) { |
| 360 | case Maxwell::Blend::Factor::Zero: | 363 | case Maxwell::Blend::Factor::Zero_D3D: |
| 361 | case Maxwell::Blend::Factor::ZeroGL: | 364 | case Maxwell::Blend::Factor::Zero_GL: |
| 362 | return 0; | 365 | return 0; |
| 363 | case Maxwell::Blend::Factor::One: | 366 | case Maxwell::Blend::Factor::One_D3D: |
| 364 | case Maxwell::Blend::Factor::OneGL: | 367 | case Maxwell::Blend::Factor::One_GL: |
| 365 | return 1; | 368 | return 1; |
| 366 | case Maxwell::Blend::Factor::SourceColor: | 369 | case Maxwell::Blend::Factor::SourceColor_D3D: |
| 367 | case Maxwell::Blend::Factor::SourceColorGL: | 370 | case Maxwell::Blend::Factor::SourceColor_GL: |
| 368 | return 2; | 371 | return 2; |
| 369 | case Maxwell::Blend::Factor::OneMinusSourceColor: | 372 | case Maxwell::Blend::Factor::OneMinusSourceColor_D3D: |
| 370 | case Maxwell::Blend::Factor::OneMinusSourceColorGL: | 373 | case Maxwell::Blend::Factor::OneMinusSourceColor_GL: |
| 371 | return 3; | 374 | return 3; |
| 372 | case Maxwell::Blend::Factor::SourceAlpha: | 375 | case Maxwell::Blend::Factor::SourceAlpha_D3D: |
| 373 | case Maxwell::Blend::Factor::SourceAlphaGL: | 376 | case Maxwell::Blend::Factor::SourceAlpha_GL: |
| 374 | return 4; | 377 | return 4; |
| 375 | case Maxwell::Blend::Factor::OneMinusSourceAlpha: | 378 | case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D: |
| 376 | case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: | 379 | case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL: |
| 377 | return 5; | 380 | return 5; |
| 378 | case Maxwell::Blend::Factor::DestAlpha: | 381 | case Maxwell::Blend::Factor::DestAlpha_D3D: |
| 379 | case Maxwell::Blend::Factor::DestAlphaGL: | 382 | case Maxwell::Blend::Factor::DestAlpha_GL: |
| 380 | return 6; | 383 | return 6; |
| 381 | case Maxwell::Blend::Factor::OneMinusDestAlpha: | 384 | case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D: |
| 382 | case Maxwell::Blend::Factor::OneMinusDestAlphaGL: | 385 | case Maxwell::Blend::Factor::OneMinusDestAlpha_GL: |
| 383 | return 7; | 386 | return 7; |
| 384 | case Maxwell::Blend::Factor::DestColor: | 387 | case Maxwell::Blend::Factor::DestColor_D3D: |
| 385 | case Maxwell::Blend::Factor::DestColorGL: | 388 | case Maxwell::Blend::Factor::DestColor_GL: |
| 386 | return 8; | 389 | return 8; |
| 387 | case Maxwell::Blend::Factor::OneMinusDestColor: | 390 | case Maxwell::Blend::Factor::OneMinusDestColor_D3D: |
| 388 | case Maxwell::Blend::Factor::OneMinusDestColorGL: | 391 | case Maxwell::Blend::Factor::OneMinusDestColor_GL: |
| 389 | return 9; | 392 | return 9; |
| 390 | case Maxwell::Blend::Factor::SourceAlphaSaturate: | 393 | case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D: |
| 391 | case Maxwell::Blend::Factor::SourceAlphaSaturateGL: | 394 | case Maxwell::Blend::Factor::SourceAlphaSaturate_GL: |
| 392 | return 10; | 395 | return 10; |
| 393 | case Maxwell::Blend::Factor::Source1Color: | 396 | case Maxwell::Blend::Factor::Source1Color_D3D: |
| 394 | case Maxwell::Blend::Factor::Source1ColorGL: | 397 | case Maxwell::Blend::Factor::Source1Color_GL: |
| 395 | return 11; | 398 | return 11; |
| 396 | case Maxwell::Blend::Factor::OneMinusSource1Color: | 399 | case Maxwell::Blend::Factor::OneMinusSource1Color_D3D: |
| 397 | case Maxwell::Blend::Factor::OneMinusSource1ColorGL: | 400 | case Maxwell::Blend::Factor::OneMinusSource1Color_GL: |
| 398 | return 12; | 401 | return 12; |
| 399 | case Maxwell::Blend::Factor::Source1Alpha: | 402 | case Maxwell::Blend::Factor::Source1Alpha_D3D: |
| 400 | case Maxwell::Blend::Factor::Source1AlphaGL: | 403 | case Maxwell::Blend::Factor::Source1Alpha_GL: |
| 401 | return 13; | 404 | return 13; |
| 402 | case Maxwell::Blend::Factor::OneMinusSource1Alpha: | 405 | case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D: |
| 403 | case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: | 406 | case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL: |
| 404 | return 14; | 407 | return 14; |
| 405 | case Maxwell::Blend::Factor::ConstantColor: | 408 | case Maxwell::Blend::Factor::BlendFactor_D3D: |
| 406 | case Maxwell::Blend::Factor::ConstantColorGL: | 409 | case Maxwell::Blend::Factor::ConstantColor_GL: |
| 407 | return 15; | 410 | return 15; |
| 408 | case Maxwell::Blend::Factor::OneMinusConstantColor: | 411 | case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D: |
| 409 | case Maxwell::Blend::Factor::OneMinusConstantColorGL: | 412 | case Maxwell::Blend::Factor::OneMinusConstantColor_GL: |
| 410 | return 16; | 413 | return 16; |
| 411 | case Maxwell::Blend::Factor::ConstantAlpha: | 414 | case Maxwell::Blend::Factor::BothSourceAlpha_D3D: |
| 412 | case Maxwell::Blend::Factor::ConstantAlphaGL: | 415 | case Maxwell::Blend::Factor::ConstantAlpha_GL: |
| 413 | return 17; | 416 | return 17; |
| 414 | case Maxwell::Blend::Factor::OneMinusConstantAlpha: | 417 | case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D: |
| 415 | case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: | 418 | case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL: |
| 416 | return 18; | 419 | return 18; |
| 417 | } | 420 | } |
| 421 | UNIMPLEMENTED_MSG("Unknown blend factor {}", static_cast<u32>(factor)); | ||
| 418 | return 0; | 422 | return 0; |
| 419 | } | 423 | } |
| 420 | 424 | ||
| 421 | Maxwell::Blend::Factor FixedPipelineState::UnpackBlendFactor(u32 packed) noexcept { | 425 | Maxwell::Blend::Factor FixedPipelineState::UnpackBlendFactor(u32 packed) noexcept { |
| 422 | static constexpr std::array LUT = { | 426 | static constexpr std::array LUT = { |
| 423 | Maxwell::Blend::Factor::Zero, | 427 | Maxwell::Blend::Factor::Zero_D3D, |
| 424 | Maxwell::Blend::Factor::One, | 428 | Maxwell::Blend::Factor::One_D3D, |
| 425 | Maxwell::Blend::Factor::SourceColor, | 429 | Maxwell::Blend::Factor::SourceColor_D3D, |
| 426 | Maxwell::Blend::Factor::OneMinusSourceColor, | 430 | Maxwell::Blend::Factor::OneMinusSourceColor_D3D, |
| 427 | Maxwell::Blend::Factor::SourceAlpha, | 431 | Maxwell::Blend::Factor::SourceAlpha_D3D, |
| 428 | Maxwell::Blend::Factor::OneMinusSourceAlpha, | 432 | Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D, |
| 429 | Maxwell::Blend::Factor::DestAlpha, | 433 | Maxwell::Blend::Factor::DestAlpha_D3D, |
| 430 | Maxwell::Blend::Factor::OneMinusDestAlpha, | 434 | Maxwell::Blend::Factor::OneMinusDestAlpha_D3D, |
| 431 | Maxwell::Blend::Factor::DestColor, | 435 | Maxwell::Blend::Factor::DestColor_D3D, |
| 432 | Maxwell::Blend::Factor::OneMinusDestColor, | 436 | Maxwell::Blend::Factor::OneMinusDestColor_D3D, |
| 433 | Maxwell::Blend::Factor::SourceAlphaSaturate, | 437 | Maxwell::Blend::Factor::SourceAlphaSaturate_D3D, |
| 434 | Maxwell::Blend::Factor::Source1Color, | 438 | Maxwell::Blend::Factor::Source1Color_D3D, |
| 435 | Maxwell::Blend::Factor::OneMinusSource1Color, | 439 | Maxwell::Blend::Factor::OneMinusSource1Color_D3D, |
| 436 | Maxwell::Blend::Factor::Source1Alpha, | 440 | Maxwell::Blend::Factor::Source1Alpha_D3D, |
| 437 | Maxwell::Blend::Factor::OneMinusSource1Alpha, | 441 | Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D, |
| 438 | Maxwell::Blend::Factor::ConstantColor, | 442 | Maxwell::Blend::Factor::BlendFactor_D3D, |
| 439 | Maxwell::Blend::Factor::OneMinusConstantColor, | 443 | Maxwell::Blend::Factor::OneMinusBlendFactor_D3D, |
| 440 | Maxwell::Blend::Factor::ConstantAlpha, | 444 | Maxwell::Blend::Factor::BothSourceAlpha_D3D, |
| 441 | Maxwell::Blend::Factor::OneMinusConstantAlpha, | 445 | Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D, |
| 442 | }; | 446 | }; |
| 447 | ASSERT(packed < LUT.size()); | ||
| 443 | return LUT[packed]; | 448 | return LUT[packed]; |
| 444 | } | 449 | } |
| 445 | 450 | ||
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index 9d60756e5..43441209c 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h | |||
| @@ -21,8 +21,8 @@ struct FixedPipelineState { | |||
| 21 | static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept; | 21 | static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept; |
| 22 | static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept; | 22 | static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept; |
| 23 | 23 | ||
| 24 | static u32 PackStencilOp(Maxwell::StencilOp op) noexcept; | 24 | static u32 PackStencilOp(Maxwell::StencilOp::Op op) noexcept; |
| 25 | static Maxwell::StencilOp UnpackStencilOp(u32 packed) noexcept; | 25 | static Maxwell::StencilOp::Op UnpackStencilOp(u32 packed) noexcept; |
| 26 | 26 | ||
| 27 | static u32 PackCullFace(Maxwell::CullFace cull) noexcept; | 27 | static u32 PackCullFace(Maxwell::CullFace cull) noexcept; |
| 28 | static Maxwell::CullFace UnpackCullFace(u32 packed) noexcept; | 28 | static Maxwell::CullFace UnpackCullFace(u32 packed) noexcept; |
| @@ -33,8 +33,8 @@ struct FixedPipelineState { | |||
| 33 | static u32 PackPolygonMode(Maxwell::PolygonMode mode) noexcept; | 33 | static u32 PackPolygonMode(Maxwell::PolygonMode mode) noexcept; |
| 34 | static Maxwell::PolygonMode UnpackPolygonMode(u32 packed) noexcept; | 34 | static Maxwell::PolygonMode UnpackPolygonMode(u32 packed) noexcept; |
| 35 | 35 | ||
| 36 | static u32 PackLogicOp(Maxwell::LogicOperation op) noexcept; | 36 | static u32 PackLogicOp(Maxwell::LogicOp::Op op) noexcept; |
| 37 | static Maxwell::LogicOperation UnpackLogicOp(u32 packed) noexcept; | 37 | static Maxwell::LogicOp::Op UnpackLogicOp(u32 packed) noexcept; |
| 38 | 38 | ||
| 39 | static u32 PackBlendEquation(Maxwell::Blend::Equation equation) noexcept; | 39 | static u32 PackBlendEquation(Maxwell::Blend::Equation equation) noexcept; |
| 40 | static Maxwell::Blend::Equation UnpackBlendEquation(u32 packed) noexcept; | 40 | static Maxwell::Blend::Equation UnpackBlendEquation(u32 packed) noexcept; |
| @@ -113,15 +113,15 @@ struct FixedPipelineState { | |||
| 113 | BitField<Position + 6, 3, u32> action_depth_pass; | 113 | BitField<Position + 6, 3, u32> action_depth_pass; |
| 114 | BitField<Position + 9, 3, u32> test_func; | 114 | BitField<Position + 9, 3, u32> test_func; |
| 115 | 115 | ||
| 116 | Maxwell::StencilOp ActionStencilFail() const noexcept { | 116 | Maxwell::StencilOp::Op ActionStencilFail() const noexcept { |
| 117 | return UnpackStencilOp(action_stencil_fail); | 117 | return UnpackStencilOp(action_stencil_fail); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | Maxwell::StencilOp ActionDepthFail() const noexcept { | 120 | Maxwell::StencilOp::Op ActionDepthFail() const noexcept { |
| 121 | return UnpackStencilOp(action_depth_fail); | 121 | return UnpackStencilOp(action_depth_fail); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | Maxwell::StencilOp ActionDepthPass() const noexcept { | 124 | Maxwell::StencilOp::Op ActionDepthPass() const noexcept { |
| 125 | return UnpackStencilOp(action_depth_pass); | 125 | return UnpackStencilOp(action_depth_pass); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| @@ -193,7 +193,6 @@ struct FixedPipelineState { | |||
| 193 | BitField<6, 5, u32> depth_format; | 193 | BitField<6, 5, u32> depth_format; |
| 194 | BitField<11, 1, u32> y_negate; | 194 | BitField<11, 1, u32> y_negate; |
| 195 | BitField<12, 1, u32> provoking_vertex_last; | 195 | BitField<12, 1, u32> provoking_vertex_last; |
| 196 | BitField<13, 1, u32> conservative_raster_enable; | ||
| 197 | BitField<14, 1, u32> smooth_lines; | 196 | BitField<14, 1, u32> smooth_lines; |
| 198 | }; | 197 | }; |
| 199 | std::array<u8, Maxwell::NumRenderTargets> color_formats; | 198 | std::array<u8, Maxwell::NumRenderTargets> color_formats; |
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index e7104d377..5c156087b 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp | |||
| @@ -323,161 +323,182 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, | |||
| 323 | Maxwell::VertexAttribute::Size size) { | 323 | Maxwell::VertexAttribute::Size size) { |
| 324 | const VkFormat format{([&]() { | 324 | const VkFormat format{([&]() { |
| 325 | switch (type) { | 325 | switch (type) { |
| 326 | case Maxwell::VertexAttribute::Type::UnsignedNorm: | 326 | case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway: |
| 327 | ASSERT_MSG(false, "Invalid vertex attribute type!"); | ||
| 328 | break; | ||
| 329 | case Maxwell::VertexAttribute::Type::UNorm: | ||
| 327 | switch (size) { | 330 | switch (size) { |
| 328 | case Maxwell::VertexAttribute::Size::Size_8: | 331 | case Maxwell::VertexAttribute::Size::Size_R8: |
| 332 | case Maxwell::VertexAttribute::Size::Size_A8: | ||
| 329 | return VK_FORMAT_R8_UNORM; | 333 | return VK_FORMAT_R8_UNORM; |
| 330 | case Maxwell::VertexAttribute::Size::Size_8_8: | 334 | case Maxwell::VertexAttribute::Size::Size_R8_G8: |
| 335 | case Maxwell::VertexAttribute::Size::Size_G8_R8: | ||
| 331 | return VK_FORMAT_R8G8_UNORM; | 336 | return VK_FORMAT_R8G8_UNORM; |
| 332 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | 337 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8: |
| 333 | return VK_FORMAT_R8G8B8_UNORM; | 338 | return VK_FORMAT_R8G8B8_UNORM; |
| 334 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 339 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8: |
| 340 | case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8: | ||
| 335 | return VK_FORMAT_R8G8B8A8_UNORM; | 341 | return VK_FORMAT_R8G8B8A8_UNORM; |
| 336 | case Maxwell::VertexAttribute::Size::Size_16: | 342 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 337 | return VK_FORMAT_R16_UNORM; | 343 | return VK_FORMAT_R16_UNORM; |
| 338 | case Maxwell::VertexAttribute::Size::Size_16_16: | 344 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 339 | return VK_FORMAT_R16G16_UNORM; | 345 | return VK_FORMAT_R16G16_UNORM; |
| 340 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 346 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 341 | return VK_FORMAT_R16G16B16_UNORM; | 347 | return VK_FORMAT_R16G16B16_UNORM; |
| 342 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 348 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 343 | return VK_FORMAT_R16G16B16A16_UNORM; | 349 | return VK_FORMAT_R16G16B16A16_UNORM; |
| 344 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 350 | case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10: |
| 345 | return VK_FORMAT_A2B10G10R10_UNORM_PACK32; | 351 | return VK_FORMAT_A2B10G10R10_UNORM_PACK32; |
| 346 | default: | 352 | default: |
| 347 | break; | 353 | break; |
| 348 | } | 354 | } |
| 349 | break; | 355 | break; |
| 350 | case Maxwell::VertexAttribute::Type::SignedNorm: | 356 | case Maxwell::VertexAttribute::Type::SNorm: |
| 351 | switch (size) { | 357 | switch (size) { |
| 352 | case Maxwell::VertexAttribute::Size::Size_8: | 358 | case Maxwell::VertexAttribute::Size::Size_R8: |
| 359 | case Maxwell::VertexAttribute::Size::Size_A8: | ||
| 353 | return VK_FORMAT_R8_SNORM; | 360 | return VK_FORMAT_R8_SNORM; |
| 354 | case Maxwell::VertexAttribute::Size::Size_8_8: | 361 | case Maxwell::VertexAttribute::Size::Size_R8_G8: |
| 362 | case Maxwell::VertexAttribute::Size::Size_G8_R8: | ||
| 355 | return VK_FORMAT_R8G8_SNORM; | 363 | return VK_FORMAT_R8G8_SNORM; |
| 356 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | 364 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8: |
| 357 | return VK_FORMAT_R8G8B8_SNORM; | 365 | return VK_FORMAT_R8G8B8_SNORM; |
| 358 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 366 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8: |
| 367 | case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8: | ||
| 359 | return VK_FORMAT_R8G8B8A8_SNORM; | 368 | return VK_FORMAT_R8G8B8A8_SNORM; |
| 360 | case Maxwell::VertexAttribute::Size::Size_16: | 369 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 361 | return VK_FORMAT_R16_SNORM; | 370 | return VK_FORMAT_R16_SNORM; |
| 362 | case Maxwell::VertexAttribute::Size::Size_16_16: | 371 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 363 | return VK_FORMAT_R16G16_SNORM; | 372 | return VK_FORMAT_R16G16_SNORM; |
| 364 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 373 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 365 | return VK_FORMAT_R16G16B16_SNORM; | 374 | return VK_FORMAT_R16G16B16_SNORM; |
| 366 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 375 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 367 | return VK_FORMAT_R16G16B16A16_SNORM; | 376 | return VK_FORMAT_R16G16B16A16_SNORM; |
| 368 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 377 | case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10: |
| 369 | return VK_FORMAT_A2B10G10R10_SNORM_PACK32; | 378 | return VK_FORMAT_A2B10G10R10_SNORM_PACK32; |
| 370 | default: | 379 | default: |
| 371 | break; | 380 | break; |
| 372 | } | 381 | } |
| 373 | break; | 382 | break; |
| 374 | case Maxwell::VertexAttribute::Type::UnsignedScaled: | 383 | case Maxwell::VertexAttribute::Type::UScaled: |
| 375 | switch (size) { | 384 | switch (size) { |
| 376 | case Maxwell::VertexAttribute::Size::Size_8: | 385 | case Maxwell::VertexAttribute::Size::Size_R8: |
| 386 | case Maxwell::VertexAttribute::Size::Size_A8: | ||
| 377 | return VK_FORMAT_R8_USCALED; | 387 | return VK_FORMAT_R8_USCALED; |
| 378 | case Maxwell::VertexAttribute::Size::Size_8_8: | 388 | case Maxwell::VertexAttribute::Size::Size_R8_G8: |
| 389 | case Maxwell::VertexAttribute::Size::Size_G8_R8: | ||
| 379 | return VK_FORMAT_R8G8_USCALED; | 390 | return VK_FORMAT_R8G8_USCALED; |
| 380 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | 391 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8: |
| 381 | return VK_FORMAT_R8G8B8_USCALED; | 392 | return VK_FORMAT_R8G8B8_USCALED; |
| 382 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 393 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8: |
| 394 | case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8: | ||
| 383 | return VK_FORMAT_R8G8B8A8_USCALED; | 395 | return VK_FORMAT_R8G8B8A8_USCALED; |
| 384 | case Maxwell::VertexAttribute::Size::Size_16: | 396 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 385 | return VK_FORMAT_R16_USCALED; | 397 | return VK_FORMAT_R16_USCALED; |
| 386 | case Maxwell::VertexAttribute::Size::Size_16_16: | 398 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 387 | return VK_FORMAT_R16G16_USCALED; | 399 | return VK_FORMAT_R16G16_USCALED; |
| 388 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 400 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 389 | return VK_FORMAT_R16G16B16_USCALED; | 401 | return VK_FORMAT_R16G16B16_USCALED; |
| 390 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 402 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 391 | return VK_FORMAT_R16G16B16A16_USCALED; | 403 | return VK_FORMAT_R16G16B16A16_USCALED; |
| 392 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 404 | case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10: |
| 393 | return VK_FORMAT_A2B10G10R10_USCALED_PACK32; | 405 | return VK_FORMAT_A2B10G10R10_USCALED_PACK32; |
| 394 | default: | 406 | default: |
| 395 | break; | 407 | break; |
| 396 | } | 408 | } |
| 397 | break; | 409 | break; |
| 398 | case Maxwell::VertexAttribute::Type::SignedScaled: | 410 | case Maxwell::VertexAttribute::Type::SScaled: |
| 399 | switch (size) { | 411 | switch (size) { |
| 400 | case Maxwell::VertexAttribute::Size::Size_8: | 412 | case Maxwell::VertexAttribute::Size::Size_R8: |
| 413 | case Maxwell::VertexAttribute::Size::Size_A8: | ||
| 401 | return VK_FORMAT_R8_SSCALED; | 414 | return VK_FORMAT_R8_SSCALED; |
| 402 | case Maxwell::VertexAttribute::Size::Size_8_8: | 415 | case Maxwell::VertexAttribute::Size::Size_R8_G8: |
| 416 | case Maxwell::VertexAttribute::Size::Size_G8_R8: | ||
| 403 | return VK_FORMAT_R8G8_SSCALED; | 417 | return VK_FORMAT_R8G8_SSCALED; |
| 404 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | 418 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8: |
| 405 | return VK_FORMAT_R8G8B8_SSCALED; | 419 | return VK_FORMAT_R8G8B8_SSCALED; |
| 406 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 420 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8: |
| 421 | case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8: | ||
| 407 | return VK_FORMAT_R8G8B8A8_SSCALED; | 422 | return VK_FORMAT_R8G8B8A8_SSCALED; |
| 408 | case Maxwell::VertexAttribute::Size::Size_16: | 423 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 409 | return VK_FORMAT_R16_SSCALED; | 424 | return VK_FORMAT_R16_SSCALED; |
| 410 | case Maxwell::VertexAttribute::Size::Size_16_16: | 425 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 411 | return VK_FORMAT_R16G16_SSCALED; | 426 | return VK_FORMAT_R16G16_SSCALED; |
| 412 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 427 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 413 | return VK_FORMAT_R16G16B16_SSCALED; | 428 | return VK_FORMAT_R16G16B16_SSCALED; |
| 414 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 429 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 415 | return VK_FORMAT_R16G16B16A16_SSCALED; | 430 | return VK_FORMAT_R16G16B16A16_SSCALED; |
| 416 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 431 | case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10: |
| 417 | return VK_FORMAT_A2B10G10R10_SSCALED_PACK32; | 432 | return VK_FORMAT_A2B10G10R10_SSCALED_PACK32; |
| 418 | default: | 433 | default: |
| 419 | break; | 434 | break; |
| 420 | } | 435 | } |
| 421 | break; | 436 | break; |
| 422 | case Maxwell::VertexAttribute::Type::UnsignedInt: | 437 | case Maxwell::VertexAttribute::Type::UInt: |
| 423 | switch (size) { | 438 | switch (size) { |
| 424 | case Maxwell::VertexAttribute::Size::Size_8: | 439 | case Maxwell::VertexAttribute::Size::Size_R8: |
| 440 | case Maxwell::VertexAttribute::Size::Size_A8: | ||
| 425 | return VK_FORMAT_R8_UINT; | 441 | return VK_FORMAT_R8_UINT; |
| 426 | case Maxwell::VertexAttribute::Size::Size_8_8: | 442 | case Maxwell::VertexAttribute::Size::Size_R8_G8: |
| 443 | case Maxwell::VertexAttribute::Size::Size_G8_R8: | ||
| 427 | return VK_FORMAT_R8G8_UINT; | 444 | return VK_FORMAT_R8G8_UINT; |
| 428 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | 445 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8: |
| 429 | return VK_FORMAT_R8G8B8_UINT; | 446 | return VK_FORMAT_R8G8B8_UINT; |
| 430 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 447 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8: |
| 448 | case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8: | ||
| 431 | return VK_FORMAT_R8G8B8A8_UINT; | 449 | return VK_FORMAT_R8G8B8A8_UINT; |
| 432 | case Maxwell::VertexAttribute::Size::Size_16: | 450 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 433 | return VK_FORMAT_R16_UINT; | 451 | return VK_FORMAT_R16_UINT; |
| 434 | case Maxwell::VertexAttribute::Size::Size_16_16: | 452 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 435 | return VK_FORMAT_R16G16_UINT; | 453 | return VK_FORMAT_R16G16_UINT; |
| 436 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 454 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 437 | return VK_FORMAT_R16G16B16_UINT; | 455 | return VK_FORMAT_R16G16B16_UINT; |
| 438 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 456 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 439 | return VK_FORMAT_R16G16B16A16_UINT; | 457 | return VK_FORMAT_R16G16B16A16_UINT; |
| 440 | case Maxwell::VertexAttribute::Size::Size_32: | 458 | case Maxwell::VertexAttribute::Size::Size_R32: |
| 441 | return VK_FORMAT_R32_UINT; | 459 | return VK_FORMAT_R32_UINT; |
| 442 | case Maxwell::VertexAttribute::Size::Size_32_32: | 460 | case Maxwell::VertexAttribute::Size::Size_R32_G32: |
| 443 | return VK_FORMAT_R32G32_UINT; | 461 | return VK_FORMAT_R32G32_UINT; |
| 444 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | 462 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32: |
| 445 | return VK_FORMAT_R32G32B32_UINT; | 463 | return VK_FORMAT_R32G32B32_UINT; |
| 446 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | 464 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32: |
| 447 | return VK_FORMAT_R32G32B32A32_UINT; | 465 | return VK_FORMAT_R32G32B32A32_UINT; |
| 448 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 466 | case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10: |
| 449 | return VK_FORMAT_A2B10G10R10_UINT_PACK32; | 467 | return VK_FORMAT_A2B10G10R10_UINT_PACK32; |
| 450 | default: | 468 | default: |
| 451 | break; | 469 | break; |
| 452 | } | 470 | } |
| 453 | break; | 471 | break; |
| 454 | case Maxwell::VertexAttribute::Type::SignedInt: | 472 | case Maxwell::VertexAttribute::Type::SInt: |
| 455 | switch (size) { | 473 | switch (size) { |
| 456 | case Maxwell::VertexAttribute::Size::Size_8: | 474 | case Maxwell::VertexAttribute::Size::Size_R8: |
| 475 | case Maxwell::VertexAttribute::Size::Size_A8: | ||
| 457 | return VK_FORMAT_R8_SINT; | 476 | return VK_FORMAT_R8_SINT; |
| 458 | case Maxwell::VertexAttribute::Size::Size_8_8: | 477 | case Maxwell::VertexAttribute::Size::Size_R8_G8: |
| 478 | case Maxwell::VertexAttribute::Size::Size_G8_R8: | ||
| 459 | return VK_FORMAT_R8G8_SINT; | 479 | return VK_FORMAT_R8G8_SINT; |
| 460 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | 480 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8: |
| 461 | return VK_FORMAT_R8G8B8_SINT; | 481 | return VK_FORMAT_R8G8B8_SINT; |
| 462 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 482 | case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8: |
| 483 | case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8: | ||
| 463 | return VK_FORMAT_R8G8B8A8_SINT; | 484 | return VK_FORMAT_R8G8B8A8_SINT; |
| 464 | case Maxwell::VertexAttribute::Size::Size_16: | 485 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 465 | return VK_FORMAT_R16_SINT; | 486 | return VK_FORMAT_R16_SINT; |
| 466 | case Maxwell::VertexAttribute::Size::Size_16_16: | 487 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 467 | return VK_FORMAT_R16G16_SINT; | 488 | return VK_FORMAT_R16G16_SINT; |
| 468 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 489 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 469 | return VK_FORMAT_R16G16B16_SINT; | 490 | return VK_FORMAT_R16G16B16_SINT; |
| 470 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 491 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 471 | return VK_FORMAT_R16G16B16A16_SINT; | 492 | return VK_FORMAT_R16G16B16A16_SINT; |
| 472 | case Maxwell::VertexAttribute::Size::Size_32: | 493 | case Maxwell::VertexAttribute::Size::Size_R32: |
| 473 | return VK_FORMAT_R32_SINT; | 494 | return VK_FORMAT_R32_SINT; |
| 474 | case Maxwell::VertexAttribute::Size::Size_32_32: | 495 | case Maxwell::VertexAttribute::Size::Size_R32_G32: |
| 475 | return VK_FORMAT_R32G32_SINT; | 496 | return VK_FORMAT_R32G32_SINT; |
| 476 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | 497 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32: |
| 477 | return VK_FORMAT_R32G32B32_SINT; | 498 | return VK_FORMAT_R32G32B32_SINT; |
| 478 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | 499 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32: |
| 479 | return VK_FORMAT_R32G32B32A32_SINT; | 500 | return VK_FORMAT_R32G32B32A32_SINT; |
| 480 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 501 | case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10: |
| 481 | return VK_FORMAT_A2B10G10R10_SINT_PACK32; | 502 | return VK_FORMAT_A2B10G10R10_SINT_PACK32; |
| 482 | default: | 503 | default: |
| 483 | break; | 504 | break; |
| @@ -485,23 +506,23 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, | |||
| 485 | break; | 506 | break; |
| 486 | case Maxwell::VertexAttribute::Type::Float: | 507 | case Maxwell::VertexAttribute::Type::Float: |
| 487 | switch (size) { | 508 | switch (size) { |
| 488 | case Maxwell::VertexAttribute::Size::Size_16: | 509 | case Maxwell::VertexAttribute::Size::Size_R16: |
| 489 | return VK_FORMAT_R16_SFLOAT; | 510 | return VK_FORMAT_R16_SFLOAT; |
| 490 | case Maxwell::VertexAttribute::Size::Size_16_16: | 511 | case Maxwell::VertexAttribute::Size::Size_R16_G16: |
| 491 | return VK_FORMAT_R16G16_SFLOAT; | 512 | return VK_FORMAT_R16G16_SFLOAT; |
| 492 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | 513 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16: |
| 493 | return VK_FORMAT_R16G16B16_SFLOAT; | 514 | return VK_FORMAT_R16G16B16_SFLOAT; |
| 494 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 515 | case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16: |
| 495 | return VK_FORMAT_R16G16B16A16_SFLOAT; | 516 | return VK_FORMAT_R16G16B16A16_SFLOAT; |
| 496 | case Maxwell::VertexAttribute::Size::Size_32: | 517 | case Maxwell::VertexAttribute::Size::Size_R32: |
| 497 | return VK_FORMAT_R32_SFLOAT; | 518 | return VK_FORMAT_R32_SFLOAT; |
| 498 | case Maxwell::VertexAttribute::Size::Size_32_32: | 519 | case Maxwell::VertexAttribute::Size::Size_R32_G32: |
| 499 | return VK_FORMAT_R32G32_SFLOAT; | 520 | return VK_FORMAT_R32G32_SFLOAT; |
| 500 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | 521 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32: |
| 501 | return VK_FORMAT_R32G32B32_SFLOAT; | 522 | return VK_FORMAT_R32G32B32_SFLOAT; |
| 502 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | 523 | case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32: |
| 503 | return VK_FORMAT_R32G32B32A32_SFLOAT; | 524 | return VK_FORMAT_R32G32B32A32_SFLOAT; |
| 504 | case Maxwell::VertexAttribute::Size::Size_11_11_10: | 525 | case Maxwell::VertexAttribute::Size::Size_B10_G11_R11: |
| 505 | return VK_FORMAT_B10G11R11_UFLOAT_PACK32; | 526 | return VK_FORMAT_B10G11R11_UFLOAT_PACK32; |
| 506 | default: | 527 | default: |
| 507 | break; | 528 | break; |
| @@ -521,29 +542,29 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, | |||
| 521 | 542 | ||
| 522 | VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison) { | 543 | VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison) { |
| 523 | switch (comparison) { | 544 | switch (comparison) { |
| 524 | case Maxwell::ComparisonOp::Never: | 545 | case Maxwell::ComparisonOp::Never_D3D: |
| 525 | case Maxwell::ComparisonOp::NeverOld: | 546 | case Maxwell::ComparisonOp::Never_GL: |
| 526 | return VK_COMPARE_OP_NEVER; | 547 | return VK_COMPARE_OP_NEVER; |
| 527 | case Maxwell::ComparisonOp::Less: | 548 | case Maxwell::ComparisonOp::Less_D3D: |
| 528 | case Maxwell::ComparisonOp::LessOld: | 549 | case Maxwell::ComparisonOp::Less_GL: |
| 529 | return VK_COMPARE_OP_LESS; | 550 | return VK_COMPARE_OP_LESS; |
| 530 | case Maxwell::ComparisonOp::Equal: | 551 | case Maxwell::ComparisonOp::Equal_D3D: |
| 531 | case Maxwell::ComparisonOp::EqualOld: | 552 | case Maxwell::ComparisonOp::Equal_GL: |
| 532 | return VK_COMPARE_OP_EQUAL; | 553 | return VK_COMPARE_OP_EQUAL; |
| 533 | case Maxwell::ComparisonOp::LessEqual: | 554 | case Maxwell::ComparisonOp::LessEqual_D3D: |
| 534 | case Maxwell::ComparisonOp::LessEqualOld: | 555 | case Maxwell::ComparisonOp::LessEqual_GL: |
| 535 | return VK_COMPARE_OP_LESS_OR_EQUAL; | 556 | return VK_COMPARE_OP_LESS_OR_EQUAL; |
| 536 | case Maxwell::ComparisonOp::Greater: | 557 | case Maxwell::ComparisonOp::Greater_D3D: |
| 537 | case Maxwell::ComparisonOp::GreaterOld: | 558 | case Maxwell::ComparisonOp::Greater_GL: |
| 538 | return VK_COMPARE_OP_GREATER; | 559 | return VK_COMPARE_OP_GREATER; |
| 539 | case Maxwell::ComparisonOp::NotEqual: | 560 | case Maxwell::ComparisonOp::NotEqual_D3D: |
| 540 | case Maxwell::ComparisonOp::NotEqualOld: | 561 | case Maxwell::ComparisonOp::NotEqual_GL: |
| 541 | return VK_COMPARE_OP_NOT_EQUAL; | 562 | return VK_COMPARE_OP_NOT_EQUAL; |
| 542 | case Maxwell::ComparisonOp::GreaterEqual: | 563 | case Maxwell::ComparisonOp::GreaterEqual_D3D: |
| 543 | case Maxwell::ComparisonOp::GreaterEqualOld: | 564 | case Maxwell::ComparisonOp::GreaterEqual_GL: |
| 544 | return VK_COMPARE_OP_GREATER_OR_EQUAL; | 565 | return VK_COMPARE_OP_GREATER_OR_EQUAL; |
| 545 | case Maxwell::ComparisonOp::Always: | 566 | case Maxwell::ComparisonOp::Always_D3D: |
| 546 | case Maxwell::ComparisonOp::AlwaysOld: | 567 | case Maxwell::ComparisonOp::Always_GL: |
| 547 | return VK_COMPARE_OP_ALWAYS; | 568 | return VK_COMPARE_OP_ALWAYS; |
| 548 | } | 569 | } |
| 549 | UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); | 570 | UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); |
| @@ -563,31 +584,31 @@ VkIndexType IndexFormat(Maxwell::IndexFormat index_format) { | |||
| 563 | return {}; | 584 | return {}; |
| 564 | } | 585 | } |
| 565 | 586 | ||
| 566 | VkStencilOp StencilOp(Maxwell::StencilOp stencil_op) { | 587 | VkStencilOp StencilOp(Maxwell::StencilOp::Op stencil_op) { |
| 567 | switch (stencil_op) { | 588 | switch (stencil_op) { |
| 568 | case Maxwell::StencilOp::Keep: | 589 | case Maxwell::StencilOp::Op::Keep_D3D: |
| 569 | case Maxwell::StencilOp::KeepOGL: | 590 | case Maxwell::StencilOp::Op::Keep_GL: |
| 570 | return VK_STENCIL_OP_KEEP; | 591 | return VK_STENCIL_OP_KEEP; |
| 571 | case Maxwell::StencilOp::Zero: | 592 | case Maxwell::StencilOp::Op::Zero_D3D: |
| 572 | case Maxwell::StencilOp::ZeroOGL: | 593 | case Maxwell::StencilOp::Op::Zero_GL: |
| 573 | return VK_STENCIL_OP_ZERO; | 594 | return VK_STENCIL_OP_ZERO; |
| 574 | case Maxwell::StencilOp::Replace: | 595 | case Maxwell::StencilOp::Op::Replace_D3D: |
| 575 | case Maxwell::StencilOp::ReplaceOGL: | 596 | case Maxwell::StencilOp::Op::Replace_GL: |
| 576 | return VK_STENCIL_OP_REPLACE; | 597 | return VK_STENCIL_OP_REPLACE; |
| 577 | case Maxwell::StencilOp::Incr: | 598 | case Maxwell::StencilOp::Op::IncrSaturate_D3D: |
| 578 | case Maxwell::StencilOp::IncrOGL: | 599 | case Maxwell::StencilOp::Op::IncrSaturate_GL: |
| 579 | return VK_STENCIL_OP_INCREMENT_AND_CLAMP; | 600 | return VK_STENCIL_OP_INCREMENT_AND_CLAMP; |
| 580 | case Maxwell::StencilOp::Decr: | 601 | case Maxwell::StencilOp::Op::DecrSaturate_D3D: |
| 581 | case Maxwell::StencilOp::DecrOGL: | 602 | case Maxwell::StencilOp::Op::DecrSaturate_GL: |
| 582 | return VK_STENCIL_OP_DECREMENT_AND_CLAMP; | 603 | return VK_STENCIL_OP_DECREMENT_AND_CLAMP; |
| 583 | case Maxwell::StencilOp::Invert: | 604 | case Maxwell::StencilOp::Op::Invert_D3D: |
| 584 | case Maxwell::StencilOp::InvertOGL: | 605 | case Maxwell::StencilOp::Op::Invert_GL: |
| 585 | return VK_STENCIL_OP_INVERT; | 606 | return VK_STENCIL_OP_INVERT; |
| 586 | case Maxwell::StencilOp::IncrWrap: | 607 | case Maxwell::StencilOp::Op::Incr_D3D: |
| 587 | case Maxwell::StencilOp::IncrWrapOGL: | 608 | case Maxwell::StencilOp::Op::Incr_GL: |
| 588 | return VK_STENCIL_OP_INCREMENT_AND_WRAP; | 609 | return VK_STENCIL_OP_INCREMENT_AND_WRAP; |
| 589 | case Maxwell::StencilOp::DecrWrap: | 610 | case Maxwell::StencilOp::Op::Decr_D3D: |
| 590 | case Maxwell::StencilOp::DecrWrapOGL: | 611 | case Maxwell::StencilOp::Op::Decr_GL: |
| 591 | return VK_STENCIL_OP_DECREMENT_AND_WRAP; | 612 | return VK_STENCIL_OP_DECREMENT_AND_WRAP; |
| 592 | } | 613 | } |
| 593 | UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil_op); | 614 | UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil_op); |
| @@ -596,20 +617,20 @@ VkStencilOp StencilOp(Maxwell::StencilOp stencil_op) { | |||
| 596 | 617 | ||
| 597 | VkBlendOp BlendEquation(Maxwell::Blend::Equation equation) { | 618 | VkBlendOp BlendEquation(Maxwell::Blend::Equation equation) { |
| 598 | switch (equation) { | 619 | switch (equation) { |
| 599 | case Maxwell::Blend::Equation::Add: | 620 | case Maxwell::Blend::Equation::Add_D3D: |
| 600 | case Maxwell::Blend::Equation::AddGL: | 621 | case Maxwell::Blend::Equation::Add_GL: |
| 601 | return VK_BLEND_OP_ADD; | 622 | return VK_BLEND_OP_ADD; |
| 602 | case Maxwell::Blend::Equation::Subtract: | 623 | case Maxwell::Blend::Equation::Subtract_D3D: |
| 603 | case Maxwell::Blend::Equation::SubtractGL: | 624 | case Maxwell::Blend::Equation::Subtract_GL: |
| 604 | return VK_BLEND_OP_SUBTRACT; | 625 | return VK_BLEND_OP_SUBTRACT; |
| 605 | case Maxwell::Blend::Equation::ReverseSubtract: | 626 | case Maxwell::Blend::Equation::ReverseSubtract_D3D: |
| 606 | case Maxwell::Blend::Equation::ReverseSubtractGL: | 627 | case Maxwell::Blend::Equation::ReverseSubtract_GL: |
| 607 | return VK_BLEND_OP_REVERSE_SUBTRACT; | 628 | return VK_BLEND_OP_REVERSE_SUBTRACT; |
| 608 | case Maxwell::Blend::Equation::Min: | 629 | case Maxwell::Blend::Equation::Min_D3D: |
| 609 | case Maxwell::Blend::Equation::MinGL: | 630 | case Maxwell::Blend::Equation::Min_GL: |
| 610 | return VK_BLEND_OP_MIN; | 631 | return VK_BLEND_OP_MIN; |
| 611 | case Maxwell::Blend::Equation::Max: | 632 | case Maxwell::Blend::Equation::Max_D3D: |
| 612 | case Maxwell::Blend::Equation::MaxGL: | 633 | case Maxwell::Blend::Equation::Max_GL: |
| 613 | return VK_BLEND_OP_MAX; | 634 | return VK_BLEND_OP_MAX; |
| 614 | } | 635 | } |
| 615 | UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation); | 636 | UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation); |
| @@ -618,62 +639,62 @@ VkBlendOp BlendEquation(Maxwell::Blend::Equation equation) { | |||
| 618 | 639 | ||
| 619 | VkBlendFactor BlendFactor(Maxwell::Blend::Factor factor) { | 640 | VkBlendFactor BlendFactor(Maxwell::Blend::Factor factor) { |
| 620 | switch (factor) { | 641 | switch (factor) { |
| 621 | case Maxwell::Blend::Factor::Zero: | 642 | case Maxwell::Blend::Factor::Zero_D3D: |
| 622 | case Maxwell::Blend::Factor::ZeroGL: | 643 | case Maxwell::Blend::Factor::Zero_GL: |
| 623 | return VK_BLEND_FACTOR_ZERO; | 644 | return VK_BLEND_FACTOR_ZERO; |
| 624 | case Maxwell::Blend::Factor::One: | 645 | case Maxwell::Blend::Factor::One_D3D: |
| 625 | case Maxwell::Blend::Factor::OneGL: | 646 | case Maxwell::Blend::Factor::One_GL: |
| 626 | return VK_BLEND_FACTOR_ONE; | 647 | return VK_BLEND_FACTOR_ONE; |
| 627 | case Maxwell::Blend::Factor::SourceColor: | 648 | case Maxwell::Blend::Factor::SourceColor_D3D: |
| 628 | case Maxwell::Blend::Factor::SourceColorGL: | 649 | case Maxwell::Blend::Factor::SourceColor_GL: |
| 629 | return VK_BLEND_FACTOR_SRC_COLOR; | 650 | return VK_BLEND_FACTOR_SRC_COLOR; |
| 630 | case Maxwell::Blend::Factor::OneMinusSourceColor: | 651 | case Maxwell::Blend::Factor::OneMinusSourceColor_D3D: |
| 631 | case Maxwell::Blend::Factor::OneMinusSourceColorGL: | 652 | case Maxwell::Blend::Factor::OneMinusSourceColor_GL: |
| 632 | return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; | 653 | return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; |
| 633 | case Maxwell::Blend::Factor::SourceAlpha: | 654 | case Maxwell::Blend::Factor::SourceAlpha_D3D: |
| 634 | case Maxwell::Blend::Factor::SourceAlphaGL: | 655 | case Maxwell::Blend::Factor::SourceAlpha_GL: |
| 635 | return VK_BLEND_FACTOR_SRC_ALPHA; | 656 | return VK_BLEND_FACTOR_SRC_ALPHA; |
| 636 | case Maxwell::Blend::Factor::OneMinusSourceAlpha: | 657 | case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D: |
| 637 | case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: | 658 | case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL: |
| 638 | return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; | 659 | return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; |
| 639 | case Maxwell::Blend::Factor::DestAlpha: | 660 | case Maxwell::Blend::Factor::DestAlpha_D3D: |
| 640 | case Maxwell::Blend::Factor::DestAlphaGL: | 661 | case Maxwell::Blend::Factor::DestAlpha_GL: |
| 641 | return VK_BLEND_FACTOR_DST_ALPHA; | 662 | return VK_BLEND_FACTOR_DST_ALPHA; |
| 642 | case Maxwell::Blend::Factor::OneMinusDestAlpha: | 663 | case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D: |
| 643 | case Maxwell::Blend::Factor::OneMinusDestAlphaGL: | 664 | case Maxwell::Blend::Factor::OneMinusDestAlpha_GL: |
| 644 | return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; | 665 | return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; |
| 645 | case Maxwell::Blend::Factor::DestColor: | 666 | case Maxwell::Blend::Factor::DestColor_D3D: |
| 646 | case Maxwell::Blend::Factor::DestColorGL: | 667 | case Maxwell::Blend::Factor::DestColor_GL: |
| 647 | return VK_BLEND_FACTOR_DST_COLOR; | 668 | return VK_BLEND_FACTOR_DST_COLOR; |
| 648 | case Maxwell::Blend::Factor::OneMinusDestColor: | 669 | case Maxwell::Blend::Factor::OneMinusDestColor_D3D: |
| 649 | case Maxwell::Blend::Factor::OneMinusDestColorGL: | 670 | case Maxwell::Blend::Factor::OneMinusDestColor_GL: |
| 650 | return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; | 671 | return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; |
| 651 | case Maxwell::Blend::Factor::SourceAlphaSaturate: | 672 | case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D: |
| 652 | case Maxwell::Blend::Factor::SourceAlphaSaturateGL: | 673 | case Maxwell::Blend::Factor::SourceAlphaSaturate_GL: |
| 653 | return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE; | 674 | return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE; |
| 654 | case Maxwell::Blend::Factor::Source1Color: | 675 | case Maxwell::Blend::Factor::Source1Color_D3D: |
| 655 | case Maxwell::Blend::Factor::Source1ColorGL: | 676 | case Maxwell::Blend::Factor::Source1Color_GL: |
| 656 | return VK_BLEND_FACTOR_SRC1_COLOR; | 677 | return VK_BLEND_FACTOR_SRC1_COLOR; |
| 657 | case Maxwell::Blend::Factor::OneMinusSource1Color: | 678 | case Maxwell::Blend::Factor::OneMinusSource1Color_D3D: |
| 658 | case Maxwell::Blend::Factor::OneMinusSource1ColorGL: | 679 | case Maxwell::Blend::Factor::OneMinusSource1Color_GL: |
| 659 | return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR; | 680 | return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR; |
| 660 | case Maxwell::Blend::Factor::Source1Alpha: | 681 | case Maxwell::Blend::Factor::Source1Alpha_D3D: |
| 661 | case Maxwell::Blend::Factor::Source1AlphaGL: | 682 | case Maxwell::Blend::Factor::Source1Alpha_GL: |
| 662 | return VK_BLEND_FACTOR_SRC1_ALPHA; | 683 | return VK_BLEND_FACTOR_SRC1_ALPHA; |
| 663 | case Maxwell::Blend::Factor::OneMinusSource1Alpha: | 684 | case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D: |
| 664 | case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: | 685 | case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL: |
| 665 | return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA; | 686 | return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA; |
| 666 | case Maxwell::Blend::Factor::ConstantColor: | 687 | case Maxwell::Blend::Factor::BlendFactor_D3D: |
| 667 | case Maxwell::Blend::Factor::ConstantColorGL: | 688 | case Maxwell::Blend::Factor::ConstantColor_GL: |
| 668 | return VK_BLEND_FACTOR_CONSTANT_COLOR; | 689 | return VK_BLEND_FACTOR_CONSTANT_COLOR; |
| 669 | case Maxwell::Blend::Factor::OneMinusConstantColor: | 690 | case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D: |
| 670 | case Maxwell::Blend::Factor::OneMinusConstantColorGL: | 691 | case Maxwell::Blend::Factor::OneMinusConstantColor_GL: |
| 671 | return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; | 692 | return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; |
| 672 | case Maxwell::Blend::Factor::ConstantAlpha: | 693 | case Maxwell::Blend::Factor::BothSourceAlpha_D3D: |
| 673 | case Maxwell::Blend::Factor::ConstantAlphaGL: | 694 | case Maxwell::Blend::Factor::ConstantAlpha_GL: |
| 674 | return VK_BLEND_FACTOR_CONSTANT_ALPHA; | 695 | return VK_BLEND_FACTOR_CONSTANT_ALPHA; |
| 675 | case Maxwell::Blend::Factor::OneMinusConstantAlpha: | 696 | case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D: |
| 676 | case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: | 697 | case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL: |
| 677 | return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA; | 698 | return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA; |
| 678 | } | 699 | } |
| 679 | UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor); | 700 | UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor); |
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h index 356d46292..6f65502d6 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.h +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h | |||
| @@ -55,7 +55,7 @@ VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison); | |||
| 55 | 55 | ||
| 56 | VkIndexType IndexFormat(Maxwell::IndexFormat index_format); | 56 | VkIndexType IndexFormat(Maxwell::IndexFormat index_format); |
| 57 | 57 | ||
| 58 | VkStencilOp StencilOp(Maxwell::StencilOp stencil_op); | 58 | VkStencilOp StencilOp(Maxwell::StencilOp::Op stencil_op); |
| 59 | 59 | ||
| 60 | VkBlendOp BlendEquation(Maxwell::Blend::Equation equation); | 60 | VkBlendOp BlendEquation(Maxwell::Blend::Equation equation); |
| 61 | 61 | ||
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index f47786f48..c3f66c8a3 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -288,7 +288,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 288 | buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes); | 288 | buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes); |
| 289 | 289 | ||
| 290 | const auto& regs{maxwell3d->regs}; | 290 | const auto& regs{maxwell3d->regs}; |
| 291 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; | 291 | const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding}; |
| 292 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { | 292 | const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 293 | const Shader::Info& info{stage_infos[stage]}; | 293 | const Shader::Info& info{stage_infos[stage]}; |
| 294 | buffer_cache.UnbindGraphicsStorageBuffers(stage); | 294 | buffer_cache.UnbindGraphicsStorageBuffers(stage); |
| @@ -664,15 +664,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 664 | .lineStippleFactor = 0, | 664 | .lineStippleFactor = 0, |
| 665 | .lineStipplePattern = 0, | 665 | .lineStipplePattern = 0, |
| 666 | }; | 666 | }; |
| 667 | VkPipelineRasterizationConservativeStateCreateInfoEXT conservative_raster{ | ||
| 668 | .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, | ||
| 669 | .pNext = nullptr, | ||
| 670 | .flags = 0, | ||
| 671 | .conservativeRasterizationMode = key.state.conservative_raster_enable != 0 | ||
| 672 | ? VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT | ||
| 673 | : VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT, | ||
| 674 | .extraPrimitiveOverestimationSize = 0.0f, | ||
| 675 | }; | ||
| 676 | VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_vertex{ | 667 | VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_vertex{ |
| 677 | .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT, | 668 | .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT, |
| 678 | .pNext = nullptr, | 669 | .pNext = nullptr, |
| @@ -683,9 +674,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { | |||
| 683 | if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) { | 674 | if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) { |
| 684 | line_state.pNext = std::exchange(rasterization_ci.pNext, &line_state); | 675 | line_state.pNext = std::exchange(rasterization_ci.pNext, &line_state); |
| 685 | } | 676 | } |
| 686 | if (device.IsExtConservativeRasterizationSupported()) { | ||
| 687 | conservative_raster.pNext = std::exchange(rasterization_ci.pNext, &conservative_raster); | ||
| 688 | } | ||
| 689 | if (device.IsExtProvokingVertexSupported()) { | 677 | if (device.IsExtProvokingVertexSupported()) { |
| 690 | provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex); | 678 | provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex); |
| 691 | } | 679 | } |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 732e7b6f2..20f1d6584 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -62,29 +62,29 @@ auto MakeSpan(Container& container) { | |||
| 62 | 62 | ||
| 63 | Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) { | 63 | Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) { |
| 64 | switch (comparison) { | 64 | switch (comparison) { |
| 65 | case Maxwell::ComparisonOp::Never: | 65 | case Maxwell::ComparisonOp::Never_D3D: |
| 66 | case Maxwell::ComparisonOp::NeverOld: | 66 | case Maxwell::ComparisonOp::Never_GL: |
| 67 | return Shader::CompareFunction::Never; | 67 | return Shader::CompareFunction::Never; |
| 68 | case Maxwell::ComparisonOp::Less: | 68 | case Maxwell::ComparisonOp::Less_D3D: |
| 69 | case Maxwell::ComparisonOp::LessOld: | 69 | case Maxwell::ComparisonOp::Less_GL: |
| 70 | return Shader::CompareFunction::Less; | 70 | return Shader::CompareFunction::Less; |
| 71 | case Maxwell::ComparisonOp::Equal: | 71 | case Maxwell::ComparisonOp::Equal_D3D: |
| 72 | case Maxwell::ComparisonOp::EqualOld: | 72 | case Maxwell::ComparisonOp::Equal_GL: |
| 73 | return Shader::CompareFunction::Equal; | 73 | return Shader::CompareFunction::Equal; |
| 74 | case Maxwell::ComparisonOp::LessEqual: | 74 | case Maxwell::ComparisonOp::LessEqual_D3D: |
| 75 | case Maxwell::ComparisonOp::LessEqualOld: | 75 | case Maxwell::ComparisonOp::LessEqual_GL: |
| 76 | return Shader::CompareFunction::LessThanEqual; | 76 | return Shader::CompareFunction::LessThanEqual; |
| 77 | case Maxwell::ComparisonOp::Greater: | 77 | case Maxwell::ComparisonOp::Greater_D3D: |
| 78 | case Maxwell::ComparisonOp::GreaterOld: | 78 | case Maxwell::ComparisonOp::Greater_GL: |
| 79 | return Shader::CompareFunction::Greater; | 79 | return Shader::CompareFunction::Greater; |
| 80 | case Maxwell::ComparisonOp::NotEqual: | 80 | case Maxwell::ComparisonOp::NotEqual_D3D: |
| 81 | case Maxwell::ComparisonOp::NotEqualOld: | 81 | case Maxwell::ComparisonOp::NotEqual_GL: |
| 82 | return Shader::CompareFunction::NotEqual; | 82 | return Shader::CompareFunction::NotEqual; |
| 83 | case Maxwell::ComparisonOp::GreaterEqual: | 83 | case Maxwell::ComparisonOp::GreaterEqual_D3D: |
| 84 | case Maxwell::ComparisonOp::GreaterEqualOld: | 84 | case Maxwell::ComparisonOp::GreaterEqual_GL: |
| 85 | return Shader::CompareFunction::GreaterThanEqual; | 85 | return Shader::CompareFunction::GreaterThanEqual; |
| 86 | case Maxwell::ComparisonOp::Always: | 86 | case Maxwell::ComparisonOp::Always_D3D: |
| 87 | case Maxwell::ComparisonOp::AlwaysOld: | 87 | case Maxwell::ComparisonOp::Always_GL: |
| 88 | return Shader::CompareFunction::Always; | 88 | return Shader::CompareFunction::Always; |
| 89 | } | 89 | } |
| 90 | UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); | 90 | UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); |
| @@ -96,15 +96,18 @@ Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribut | |||
| 96 | return Shader::AttributeType::Disabled; | 96 | return Shader::AttributeType::Disabled; |
| 97 | } | 97 | } |
| 98 | switch (attr.Type()) { | 98 | switch (attr.Type()) { |
| 99 | case Maxwell::VertexAttribute::Type::SignedNorm: | 99 | case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway: |
| 100 | case Maxwell::VertexAttribute::Type::UnsignedNorm: | 100 | ASSERT_MSG(false, "Invalid vertex attribute type!"); |
| 101 | case Maxwell::VertexAttribute::Type::UnsignedScaled: | 101 | return Shader::AttributeType::Disabled; |
| 102 | case Maxwell::VertexAttribute::Type::SignedScaled: | 102 | case Maxwell::VertexAttribute::Type::SNorm: |
| 103 | case Maxwell::VertexAttribute::Type::UNorm: | ||
| 104 | case Maxwell::VertexAttribute::Type::UScaled: | ||
| 105 | case Maxwell::VertexAttribute::Type::SScaled: | ||
| 103 | case Maxwell::VertexAttribute::Type::Float: | 106 | case Maxwell::VertexAttribute::Type::Float: |
| 104 | return Shader::AttributeType::Float; | 107 | return Shader::AttributeType::Float; |
| 105 | case Maxwell::VertexAttribute::Type::SignedInt: | 108 | case Maxwell::VertexAttribute::Type::SInt: |
| 106 | return Shader::AttributeType::SignedInt; | 109 | return Shader::AttributeType::SignedInt; |
| 107 | case Maxwell::VertexAttribute::Type::UnsignedInt: | 110 | case Maxwell::VertexAttribute::Type::UInt: |
| 108 | return Shader::AttributeType::UnsignedInt; | 111 | return Shader::AttributeType::UnsignedInt; |
| 109 | } | 112 | } |
| 110 | return Shader::AttributeType::Float; | 113 | return Shader::AttributeType::Float; |
| @@ -162,16 +165,14 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program | |||
| 162 | } | 165 | } |
| 163 | break; | 166 | break; |
| 164 | case Shader::Stage::TessellationEval: | 167 | case Shader::Stage::TessellationEval: |
| 165 | // We have to flip tessellation clockwise for some reason... | ||
| 166 | info.tess_clockwise = key.state.tessellation_clockwise == 0; | ||
| 167 | info.tess_primitive = [&key] { | 168 | info.tess_primitive = [&key] { |
| 168 | const u32 raw{key.state.tessellation_primitive.Value()}; | 169 | const u32 raw{key.state.tessellation_primitive.Value()}; |
| 169 | switch (static_cast<Maxwell::TessellationPrimitive>(raw)) { | 170 | switch (static_cast<Maxwell::Tessellation::DomainType>(raw)) { |
| 170 | case Maxwell::TessellationPrimitive::Isolines: | 171 | case Maxwell::Tessellation::DomainType::Isolines: |
| 171 | return Shader::TessPrimitive::Isolines; | 172 | return Shader::TessPrimitive::Isolines; |
| 172 | case Maxwell::TessellationPrimitive::Triangles: | 173 | case Maxwell::Tessellation::DomainType::Triangles: |
| 173 | return Shader::TessPrimitive::Triangles; | 174 | return Shader::TessPrimitive::Triangles; |
| 174 | case Maxwell::TessellationPrimitive::Quads: | 175 | case Maxwell::Tessellation::DomainType::Quads: |
| 175 | return Shader::TessPrimitive::Quads; | 176 | return Shader::TessPrimitive::Quads; |
| 176 | } | 177 | } |
| 177 | ASSERT(false); | 178 | ASSERT(false); |
| @@ -179,12 +180,12 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program | |||
| 179 | }(); | 180 | }(); |
| 180 | info.tess_spacing = [&] { | 181 | info.tess_spacing = [&] { |
| 181 | const u32 raw{key.state.tessellation_spacing}; | 182 | const u32 raw{key.state.tessellation_spacing}; |
| 182 | switch (static_cast<Maxwell::TessellationSpacing>(raw)) { | 183 | switch (static_cast<Maxwell::Tessellation::Spacing>(raw)) { |
| 183 | case Maxwell::TessellationSpacing::Equal: | 184 | case Maxwell::Tessellation::Spacing::Integer: |
| 184 | return Shader::TessSpacing::Equal; | 185 | return Shader::TessSpacing::Equal; |
| 185 | case Maxwell::TessellationSpacing::FractionalOdd: | 186 | case Maxwell::Tessellation::Spacing::FractionalOdd: |
| 186 | return Shader::TessSpacing::FractionalOdd; | 187 | return Shader::TessSpacing::FractionalOdd; |
| 187 | case Maxwell::TessellationSpacing::FractionalEven: | 188 | case Maxwell::Tessellation::Spacing::FractionalEven: |
| 188 | return Shader::TessSpacing::FractionalEven; | 189 | return Shader::TessSpacing::FractionalEven; |
| 189 | } | 190 | } |
| 190 | ASSERT(false); | 191 | ASSERT(false); |
| @@ -490,7 +491,7 @@ GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const | |||
| 490 | // If games are using a small index count, we can assume these are full screen quads. | 491 | // If games are using a small index count, we can assume these are full screen quads. |
| 491 | // Usually these shaders are only used once for building textures so we can assume they | 492 | // Usually these shaders are only used once for building textures so we can assume they |
| 492 | // can't be built async | 493 | // can't be built async |
| 493 | if (maxwell3d->regs.index_array.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) { | 494 | if (maxwell3d->regs.index_buffer.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) { |
| 494 | return pipeline; | 495 | return pipeline; |
| 495 | } | 496 | } |
| 496 | return nullptr; | 497 | return nullptr; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index acfd5da7d..892cd94a3 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -70,7 +70,7 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in | |||
| 70 | const float width = conv(src.scale_x * 2.0f); | 70 | const float width = conv(src.scale_x * 2.0f); |
| 71 | float y = conv(src.translate_y - src.scale_y); | 71 | float y = conv(src.translate_y - src.scale_y); |
| 72 | float height = conv(src.scale_y * 2.0f); | 72 | float height = conv(src.scale_y * 2.0f); |
| 73 | bool y_negate = regs.screen_y_control.y_negate; | 73 | bool y_negate = regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft; |
| 74 | 74 | ||
| 75 | if (!device.IsNvViewportSwizzleSupported()) { | 75 | if (!device.IsNvViewportSwizzleSupported()) { |
| 76 | y_negate = y_negate != (src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY); | 76 | y_negate = y_negate != (src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY); |
| @@ -130,11 +130,11 @@ VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u3 | |||
| 130 | DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_instanced, | 130 | DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_instanced, |
| 131 | bool is_indexed) { | 131 | bool is_indexed) { |
| 132 | DrawParams params{ | 132 | DrawParams params{ |
| 133 | .base_instance = regs.vb_base_instance, | 133 | .base_instance = regs.global_base_instance_index, |
| 134 | .num_instances = is_instanced ? num_instances : 1, | 134 | .num_instances = is_instanced ? num_instances : 1, |
| 135 | .base_vertex = is_indexed ? regs.vb_element_base : regs.vertex_buffer.first, | 135 | .base_vertex = is_indexed ? regs.global_base_vertex_index : regs.vertex_buffer.first, |
| 136 | .num_vertices = is_indexed ? regs.index_array.count : regs.vertex_buffer.count, | 136 | .num_vertices = is_indexed ? regs.index_buffer.count : regs.vertex_buffer.count, |
| 137 | .first_index = is_indexed ? regs.index_array.first : 0, | 137 | .first_index = is_indexed ? regs.index_buffer.first : 0, |
| 138 | .is_indexed = is_indexed, | 138 | .is_indexed = is_indexed, |
| 139 | }; | 139 | }; |
| 140 | if (regs.draw.topology == Maxwell::PrimitiveTopology::Quads) { | 140 | if (regs.draw.topology == Maxwell::PrimitiveTopology::Quads) { |
| @@ -225,10 +225,10 @@ void RasterizerVulkan::Clear() { | |||
| 225 | query_cache.UpdateCounters(); | 225 | query_cache.UpdateCounters(); |
| 226 | 226 | ||
| 227 | auto& regs = maxwell3d->regs; | 227 | auto& regs = maxwell3d->regs; |
| 228 | const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || | 228 | const bool use_color = regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B || |
| 229 | regs.clear_buffers.A; | 229 | regs.clear_surface.A; |
| 230 | const bool use_depth = regs.clear_buffers.Z; | 230 | const bool use_depth = regs.clear_surface.Z; |
| 231 | const bool use_stencil = regs.clear_buffers.S; | 231 | const bool use_stencil = regs.clear_surface.S; |
| 232 | if (!use_color && !use_depth && !use_stencil) { | 232 | if (!use_color && !use_depth && !use_stencil) { |
| 233 | return; | 233 | return; |
| 234 | } | 234 | } |
| @@ -254,9 +254,9 @@ void RasterizerVulkan::Clear() { | |||
| 254 | default_scissor.extent.height = std::numeric_limits<s32>::max(); | 254 | default_scissor.extent.height = std::numeric_limits<s32>::max(); |
| 255 | 255 | ||
| 256 | VkClearRect clear_rect{ | 256 | VkClearRect clear_rect{ |
| 257 | .rect = regs.clear_flags.scissor ? GetScissorState(regs, 0, up_scale, down_shift) | 257 | .rect = regs.clear_control.use_scissor ? GetScissorState(regs, 0, up_scale, down_shift) |
| 258 | : default_scissor, | 258 | : default_scissor, |
| 259 | .baseArrayLayer = regs.clear_buffers.layer, | 259 | .baseArrayLayer = regs.clear_surface.layer, |
| 260 | .layerCount = 1, | 260 | .layerCount = 1, |
| 261 | }; | 261 | }; |
| 262 | if (clear_rect.rect.extent.width == 0 || clear_rect.rect.extent.height == 0) { | 262 | if (clear_rect.rect.extent.width == 0 || clear_rect.rect.extent.height == 0) { |
| @@ -267,7 +267,7 @@ void RasterizerVulkan::Clear() { | |||
| 267 | .height = std::min(clear_rect.rect.extent.height, render_area.height), | 267 | .height = std::min(clear_rect.rect.extent.height, render_area.height), |
| 268 | }; | 268 | }; |
| 269 | 269 | ||
| 270 | const u32 color_attachment = regs.clear_buffers.RT; | 270 | const u32 color_attachment = regs.clear_surface.RT; |
| 271 | if (use_color && framebuffer->HasAspectColorBit(color_attachment)) { | 271 | if (use_color && framebuffer->HasAspectColorBit(color_attachment)) { |
| 272 | VkClearValue clear_value; | 272 | VkClearValue clear_value; |
| 273 | bool is_integer = false; | 273 | bool is_integer = false; |
| @@ -289,7 +289,8 @@ void RasterizerVulkan::Clear() { | |||
| 289 | break; | 289 | break; |
| 290 | } | 290 | } |
| 291 | if (!is_integer) { | 291 | if (!is_integer) { |
| 292 | std::memcpy(clear_value.color.float32, regs.clear_color, sizeof(regs.clear_color)); | 292 | std::memcpy(clear_value.color.float32, regs.clear_color.data(), |
| 293 | regs.clear_color.size() * sizeof(f32)); | ||
| 293 | } else if (!is_signed) { | 294 | } else if (!is_signed) { |
| 294 | for (size_t i = 0; i < 4; i++) { | 295 | for (size_t i = 0; i < 4; i++) { |
| 295 | clear_value.color.uint32[i] = static_cast<u32>( | 296 | clear_value.color.uint32[i] = static_cast<u32>( |
| @@ -648,23 +649,23 @@ void RasterizerVulkan::UpdateDynamicStates() { | |||
| 648 | 649 | ||
| 649 | void RasterizerVulkan::BeginTransformFeedback() { | 650 | void RasterizerVulkan::BeginTransformFeedback() { |
| 650 | const auto& regs = maxwell3d->regs; | 651 | const auto& regs = maxwell3d->regs; |
| 651 | if (regs.tfb_enabled == 0) { | 652 | if (regs.transform_feedback_enabled == 0) { |
| 652 | return; | 653 | return; |
| 653 | } | 654 | } |
| 654 | if (!device.IsExtTransformFeedbackSupported()) { | 655 | if (!device.IsExtTransformFeedbackSupported()) { |
| 655 | LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported"); | 656 | LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported"); |
| 656 | return; | 657 | return; |
| 657 | } | 658 | } |
| 658 | UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationControl) || | 659 | UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) || |
| 659 | regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationEval) || | 660 | regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) || |
| 660 | regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::Geometry)); | 661 | regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry)); |
| 661 | scheduler.Record( | 662 | scheduler.Record( |
| 662 | [](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); }); | 663 | [](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); }); |
| 663 | } | 664 | } |
| 664 | 665 | ||
| 665 | void RasterizerVulkan::EndTransformFeedback() { | 666 | void RasterizerVulkan::EndTransformFeedback() { |
| 666 | const auto& regs = maxwell3d->regs; | 667 | const auto& regs = maxwell3d->regs; |
| 667 | if (regs.tfb_enabled == 0) { | 668 | if (regs.transform_feedback_enabled == 0) { |
| 668 | return; | 669 | return; |
| 669 | } | 670 | } |
| 670 | if (!device.IsExtTransformFeedbackSupported()) { | 671 | if (!device.IsExtTransformFeedbackSupported()) { |
| @@ -728,11 +729,11 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) { | |||
| 728 | if (!state_tracker.TouchDepthBias()) { | 729 | if (!state_tracker.TouchDepthBias()) { |
| 729 | return; | 730 | return; |
| 730 | } | 731 | } |
| 731 | float units = regs.polygon_offset_units / 2.0f; | 732 | float units = regs.depth_bias / 2.0f; |
| 732 | const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::S8_UINT_Z24_UNORM || | 733 | const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::Z24_UNORM_S8_UINT || |
| 733 | regs.zeta.format == Tegra::DepthFormat::D24X8_UNORM || | 734 | regs.zeta.format == Tegra::DepthFormat::X8Z24_UNORM || |
| 734 | regs.zeta.format == Tegra::DepthFormat::D24S8_UNORM || | 735 | regs.zeta.format == Tegra::DepthFormat::S8Z24_UNORM || |
| 735 | regs.zeta.format == Tegra::DepthFormat::D24C8_UNORM; | 736 | regs.zeta.format == Tegra::DepthFormat::V8Z24_UNORM; |
| 736 | if (is_d24 && !device.SupportsD24DepthBuffer()) { | 737 | if (is_d24 && !device.SupportsD24DepthBuffer()) { |
| 737 | // the base formulas can be obtained from here: | 738 | // the base formulas can be obtained from here: |
| 738 | // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias | 739 | // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias |
| @@ -740,8 +741,8 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) { | |||
| 740 | static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127)); | 741 | static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127)); |
| 741 | units = static_cast<float>(static_cast<double>(units) * rescale_factor); | 742 | units = static_cast<float>(static_cast<double>(units) * rescale_factor); |
| 742 | } | 743 | } |
| 743 | scheduler.Record([constant = units, clamp = regs.polygon_offset_clamp, | 744 | scheduler.Record([constant = units, clamp = regs.depth_bias_clamp, |
| 744 | factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) { | 745 | factor = regs.slope_scale_depth_bias](vk::CommandBuffer cmdbuf) { |
| 745 | cmdbuf.SetDepthBias(constant, clamp, factor); | 746 | cmdbuf.SetDepthBias(constant, clamp, factor); |
| 746 | }); | 747 | }); |
| 747 | } | 748 | } |
| @@ -771,10 +772,11 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) | |||
| 771 | if (regs.stencil_two_side_enable) { | 772 | if (regs.stencil_two_side_enable) { |
| 772 | // Separate values per face | 773 | // Separate values per face |
| 773 | scheduler.Record( | 774 | scheduler.Record( |
| 774 | [front_ref = regs.stencil_front_func_ref, front_write_mask = regs.stencil_front_mask, | 775 | [front_ref = regs.stencil_front_func.ref, |
| 775 | front_test_mask = regs.stencil_front_func_mask, back_ref = regs.stencil_back_func_ref, | 776 | front_write_mask = regs.stencil_front_func.mask, |
| 776 | back_write_mask = regs.stencil_back_mask, | 777 | front_test_mask = regs.stencil_front_func.func_mask, |
| 777 | back_test_mask = regs.stencil_back_func_mask](vk::CommandBuffer cmdbuf) { | 778 | back_ref = regs.stencil_back_func.ref, back_write_mask = regs.stencil_back_func.mask, |
| 779 | back_test_mask = regs.stencil_back_func.func_mask](vk::CommandBuffer cmdbuf) { | ||
| 778 | // Front face | 780 | // Front face |
| 779 | cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_BIT, front_ref); | 781 | cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_BIT, front_ref); |
| 780 | cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_BIT, front_write_mask); | 782 | cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_BIT, front_write_mask); |
| @@ -787,8 +789,9 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) | |||
| 787 | }); | 789 | }); |
| 788 | } else { | 790 | } else { |
| 789 | // Front face defines both faces | 791 | // Front face defines both faces |
| 790 | scheduler.Record([ref = regs.stencil_front_func_ref, write_mask = regs.stencil_front_mask, | 792 | scheduler.Record([ref = regs.stencil_front_func.ref, |
| 791 | test_mask = regs.stencil_front_func_mask](vk::CommandBuffer cmdbuf) { | 793 | write_mask = regs.stencil_front_func.mask, |
| 794 | test_mask = regs.stencil_front_func.func_mask](vk::CommandBuffer cmdbuf) { | ||
| 792 | cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, ref); | 795 | cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, ref); |
| 793 | cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, write_mask); | 796 | cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, write_mask); |
| 794 | cmdbuf.SetStencilCompareMask(VK_STENCIL_FACE_FRONT_AND_BACK, test_mask); | 797 | cmdbuf.SetStencilCompareMask(VK_STENCIL_FACE_FRONT_AND_BACK, test_mask); |
| @@ -800,7 +803,8 @@ void RasterizerVulkan::UpdateLineWidth(Tegra::Engines::Maxwell3D::Regs& regs) { | |||
| 800 | if (!state_tracker.TouchLineWidth()) { | 803 | if (!state_tracker.TouchLineWidth()) { |
| 801 | return; | 804 | return; |
| 802 | } | 805 | } |
| 803 | const float width = regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased; | 806 | const float width = |
| 807 | regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased; | ||
| 804 | scheduler.Record([width](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineWidth(width); }); | 808 | scheduler.Record([width](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineWidth(width); }); |
| 805 | } | 809 | } |
| 806 | 810 | ||
| @@ -808,10 +812,10 @@ void RasterizerVulkan::UpdateCullMode(Tegra::Engines::Maxwell3D::Regs& regs) { | |||
| 808 | if (!state_tracker.TouchCullMode()) { | 812 | if (!state_tracker.TouchCullMode()) { |
| 809 | return; | 813 | return; |
| 810 | } | 814 | } |
| 811 | scheduler.Record( | 815 | scheduler.Record([enabled = regs.gl_cull_test_enabled, |
| 812 | [enabled = regs.cull_test_enabled, cull_face = regs.cull_face](vk::CommandBuffer cmdbuf) { | 816 | cull_face = regs.gl_cull_face](vk::CommandBuffer cmdbuf) { |
| 813 | cmdbuf.SetCullModeEXT(enabled ? MaxwellToVK::CullFace(cull_face) : VK_CULL_MODE_NONE); | 817 | cmdbuf.SetCullModeEXT(enabled ? MaxwellToVK::CullFace(cull_face) : VK_CULL_MODE_NONE); |
| 814 | }); | 818 | }); |
| 815 | } | 819 | } |
| 816 | 820 | ||
| 817 | void RasterizerVulkan::UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Regs& regs) { | 821 | void RasterizerVulkan::UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Regs& regs) { |
| @@ -860,8 +864,8 @@ void RasterizerVulkan::UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs) { | |||
| 860 | return; | 864 | return; |
| 861 | } | 865 | } |
| 862 | 866 | ||
| 863 | VkFrontFace front_face = MaxwellToVK::FrontFace(regs.front_face); | 867 | VkFrontFace front_face = MaxwellToVK::FrontFace(regs.gl_front_face); |
| 864 | if (regs.screen_y_control.triangle_rast_flip != 0) { | 868 | if (regs.window_origin.flip_y != 0) { |
| 865 | front_face = front_face == VK_FRONT_FACE_CLOCKWISE ? VK_FRONT_FACE_COUNTER_CLOCKWISE | 869 | front_face = front_face == VK_FRONT_FACE_CLOCKWISE ? VK_FRONT_FACE_COUNTER_CLOCKWISE |
| 866 | : VK_FRONT_FACE_CLOCKWISE; | 870 | : VK_FRONT_FACE_CLOCKWISE; |
| 867 | } | 871 | } |
| @@ -873,16 +877,16 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) { | |||
| 873 | if (!state_tracker.TouchStencilOp()) { | 877 | if (!state_tracker.TouchStencilOp()) { |
| 874 | return; | 878 | return; |
| 875 | } | 879 | } |
| 876 | const Maxwell::StencilOp fail = regs.stencil_front_op_fail; | 880 | const Maxwell::StencilOp::Op fail = regs.stencil_front_op.fail; |
| 877 | const Maxwell::StencilOp zfail = regs.stencil_front_op_zfail; | 881 | const Maxwell::StencilOp::Op zfail = regs.stencil_front_op.zfail; |
| 878 | const Maxwell::StencilOp zpass = regs.stencil_front_op_zpass; | 882 | const Maxwell::StencilOp::Op zpass = regs.stencil_front_op.zpass; |
| 879 | const Maxwell::ComparisonOp compare = regs.stencil_front_func_func; | 883 | const Maxwell::ComparisonOp compare = regs.stencil_front_op.func; |
| 880 | if (regs.stencil_two_side_enable) { | 884 | if (regs.stencil_two_side_enable) { |
| 881 | // Separate stencil op per face | 885 | // Separate stencil op per face |
| 882 | const Maxwell::StencilOp back_fail = regs.stencil_back_op_fail; | 886 | const Maxwell::StencilOp::Op back_fail = regs.stencil_back_op.fail; |
| 883 | const Maxwell::StencilOp back_zfail = regs.stencil_back_op_zfail; | 887 | const Maxwell::StencilOp::Op back_zfail = regs.stencil_back_op.zfail; |
| 884 | const Maxwell::StencilOp back_zpass = regs.stencil_back_op_zpass; | 888 | const Maxwell::StencilOp::Op back_zpass = regs.stencil_back_op.zpass; |
| 885 | const Maxwell::ComparisonOp back_compare = regs.stencil_back_func_func; | 889 | const Maxwell::ComparisonOp back_compare = regs.stencil_back_op.func; |
| 886 | scheduler.Record([fail, zfail, zpass, compare, back_fail, back_zfail, back_zpass, | 890 | scheduler.Record([fail, zfail, zpass, compare, back_fail, back_zfail, back_zpass, |
| 887 | back_compare](vk::CommandBuffer cmdbuf) { | 891 | back_compare](vk::CommandBuffer cmdbuf) { |
| 888 | cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_BIT, MaxwellToVK::StencilOp(fail), | 892 | cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_BIT, MaxwellToVK::StencilOp(fail), |
| @@ -954,15 +958,15 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs) | |||
| 954 | dirty[Dirty::VertexBinding0 + index] = false; | 958 | dirty[Dirty::VertexBinding0 + index] = false; |
| 955 | 959 | ||
| 956 | const u32 binding{static_cast<u32>(index)}; | 960 | const u32 binding{static_cast<u32>(index)}; |
| 957 | const auto& input_binding{regs.vertex_array[binding]}; | 961 | const auto& input_binding{regs.vertex_streams[binding]}; |
| 958 | const bool is_instanced{regs.instanced_arrays.IsInstancingEnabled(binding)}; | 962 | const bool is_instanced{regs.vertex_stream_instances.IsInstancingEnabled(binding)}; |
| 959 | bindings.push_back({ | 963 | bindings.push_back({ |
| 960 | .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, | 964 | .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, |
| 961 | .pNext = nullptr, | 965 | .pNext = nullptr, |
| 962 | .binding = binding, | 966 | .binding = binding, |
| 963 | .stride = input_binding.stride, | 967 | .stride = input_binding.stride, |
| 964 | .inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX, | 968 | .inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX, |
| 965 | .divisor = is_instanced ? input_binding.divisor : 1, | 969 | .divisor = is_instanced ? input_binding.frequency : 1, |
| 966 | }); | 970 | }); |
| 967 | } | 971 | } |
| 968 | scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) { | 972 | scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) { |
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index f234e1a31..ed98c8370 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp | |||
| @@ -51,8 +51,8 @@ Flags MakeInvalidationFlags() { | |||
| 51 | void SetupDirtyViewports(Tables& tables) { | 51 | void SetupDirtyViewports(Tables& tables) { |
| 52 | FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports); | 52 | FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports); |
| 53 | FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports); | 53 | FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports); |
| 54 | tables[0][OFF(viewport_transform_enabled)] = Viewports; | 54 | tables[0][OFF(viewport_scale_offset_enbled)] = Viewports; |
| 55 | tables[1][OFF(screen_y_control)] = Viewports; | 55 | tables[1][OFF(window_origin)] = Viewports; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | void SetupDirtyScissors(Tables& tables) { | 58 | void SetupDirtyScissors(Tables& tables) { |
| @@ -61,9 +61,9 @@ void SetupDirtyScissors(Tables& tables) { | |||
| 61 | 61 | ||
| 62 | void SetupDirtyDepthBias(Tables& tables) { | 62 | void SetupDirtyDepthBias(Tables& tables) { |
| 63 | auto& table = tables[0]; | 63 | auto& table = tables[0]; |
| 64 | table[OFF(polygon_offset_units)] = DepthBias; | 64 | table[OFF(depth_bias)] = DepthBias; |
| 65 | table[OFF(polygon_offset_clamp)] = DepthBias; | 65 | table[OFF(depth_bias_clamp)] = DepthBias; |
| 66 | table[OFF(polygon_offset_factor)] = DepthBias; | 66 | table[OFF(slope_scale_depth_bias)] = DepthBias; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | void SetupDirtyBlendConstants(Tables& tables) { | 69 | void SetupDirtyBlendConstants(Tables& tables) { |
| @@ -77,12 +77,12 @@ void SetupDirtyDepthBounds(Tables& tables) { | |||
| 77 | void SetupDirtyStencilProperties(Tables& tables) { | 77 | void SetupDirtyStencilProperties(Tables& tables) { |
| 78 | auto& table = tables[0]; | 78 | auto& table = tables[0]; |
| 79 | table[OFF(stencil_two_side_enable)] = StencilProperties; | 79 | table[OFF(stencil_two_side_enable)] = StencilProperties; |
| 80 | table[OFF(stencil_front_func_ref)] = StencilProperties; | 80 | table[OFF(stencil_front_func.ref)] = StencilProperties; |
| 81 | table[OFF(stencil_front_mask)] = StencilProperties; | 81 | table[OFF(stencil_front_func.mask)] = StencilProperties; |
| 82 | table[OFF(stencil_front_func_mask)] = StencilProperties; | 82 | table[OFF(stencil_front_func.func_mask)] = StencilProperties; |
| 83 | table[OFF(stencil_back_func_ref)] = StencilProperties; | 83 | table[OFF(stencil_back_func.ref)] = StencilProperties; |
| 84 | table[OFF(stencil_back_mask)] = StencilProperties; | 84 | table[OFF(stencil_back_func.mask)] = StencilProperties; |
| 85 | table[OFF(stencil_back_func_mask)] = StencilProperties; | 85 | table[OFF(stencil_back_func.func_mask)] = StencilProperties; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | void SetupDirtyLineWidth(Tables& tables) { | 88 | void SetupDirtyLineWidth(Tables& tables) { |
| @@ -92,8 +92,8 @@ void SetupDirtyLineWidth(Tables& tables) { | |||
| 92 | 92 | ||
| 93 | void SetupDirtyCullMode(Tables& tables) { | 93 | void SetupDirtyCullMode(Tables& tables) { |
| 94 | auto& table = tables[0]; | 94 | auto& table = tables[0]; |
| 95 | table[OFF(cull_face)] = CullMode; | 95 | table[OFF(gl_cull_face)] = CullMode; |
| 96 | table[OFF(cull_test_enabled)] = CullMode; | 96 | table[OFF(gl_cull_test_enabled)] = CullMode; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | void SetupDirtyDepthBoundsEnable(Tables& tables) { | 99 | void SetupDirtyDepthBoundsEnable(Tables& tables) { |
| @@ -114,20 +114,20 @@ void SetupDirtyDepthCompareOp(Tables& tables) { | |||
| 114 | 114 | ||
| 115 | void SetupDirtyFrontFace(Tables& tables) { | 115 | void SetupDirtyFrontFace(Tables& tables) { |
| 116 | auto& table = tables[0]; | 116 | auto& table = tables[0]; |
| 117 | table[OFF(front_face)] = FrontFace; | 117 | table[OFF(gl_front_face)] = FrontFace; |
| 118 | table[OFF(screen_y_control)] = FrontFace; | 118 | table[OFF(window_origin)] = FrontFace; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | void SetupDirtyStencilOp(Tables& tables) { | 121 | void SetupDirtyStencilOp(Tables& tables) { |
| 122 | auto& table = tables[0]; | 122 | auto& table = tables[0]; |
| 123 | table[OFF(stencil_front_op_fail)] = StencilOp; | 123 | table[OFF(stencil_front_op.fail)] = StencilOp; |
| 124 | table[OFF(stencil_front_op_zfail)] = StencilOp; | 124 | table[OFF(stencil_front_op.zfail)] = StencilOp; |
| 125 | table[OFF(stencil_front_op_zpass)] = StencilOp; | 125 | table[OFF(stencil_front_op.zpass)] = StencilOp; |
| 126 | table[OFF(stencil_front_func_func)] = StencilOp; | 126 | table[OFF(stencil_front_op.func)] = StencilOp; |
| 127 | table[OFF(stencil_back_op_fail)] = StencilOp; | 127 | table[OFF(stencil_back_op.fail)] = StencilOp; |
| 128 | table[OFF(stencil_back_op_zfail)] = StencilOp; | 128 | table[OFF(stencil_back_op.zfail)] = StencilOp; |
| 129 | table[OFF(stencil_back_op_zpass)] = StencilOp; | 129 | table[OFF(stencil_back_op.zpass)] = StencilOp; |
| 130 | table[OFF(stencil_back_func_func)] = StencilOp; | 130 | table[OFF(stencil_back_op.func)] = StencilOp; |
| 131 | 131 | ||
| 132 | // Table 0 is used by StencilProperties | 132 | // Table 0 is used by StencilProperties |
| 133 | tables[1][OFF(stencil_two_side_enable)] = StencilOp; | 133 | tables[1][OFF(stencil_two_side_enable)] = StencilOp; |
| @@ -139,10 +139,10 @@ void SetupDirtyStencilTestEnable(Tables& tables) { | |||
| 139 | 139 | ||
| 140 | void SetupDirtyBlending(Tables& tables) { | 140 | void SetupDirtyBlending(Tables& tables) { |
| 141 | tables[0][OFF(color_mask_common)] = Blending; | 141 | tables[0][OFF(color_mask_common)] = Blending; |
| 142 | tables[0][OFF(independent_blend_enable)] = Blending; | 142 | tables[0][OFF(blend_per_target_enabled)] = Blending; |
| 143 | FillBlock(tables[0], OFF(color_mask), NUM(color_mask), Blending); | 143 | FillBlock(tables[0], OFF(color_mask), NUM(color_mask), Blending); |
| 144 | FillBlock(tables[0], OFF(blend), NUM(blend), Blending); | 144 | FillBlock(tables[0], OFF(blend), NUM(blend), Blending); |
| 145 | FillBlock(tables[0], OFF(independent_blend), NUM(independent_blend), Blending); | 145 | FillBlock(tables[0], OFF(blend_per_target), NUM(blend_per_target), Blending); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | void SetupDirtyViewportSwizzles(Tables& tables) { | 148 | void SetupDirtyViewportSwizzles(Tables& tables) { |
| @@ -166,10 +166,10 @@ void SetupDirtyVertexBindings(Tables& tables) { | |||
| 166 | static constexpr size_t divisor_offset = 3; | 166 | static constexpr size_t divisor_offset = 3; |
| 167 | for (size_t i = 0; i < Regs::NumVertexArrays; ++i) { | 167 | for (size_t i = 0; i < Regs::NumVertexArrays; ++i) { |
| 168 | const u8 flag = static_cast<u8>(VertexBinding0 + i); | 168 | const u8 flag = static_cast<u8>(VertexBinding0 + i); |
| 169 | tables[0][OFF(instanced_arrays) + i] = VertexInput; | 169 | tables[0][OFF(vertex_stream_instances) + i] = VertexInput; |
| 170 | tables[1][OFF(instanced_arrays) + i] = flag; | 170 | tables[1][OFF(vertex_stream_instances) + i] = flag; |
| 171 | tables[0][OFF(vertex_array) + i * NUM(vertex_array[0]) + divisor_offset] = VertexInput; | 171 | tables[0][OFF(vertex_streams) + i * NUM(vertex_streams[0]) + divisor_offset] = VertexInput; |
| 172 | tables[1][OFF(vertex_array) + i * NUM(vertex_array[0]) + divisor_offset] = flag; | 172 | tables[1][OFF(vertex_streams) + i * NUM(vertex_streams[0]) + divisor_offset] = flag; |
| 173 | } | 173 | } |
| 174 | } | 174 | } |
| 175 | } // Anonymous namespace | 175 | } // Anonymous namespace |
diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp index f53066579..d9482371b 100644 --- a/src/video_core/shader_cache.cpp +++ b/src/video_core/shader_cache.cpp | |||
| @@ -43,14 +43,14 @@ bool ShaderCache::RefreshStages(std::array<u64, 6>& unique_hashes) { | |||
| 43 | } | 43 | } |
| 44 | dirty[VideoCommon::Dirty::Shaders] = false; | 44 | dirty[VideoCommon::Dirty::Shaders] = false; |
| 45 | 45 | ||
| 46 | const GPUVAddr base_addr{maxwell3d->regs.code_address.CodeAddress()}; | 46 | const GPUVAddr base_addr{maxwell3d->regs.program_region.Address()}; |
| 47 | for (size_t index = 0; index < Tegra::Engines::Maxwell3D::Regs::MaxShaderProgram; ++index) { | 47 | for (size_t index = 0; index < Tegra::Engines::Maxwell3D::Regs::MaxShaderProgram; ++index) { |
| 48 | if (!maxwell3d->regs.IsShaderConfigEnabled(index)) { | 48 | if (!maxwell3d->regs.IsShaderConfigEnabled(index)) { |
| 49 | unique_hashes[index] = 0; | 49 | unique_hashes[index] = 0; |
| 50 | continue; | 50 | continue; |
| 51 | } | 51 | } |
| 52 | const auto& shader_config{maxwell3d->regs.shader_config[index]}; | 52 | const auto& shader_config{maxwell3d->regs.pipelines[index]}; |
| 53 | const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderProgram>(index)}; | 53 | const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderType>(index)}; |
| 54 | const GPUVAddr shader_addr{base_addr + shader_config.offset}; | 54 | const GPUVAddr shader_addr{base_addr + shader_config.offset}; |
| 55 | const std::optional<VAddr> cpu_shader_addr{gpu_memory->GpuToCpuAddress(shader_addr)}; | 55 | const std::optional<VAddr> cpu_shader_addr{gpu_memory->GpuToCpuAddress(shader_addr)}; |
| 56 | if (!cpu_shader_addr) { | 56 | if (!cpu_shader_addr) { |
| @@ -90,14 +90,14 @@ const ShaderInfo* ShaderCache::ComputeShader() { | |||
| 90 | void ShaderCache::GetGraphicsEnvironments(GraphicsEnvironments& result, | 90 | void ShaderCache::GetGraphicsEnvironments(GraphicsEnvironments& result, |
| 91 | const std::array<u64, NUM_PROGRAMS>& unique_hashes) { | 91 | const std::array<u64, NUM_PROGRAMS>& unique_hashes) { |
| 92 | size_t env_index{}; | 92 | size_t env_index{}; |
| 93 | const GPUVAddr base_addr{maxwell3d->regs.code_address.CodeAddress()}; | 93 | const GPUVAddr base_addr{maxwell3d->regs.program_region.Address()}; |
| 94 | for (size_t index = 0; index < NUM_PROGRAMS; ++index) { | 94 | for (size_t index = 0; index < NUM_PROGRAMS; ++index) { |
| 95 | if (unique_hashes[index] == 0) { | 95 | if (unique_hashes[index] == 0) { |
| 96 | continue; | 96 | continue; |
| 97 | } | 97 | } |
| 98 | const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderProgram>(index)}; | 98 | const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderType>(index)}; |
| 99 | auto& env{result.envs[index]}; | 99 | auto& env{result.envs[index]}; |
| 100 | const u32 start_address{maxwell3d->regs.shader_config[index].offset}; | 100 | const u32 start_address{maxwell3d->regs.pipelines[index].offset}; |
| 101 | env = GraphicsEnvironment{*maxwell3d, *gpu_memory, program, base_addr, start_address}; | 101 | env = GraphicsEnvironment{*maxwell3d, *gpu_memory, program, base_addr, start_address}; |
| 102 | env.SetCachedSize(shader_infos[index]->size_bytes); | 102 | env.SetCachedSize(shader_infos[index]->size_bytes); |
| 103 | result.env_ptrs[env_index++] = &env; | 103 | result.env_ptrs[env_index++] = &env; |
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp index 5f7625947..fbabb3219 100644 --- a/src/video_core/shader_environment.cpp +++ b/src/video_core/shader_environment.cpp | |||
| @@ -250,34 +250,34 @@ Shader::TextureType GenericEnvironment::ReadTextureTypeImpl(GPUVAddr tic_addr, u | |||
| 250 | 250 | ||
| 251 | GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, | 251 | GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, |
| 252 | Tegra::MemoryManager& gpu_memory_, | 252 | Tegra::MemoryManager& gpu_memory_, |
| 253 | Maxwell::ShaderProgram program, GPUVAddr program_base_, | 253 | Maxwell::ShaderType program, GPUVAddr program_base_, |
| 254 | u32 start_address_) | 254 | u32 start_address_) |
| 255 | : GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} { | 255 | : GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} { |
| 256 | gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph)); | 256 | gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph)); |
| 257 | initial_offset = sizeof(sph); | 257 | initial_offset = sizeof(sph); |
| 258 | gp_passthrough_mask = maxwell3d->regs.gp_passthrough_mask; | 258 | gp_passthrough_mask = maxwell3d->regs.post_vtg_shader_attrib_skip_mask; |
| 259 | switch (program) { | 259 | switch (program) { |
| 260 | case Maxwell::ShaderProgram::VertexA: | 260 | case Maxwell::ShaderType::VertexA: |
| 261 | stage = Shader::Stage::VertexA; | 261 | stage = Shader::Stage::VertexA; |
| 262 | stage_index = 0; | 262 | stage_index = 0; |
| 263 | break; | 263 | break; |
| 264 | case Maxwell::ShaderProgram::VertexB: | 264 | case Maxwell::ShaderType::VertexB: |
| 265 | stage = Shader::Stage::VertexB; | 265 | stage = Shader::Stage::VertexB; |
| 266 | stage_index = 0; | 266 | stage_index = 0; |
| 267 | break; | 267 | break; |
| 268 | case Maxwell::ShaderProgram::TesselationControl: | 268 | case Maxwell::ShaderType::TessellationInit: |
| 269 | stage = Shader::Stage::TessellationControl; | 269 | stage = Shader::Stage::TessellationControl; |
| 270 | stage_index = 1; | 270 | stage_index = 1; |
| 271 | break; | 271 | break; |
| 272 | case Maxwell::ShaderProgram::TesselationEval: | 272 | case Maxwell::ShaderType::Tessellation: |
| 273 | stage = Shader::Stage::TessellationEval; | 273 | stage = Shader::Stage::TessellationEval; |
| 274 | stage_index = 2; | 274 | stage_index = 2; |
| 275 | break; | 275 | break; |
| 276 | case Maxwell::ShaderProgram::Geometry: | 276 | case Maxwell::ShaderType::Geometry: |
| 277 | stage = Shader::Stage::Geometry; | 277 | stage = Shader::Stage::Geometry; |
| 278 | stage_index = 3; | 278 | stage_index = 3; |
| 279 | break; | 279 | break; |
| 280 | case Maxwell::ShaderProgram::Fragment: | 280 | case Maxwell::ShaderType::Pixel: |
| 281 | stage = Shader::Stage::Fragment; | 281 | stage = Shader::Stage::Fragment; |
| 282 | stage_index = 4; | 282 | stage_index = 4; |
| 283 | break; | 283 | break; |
| @@ -288,7 +288,7 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, | |||
| 288 | const u64 local_size{sph.LocalMemorySize()}; | 288 | const u64 local_size{sph.LocalMemorySize()}; |
| 289 | ASSERT(local_size <= std::numeric_limits<u32>::max()); | 289 | ASSERT(local_size <= std::numeric_limits<u32>::max()); |
| 290 | local_memory_size = static_cast<u32>(local_size) + sph.common3.shader_local_memory_crs_size; | 290 | local_memory_size = static_cast<u32>(local_size) + sph.common3.shader_local_memory_crs_size; |
| 291 | texture_bound = maxwell3d->regs.tex_cb_index; | 291 | texture_bound = maxwell3d->regs.bindless_texture_const_buffer_slot; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) { | 294 | u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) { |
| @@ -304,8 +304,9 @@ u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) { | |||
| 304 | 304 | ||
| 305 | Shader::TextureType GraphicsEnvironment::ReadTextureType(u32 handle) { | 305 | Shader::TextureType GraphicsEnvironment::ReadTextureType(u32 handle) { |
| 306 | const auto& regs{maxwell3d->regs}; | 306 | const auto& regs{maxwell3d->regs}; |
| 307 | const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; | 307 | const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding}; |
| 308 | return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, via_header_index, handle); | 308 | return ReadTextureTypeImpl(regs.tex_header.Address(), regs.tex_header.limit, via_header_index, |
| 309 | handle); | ||
| 309 | } | 310 | } |
| 310 | 311 | ||
| 311 | ComputeEnvironment::ComputeEnvironment(Tegra::Engines::KeplerCompute& kepler_compute_, | 312 | ComputeEnvironment::ComputeEnvironment(Tegra::Engines::KeplerCompute& kepler_compute_, |
diff --git a/src/video_core/shader_environment.h b/src/video_core/shader_environment.h index 5a145f33a..8b3b8e9f5 100644 --- a/src/video_core/shader_environment.h +++ b/src/video_core/shader_environment.h | |||
| @@ -93,7 +93,7 @@ public: | |||
| 93 | explicit GraphicsEnvironment() = default; | 93 | explicit GraphicsEnvironment() = default; |
| 94 | explicit GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, | 94 | explicit GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, |
| 95 | Tegra::MemoryManager& gpu_memory_, | 95 | Tegra::MemoryManager& gpu_memory_, |
| 96 | Tegra::Engines::Maxwell3D::Regs::ShaderProgram program, | 96 | Tegra::Engines::Maxwell3D::Regs::ShaderType program, |
| 97 | GPUVAddr program_base_, u32 start_address_); | 97 | GPUVAddr program_base_, u32 start_address_); |
| 98 | 98 | ||
| 99 | ~GraphicsEnvironment() override = default; | 99 | ~GraphicsEnvironment() override = default; |
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index a2bf08294..6bd133d10 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp | |||
| @@ -73,17 +73,17 @@ bool SurfaceTargetIsArray(SurfaceTarget target) { | |||
| 73 | 73 | ||
| 74 | PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { | 74 | PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { |
| 75 | switch (format) { | 75 | switch (format) { |
| 76 | case Tegra::DepthFormat::S8_UINT_Z24_UNORM: | 76 | case Tegra::DepthFormat::Z24_UNORM_S8_UINT: |
| 77 | return PixelFormat::S8_UINT_D24_UNORM; | 77 | return PixelFormat::S8_UINT_D24_UNORM; |
| 78 | case Tegra::DepthFormat::D24S8_UNORM: | 78 | case Tegra::DepthFormat::S8Z24_UNORM: |
| 79 | return PixelFormat::D24_UNORM_S8_UINT; | 79 | return PixelFormat::D24_UNORM_S8_UINT; |
| 80 | case Tegra::DepthFormat::D32_FLOAT: | 80 | case Tegra::DepthFormat::Z32_FLOAT: |
| 81 | return PixelFormat::D32_FLOAT; | 81 | return PixelFormat::D32_FLOAT; |
| 82 | case Tegra::DepthFormat::D16_UNORM: | 82 | case Tegra::DepthFormat::Z16_UNORM: |
| 83 | return PixelFormat::D16_UNORM; | 83 | return PixelFormat::D16_UNORM; |
| 84 | case Tegra::DepthFormat::S8_UINT: | 84 | case Tegra::DepthFormat::S8_UINT: |
| 85 | return PixelFormat::S8_UINT; | 85 | return PixelFormat::S8_UINT; |
| 86 | case Tegra::DepthFormat::D32_FLOAT_S8X24_UINT: | 86 | case Tegra::DepthFormat::Z32_FLOAT_X24S8_UINT: |
| 87 | return PixelFormat::D32_FLOAT_S8_UINT; | 87 | return PixelFormat::D32_FLOAT_S8_UINT; |
| 88 | default: | 88 | default: |
| 89 | UNIMPLEMENTED_MSG("Unimplemented format={}", format); | 89 | UNIMPLEMENTED_MSG("Unimplemented format={}", format); |
| @@ -117,9 +117,9 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) | |||
| 117 | return PixelFormat::R32G32_UINT; | 117 | return PixelFormat::R32G32_UINT; |
| 118 | case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT: | 118 | case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT: |
| 119 | return PixelFormat::R16G16B16X16_FLOAT; | 119 | return PixelFormat::R16G16B16X16_FLOAT; |
| 120 | case Tegra::RenderTargetFormat::B8G8R8A8_UNORM: | 120 | case Tegra::RenderTargetFormat::A8R8G8B8_UNORM: |
| 121 | return PixelFormat::B8G8R8A8_UNORM; | 121 | return PixelFormat::B8G8R8A8_UNORM; |
| 122 | case Tegra::RenderTargetFormat::B8G8R8A8_SRGB: | 122 | case Tegra::RenderTargetFormat::A8R8G8B8_SRGB: |
| 123 | return PixelFormat::B8G8R8A8_SRGB; | 123 | return PixelFormat::B8G8R8A8_SRGB; |
| 124 | case Tegra::RenderTargetFormat::A2B10G10R10_UNORM: | 124 | case Tegra::RenderTargetFormat::A2B10G10R10_UNORM: |
| 125 | return PixelFormat::A2B10G10R10_UNORM; | 125 | return PixelFormat::A2B10G10R10_UNORM; |
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index 6c073ee57..852ec2519 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <fmt/format.h> | ||
| 5 | |||
| 4 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 5 | #include "video_core/surface.h" | 7 | #include "video_core/surface.h" |
| 6 | #include "video_core/texture_cache/format_lookup_table.h" | 8 | #include "video_core/texture_cache/format_lookup_table.h" |
| @@ -12,6 +14,7 @@ | |||
| 12 | 14 | ||
| 13 | namespace VideoCommon { | 15 | namespace VideoCommon { |
| 14 | 16 | ||
| 17 | using Tegra::Engines::Maxwell3D; | ||
| 15 | using Tegra::Texture::TextureType; | 18 | using Tegra::Texture::TextureType; |
| 16 | using Tegra::Texture::TICEntry; | 19 | using Tegra::Texture::TICEntry; |
| 17 | using VideoCore::Surface::PixelFormat; | 20 | using VideoCore::Surface::PixelFormat; |
| @@ -107,12 +110,13 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { | |||
| 107 | } | 110 | } |
| 108 | } | 111 | } |
| 109 | 112 | ||
| 110 | ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept { | 113 | ImageInfo::ImageInfo(const Maxwell3D::Regs& regs, size_t index) noexcept { |
| 111 | const auto& rt = regs.rt[index]; | 114 | const auto& rt = regs.rt[index]; |
| 112 | format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format); | 115 | format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format); |
| 113 | rescaleable = false; | 116 | rescaleable = false; |
| 114 | if (rt.tile_mode.is_pitch_linear) { | 117 | if (rt.tile_mode.is_pitch_linear) { |
| 115 | ASSERT(rt.tile_mode.is_3d == 0); | 118 | ASSERT(rt.tile_mode.dim_control == |
| 119 | Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesArray); | ||
| 116 | type = ImageType::Linear; | 120 | type = ImageType::Linear; |
| 117 | pitch = rt.width; | 121 | pitch = rt.width; |
| 118 | size = Extent3D{ | 122 | size = Extent3D{ |
| @@ -124,15 +128,16 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) | |||
| 124 | } | 128 | } |
| 125 | size.width = rt.width; | 129 | size.width = rt.width; |
| 126 | size.height = rt.height; | 130 | size.height = rt.height; |
| 127 | layer_stride = rt.layer_stride * 4; | 131 | layer_stride = rt.array_pitch * 4; |
| 128 | maybe_unaligned_layer_stride = layer_stride; | 132 | maybe_unaligned_layer_stride = layer_stride; |
| 129 | num_samples = NumSamples(regs.multisample_mode); | 133 | num_samples = NumSamples(regs.anti_alias_samples_mode); |
| 130 | block = Extent3D{ | 134 | block = Extent3D{ |
| 131 | .width = rt.tile_mode.block_width, | 135 | .width = rt.tile_mode.block_width, |
| 132 | .height = rt.tile_mode.block_height, | 136 | .height = rt.tile_mode.block_height, |
| 133 | .depth = rt.tile_mode.block_depth, | 137 | .depth = rt.tile_mode.block_depth, |
| 134 | }; | 138 | }; |
| 135 | if (rt.tile_mode.is_3d) { | 139 | if (rt.tile_mode.dim_control == |
| 140 | Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesDepth) { | ||
| 136 | type = ImageType::e3D; | 141 | type = ImageType::e3D; |
| 137 | size.depth = rt.depth; | 142 | size.depth = rt.depth; |
| 138 | } else { | 143 | } else { |
| @@ -146,31 +151,37 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) | |||
| 146 | 151 | ||
| 147 | ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept { | 152 | ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept { |
| 148 | format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format); | 153 | format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format); |
| 149 | size.width = regs.zeta_width; | 154 | size.width = regs.zeta_size.width; |
| 150 | size.height = regs.zeta_height; | 155 | size.height = regs.zeta_size.height; |
| 151 | rescaleable = false; | 156 | rescaleable = false; |
| 152 | resources.levels = 1; | 157 | resources.levels = 1; |
| 153 | layer_stride = regs.zeta.layer_stride * 4; | 158 | layer_stride = regs.zeta.array_pitch * 4; |
| 154 | maybe_unaligned_layer_stride = layer_stride; | 159 | maybe_unaligned_layer_stride = layer_stride; |
| 155 | num_samples = NumSamples(regs.multisample_mode); | 160 | num_samples = NumSamples(regs.anti_alias_samples_mode); |
| 156 | block = Extent3D{ | 161 | block = Extent3D{ |
| 157 | .width = regs.zeta.tile_mode.block_width, | 162 | .width = regs.zeta.tile_mode.block_width, |
| 158 | .height = regs.zeta.tile_mode.block_height, | 163 | .height = regs.zeta.tile_mode.block_height, |
| 159 | .depth = regs.zeta.tile_mode.block_depth, | 164 | .depth = regs.zeta.tile_mode.block_depth, |
| 160 | }; | 165 | }; |
| 161 | if (regs.zeta.tile_mode.is_pitch_linear) { | 166 | if (regs.zeta.tile_mode.is_pitch_linear) { |
| 162 | ASSERT(regs.zeta.tile_mode.is_3d == 0); | 167 | ASSERT(regs.zeta.tile_mode.dim_control == |
| 168 | Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesArray); | ||
| 163 | type = ImageType::Linear; | 169 | type = ImageType::Linear; |
| 164 | pitch = size.width * BytesPerBlock(format); | 170 | pitch = size.width * BytesPerBlock(format); |
| 165 | } else if (regs.zeta.tile_mode.is_3d) { | 171 | } else if (regs.zeta.tile_mode.dim_control == |
| 172 | Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesDepth) { | ||
| 166 | ASSERT(regs.zeta.tile_mode.is_pitch_linear == 0); | 173 | ASSERT(regs.zeta.tile_mode.is_pitch_linear == 0); |
| 174 | ASSERT(regs.zeta_size.dim_control == | ||
| 175 | Maxwell3D::Regs::ZetaSize::DimensionControl::ArraySizeOne); | ||
| 167 | type = ImageType::e3D; | 176 | type = ImageType::e3D; |
| 168 | size.depth = regs.zeta_depth; | 177 | size.depth = regs.zeta_size.depth; |
| 169 | } else { | 178 | } else { |
| 179 | ASSERT(regs.zeta_size.dim_control == | ||
| 180 | Maxwell3D::Regs::ZetaSize::DimensionControl::DepthDefinesArray); | ||
| 170 | rescaleable = block.depth == 0; | 181 | rescaleable = block.depth == 0; |
| 171 | downscaleable = size.height > 512; | 182 | downscaleable = size.height > 512; |
| 172 | type = ImageType::e2D; | 183 | type = ImageType::e2D; |
| 173 | resources.layers = regs.zeta_depth; | 184 | resources.layers = regs.zeta_size.depth; |
| 174 | } | 185 | } |
| 175 | } | 186 | } |
| 176 | 187 | ||
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index eaf4a1c95..413baf730 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -189,15 +189,16 @@ typename P::Sampler* TextureCache<P>::GetComputeSampler(u32 index) { | |||
| 189 | 189 | ||
| 190 | template <class P> | 190 | template <class P> |
| 191 | void TextureCache<P>::SynchronizeGraphicsDescriptors() { | 191 | void TextureCache<P>::SynchronizeGraphicsDescriptors() { |
| 192 | using SamplerIndex = Tegra::Engines::Maxwell3D::Regs::SamplerIndex; | 192 | using SamplerBinding = Tegra::Engines::Maxwell3D::Regs::SamplerBinding; |
| 193 | const bool linked_tsc = maxwell3d->regs.sampler_index == SamplerIndex::ViaHeaderIndex; | 193 | const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding; |
| 194 | const u32 tic_limit = maxwell3d->regs.tic.limit; | 194 | const u32 tic_limit = maxwell3d->regs.tex_header.limit; |
| 195 | const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tsc.limit; | 195 | const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit; |
| 196 | if (channel_state->graphics_sampler_table.Synchornize(maxwell3d->regs.tsc.Address(), | 196 | if (channel_state->graphics_sampler_table.Synchornize(maxwell3d->regs.tex_sampler.Address(), |
| 197 | tsc_limit)) { | 197 | tsc_limit)) { |
| 198 | channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); | 198 | channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); |
| 199 | } | 199 | } |
| 200 | if (channel_state->graphics_image_table.Synchornize(maxwell3d->regs.tic.Address(), tic_limit)) { | 200 | if (channel_state->graphics_image_table.Synchornize(maxwell3d->regs.tex_header.Address(), |
| 201 | tic_limit)) { | ||
| 201 | channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); | 202 | channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); |
| 202 | } | 203 | } |
| 203 | } | 204 | } |
| @@ -352,8 +353,8 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 352 | down_shift = Settings::values.resolution_info.down_shift; | 353 | down_shift = Settings::values.resolution_info.down_shift; |
| 353 | } | 354 | } |
| 354 | render_targets.size = Extent2D{ | 355 | render_targets.size = Extent2D{ |
| 355 | (maxwell3d->regs.render_area.width * up_scale) >> down_shift, | 356 | (maxwell3d->regs.surface_clip.width * up_scale) >> down_shift, |
| 356 | (maxwell3d->regs.render_area.height * up_scale) >> down_shift, | 357 | (maxwell3d->regs.surface_clip.height * up_scale) >> down_shift, |
| 357 | }; | 358 | }; |
| 358 | render_targets.is_rescaled = is_rescaling; | 359 | render_targets.is_rescaled = is_rescaling; |
| 359 | 360 | ||
| @@ -1980,7 +1981,7 @@ bool TextureCache<P>::IsFullClear(ImageViewId id) { | |||
| 1980 | // Images with multiple resources can't be cleared in a single call | 1981 | // Images with multiple resources can't be cleared in a single call |
| 1981 | return false; | 1982 | return false; |
| 1982 | } | 1983 | } |
| 1983 | if (regs.clear_flags.scissor == 0) { | 1984 | if (regs.clear_control.use_scissor == 0) { |
| 1984 | // If scissor testing is disabled, the clear is always full | 1985 | // If scissor testing is disabled, the clear is always full |
| 1985 | return true; | 1986 | return true; |
| 1986 | } | 1987 | } |
diff --git a/src/video_core/transform_feedback.cpp b/src/video_core/transform_feedback.cpp index 7e605981c..45071185a 100644 --- a/src/video_core/transform_feedback.cpp +++ b/src/video_core/transform_feedback.cpp | |||
| @@ -15,51 +15,51 @@ namespace VideoCommon { | |||
| 15 | std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings( | 15 | std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings( |
| 16 | const TransformFeedbackState& state) { | 16 | const TransformFeedbackState& state) { |
| 17 | static constexpr std::array VECTORS{ | 17 | static constexpr std::array VECTORS{ |
| 18 | 28, // gl_Position | 18 | 28U, // gl_Position |
| 19 | 32, // Generic 0 | 19 | 32U, // Generic 0 |
| 20 | 36, // Generic 1 | 20 | 36U, // Generic 1 |
| 21 | 40, // Generic 2 | 21 | 40U, // Generic 2 |
| 22 | 44, // Generic 3 | 22 | 44U, // Generic 3 |
| 23 | 48, // Generic 4 | 23 | 48U, // Generic 4 |
| 24 | 52, // Generic 5 | 24 | 52U, // Generic 5 |
| 25 | 56, // Generic 6 | 25 | 56U, // Generic 6 |
| 26 | 60, // Generic 7 | 26 | 60U, // Generic 7 |
| 27 | 64, // Generic 8 | 27 | 64U, // Generic 8 |
| 28 | 68, // Generic 9 | 28 | 68U, // Generic 9 |
| 29 | 72, // Generic 10 | 29 | 72U, // Generic 10 |
| 30 | 76, // Generic 11 | 30 | 76U, // Generic 11 |
| 31 | 80, // Generic 12 | 31 | 80U, // Generic 12 |
| 32 | 84, // Generic 13 | 32 | 84U, // Generic 13 |
| 33 | 88, // Generic 14 | 33 | 88U, // Generic 14 |
| 34 | 92, // Generic 15 | 34 | 92U, // Generic 15 |
| 35 | 96, // Generic 16 | 35 | 96U, // Generic 16 |
| 36 | 100, // Generic 17 | 36 | 100U, // Generic 17 |
| 37 | 104, // Generic 18 | 37 | 104U, // Generic 18 |
| 38 | 108, // Generic 19 | 38 | 108U, // Generic 19 |
| 39 | 112, // Generic 20 | 39 | 112U, // Generic 20 |
| 40 | 116, // Generic 21 | 40 | 116U, // Generic 21 |
| 41 | 120, // Generic 22 | 41 | 120U, // Generic 22 |
| 42 | 124, // Generic 23 | 42 | 124U, // Generic 23 |
| 43 | 128, // Generic 24 | 43 | 128U, // Generic 24 |
| 44 | 132, // Generic 25 | 44 | 132U, // Generic 25 |
| 45 | 136, // Generic 26 | 45 | 136U, // Generic 26 |
| 46 | 140, // Generic 27 | 46 | 140U, // Generic 27 |
| 47 | 144, // Generic 28 | 47 | 144U, // Generic 28 |
| 48 | 148, // Generic 29 | 48 | 148U, // Generic 29 |
| 49 | 152, // Generic 30 | 49 | 152U, // Generic 30 |
| 50 | 156, // Generic 31 | 50 | 156U, // Generic 31 |
| 51 | 160, // gl_FrontColor | 51 | 160U, // gl_FrontColor |
| 52 | 164, // gl_FrontSecondaryColor | 52 | 164U, // gl_FrontSecondaryColor |
| 53 | 160, // gl_BackColor | 53 | 160U, // gl_BackColor |
| 54 | 164, // gl_BackSecondaryColor | 54 | 164U, // gl_BackSecondaryColor |
| 55 | 192, // gl_TexCoord[0] | 55 | 192U, // gl_TexCoord[0] |
| 56 | 196, // gl_TexCoord[1] | 56 | 196U, // gl_TexCoord[1] |
| 57 | 200, // gl_TexCoord[2] | 57 | 200U, // gl_TexCoord[2] |
| 58 | 204, // gl_TexCoord[3] | 58 | 204U, // gl_TexCoord[3] |
| 59 | 208, // gl_TexCoord[4] | 59 | 208U, // gl_TexCoord[4] |
| 60 | 212, // gl_TexCoord[5] | 60 | 212U, // gl_TexCoord[5] |
| 61 | 216, // gl_TexCoord[6] | 61 | 216U, // gl_TexCoord[6] |
| 62 | 220, // gl_TexCoord[7] | 62 | 220U, // gl_TexCoord[7] |
| 63 | }; | 63 | }; |
| 64 | std::vector<Shader::TransformFeedbackVarying> xfb(256); | 64 | std::vector<Shader::TransformFeedbackVarying> xfb(256); |
| 65 | for (size_t buffer = 0; buffer < state.layouts.size(); ++buffer) { | 65 | for (size_t buffer = 0; buffer < state.layouts.size(); ++buffer) { |
| @@ -68,8 +68,20 @@ std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings( | |||
| 68 | const u32 varying_count = layout.varying_count; | 68 | const u32 varying_count = layout.varying_count; |
| 69 | u32 highest = 0; | 69 | u32 highest = 0; |
| 70 | for (u32 offset = 0; offset < varying_count; ++offset) { | 70 | for (u32 offset = 0; offset < varying_count; ++offset) { |
| 71 | const u32 base_offset = offset; | 71 | const auto get_attribute = [&locations](u32 index) -> u32 { |
| 72 | const u8 location = locations[offset]; | 72 | switch (index % 4) { |
| 73 | case 0: | ||
| 74 | return locations[index / 4].attribute0.Value(); | ||
| 75 | case 1: | ||
| 76 | return locations[index / 4].attribute1.Value(); | ||
| 77 | case 2: | ||
| 78 | return locations[index / 4].attribute2.Value(); | ||
| 79 | case 3: | ||
| 80 | return locations[index / 4].attribute3.Value(); | ||
| 81 | } | ||
| 82 | UNREACHABLE(); | ||
| 83 | return 0; | ||
| 84 | }; | ||
| 73 | 85 | ||
| 74 | UNIMPLEMENTED_IF_MSG(layout.stream != 0, "Stream is not zero: {}", layout.stream); | 86 | UNIMPLEMENTED_IF_MSG(layout.stream != 0, "Stream is not zero: {}", layout.stream); |
| 75 | Shader::TransformFeedbackVarying varying{ | 87 | Shader::TransformFeedbackVarying varying{ |
| @@ -78,16 +90,18 @@ std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings( | |||
| 78 | .offset = offset * 4, | 90 | .offset = offset * 4, |
| 79 | .components = 1, | 91 | .components = 1, |
| 80 | }; | 92 | }; |
| 81 | if (std::ranges::find(VECTORS, Common::AlignDown(location, 4)) != VECTORS.end()) { | 93 | const u32 base_offset = offset; |
| 82 | UNIMPLEMENTED_IF_MSG(location % 4 != 0, "Unaligned TFB"); | 94 | const auto attribute{get_attribute(offset)}; |
| 95 | if (std::ranges::find(VECTORS, Common::AlignDown(attribute, 4)) != VECTORS.end()) { | ||
| 96 | UNIMPLEMENTED_IF_MSG(attribute % 4 != 0, "Unaligned TFB {}", attribute); | ||
| 83 | 97 | ||
| 84 | const u8 base_index = location / 4; | 98 | const auto base_index = attribute / 4; |
| 85 | while (offset + 1 < varying_count && base_index == locations[offset + 1] / 4) { | 99 | while (offset + 1 < varying_count && base_index == get_attribute(offset + 1) / 4) { |
| 86 | ++offset; | 100 | ++offset; |
| 87 | ++varying.components; | 101 | ++varying.components; |
| 88 | } | 102 | } |
| 89 | } | 103 | } |
| 90 | xfb[location] = varying; | 104 | xfb[attribute] = varying; |
| 91 | highest = std::max(highest, (base_offset + varying.components) * 4); | 105 | highest = std::max(highest, (base_offset + varying.components) * 4); |
| 92 | } | 106 | } |
| 93 | UNIMPLEMENTED_IF(highest != layout.stride); | 107 | UNIMPLEMENTED_IF(highest != layout.stride); |
diff --git a/src/video_core/transform_feedback.h b/src/video_core/transform_feedback.h index a519adb59..d13eb16c3 100644 --- a/src/video_core/transform_feedback.h +++ b/src/video_core/transform_feedback.h | |||
| @@ -19,7 +19,8 @@ struct TransformFeedbackState { | |||
| 19 | u32 stride; | 19 | u32 stride; |
| 20 | }; | 20 | }; |
| 21 | std::array<Layout, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> layouts; | 21 | std::array<Layout, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> layouts; |
| 22 | std::array<std::array<u8, 128>, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> | 22 | std::array<std::array<Tegra::Engines::Maxwell3D::Regs::StreamOutLayout, 32>, |
| 23 | Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> | ||
| 23 | varyings; | 24 | varyings; |
| 24 | }; | 25 | }; |
| 25 | 26 | ||