diff --git a/rpcs3/Emu/RSX/GL/GLProcTable.h b/rpcs3/Emu/RSX/GL/GLProcTable.h index ad8943bd4f..b4a9c1c289 100644 --- a/rpcs3/Emu/RSX/GL/GLProcTable.h +++ b/rpcs3/Emu/RSX/GL/GLProcTable.h @@ -284,6 +284,13 @@ OPENGL_PROC(PFNGLTEXTUREBARRIERNVPROC, TextureBarrierNV); // Memory barrier OPENGL_PROC(PFNGLMEMORYBARRIERPROC, MemoryBarrier); +// Bindless texture +OPENGL_PROC(PFNGLGETTEXTUREHANDLEARBPROC, GetTextureHandleARB); +OPENGL_PROC(PFNGLMAKETEXTUREHANDLERESIDENTARBPROC, MakeTextureHandleResidentARB); +OPENGL_PROC(PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC, MakeTextureHandleNonResidentARB); +OPENGL_PROC(PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC, ProgramUniformHandleui64ARB); +OPENGL_PROC(PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC, ProgramUniformHandleui64vARB); + // ARB_compute_shader OPENGL_PROC(PFNGLDISPATCHCOMPUTEPROC, DispatchCompute); diff --git a/rpcs3/Emu/RSX/GL/glutils/common.h b/rpcs3/Emu/RSX/GL/glutils/common.h index 12f54b794a..326a79b9e8 100644 --- a/rpcs3/Emu/RSX/GL/glutils/common.h +++ b/rpcs3/Emu/RSX/GL/glutils/common.h @@ -53,6 +53,7 @@ namespace gl { using flags32_t = u32; using handle32_t = u32; + using handle64_t = u64; template class save_binding_state_base diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index e2f02afdfa..86dec13ee6 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -219,6 +219,13 @@ namespace gl texture::~texture() { gl::get_command_context()->unbind_texture(static_cast(m_target), m_id); + + if (m_handle64) + { + glMakeTextureHandleNonResidentARB(m_handle64); + m_handle64 = GL_NONE; + } + glDeleteTextures(1, &m_id); m_id = GL_NONE; } diff --git a/rpcs3/Emu/RSX/GL/glutils/image.h b/rpcs3/Emu/RSX/GL/glutils/image.h index bd974c226a..d01112bade 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.h +++ b/rpcs3/Emu/RSX/GL/glutils/image.h @@ -59,7 +59,28 @@ namespace gl GLuint num_layers; }; - class texture : public named_object + template + struct bindless_texture_t : public named_object + { + handle64_t handle() const + { + if (m_handle64) + { + return m_handle64; + } + + ensure(gl::get_driver_caps().ARB_bindless_texture_supported, "Bindless handles are not supported on this device."); + m_handle64 = ensure(glGetTextureHandleARB(m_id), "Failed to get image handle from OpenGL driver."); + glMakeTextureHandleResidentARB(m_handle64); + return m_handle64; + } + + protected: + using named_object::m_id; + mutable GLuint64 m_handle64 = GL_NONE; + }; + + class texture : public bindless_texture_t { friend class texture_view; @@ -181,6 +202,8 @@ namespace gl }; protected: + mutable GLuint64 m_handle64 = GL_NONE; + GLuint m_width = 0; GLuint m_height = 0; GLuint m_depth = 0; @@ -345,9 +368,11 @@ namespace gl } }; - class texture_view : public named_object + class texture_view : public bindless_texture_t { protected: + mutable GLuint64 m_handle64 = GL_NONE; + GLenum m_target = 0; GLenum m_format = 0; GLenum m_view_format = 0; diff --git a/rpcs3/Emu/RSX/GL/glutils/program.h b/rpcs3/Emu/RSX/GL/glutils/program.h index 3f6601be78..0568bc5547 100644 --- a/rpcs3/Emu/RSX/GL/glutils/program.h +++ b/rpcs3/Emu/RSX/GL/glutils/program.h @@ -7,6 +7,8 @@ #include "Utilities/geometry.h" #include "Utilities/mutex.h" +#include + namespace gl { namespace glsl @@ -91,6 +93,7 @@ namespace gl void operator = (unsigned rhs) const { glProgramUniform1ui(m_program.id(), location(), rhs); } void operator = (float rhs) const { glProgramUniform1f(m_program.id(), location(), rhs); } void operator = (bool rhs) const { glProgramUniform1ui(m_program.id(), location(), rhs ? 1 : 0); } + void operator = (handle64_t rhs) const { glProgramUniformHandleui64ARB(m_program.id(), location(), rhs); } void operator = (const color1i& rhs) const { glProgramUniform1i(m_program.id(), location(), rhs.r); } void operator = (const color1f& rhs) const { glProgramUniform1f(m_program.id(), location(), rhs.r); } void operator = (const color2i& rhs) const { glProgramUniform2i(m_program.id(), location(), rhs.r, rhs.g); } @@ -101,7 +104,8 @@ namespace gl void operator = (const color4f& rhs) const { glProgramUniform4f(m_program.id(), location(), rhs.r, rhs.g, rhs.b, rhs.a); } void operator = (const areaf& rhs) const { glProgramUniform4f(m_program.id(), location(), rhs.x1, rhs.y1, rhs.x2, rhs.y2); } void operator = (const areai& rhs) const { glProgramUniform4i(m_program.id(), location(), rhs.x1, rhs.y1, rhs.x2, rhs.y2); } - void operator = (const std::vector& rhs) const { glProgramUniform1iv(m_program.id(), location(), ::size32(rhs), rhs.data()); } + void operator = (const std::span& rhs) const { glProgramUniform1iv(m_program.id(), location(), ::size32(rhs), rhs.data()); } + void operator = (const std::span& rhs) const { glProgramUniformHandleui64vARB(m_program.id(), location(), ::size32(rhs), rhs.data()); } }; class uniforms_t