forked from eden-emu/eden
		
	gl_rasterizer: Generate shaders and upload uniforms.
This commit is contained in:
		
							parent
							
								
									8df3222eb3
								
							
						
					
					
						commit
						1a3dbd49ef
					
				
					 2 changed files with 77 additions and 32 deletions
				
			
		|  | @ -96,10 +96,14 @@ RasterizerOpenGL::RasterizerOpenGL() { | ||||||
| 
 | 
 | ||||||
|     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer->GetHandle()); |     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer->GetHandle()); | ||||||
| 
 | 
 | ||||||
|     vs_uniform_buffer.Create(); |     for (unsigned index = 0; index < uniform_buffers.size(); ++index) { | ||||||
|     glBindBuffer(GL_UNIFORM_BUFFER, vs_uniform_buffer.handle); |         auto& buffer = uniform_buffers[index]; | ||||||
|     glBufferData(GL_UNIFORM_BUFFER, sizeof(GLShader::VSUniformData), nullptr, GL_STREAM_COPY); |         buffer.Create(); | ||||||
|     glBindBufferBase(GL_UNIFORM_BUFFER, 1, vs_uniform_buffer.handle); |         glBindBuffer(GL_UNIFORM_BUFFER, buffer.handle); | ||||||
|  |         glBufferData(GL_UNIFORM_BUFFER, sizeof(GLShader::MaxwellUniformData), nullptr, | ||||||
|  |                      GL_STREAM_COPY); | ||||||
|  |         glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer.handle); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     accelerate_draw = AccelDraw::Disabled; |     accelerate_draw = AccelDraw::Disabled; | ||||||
| 
 | 
 | ||||||
|  | @ -167,15 +171,69 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { | ||||||
|     buffer_offset += data_size; |     buffer_offset += data_size; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SetupVertexShader(GLShader::VSUniformData* ub_ptr, GLintptr buffer_offset) { | void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos) { | ||||||
|     MICROPROFILE_SCOPE(OpenGL_VS); |     // Helper function for uploading uniform data
 | ||||||
|     UNREACHABLE(); |     const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { | ||||||
| } |         if (has_ARB_direct_state_access) { | ||||||
|  |             glCopyNamedBufferSubData(stream_buffer->GetHandle(), handle, offset, 0, size); | ||||||
|  |         } else { | ||||||
|  |             glBindBuffer(GL_COPY_WRITE_BUFFER, handle); | ||||||
|  |             glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SetupFragmentShader(GLShader::FSUniformData* ub_ptr, |     auto& gpu = Core::System().GetInstance().GPU().Maxwell3D(); | ||||||
|                                            GLintptr buffer_offset) { |     ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!"); | ||||||
|     MICROPROFILE_SCOPE(OpenGL_FS); | 
 | ||||||
|     UNREACHABLE(); |     for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { | ||||||
|  |         ptr_pos += sizeof(GLShader::MaxwellUniformData); | ||||||
|  | 
 | ||||||
|  |         auto& shader_config = gpu.regs.shader_config[index]; | ||||||
|  |         const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)}; | ||||||
|  | 
 | ||||||
|  |         // VertexB program is always enabled, despite bit setting
 | ||||||
|  |         const bool is_enabled{shader_config.enable || program == Maxwell::ShaderProgram::VertexB}; | ||||||
|  | 
 | ||||||
|  |         // Skip stages that are not enabled
 | ||||||
|  |         if (!is_enabled) { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Upload uniform data as one UBO per stage
 | ||||||
|  |         const auto& stage = index - 1; // Stage indices are 0 - 5
 | ||||||
|  |         const GLintptr ubo_offset = buffer_offset + static_cast<GLintptr>(ptr_pos); | ||||||
|  |         copy_buffer(uniform_buffers[stage].handle, ubo_offset, | ||||||
|  |                     sizeof(GLShader::MaxwellUniformData)); | ||||||
|  |         GLShader::MaxwellUniformData* ub_ptr = | ||||||
|  |             reinterpret_cast<GLShader::MaxwellUniformData*>(&buffer_ptr[ptr_pos]); | ||||||
|  |         ub_ptr->SetFromRegs(gpu.state.shader_stages[stage]); | ||||||
|  | 
 | ||||||
|  |         // Fetch program code from memory
 | ||||||
|  |         GLShader::ProgramCode program_code; | ||||||
|  |         const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; | ||||||
|  |         const VAddr cpu_address{gpu.memory_manager.PhysicalToVirtualAddress(gpu_address)}; | ||||||
|  |         Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64)); | ||||||
|  |         GLShader::ShaderSetup setup{std::move(program_code)}; | ||||||
|  | 
 | ||||||
|  |         switch (program) { | ||||||
|  |         case Maxwell::ShaderProgram::VertexB: { | ||||||
|  |             GLShader::MaxwellVSConfig vs_config{setup}; | ||||||
|  |             shader_program_manager->UseProgrammableVertexShader(vs_config, setup); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         case Maxwell::ShaderProgram::Fragment: { | ||||||
|  |             GLShader::MaxwellFSConfig fs_config{setup}; | ||||||
|  |             shader_program_manager->UseProgrammableFragmentShader(fs_config, setup); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         default: | ||||||
|  |             LOG_CRITICAL(HW_GPU, "Unimplemented shader index=%d, enable=%d, offset=0x%08X", index, | ||||||
|  |                          shader_config.enable.Value(), shader_config.offset); | ||||||
|  |             UNREACHABLE(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     shader_program_manager->UseTrivialGeometryShader(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { | bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { | ||||||
|  | @ -260,7 +318,9 @@ void RasterizerOpenGL::DrawArrays() { | ||||||
|     if (is_indexed) { |     if (is_indexed) { | ||||||
|         UNREACHABLE(); |         UNREACHABLE(); | ||||||
|     } |     } | ||||||
|     buffer_size += sizeof(GLShader::VSUniformData); | 
 | ||||||
|  |     // Uniform space for the 5 shader stages
 | ||||||
|  |     buffer_size += sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; | ||||||
| 
 | 
 | ||||||
|     size_t ptr_pos = 0; |     size_t ptr_pos = 0; | ||||||
|     u8* buffer_ptr; |     u8* buffer_ptr; | ||||||
|  | @ -276,24 +336,10 @@ void RasterizerOpenGL::DrawArrays() { | ||||||
|         UNREACHABLE(); |         UNREACHABLE(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     SetupVertexShader(reinterpret_cast<GLShader::VSUniformData*>(&buffer_ptr[ptr_pos]), |     SetupShaders(buffer_ptr, buffer_offset, ptr_pos); | ||||||
|                       buffer_offset + static_cast<GLintptr>(ptr_pos)); |  | ||||||
|     const GLintptr vs_ubo_offset = buffer_offset + static_cast<GLintptr>(ptr_pos); |  | ||||||
|     ptr_pos += sizeof(GLShader::VSUniformData); |  | ||||||
| 
 | 
 | ||||||
|     stream_buffer->Unmap(); |     stream_buffer->Unmap(); | ||||||
| 
 | 
 | ||||||
|     const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { |  | ||||||
|         if (has_ARB_direct_state_access) { |  | ||||||
|             glCopyNamedBufferSubData(stream_buffer->GetHandle(), handle, offset, 0, size); |  | ||||||
|         } else { |  | ||||||
|             glBindBuffer(GL_COPY_WRITE_BUFFER, handle); |  | ||||||
|             glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size); |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     copy_buffer(vs_uniform_buffer.handle, vs_ubo_offset, sizeof(GLShader::VSUniformData)); |  | ||||||
| 
 |  | ||||||
|     shader_program_manager->ApplyTo(state); |     shader_program_manager->ApplyTo(state); | ||||||
|     state.Apply(); |     state.Apply(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,6 +15,7 @@ | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/hash.h" | #include "common/hash.h" | ||||||
| #include "common/vector_math.h" | #include "common/vector_math.h" | ||||||
|  | #include "video_core/engines/maxwell_3d.h" | ||||||
| #include "video_core/rasterizer_interface.h" | #include "video_core/rasterizer_interface.h" | ||||||
| #include "video_core/renderer_opengl/gl_rasterizer_cache.h" | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" | ||||||
| #include "video_core/renderer_opengl/gl_resource_manager.h" | #include "video_core/renderer_opengl/gl_resource_manager.h" | ||||||
|  | @ -141,11 +142,9 @@ private: | ||||||
|     void AnalyzeVertexArray(bool is_indexed); |     void AnalyzeVertexArray(bool is_indexed); | ||||||
|     void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset); |     void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset); | ||||||
| 
 | 
 | ||||||
|     OGLBuffer vs_uniform_buffer; |     std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> uniform_buffers; | ||||||
| 
 | 
 | ||||||
|     void SetupVertexShader(GLShader::VSUniformData* ub_ptr, GLintptr buffer_offset); |     void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos); | ||||||
| 
 |  | ||||||
|     void SetupFragmentShader(GLShader::FSUniformData* ub_ptr, GLintptr buffer_offset); |  | ||||||
| 
 | 
 | ||||||
|     enum class AccelDraw { Disabled, Arrays, Indexed }; |     enum class AccelDraw { Disabled, Arrays, Indexed }; | ||||||
|     AccelDraw accelerate_draw; |     AccelDraw accelerate_draw; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei