summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2018-08-11 19:21:31 -0500
committerGravatar Subv2018-08-14 22:25:07 -0500
commitc5284efd4f04bca05b1f5c61dce59090a7edf61e (patch)
treea4bf294444c67058812f010d01a60e44aa1c80b6 /src
parentMerge pull request #1069 from bunnei/vtx-sz (diff)
downloadyuzu-c5284efd4f04bca05b1f5c61dce59090a7edf61e.tar.gz
yuzu-c5284efd4f04bca05b1f5c61dce59090a7edf61e.tar.xz
yuzu-c5284efd4f04bca05b1f5c61dce59090a7edf61e.zip
Rasterizer: Implemented instanced rendering.
We keep track of the current instance and update an uniform in the shaders to let them know which instance they are. Instanced vertex arrays are not yet implemented.
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