mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-11-18 11:37:33 +01:00
gl_rasterizer: Generate shaders and upload uniforms.
This commit is contained in:
parent
85d77a3d24
commit
beddc8afd2
@ -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,16 +171,70 @@ 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto& gpu = Core::System().GetInstance().GPU().Maxwell3D();
|
||||||
|
ASSERT_MSG(!gpu.regs.shader_config[0].enable, "VertexA is unsupported!");
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::SetupFragmentShader(GLShader::FSUniformData* ub_ptr,
|
// Upload uniform data as one UBO per stage
|
||||||
GLintptr buffer_offset) {
|
const auto& stage = index - 1; // Stage indices are 0 - 5
|
||||||
MICROPROFILE_SCOPE(OpenGL_FS);
|
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();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_program_manager->UseTrivialGeometryShader();
|
||||||
|
}
|
||||||
|
|
||||||
bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
|
bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
|
||||||
accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays;
|
accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays;
|
||||||
@ -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…
Reference in New Issue
Block a user