generic texture allocator

This commit is contained in:
BreadFish64 2020-06-27 13:13:37 -05:00
parent cae4b7aaf7
commit ea2584c54d
3 changed files with 68 additions and 10 deletions

View file

@ -777,21 +777,20 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
// which causes unpredictable behavior on the host. // which causes unpredictable behavior on the host.
// Making a copy to sample from eliminates this issue and seems to be fairly cheap. // Making a copy to sample from eliminates this issue and seems to be fairly cheap.
temp_tex.Create(); temp_tex.Create();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, temp_tex.handle); glBindTexture(GL_TEXTURE_2D, temp_tex.handle);
auto [internal_format, format, type] = GetFormatTuple(color_surface->pixel_format); auto [internal_format, format, type] = GetFormatTuple(color_surface->pixel_format);
ASSERT_MSG(GLAD_GL_ARB_texture_storage, "ARB_texture_storage not supported"); OGLTexture::Allocate(GL_TEXTURE_2D, color_surface->max_level, internal_format, format, type,
glTexStorage2D(GL_TEXTURE_2D, color_surface->max_level + 1, internal_format, color_surface->GetScaledWidth(), color_surface->GetScaledHeight());
color_surface->GetScaledWidth(), color_surface->GetScaledHeight());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, state.texture_units[0].texture_2d); glBindTexture(GL_TEXTURE_2D, state.texture_units[0].texture_2d);
for (std::size_t mip{0}; mip <= color_surface->max_level; ++mip) { for (std::size_t level{0}; level <= color_surface->max_level; ++level) {
glCopyImageSubData(color_surface->texture.handle, GL_TEXTURE_2D, mip, 0, 0, 0, glCopyImageSubData(color_surface->texture.handle, GL_TEXTURE_2D, level, 0, 0, 0,
temp_tex.handle, GL_TEXTURE_2D, mip, 0, 0, 0, temp_tex.handle, GL_TEXTURE_2D, level, 0, 0, 0,
color_surface->GetScaledWidth() >> mip, color_surface->GetScaledWidth() >> level,
color_surface->GetScaledHeight() >> mip, 1); color_surface->GetScaledHeight() >> level, 1);
} }
for (auto& unit : state.texture_units) { for (auto& unit : state.texture_units) {

View file

@ -9,6 +9,7 @@
#include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_resource_manager.h"
#include "video_core/renderer_opengl/gl_shader_util.h" #include "video_core/renderer_opengl/gl_shader_util.h"
#include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_state.h"
#include "video_core/renderer_opengl/gl_vars.h"
MICROPROFILE_DEFINE(OpenGL_ResourceCreation, "OpenGL", "Resource Creation", MP_RGB(128, 128, 192)); MICROPROFILE_DEFINE(OpenGL_ResourceCreation, "OpenGL", "Resource Creation", MP_RGB(128, 128, 192));
MICROPROFILE_DEFINE(OpenGL_ResourceDeletion, "OpenGL", "Resource Deletion", MP_RGB(128, 128, 192)); MICROPROFILE_DEFINE(OpenGL_ResourceDeletion, "OpenGL", "Resource Deletion", MP_RGB(128, 128, 192));
@ -51,6 +52,62 @@ void OGLTexture::Release() {
handle = 0; handle = 0;
} }
void OGLTexture::Allocate(GLenum target, GLsizei levels, GLenum internalformat,
GLenum format, GLenum type, GLsizei width, GLsizei height,
GLsizei depth) {
const bool tex_storage = GLAD_GL_ARB_texture_storage || GLES;
switch (target) {
case GL_TEXTURE_1D:
case GL_TEXTURE:
if (tex_storage) {
glTexStorage1D(target, levels, internalformat, width);
} else {
for (GLsizei level{0}; level < levels; ++level) {
width >>= 1;
glTexImage1D(target, level, internalformat, width, 0, format, type, nullptr);
}
}
break;
case GL_TEXTURE_2D:
case GL_TEXTURE_1D_ARRAY:
case GL_TEXTURE_RECTANGLE:
case GL_TEXTURE_CUBE_MAP:
if (tex_storage) {
glTexStorage2D(target, levels, internalformat, width, height);
} else {
for (GLsizei level{0}; level < levels; ++level) {
width >>= 1;
if (target != GL_TEXTURE_1D_ARRAY)
height >>= 1;
glTexImage2D(target, level, internalformat, width, height, 0, format, type,
nullptr);
}
}
break;
case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
if (tex_storage) {
glTexStorage3D(target, levels, internalformat, width, height, depth);
} else {
for (GLsizei level{0}; level < levels; ++level) {
glTexImage3D(target, level, internalformat, width, height, depth, 0, format, type,
nullptr);
}
width >>= 1;
height >>= 1;
if (target == GL_TEXTURE_3D)
depth >>= 1;
}
break;
}
if (!tex_storage) {
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels - 1);
}
}
void OGLSampler::Create() { void OGLSampler::Create() {
if (handle != 0) if (handle != 0)
return; return;

View file

@ -59,6 +59,8 @@ public:
/// Deletes the internal OpenGL resource /// Deletes the internal OpenGL resource
void Release(); void Release();
static void Allocate(GLenum target, GLsizei levels, GLenum internalformat, GLenum format, GLenum type, GLsizei width, GLsizei height = 1, GLsizei depth = 1);
GLuint handle = 0; GLuint handle = 0;
}; };