mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #337 from Subv/used_buffers
GPU: Don't use explicit binding points when uploading the constbuffers to opengl
This commit is contained in:
		
						commit
						d6d7d0989c
					
				| @ -193,6 +193,9 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size | ||||
|     auto& gpu = Core::System().GetInstance().GPU().Maxwell3D(); | ||||
|     ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!"); | ||||
| 
 | ||||
|     // Next available bindpoint to use when uploading the const buffers to the GLSL shaders.
 | ||||
|     u32 current_constbuffer_bindpoint = 0; | ||||
| 
 | ||||
|     for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { | ||||
|         ptr_pos += sizeof(GLShader::MaxwellUniformData); | ||||
| 
 | ||||
| @ -244,9 +247,13 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size | ||||
|             UNREACHABLE(); | ||||
|         } | ||||
| 
 | ||||
|         GLuint gl_stage_program = shader_program_manager->GetCurrentProgramStage( | ||||
|             static_cast<Maxwell::ShaderStage>(stage)); | ||||
| 
 | ||||
|         // Configure the const buffers for this shader stage.
 | ||||
|         SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), | ||||
|                           shader_resources.const_buffer_entries); | ||||
|         current_constbuffer_bindpoint = | ||||
|             SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), gl_stage_program, | ||||
|                               current_constbuffer_bindpoint, shader_resources.const_buffer_entries); | ||||
|     } | ||||
| 
 | ||||
|     shader_program_manager->UseTrivialGeometryShader(); | ||||
| @ -543,8 +550,9 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, | ||||
|                                          const std::vector<GLShader::ConstBufferEntry>& entries) { | ||||
| u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint program, | ||||
|                                         u32 current_bindpoint, | ||||
|                                         const std::vector<GLShader::ConstBufferEntry>& entries) { | ||||
|     auto& gpu = Core::System::GetInstance().GPU(); | ||||
|     auto& maxwell3d = gpu.Get3DEngine(); | ||||
| 
 | ||||
| @ -568,7 +576,7 @@ void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, | ||||
| 
 | ||||
|         ASSERT_MSG(buffer.enabled, "Attempted to upload disabled constbuffer"); | ||||
|         buffer_draw_state.enabled = true; | ||||
|         buffer_draw_state.bindpoint = bindpoint; | ||||
|         buffer_draw_state.bindpoint = current_bindpoint + bindpoint; | ||||
| 
 | ||||
|         VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address); | ||||
|         std::vector<u8> data(used_buffer.GetSize() * sizeof(float)); | ||||
| @ -577,9 +585,18 @@ void RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, | ||||
|         glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); | ||||
|         glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); | ||||
|         glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); | ||||
| 
 | ||||
|         // Now configure the bindpoint of the buffer inside the shader
 | ||||
|         std::string buffer_name = used_buffer.GetName(); | ||||
|         GLuint index = | ||||
|             glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, buffer_name.c_str()); | ||||
|         if (index != -1) | ||||
|             glShaderStorageBlockBinding(program, index, buffer_draw_state.bindpoint); | ||||
|     } | ||||
| 
 | ||||
|     state.Apply(); | ||||
| 
 | ||||
|     return current_bindpoint + entries.size(); | ||||
| } | ||||
| 
 | ||||
| void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface, | ||||
|  | ||||
| @ -87,9 +87,17 @@ private: | ||||
|     /// Binds the required textures to OpenGL before drawing a batch.
 | ||||
|     void BindTextures(); | ||||
| 
 | ||||
|     /// Configures the current constbuffers to use for the draw command.
 | ||||
|     void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, | ||||
|                            const std::vector<GLShader::ConstBufferEntry>& entries); | ||||
|     /*
 | ||||
|      * Configures the current constbuffers to use for the draw command. | ||||
|      * @param stage The shader stage to configure buffers for. | ||||
|      * @param program The OpenGL program object that contains the specified stage. | ||||
|      * @param current_bindpoint The offset at which to start counting new buffer bindpoints. | ||||
|      * @param entries Vector describing the buffers that are actually used in the guest shader. | ||||
|      * @returns The next available bindpoint for use in the next shader stage. | ||||
|      */ | ||||
|     u32 SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, GLuint program, | ||||
|                           u32 current_bindpoint, | ||||
|                           const std::vector<GLShader::ConstBufferEntry>& entries); | ||||
| 
 | ||||
|     /// Syncs the viewport to match the guest state
 | ||||
|     void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale); | ||||
|  | ||||
| @ -192,7 +192,7 @@ private: | ||||
| 
 | ||||
|     /// Generates code representing a uniform (C buffer) register.
 | ||||
|     std::string GetUniform(const Uniform& reg) { | ||||
|         declr_const_buffers[reg.index].MarkAsUsed(reg.index, reg.offset); | ||||
|         declr_const_buffers[reg.index].MarkAsUsed(reg.index, reg.offset, stage); | ||||
|         return 'c' + std::to_string(reg.index) + '[' + std::to_string(reg.offset) + ']'; | ||||
|     } | ||||
| 
 | ||||
| @ -478,8 +478,7 @@ private: | ||||
| 
 | ||||
|         unsigned const_buffer_layout = 0; | ||||
|         for (const auto& entry : GetConstBuffersDeclarations()) { | ||||
|             declarations.AddLine("layout(std430, binding = " + std::to_string(const_buffer_layout) + | ||||
|                                  ") buffer c" + std::to_string(entry.GetIndex()) + "_buffer"); | ||||
|             declarations.AddLine("layout(std430) buffer " + entry.GetName()); | ||||
|             declarations.AddLine("{"); | ||||
|             declarations.AddLine("    float c" + std::to_string(entry.GetIndex()) + "[];"); | ||||
|             declarations.AddLine("};"); | ||||
|  | ||||
| @ -19,10 +19,13 @@ constexpr size_t MAX_PROGRAM_CODE_LENGTH{0x1000}; | ||||
| using ProgramCode = std::array<u64, MAX_PROGRAM_CODE_LENGTH>; | ||||
| 
 | ||||
| class ConstBufferEntry { | ||||
|     using Maxwell = Tegra::Engines::Maxwell3D::Regs; | ||||
| 
 | ||||
| public: | ||||
|     void MarkAsUsed(unsigned index, unsigned offset) { | ||||
|     void MarkAsUsed(unsigned index, unsigned offset, Maxwell::ShaderStage stage) { | ||||
|         is_used = true; | ||||
|         this->index = index; | ||||
|         this->stage = stage; | ||||
|         max_offset = std::max(max_offset, offset); | ||||
|     } | ||||
| 
 | ||||
| @ -38,10 +41,19 @@ public: | ||||
|         return max_offset + 1; | ||||
|     } | ||||
| 
 | ||||
|     std::string GetName() const { | ||||
|         return BufferBaseNames[static_cast<size_t>(stage)] + std::to_string(index); | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     static constexpr std::array<const char*, Maxwell::MaxShaderStage> BufferBaseNames = { | ||||
|         "buffer_vs_c", "buffer_tessc_c", "buffer_tesse_c", "buffer_gs_c", "buffer_fs_c", | ||||
|     }; | ||||
| 
 | ||||
|     bool is_used{}; | ||||
|     unsigned index{}; | ||||
|     unsigned max_offset{}; | ||||
|     Maxwell::ShaderStage stage; | ||||
| }; | ||||
| 
 | ||||
| struct ShaderEntries { | ||||
|  | ||||
| @ -121,6 +121,17 @@ public: | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) { | ||||
|         switch (stage) { | ||||
|         case Maxwell3D::Regs::ShaderStage::Vertex: | ||||
|             return current.vs; | ||||
|         case Maxwell3D::Regs::ShaderStage::Fragment: | ||||
|             return current.fs; | ||||
|         } | ||||
| 
 | ||||
|         UNREACHABLE(); | ||||
|     } | ||||
| 
 | ||||
|     void UseTrivialGeometryShader() { | ||||
|         current.gs = 0; | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei