|
|
@ -36,7 +36,8 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
|
|
|
|
MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
|
|
|
|
MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
|
|
|
|
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
|
|
|
MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
|
|
|
|
|
|
|
|
|
|
|
|
RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window) : emu_window{window} {
|
|
|
|
RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window)
|
|
|
|
|
|
|
|
: emu_window{window}, stream_buffer(GL_ARRAY_BUFFER, STREAM_BUFFER_SIZE) {
|
|
|
|
// Create sampler objects
|
|
|
|
// Create sampler objects
|
|
|
|
for (size_t i = 0; i < texture_samplers.size(); ++i) {
|
|
|
|
for (size_t i = 0; i < texture_samplers.size(); ++i) {
|
|
|
|
texture_samplers[i].Create();
|
|
|
|
texture_samplers[i].Create();
|
|
|
@ -57,9 +58,7 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window) : emu_wind
|
|
|
|
const std::string_view extension{
|
|
|
|
const std::string_view extension{
|
|
|
|
reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i))};
|
|
|
|
reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i))};
|
|
|
|
|
|
|
|
|
|
|
|
if (extension == "GL_ARB_buffer_storage") {
|
|
|
|
if (extension == "GL_ARB_direct_state_access") {
|
|
|
|
has_ARB_buffer_storage = true;
|
|
|
|
|
|
|
|
} else if (extension == "GL_ARB_direct_state_access") {
|
|
|
|
|
|
|
|
has_ARB_direct_state_access = true;
|
|
|
|
has_ARB_direct_state_access = true;
|
|
|
|
} else if (extension == "GL_ARB_separate_shader_objects") {
|
|
|
|
} else if (extension == "GL_ARB_separate_shader_objects") {
|
|
|
|
has_ARB_separate_shader_objects = true;
|
|
|
|
has_ARB_separate_shader_objects = true;
|
|
|
@ -86,16 +85,14 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window) : emu_wind
|
|
|
|
|
|
|
|
|
|
|
|
hw_vao.Create();
|
|
|
|
hw_vao.Create();
|
|
|
|
|
|
|
|
|
|
|
|
stream_buffer = OGLStreamBuffer::MakeBuffer(has_ARB_buffer_storage, GL_ARRAY_BUFFER);
|
|
|
|
state.draw.vertex_buffer = stream_buffer.GetHandle();
|
|
|
|
stream_buffer->Create(STREAM_BUFFER_SIZE, STREAM_BUFFER_SIZE / 2);
|
|
|
|
|
|
|
|
state.draw.vertex_buffer = stream_buffer->GetHandle();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
shader_program_manager = std::make_unique<GLShader::ProgramManager>();
|
|
|
|
shader_program_manager = std::make_unique<GLShader::ProgramManager>();
|
|
|
|
state.draw.shader_program = 0;
|
|
|
|
state.draw.shader_program = 0;
|
|
|
|
state.draw.vertex_array = hw_vao.handle;
|
|
|
|
state.draw.vertex_array = hw_vao.handle;
|
|
|
|
state.Apply();
|
|
|
|
state.Apply();
|
|
|
|
|
|
|
|
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer->GetHandle());
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer.GetHandle());
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned index = 0; index < uniform_buffers.size(); ++index) {
|
|
|
|
for (unsigned index = 0; index < uniform_buffers.size(); ++index) {
|
|
|
|
auto& buffer = uniform_buffers[index];
|
|
|
|
auto& buffer = uniform_buffers[index];
|
|
|
@ -111,13 +108,7 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window) : emu_wind
|
|
|
|
LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!");
|
|
|
|
LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RasterizerOpenGL::~RasterizerOpenGL() {
|
|
|
|
RasterizerOpenGL::~RasterizerOpenGL() {}
|
|
|
|
if (stream_buffer != nullptr) {
|
|
|
|
|
|
|
|
state.draw.vertex_buffer = stream_buffer->GetHandle();
|
|
|
|
|
|
|
|
state.Apply();
|
|
|
|
|
|
|
|
stream_buffer->Release();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
|
|
|
|
std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
|
|
|
|
GLintptr buffer_offset) {
|
|
|
|
GLintptr buffer_offset) {
|
|
|
@ -126,7 +117,7 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
|
|
|
|
const auto& memory_manager = Core::System::GetInstance().GPU().memory_manager;
|
|
|
|
const auto& memory_manager = Core::System::GetInstance().GPU().memory_manager;
|
|
|
|
|
|
|
|
|
|
|
|
state.draw.vertex_array = hw_vao.handle;
|
|
|
|
state.draw.vertex_array = hw_vao.handle;
|
|
|
|
state.draw.vertex_buffer = stream_buffer->GetHandle();
|
|
|
|
state.draw.vertex_buffer = stream_buffer.GetHandle();
|
|
|
|
state.Apply();
|
|
|
|
state.Apply();
|
|
|
|
|
|
|
|
|
|
|
|
// Upload all guest vertex arrays sequentially to our buffer
|
|
|
|
// Upload all guest vertex arrays sequentially to our buffer
|
|
|
@ -145,7 +136,7 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
|
|
|
|
Memory::ReadBlock(*memory_manager->GpuToCpuAddress(start), array_ptr, size);
|
|
|
|
Memory::ReadBlock(*memory_manager->GpuToCpuAddress(start), array_ptr, size);
|
|
|
|
|
|
|
|
|
|
|
|
// Bind the vertex array to the buffer at the current offset.
|
|
|
|
// Bind the vertex array to the buffer at the current offset.
|
|
|
|
glBindVertexBuffer(index, stream_buffer->GetHandle(), buffer_offset, vertex_array.stride);
|
|
|
|
glBindVertexBuffer(index, stream_buffer.GetHandle(), buffer_offset, vertex_array.stride);
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_MSG(vertex_array.divisor == 0, "Vertex buffer divisor unimplemented");
|
|
|
|
ASSERT_MSG(vertex_array.divisor == 0, "Vertex buffer divisor unimplemented");
|
|
|
|
|
|
|
|
|
|
|
@ -205,7 +196,7 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) {
|
|
|
|
// Helper function for uploading uniform data
|
|
|
|
// Helper function for uploading uniform data
|
|
|
|
const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) {
|
|
|
|
const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) {
|
|
|
|
if (has_ARB_direct_state_access) {
|
|
|
|
if (has_ARB_direct_state_access) {
|
|
|
|
glCopyNamedBufferSubData(stream_buffer->GetHandle(), handle, offset, 0, size);
|
|
|
|
glCopyNamedBufferSubData(stream_buffer.GetHandle(), handle, offset, 0, size);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
glBindBuffer(GL_COPY_WRITE_BUFFER, handle);
|
|
|
|
glBindBuffer(GL_COPY_WRITE_BUFFER, handle);
|
|
|
|
glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size);
|
|
|
|
glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, offset, 0, size);
|
|
|
@ -456,7 +447,7 @@ void RasterizerOpenGL::DrawArrays() {
|
|
|
|
const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()};
|
|
|
|
const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()};
|
|
|
|
const unsigned vertex_num{is_indexed ? regs.index_array.count : regs.vertex_buffer.count};
|
|
|
|
const unsigned vertex_num{is_indexed ? regs.index_array.count : regs.vertex_buffer.count};
|
|
|
|
|
|
|
|
|
|
|
|
state.draw.vertex_buffer = stream_buffer->GetHandle();
|
|
|
|
state.draw.vertex_buffer = stream_buffer.GetHandle();
|
|
|
|
state.Apply();
|
|
|
|
state.Apply();
|
|
|
|
|
|
|
|
|
|
|
|
size_t buffer_size = CalculateVertexArraysSize();
|
|
|
|
size_t buffer_size = CalculateVertexArraysSize();
|
|
|
@ -471,8 +462,8 @@ void RasterizerOpenGL::DrawArrays() {
|
|
|
|
|
|
|
|
|
|
|
|
u8* buffer_ptr;
|
|
|
|
u8* buffer_ptr;
|
|
|
|
GLintptr buffer_offset;
|
|
|
|
GLintptr buffer_offset;
|
|
|
|
std::tie(buffer_ptr, buffer_offset) =
|
|
|
|
std::tie(buffer_ptr, buffer_offset, std::ignore) =
|
|
|
|
stream_buffer->Map(static_cast<GLsizeiptr>(buffer_size), 4);
|
|
|
|
stream_buffer.Map(static_cast<GLsizeiptr>(buffer_size), 4);
|
|
|
|
|
|
|
|
|
|
|
|
u8* offseted_buffer;
|
|
|
|
u8* offseted_buffer;
|
|
|
|
std::tie(offseted_buffer, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset);
|
|
|
|
std::tie(offseted_buffer, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset);
|
|
|
@ -500,7 +491,8 @@ void RasterizerOpenGL::DrawArrays() {
|
|
|
|
|
|
|
|
|
|
|
|
SetupShaders(offseted_buffer, buffer_offset);
|
|
|
|
SetupShaders(offseted_buffer, buffer_offset);
|
|
|
|
|
|
|
|
|
|
|
|
stream_buffer->Unmap();
|
|
|
|
// TODO: Don't use buffer_size here, use the updated buffer_offset.
|
|
|
|
|
|
|
|
stream_buffer.Unmap(buffer_size);
|
|
|
|
|
|
|
|
|
|
|
|
shader_program_manager->ApplyTo(state);
|
|
|
|
shader_program_manager->ApplyTo(state);
|
|
|
|
state.Apply();
|
|
|
|
state.Apply();
|
|
|
|