diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.h | 5 |
7 files changed, 28 insertions, 5 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index a46ed4bd7..68f91cc75 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -222,6 +222,18 @@ void Maxwell3D::DrawArrays() { | |||
| 222 | debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); | 222 | debug_context->OnEvent(Tegra::DebugContext::Event::FinishedPrimitiveBatch, nullptr); |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | // Both instance configuration registers can not be set at the same time. | ||
| 226 | ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, | ||
| 227 | "Illegal combination of instancing parameters"); | ||
| 228 | |||
| 229 | if (regs.draw.instance_next) { | ||
| 230 | // Increment the current instance *before* drawing. | ||
| 231 | state.current_instance += 1; | ||
| 232 | } else if (!regs.draw.instance_cont) { | ||
| 233 | // Reset the current instance to 0. | ||
| 234 | state.current_instance = 0; | ||
| 235 | } | ||
| 236 | |||
| 225 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; | 237 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; |
| 226 | rasterizer.AccelerateDrawBatch(is_indexed); | 238 | rasterizer.AccelerateDrawBatch(is_indexed); |
| 227 | 239 | ||
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 1b30ce018..771eb5abc 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -638,6 +638,8 @@ public: | |||
| 638 | union { | 638 | union { |
| 639 | u32 vertex_begin_gl; | 639 | u32 vertex_begin_gl; |
| 640 | BitField<0, 16, PrimitiveTopology> topology; | 640 | BitField<0, 16, PrimitiveTopology> topology; |
| 641 | BitField<26, 1, u32> instance_next; | ||
| 642 | BitField<27, 1, u32> instance_cont; | ||
| 641 | }; | 643 | }; |
| 642 | } draw; | 644 | } draw; |
| 643 | 645 | ||
| @@ -830,6 +832,7 @@ public: | |||
| 830 | }; | 832 | }; |
| 831 | 833 | ||
| 832 | std::array<ShaderStageInfo, Regs::MaxShaderStage> shader_stages; | 834 | std::array<ShaderStageInfo, Regs::MaxShaderStage> shader_stages; |
| 835 | u32 current_instance = 0; ///< Current instance to be used to simulate instanced rendering. | ||
| 833 | }; | 836 | }; |
| 834 | 837 | ||
| 835 | State state{}; | 838 | State state{}; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 9d1549fe9..93eadde7a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -124,7 +124,7 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | |||
| 124 | glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset, | 124 | glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset, |
| 125 | vertex_array.stride); | 125 | vertex_array.stride); |
| 126 | 126 | ||
| 127 | ASSERT_MSG(vertex_array.divisor == 0, "Vertex buffer divisor unimplemented"); | 127 | ASSERT_MSG(vertex_array.divisor == 0, "Instanced vertex arrays are not supported"); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. | 130 | // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index dabf98b74..5a05c79ef 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -538,7 +538,7 @@ private: | |||
| 538 | // vertex shader, and what's the value of the fourth element when inside a Tess Eval | 538 | // vertex shader, and what's the value of the fourth element when inside a Tess Eval |
| 539 | // shader. | 539 | // shader. |
| 540 | ASSERT(stage == Maxwell3D::Regs::ShaderStage::Vertex); | 540 | ASSERT(stage == Maxwell3D::Regs::ShaderStage::Vertex); |
| 541 | return "vec4(0, 0, uintBitsToFloat(gl_InstanceID), uintBitsToFloat(gl_VertexID))"; | 541 | return "vec4(0, 0, uintBitsToFloat(instance_id.x), uintBitsToFloat(gl_VertexID))"; |
| 542 | default: | 542 | default: |
| 543 | const u32 index{static_cast<u32>(attribute) - | 543 | const u32 index{static_cast<u32>(attribute) - |
| 544 | static_cast<u32>(Attribute::Index::Attribute_0)}; | 544 | static_cast<u32>(Attribute::Index::Attribute_0)}; |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 129c777d1..57e0e1726 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -38,6 +38,7 @@ out vec4 position; | |||
| 38 | 38 | ||
| 39 | layout (std140) uniform vs_config { | 39 | layout (std140) uniform vs_config { |
| 40 | vec4 viewport_flip; | 40 | vec4 viewport_flip; |
| 41 | uvec4 instance_id; | ||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | void main() { | 44 | void main() { |
| @@ -90,6 +91,7 @@ out vec4 color; | |||
| 90 | 91 | ||
| 91 | layout (std140) uniform fs_config { | 92 | layout (std140) uniform fs_config { |
| 92 | vec4 viewport_flip; | 93 | vec4 viewport_flip; |
| 94 | uvec4 instance_id; | ||
| 93 | }; | 95 | }; |
| 94 | 96 | ||
| 95 | void main() { | 97 | void main() { |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 415d42fda..f0886caac 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp | |||
| @@ -37,11 +37,16 @@ void SetShaderUniformBlockBindings(GLuint shader) { | |||
| 37 | } // namespace Impl | 37 | } // namespace Impl |
| 38 | 38 | ||
| 39 | void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) { | 39 | void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) { |
| 40 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 40 | const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); |
| 41 | const auto& regs = gpu.regs; | ||
| 42 | const auto& state = gpu.state; | ||
| 41 | 43 | ||
| 42 | // TODO(bunnei): Support more than one viewport | 44 | // TODO(bunnei): Support more than one viewport |
| 43 | viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; | 45 | viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; |
| 44 | viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; | 46 | viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; |
| 47 | |||
| 48 | // We only assign the instance to the first component of the vector, the rest is just padding. | ||
| 49 | instance_id[0] = state.current_instance; | ||
| 45 | } | 50 | } |
| 46 | 51 | ||
| 47 | } // namespace GLShader | 52 | } // namespace GLShader |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index 716933a0b..75fa73605 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -24,14 +24,15 @@ void SetShaderUniformBlockBindings(GLuint shader); | |||
| 24 | } // namespace Impl | 24 | } // namespace Impl |
| 25 | 25 | ||
| 26 | /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned | 26 | /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned |
| 27 | // NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at | 27 | // NOTE: Always keep a vec4 at the end. The GL spec is not clear whether the alignment at |
| 28 | // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. | 28 | // the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. |
| 29 | // Not following that rule will cause problems on some AMD drivers. | 29 | // Not following that rule will cause problems on some AMD drivers. |
| 30 | struct MaxwellUniformData { | 30 | struct MaxwellUniformData { |
| 31 | void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); | 31 | void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage); |
| 32 | alignas(16) GLvec4 viewport_flip; | 32 | alignas(16) GLvec4 viewport_flip; |
| 33 | alignas(16) GLuvec4 instance_id; | ||
| 33 | }; | 34 | }; |
| 34 | static_assert(sizeof(MaxwellUniformData) == 16, "MaxwellUniformData structure size is incorrect"); | 35 | static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect"); |
| 35 | static_assert(sizeof(MaxwellUniformData) < 16384, | 36 | static_assert(sizeof(MaxwellUniformData) < 16384, |
| 36 | "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); | 37 | "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); |
| 37 | 38 | ||