Преглед изворни кода

gl_rasterizer_cache: Use texture buffers to emulate texture buffers

ReinUsesLisp пре 7 година
родитељ
комит
07f7ce1da2

+ 28 - 9
src/video_core/renderer_opengl/gl_rasterizer_cache.cpp

@@ -149,6 +149,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
 
     switch (params.target) {
     case SurfaceTarget::Texture1D:
+    case SurfaceTarget::TextureBuffer:
     case SurfaceTarget::Texture2D:
         params.depth = 1;
         break;
@@ -389,6 +390,8 @@ static GLenum SurfaceTargetToGL(SurfaceTarget target) {
     switch (target) {
     case SurfaceTarget::Texture1D:
         return GL_TEXTURE_1D;
+    case SurfaceTarget::TextureBuffer:
+        return GL_TEXTURE_BUFFER;
     case SurfaceTarget::Texture2D:
         return GL_TEXTURE_2D;
     case SurfaceTarget::Texture3D:
@@ -600,29 +603,35 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
 
     switch (params.target) {
     case SurfaceTarget::Texture1D:
-        glTextureStorage1D(texture.handle, params.max_mip_level, format_tuple.internal_format,
-                           width);
+        glTextureStorage1D(texture.handle, params.max_mip_level, gl_internal_format, width);
+        break;
+    case SurfaceTarget::TextureBuffer:
+        texture_buffer.Create();
+        glNamedBufferStorage(texture_buffer.handle,
+                             params.width * GetBytesPerPixel(params.pixel_format), nullptr,
+                             GL_DYNAMIC_STORAGE_BIT);
+        glTextureBuffer(texture.handle, gl_internal_format, texture_buffer.handle);
         break;
     case SurfaceTarget::Texture2D:
     case SurfaceTarget::TextureCubemap:
-        glTextureStorage2D(texture.handle, params.max_mip_level, format_tuple.internal_format,
-                           width, height);
+        glTextureStorage2D(texture.handle, params.max_mip_level, gl_internal_format, width, height);
         break;
     case SurfaceTarget::Texture3D:
     case SurfaceTarget::Texture2DArray:
     case SurfaceTarget::TextureCubeArray:
-        glTextureStorage3D(texture.handle, params.max_mip_level, format_tuple.internal_format,
-                           width, height, params.depth);
+        glTextureStorage3D(texture.handle, params.max_mip_level, gl_internal_format, width, height,
+                           params.depth);
         break;
     default:
         LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
                      static_cast<u32>(params.target));
         UNREACHABLE();
-        glTextureStorage2D(texture.handle, params.max_mip_level, format_tuple.internal_format,
-                           width, height);
+        glTextureStorage2D(texture.handle, params.max_mip_level, gl_internal_format, width, height);
     }
 
-    ApplyTextureDefaults(texture.handle, params.max_mip_level);
+    if (params.target != SurfaceTarget::TextureBuffer) {
+        ApplyTextureDefaults(texture.handle, params.max_mip_level);
+    }
 
     OpenGL::LabelGLObject(GL_TEXTURE, texture.handle, params.gpu_addr, params.IdentityString());
 }
@@ -785,6 +794,13 @@ void CachedSurface::UploadGLMipmapTexture(RasterizerTemporaryMemory& res_cache_t
             glTextureSubImage1D(texture.handle, mip_map, x0, static_cast<GLsizei>(rect.GetWidth()),
                                 tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
             break;
+        case SurfaceTarget::TextureBuffer:
+            ASSERT(mip_map == 0);
+            glNamedBufferSubData(texture_buffer.handle, x0,
+                                 static_cast<GLsizeiptr>(rect.GetWidth()) *
+                                     GetBytesPerPixel(params.pixel_format),
+                                 &gl_buffer[mip_map][buffer_offset]);
+            break;
         case SurfaceTarget::Texture2D:
             glTextureSubImage2D(texture.handle, mip_map, x0, y0,
                                 static_cast<GLsizei>(rect.GetWidth()),
@@ -860,6 +876,9 @@ void CachedSurface::UpdateSwizzle(Tegra::Texture::SwizzleSource swizzle_x,
                                   Tegra::Texture::SwizzleSource swizzle_y,
                                   Tegra::Texture::SwizzleSource swizzle_z,
                                   Tegra::Texture::SwizzleSource swizzle_w) {
+    if (params.target == SurfaceTarget::TextureBuffer) {
+        return;
+    }
     const GLenum new_x = MaxwellToGL::SwizzleSource(swizzle_x);
     const GLenum new_y = MaxwellToGL::SwizzleSource(swizzle_y);
     const GLenum new_z = MaxwellToGL::SwizzleSource(swizzle_z);

+ 3 - 0
src/video_core/renderer_opengl/gl_rasterizer_cache.h

@@ -250,6 +250,8 @@ struct SurfaceParams {
         switch (target) {
         case SurfaceTarget::Texture1D:
             return "1D";
+        case SurfaceTarget::TextureBuffer:
+            return "Buffer";
         case SurfaceTarget::Texture2D:
             return "2D";
         case SurfaceTarget::Texture3D:
@@ -439,6 +441,7 @@ private:
 
     OGLTexture texture;
     OGLTexture discrepant_view;
+    OGLBuffer texture_buffer;
     SurfaceParams params{};
     GLenum gl_target{};
     GLenum gl_internal_format{};

+ 0 - 1
src/video_core/renderer_opengl/renderer_opengl.cpp

@@ -471,7 +471,6 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum
     }
 }
 
-/// Initialize the renderer
 bool RendererOpenGL::Init() {
     Core::Frontend::ScopeAcquireWindowContext acquire_context{render_window};
 

+ 3 - 1
src/video_core/surface.cpp

@@ -13,7 +13,7 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t
     case Tegra::Texture::TextureType::Texture1D:
         return SurfaceTarget::Texture1D;
     case Tegra::Texture::TextureType::Texture1DBuffer:
-        return SurfaceTarget::Texture1D; // Fixme
+        return SurfaceTarget::TextureBuffer;
     case Tegra::Texture::TextureType::Texture2D:
     case Tegra::Texture::TextureType::Texture2DNoMipmap:
         return SurfaceTarget::Texture2D;
@@ -37,6 +37,7 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t
 bool SurfaceTargetIsLayered(SurfaceTarget target) {
     switch (target) {
     case SurfaceTarget::Texture1D:
+    case SurfaceTarget::TextureBuffer:
     case SurfaceTarget::Texture2D:
     case SurfaceTarget::Texture3D:
         return false;
@@ -55,6 +56,7 @@ bool SurfaceTargetIsLayered(SurfaceTarget target) {
 bool SurfaceTargetIsArray(SurfaceTarget target) {
     switch (target) {
     case SurfaceTarget::Texture1D:
+    case SurfaceTarget::TextureBuffer:
     case SurfaceTarget::Texture2D:
     case SurfaceTarget::Texture3D:
     case SurfaceTarget::TextureCubemap:

+ 1 - 0
src/video_core/surface.h

@@ -114,6 +114,7 @@ enum class SurfaceType {
 
 enum class SurfaceTarget {
     Texture1D,
+    TextureBuffer,
     Texture2D,
     Texture3D,
     Texture1DArray,