summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-04-08 00:00:11 -0400
committerGravatar bunnei2018-04-13 23:48:29 -0400
commitbeddc8afd208a71b1ec0f012103e3ac3e058c140 (patch)
tree09e1302fb1feac9a8ac2fafd15fb537b279b5873 /src
parentgl_shader_decompiler: Basic impl. for very simple vertex shaders. (diff)
downloadyuzu-beddc8afd208a71b1ec0f012103e3ac3e058c140.tar.gz
yuzu-beddc8afd208a71b1ec0f012103e3ac3e058c140.tar.xz
yuzu-beddc8afd208a71b1ec0f012103e3ac3e058c140.zip
gl_rasterizer: Generate shaders and upload uniforms.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp102
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h7
2 files changed, 77 insertions, 32 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 2d58df45b..f75d4c658 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -96,10 +96,14 @@ RasterizerOpenGL::RasterizerOpenGL() {
96 96
97 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer->GetHandle()); 97 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer->GetHandle());
98 98
99 vs_uniform_buffer.Create(); 99 for (unsigned index = 0; index < uniform_buffers.size(); ++index) {
100 glBindBuffer(GL_UNIFORM_BUFFER, vs_uniform_buffer.handle); 100 auto& buffer = uniform_buffers[index];
101 glBufferData(GL_UNIFORM_BUFFER, sizeof(GLShader::VSUniformData), nullptr, GL_STREAM_COPY); 101 buffer.Create();
102 glBindBufferBase(GL_UNIFORM_BUFFER, 1, vs_uniform_buffer.handle); 102 glBindBuffer(GL_UNIFORM_BUFFER, buffer.handle);
103 glBufferData(GL_UNIFORM_BUFFER, sizeof(GLShader::MaxwellUniformData), nullptr,
104 GL_STREAM_COPY);
105 glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer.handle);
106 }
103 107
104 accelerate_draw = AccelDraw::Disabled; 108 accelerate_draw = AccelDraw::Disabled;
105 109
@@ -167,15 +171,69 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) {
167 buffer_offset += data_size; 171 buffer_offset += data_size;
168} 172}
169 173
170void RasterizerOpenGL::SetupVertexShader(GLShader::VSUniformData* ub_ptr, GLintptr buffer_offset) { 174void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos) {
171 MICROPROFILE_SCOPE(OpenGL_VS); 175 // Helper function for uploading uniform data
172 UNREACHABLE(); 176 const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) {
173} 177 if (has_ARB_direct_state_access) {
178 glCopyNamedBufferSubData(stream_buffer->GetHandle(), handle, offset, 0, size);
179 } else {
180 glBindBuffer(GL_COPY_WRITE_BUFFER, handle);
181 glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size);
182 }
183 };
174 184
175void RasterizerOpenGL::SetupFragmentShader(GLShader::FSUniformData* ub_ptr, 185 auto& gpu = Core::System().GetInstance().GPU().Maxwell3D();
176 GLintptr buffer_offset) { 186 ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!");
177 MICROPROFILE_SCOPE(OpenGL_FS); 187
178 UNREACHABLE(); 188 for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) {
189 ptr_pos += sizeof(GLShader::MaxwellUniformData);
190
191 auto& shader_config = gpu.regs.shader_config[index];
192 const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)};
193
194 // VertexB program is always enabled, despite bit setting
195 const bool is_enabled{shader_config.enable || program == Maxwell::ShaderProgram::VertexB};
196
197 // Skip stages that are not enabled
198 if (!is_enabled) {
199 continue;
200 }
201
202 // Upload uniform data as one UBO per stage
203 const auto& stage = index - 1; // Stage indices are 0 - 5
204 const GLintptr ubo_offset = buffer_offset + static_cast<GLintptr>(ptr_pos);
205 copy_buffer(uniform_buffers[stage].handle, ubo_offset,
206 sizeof(GLShader::MaxwellUniformData));
207 GLShader::MaxwellUniformData* ub_ptr =
208 reinterpret_cast<GLShader::MaxwellUniformData*>(&buffer_ptr[ptr_pos]);
209 ub_ptr->SetFromRegs(gpu.state.shader_stages[stage]);
210
211 // Fetch program code from memory
212 GLShader::ProgramCode program_code;
213 const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset};
214 const VAddr cpu_address{gpu.memory_manager.PhysicalToVirtualAddress(gpu_address)};
215 Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64));
216 GLShader::ShaderSetup setup{std::move(program_code)};
217
218 switch (program) {
219 case Maxwell::ShaderProgram::VertexB: {
220 GLShader::MaxwellVSConfig vs_config{setup};
221 shader_program_manager->UseProgrammableVertexShader(vs_config, setup);
222 break;
223 }
224 case Maxwell::ShaderProgram::Fragment: {
225 GLShader::MaxwellFSConfig fs_config{setup};
226 shader_program_manager->UseProgrammableFragmentShader(fs_config, setup);
227 break;
228 }
229 default:
230 LOG_CRITICAL(HW_GPU, "Unimplemented shader index=%d, enable=%d, offset=0x%08X", index,
231 shader_config.enable.Value(), shader_config.offset);
232 UNREACHABLE();
233 }
234 }
235
236 shader_program_manager->UseTrivialGeometryShader();
179} 237}
180 238
181bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { 239bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
@@ -260,7 +318,9 @@ void RasterizerOpenGL::DrawArrays() {
260 if (is_indexed) { 318 if (is_indexed) {
261 UNREACHABLE(); 319 UNREACHABLE();
262 } 320 }
263 buffer_size += sizeof(GLShader::VSUniformData); 321
322 // Uniform space for the 5 shader stages
323 buffer_size += sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage;
264 324
265 size_t ptr_pos = 0; 325 size_t ptr_pos = 0;
266 u8* buffer_ptr; 326 u8* buffer_ptr;
@@ -276,24 +336,10 @@ void RasterizerOpenGL::DrawArrays() {
276 UNREACHABLE(); 336 UNREACHABLE();
277 } 337 }
278 338
279 SetupVertexShader(reinterpret_cast<GLShader::VSUniformData*>(&buffer_ptr[ptr_pos]), 339 SetupShaders(buffer_ptr, buffer_offset, ptr_pos);
280 buffer_offset + static_cast<GLintptr>(ptr_pos));
281 const GLintptr vs_ubo_offset = buffer_offset + static_cast<GLintptr>(ptr_pos);
282 ptr_pos += sizeof(GLShader::VSUniformData);
283 340
284 stream_buffer->Unmap(); 341 stream_buffer->Unmap();
285 342
286 const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) {
287 if (has_ARB_direct_state_access) {
288 glCopyNamedBufferSubData(stream_buffer->GetHandle(), handle, offset, 0, size);
289 } else {
290 glBindBuffer(GL_COPY_WRITE_BUFFER, handle);
291 glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size);
292 }
293 };
294
295 copy_buffer(vs_uniform_buffer.handle, vs_ubo_offset, sizeof(GLShader::VSUniformData));
296
297 shader_program_manager->ApplyTo(state); 343 shader_program_manager->ApplyTo(state);
298 state.Apply(); 344 state.Apply();
299 345
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index b508f5acc..32b897eb2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -15,6 +15,7 @@
15#include "common/common_types.h" 15#include "common/common_types.h"
16#include "common/hash.h" 16#include "common/hash.h"
17#include "common/vector_math.h" 17#include "common/vector_math.h"
18#include "video_core/engines/maxwell_3d.h"
18#include "video_core/rasterizer_interface.h" 19#include "video_core/rasterizer_interface.h"
19#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 20#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
20#include "video_core/renderer_opengl/gl_resource_manager.h" 21#include "video_core/renderer_opengl/gl_resource_manager.h"
@@ -141,11 +142,9 @@ private:
141 void AnalyzeVertexArray(bool is_indexed); 142 void AnalyzeVertexArray(bool is_indexed);
142 void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset); 143 void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset);
143 144
144 OGLBuffer vs_uniform_buffer; 145 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> uniform_buffers;
145 146
146 void SetupVertexShader(GLShader::VSUniformData* ub_ptr, GLintptr buffer_offset); 147 void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos);
147
148 void SetupFragmentShader(GLShader::FSUniformData* ub_ptr, GLintptr buffer_offset);
149 148
150 enum class AccelDraw { Disabled, Arrays, Indexed }; 149 enum class AccelDraw { Disabled, Arrays, Indexed };
151 AccelDraw accelerate_draw; 150 AccelDraw accelerate_draw;