summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp12
-rw-r--r--src/video_core/engines/maxwell_3d.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h5
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
39layout (std140) uniform vs_config { 39layout (std140) uniform vs_config {
40 vec4 viewport_flip; 40 vec4 viewport_flip;
41 uvec4 instance_id;
41}; 42};
42 43
43void main() { 44void main() {
@@ -90,6 +91,7 @@ out vec4 color;
90 91
91layout (std140) uniform fs_config { 92layout (std140) uniform fs_config {
92 vec4 viewport_flip; 93 vec4 viewport_flip;
94 uvec4 instance_id;
93}; 95};
94 96
95void main() { 97void 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
39void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) { 39void 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.
30struct MaxwellUniformData { 30struct 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};
34static_assert(sizeof(MaxwellUniformData) == 16, "MaxwellUniformData structure size is incorrect"); 35static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect");
35static_assert(sizeof(MaxwellUniformData) < 16384, 36static_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