summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp19
-rw-r--r--src/video_core/engines/maxwell_3d.h5
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp82
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h24
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h3
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_state.h9
-rw-r--r--src/video_core/renderer_opengl/gl_stream_buffer.cpp26
-rw-r--r--src/video_core/renderer_opengl/gl_stream_buffer.h3
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp30
13 files changed, 151 insertions, 111 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 0ed7bc5d8..d64a5080b 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -135,6 +135,25 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
if (regs.reg_array[method_call.method] != method_call.argument) {
regs.reg_array[method_call.method] = method_call.argument;
+ // Color buffers
+ constexpr u32 first_rt_reg = MAXWELL3D_REG_INDEX(rt);
+ constexpr u32 registers_per_rt = sizeof(regs.rt[0]) / sizeof(u32);
+ if (method_call.method >= first_rt_reg &&
+ method_call.method < first_rt_reg + registers_per_rt * Regs::NumRenderTargets) {
+ const std::size_t rt_index = (method_call.method - first_rt_reg) / registers_per_rt;
+ dirty_flags.color_buffer |= 1u << static_cast<u32>(rt_index);
+ }
+
+ // Zeta buffer
+ constexpr u32 registers_in_zeta = sizeof(regs.zeta) / sizeof(u32);
+ if (method_call.method == MAXWELL3D_REG_INDEX(zeta_enable) ||
+ method_call.method == MAXWELL3D_REG_INDEX(zeta_width) ||
+ method_call.method == MAXWELL3D_REG_INDEX(zeta_height) ||
+ (method_call.method >= MAXWELL3D_REG_INDEX(zeta) &&
+ method_call.method < MAXWELL3D_REG_INDEX(zeta) + registers_in_zeta)) {
+ dirty_flags.zeta_buffer = true;
+ }
+
// Shader
constexpr u32 shader_registers_count =
sizeof(regs.shader_config[0]) * Regs::MaxShaderProgram / sizeof(u32);
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index d50e5a126..1f76aa670 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1089,12 +1089,17 @@ public:
MemoryManager& memory_manager;
struct DirtyFlags {
+ u8 color_buffer = 0xFF;
+ bool zeta_buffer = true;
+
bool shaders = true;
bool vertex_attrib_format = true;
u32 vertex_array = 0xFFFFFFFF;
void OnMemoryWrite() {
+ color_buffer = 0xFF;
+ zeta_buffer = true;
shaders = true;
vertex_array = 0xFFFFFFFF;
}
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 46a6c0308..bd2b30e77 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -14,7 +14,7 @@
namespace OpenGL {
OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size)
- : RasterizerCache{rasterizer}, stream_buffer(GL_ARRAY_BUFFER, size) {}
+ : RasterizerCache{rasterizer}, stream_buffer(size, true) {}
GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size,
std::size_t alignment, bool cache) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 27d259f51..2bf086902 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -135,27 +135,31 @@ void RasterizerOpenGL::CheckExtensions() {
}
}
-void RasterizerOpenGL::SetupVertexFormat() {
+GLuint RasterizerOpenGL::SetupVertexFormat() {
auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs;
- if (!gpu.dirty_flags.vertex_attrib_format)
- return;
+ if (!gpu.dirty_flags.vertex_attrib_format) {
+ return state.draw.vertex_array;
+ }
gpu.dirty_flags.vertex_attrib_format = false;
MICROPROFILE_SCOPE(OpenGL_VAO);
auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
- auto& VAO = iter->second;
+ auto& vao_entry = iter->second;
if (is_cache_miss) {
- VAO.Create();
- state.draw.vertex_array = VAO.handle;
- state.ApplyVertexBufferState();
+ vao_entry.Create();
+ const GLuint vao = vao_entry.handle;
- // The index buffer binding is stored within the VAO. Stupid OpenGL, but easy to work
- // around.
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_cache.GetHandle());
+ // Eventhough we are using DSA to create this vertex array, there is a bug on Intel's blob
+ // that fails to properly create the vertex array if it's not bound even after creating it
+ // with glCreateVertexArrays
+ state.draw.vertex_array = vao;
+ state.ApplyVertexArrayState();
+
+ glVertexArrayElementBuffer(vao, buffer_cache.GetHandle());
// Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
// Enables the first 16 vertex attributes always, as we don't know which ones are actually
@@ -163,7 +167,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
// for now to avoid OpenGL errors.
// TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
// assume every shader uses them all.
- for (unsigned index = 0; index < 16; ++index) {
+ for (u32 index = 0; index < 16; ++index) {
const auto& attrib = regs.vertex_attrib_format[index];
// Ignore invalid attributes.
@@ -178,28 +182,29 @@ void RasterizerOpenGL::SetupVertexFormat() {
ASSERT(buffer.IsEnabled());
- glEnableVertexAttribArray(index);
+ glEnableVertexArrayAttrib(vao, index);
if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
attrib.type ==
Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
- glVertexAttribIFormat(index, attrib.ComponentCount(),
- MaxwellToGL::VertexType(attrib), attrib.offset);
+ glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(),
+ MaxwellToGL::VertexType(attrib), attrib.offset);
} else {
- glVertexAttribFormat(index, attrib.ComponentCount(),
- MaxwellToGL::VertexType(attrib),
- attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
+ glVertexArrayAttribFormat(
+ vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
+ attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
}
- glVertexAttribBinding(index, attrib.buffer);
+ glVertexArrayAttribBinding(vao, index, attrib.buffer);
}
}
- state.draw.vertex_array = VAO.handle;
- state.ApplyVertexBufferState();
// Rebinding the VAO invalidates the vertex buffer bindings.
gpu.dirty_flags.vertex_array = 0xFFFFFFFF;
+
+ state.draw.vertex_array = vao_entry.handle;
+ return vao_entry.handle;
}
-void RasterizerOpenGL::SetupVertexBuffer() {
+void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs;
@@ -217,7 +222,7 @@ void RasterizerOpenGL::SetupVertexBuffer() {
if (!vertex_array.IsEnabled())
continue;
- Tegra::GPUVAddr start = vertex_array.StartAddress();
+ const Tegra::GPUVAddr start = vertex_array.StartAddress();
const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
ASSERT(end > start);
@@ -225,21 +230,18 @@ void RasterizerOpenGL::SetupVertexBuffer() {
const GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size);
// Bind the vertex array to the buffer at the current offset.
- glBindVertexBuffer(index, buffer_cache.GetHandle(), vertex_buffer_offset,
- vertex_array.stride);
+ glVertexArrayVertexBuffer(vao, index, buffer_cache.GetHandle(), vertex_buffer_offset,
+ vertex_array.stride);
if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
// Enable vertex buffer instancing with the specified divisor.
- glVertexBindingDivisor(index, vertex_array.divisor);
+ glVertexArrayBindingDivisor(vao, index, vertex_array.divisor);
} else {
// Disable the vertex buffer instancing.
- glVertexBindingDivisor(index, 0);
+ glVertexArrayBindingDivisor(vao, index, 0);
}
}
- // Implicit set by glBindVertexBuffer. Stupid glstate handling...
- state.draw.vertex_buffer = buffer_cache.GetHandle();
-
gpu.dirty_flags.vertex_array = 0;
}
@@ -488,7 +490,19 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
bool using_depth_fb, bool preserve_contents,
std::optional<std::size_t> single_color_target) {
MICROPROFILE_SCOPE(OpenGL_Framebuffer);
- const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
+ const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
+ const auto& regs = gpu.regs;
+
+ const FramebufferConfigState fb_config_state{using_color_fb, using_depth_fb, preserve_contents,
+ single_color_target};
+ if (fb_config_state == current_framebuffer_config_state && gpu.dirty_flags.color_buffer == 0 &&
+ !gpu.dirty_flags.zeta_buffer) {
+ // Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or
+ // single color targets). This is done because the guest registers may not change but the
+ // host framebuffer may contain different attachments
+ return;
+ }
+ current_framebuffer_config_state = fb_config_state;
Surface depth_surface;
if (using_depth_fb) {
@@ -691,9 +705,6 @@ void RasterizerOpenGL::DrawArrays() {
// Draw the vertex batch
const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
- state.draw.vertex_buffer = buffer_cache.GetHandle();
- state.ApplyVertexBufferState();
-
std::size_t buffer_size = CalculateVertexArraysSize();
// Add space for index buffer (keeping in mind non-core primitives)
@@ -723,8 +734,9 @@ void RasterizerOpenGL::DrawArrays() {
gpu.dirty_flags.vertex_array = 0xFFFFFFFF;
}
- SetupVertexFormat();
- SetupVertexBuffer();
+ const GLuint vao = SetupVertexFormat();
+ SetupVertexBuffer(vao);
+
DrawParameters params = SetupDraw();
SetupShaders(params.primitive_mode);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index a53edee6d..21c51f874 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -99,6 +99,23 @@ private:
float max_anisotropic = 1.0f;
};
+ struct FramebufferConfigState {
+ bool using_color_fb{};
+ bool using_depth_fb{};
+ bool preserve_contents{};
+ std::optional<std::size_t> single_color_target;
+
+ bool operator==(const FramebufferConfigState& rhs) const {
+ return std::tie(using_color_fb, using_depth_fb, preserve_contents,
+ single_color_target) == std::tie(rhs.using_color_fb, rhs.using_depth_fb,
+ rhs.preserve_contents,
+ rhs.single_color_target);
+ }
+ bool operator!=(const FramebufferConfigState& rhs) const {
+ return !operator==(rhs);
+ }
+ };
+
/**
* Configures the color and depth framebuffer states.
* @param use_color_fb If true, configure color framebuffers.
@@ -203,6 +220,7 @@ private:
vertex_array_cache;
std::map<FramebufferCacheKey, OGLFramebuffer> framebuffer_cache;
+ FramebufferConfigState current_framebuffer_config_state;
std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers;
@@ -215,8 +233,10 @@ private:
std::size_t CalculateIndexBufferSize() const;
- void SetupVertexFormat();
- void SetupVertexBuffer();
+ /// Updates and returns a vertex array object representing current vertex format
+ GLuint SetupVertexFormat();
+
+ void SetupVertexBuffer(GLuint vao);
DrawParameters SetupDraw();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index bff0c65cd..a05b8b936 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -919,9 +919,16 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
}
Surface RasterizerCacheOpenGL::GetDepthBufferSurface(bool preserve_contents) {
- const auto& regs{Core::System::GetInstance().GPU().Maxwell3D().regs};
+ auto& gpu{Core::System::GetInstance().GPU().Maxwell3D()};
+ const auto& regs{gpu.regs};
+
+ if (!gpu.dirty_flags.zeta_buffer) {
+ return last_depth_buffer;
+ }
+ gpu.dirty_flags.zeta_buffer = false;
+
if (!regs.zeta.Address() || !regs.zeta_enable) {
- return {};
+ return last_depth_buffer = {};
}
SurfaceParams depth_params{SurfaceParams::CreateForDepthBuffer(
@@ -929,25 +936,31 @@ Surface RasterizerCacheOpenGL::GetDepthBufferSurface(bool preserve_contents) {
regs.zeta.memory_layout.block_width, regs.zeta.memory_layout.block_height,
regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)};
- return GetSurface(depth_params, preserve_contents);
+ return last_depth_buffer = GetSurface(depth_params, preserve_contents);
}
Surface RasterizerCacheOpenGL::GetColorBufferSurface(std::size_t index, bool preserve_contents) {
- const auto& regs{Core::System::GetInstance().GPU().Maxwell3D().regs};
+ auto& gpu{Core::System::GetInstance().GPU().Maxwell3D()};
+ const auto& regs{gpu.regs};
+
+ if ((gpu.dirty_flags.color_buffer & (1u << static_cast<u32>(index))) == 0) {
+ return last_color_buffers[index];
+ }
+ gpu.dirty_flags.color_buffer &= ~(1u << static_cast<u32>(index));
ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets);
if (index >= regs.rt_control.count) {
- return {};
+ return last_color_buffers[index] = {};
}
if (regs.rt[index].Address() == 0 || regs.rt[index].format == Tegra::RenderTargetFormat::NONE) {
- return {};
+ return last_color_buffers[index] = {};
}
const SurfaceParams color_params{SurfaceParams::CreateForFramebuffer(index)};
- return GetSurface(color_params, preserve_contents);
+ return last_color_buffers[index] = GetSurface(color_params, preserve_contents);
}
void RasterizerCacheOpenGL::LoadSurface(const Surface& surface) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 7223700c4..37611c4fc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -396,6 +396,9 @@ private:
/// Use a Pixel Buffer Object to download the previous texture and then upload it to the new one
/// using the new format.
OGLBuffer copy_pbo;
+
+ std::array<Surface, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> last_color_buffers;
+ Surface last_depth_buffer;
};
} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
index c17d5ac00..1da744158 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp
@@ -117,7 +117,7 @@ void OGLBuffer::Create() {
return;
MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
- glGenBuffers(1, &handle);
+ glCreateBuffers(1, &handle);
}
void OGLBuffer::Release() {
@@ -126,7 +126,6 @@ void OGLBuffer::Release() {
MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
glDeleteBuffers(1, &handle);
- OpenGLState::GetCurState().ResetBuffer(handle).Apply();
handle = 0;
}
@@ -152,7 +151,7 @@ void OGLVertexArray::Create() {
return;
MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
- glGenVertexArrays(1, &handle);
+ glCreateVertexArrays(1, &handle);
}
void OGLVertexArray::Release() {
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index dc0a5ed5e..b7ba59350 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -83,8 +83,6 @@ OpenGLState::OpenGLState() {
draw.read_framebuffer = 0;
draw.draw_framebuffer = 0;
draw.vertex_array = 0;
- draw.vertex_buffer = 0;
- draw.uniform_buffer = 0;
draw.shader_program = 0;
draw.program_pipeline = 0;
@@ -505,7 +503,6 @@ void OpenGLState::ApplySamplers() const {
}
void OpenGLState::ApplyFramebufferState() const {
- // Framebuffer
if (draw.read_framebuffer != cur_state.draw.read_framebuffer) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
}
@@ -514,16 +511,10 @@ void OpenGLState::ApplyFramebufferState() const {
}
}
-void OpenGLState::ApplyVertexBufferState() const {
- // Vertex array
+void OpenGLState::ApplyVertexArrayState() const {
if (draw.vertex_array != cur_state.draw.vertex_array) {
glBindVertexArray(draw.vertex_array);
}
-
- // Vertex buffer
- if (draw.vertex_buffer != cur_state.draw.vertex_buffer) {
- glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer);
- }
}
void OpenGLState::ApplyDepthClamp() const {
@@ -543,11 +534,7 @@ void OpenGLState::ApplyDepthClamp() const {
void OpenGLState::Apply() const {
ApplyFramebufferState();
- ApplyVertexBufferState();
- // Uniform buffer
- if (draw.uniform_buffer != cur_state.draw.uniform_buffer) {
- glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer);
- }
+ ApplyVertexArrayState();
// Shader program
if (draw.shader_program != cur_state.draw.shader_program) {
@@ -638,16 +625,6 @@ OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
return *this;
}
-OpenGLState& OpenGLState::ResetBuffer(GLuint handle) {
- if (draw.vertex_buffer == handle) {
- draw.vertex_buffer = 0;
- }
- if (draw.uniform_buffer == handle) {
- draw.uniform_buffer = 0;
- }
- return *this;
-}
-
OpenGLState& OpenGLState::ResetVertexArray(GLuint handle) {
if (draw.vertex_array == handle) {
draw.vertex_array = 0;
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 439bfbc98..a5a7c0920 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -154,8 +154,6 @@ public:
GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING
GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING
GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING
- GLuint vertex_buffer; // GL_ARRAY_BUFFER_BINDING
- GLuint uniform_buffer; // GL_UNIFORM_BUFFER_BINDING
GLuint shader_program; // GL_CURRENT_PROGRAM
GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING
} draw;
@@ -206,10 +204,10 @@ public:
}
/// Apply this state as the current OpenGL state
void Apply() const;
- /// Apply only the state afecting the framebuffer
+ /// Apply only the state affecting the framebuffer
void ApplyFramebufferState() const;
- /// Apply only the state afecting the vertex buffer
- void ApplyVertexBufferState() const;
+ /// Apply only the state affecting the vertex array
+ void ApplyVertexArrayState() const;
/// Set the initial OpenGL state
static void ApplyDefaultState();
/// Resets any references to the given resource
@@ -217,7 +215,6 @@ public:
OpenGLState& ResetSampler(GLuint handle);
OpenGLState& ResetProgram(GLuint handle);
OpenGLState& ResetPipeline(GLuint handle);
- OpenGLState& ResetBuffer(GLuint handle);
OpenGLState& ResetVertexArray(GLuint handle);
OpenGLState& ResetFramebuffer(GLuint handle);
void EmulateViewportWithScissor();
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
index b97b895a4..d0b14b3f6 100644
--- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp
+++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
@@ -15,13 +15,12 @@ MICROPROFILE_DEFINE(OpenGL_StreamBuffer, "OpenGL", "Stream Buffer Orphaning",
namespace OpenGL {
-OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coherent)
- : gl_target(target), buffer_size(size) {
+OGLStreamBuffer::OGLStreamBuffer(GLsizeiptr size, bool vertex_data_usage, bool prefer_coherent)
+ : buffer_size(size) {
gl_buffer.Create();
- glBindBuffer(gl_target, gl_buffer.handle);
GLsizeiptr allocate_size = size;
- if (target == GL_ARRAY_BUFFER) {
+ if (vertex_data_usage) {
// On AMD GPU there is a strange crash in indexed drawing. The crash happens when the buffer
// read position is near the end and is an out-of-bound access to the vertex buffer. This is
// probably a bug in the driver and is related to the usage of vec3<byte> attributes in the
@@ -35,18 +34,17 @@ OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coh
coherent = prefer_coherent;
const GLbitfield flags =
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0);
- glBufferStorage(gl_target, allocate_size, nullptr, flags);
- mapped_ptr = static_cast<u8*>(glMapBufferRange(
- gl_target, 0, buffer_size, flags | (coherent ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT)));
+ glNamedBufferStorage(gl_buffer.handle, allocate_size, nullptr, flags);
+ mapped_ptr = static_cast<u8*>(glMapNamedBufferRange(
+ gl_buffer.handle, 0, buffer_size, flags | (coherent ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT)));
} else {
- glBufferData(gl_target, allocate_size, nullptr, GL_STREAM_DRAW);
+ glNamedBufferData(gl_buffer.handle, allocate_size, nullptr, GL_STREAM_DRAW);
}
}
OGLStreamBuffer::~OGLStreamBuffer() {
if (persistent) {
- glBindBuffer(gl_target, gl_buffer.handle);
- glUnmapBuffer(gl_target);
+ glUnmapNamedBuffer(gl_buffer.handle);
}
gl_buffer.Release();
}
@@ -74,7 +72,7 @@ std::tuple<u8*, GLintptr, bool> OGLStreamBuffer::Map(GLsizeiptr size, GLintptr a
invalidate = true;
if (persistent) {
- glUnmapBuffer(gl_target);
+ glUnmapNamedBuffer(gl_buffer.handle);
}
}
@@ -84,7 +82,7 @@ std::tuple<u8*, GLintptr, bool> OGLStreamBuffer::Map(GLsizeiptr size, GLintptr a
(coherent ? GL_MAP_COHERENT_BIT : GL_MAP_FLUSH_EXPLICIT_BIT) |
(invalidate ? GL_MAP_INVALIDATE_BUFFER_BIT : GL_MAP_UNSYNCHRONIZED_BIT);
mapped_ptr = static_cast<u8*>(
- glMapBufferRange(gl_target, buffer_pos, buffer_size - buffer_pos, flags));
+ glMapNamedBufferRange(gl_buffer.handle, buffer_pos, buffer_size - buffer_pos, flags));
mapped_offset = buffer_pos;
}
@@ -95,11 +93,11 @@ void OGLStreamBuffer::Unmap(GLsizeiptr size) {
ASSERT(size <= mapped_size);
if (!coherent && size > 0) {
- glFlushMappedBufferRange(gl_target, buffer_pos - mapped_offset, size);
+ glFlushMappedNamedBufferRange(gl_buffer.handle, buffer_pos - mapped_offset, size);
}
if (!persistent) {
- glUnmapBuffer(gl_target);
+ glUnmapNamedBuffer(gl_buffer.handle);
}
buffer_pos += size;
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.h b/src/video_core/renderer_opengl/gl_stream_buffer.h
index ae7961bd7..3d18ecb4d 100644
--- a/src/video_core/renderer_opengl/gl_stream_buffer.h
+++ b/src/video_core/renderer_opengl/gl_stream_buffer.h
@@ -13,7 +13,7 @@ namespace OpenGL {
class OGLStreamBuffer : private NonCopyable {
public:
- explicit OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coherent = false);
+ explicit OGLStreamBuffer(GLsizeiptr size, bool vertex_data_usage, bool prefer_coherent = false);
~OGLStreamBuffer();
GLuint GetHandle() const;
@@ -33,7 +33,6 @@ public:
private:
OGLBuffer gl_buffer;
- GLenum gl_target;
bool coherent = false;
bool persistent = false;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 235732d86..c268c9686 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -245,20 +245,20 @@ void RendererOpenGL::InitOpenGLObjects() {
// Generate VAO
vertex_array.Create();
-
state.draw.vertex_array = vertex_array.handle;
- state.draw.vertex_buffer = vertex_buffer.handle;
- state.draw.uniform_buffer = 0;
- state.Apply();
// Attach vertex data to VAO
- glBufferData(GL_ARRAY_BUFFER, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
- glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex),
- (GLvoid*)offsetof(ScreenRectVertex, position));
- glVertexAttribPointer(attrib_tex_coord, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex),
- (GLvoid*)offsetof(ScreenRectVertex, tex_coord));
- glEnableVertexAttribArray(attrib_position);
- glEnableVertexAttribArray(attrib_tex_coord);
+ glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
+ glVertexArrayAttribFormat(vertex_array.handle, attrib_position, 2, GL_FLOAT, GL_FALSE,
+ offsetof(ScreenRectVertex, position));
+ glVertexArrayAttribFormat(vertex_array.handle, attrib_tex_coord, 2, GL_FLOAT, GL_FALSE,
+ offsetof(ScreenRectVertex, tex_coord));
+ glVertexArrayAttribBinding(vertex_array.handle, attrib_position, 0);
+ glVertexArrayAttribBinding(vertex_array.handle, attrib_tex_coord, 0);
+ glEnableVertexArrayAttrib(vertex_array.handle, attrib_position);
+ glEnableVertexArrayAttrib(vertex_array.handle, attrib_tex_coord);
+ glVertexArrayVertexBuffer(vertex_array.handle, 0, vertex_buffer.handle, 0,
+ sizeof(ScreenRectVertex));
// Allocate textures for the screen
screen_info.texture.resource.Create();
@@ -370,14 +370,12 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
state.texture_units[0].texture = screen_info.display_texture;
state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
// Workaround brigthness problems in SMO by enabling sRGB in the final output
- // if it has been used in the frame
- // Needed because of this bug in QT
- // QTBUG-50987
+ // if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987
state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed();
state.Apply();
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data());
+ glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), vertices.data());
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- // restore default state
+ // Restore default state
state.framebuffer_srgb.enabled = false;
state.texture_units[0].texture = 0;
state.Apply();