diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 49 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 32 | 
3 files changed, 74 insertions, 14 deletions
| diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2b29fc45f..089daf96f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1014,8 +1014,11 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,          texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc);          Surface surface = res_cache.GetTextureSurface(texture, entry);          if (surface != nullptr) { -            state.texture_units[current_bindpoint].texture = surface->Texture().handle; -            state.texture_units[current_bindpoint].target = surface->Target(); +            const GLuint handle = +                entry.IsArray() ? surface->TextureLayer().handle : surface->Texture().handle; +            const GLenum target = entry.IsArray() ? surface->TargetLayer() : surface->Target(); +            state.texture_units[current_bindpoint].texture = handle; +            state.texture_units[current_bindpoint].target = target;              state.texture_units[current_bindpoint].swizzle.r =                  MaxwellToGL::SwizzleSource(texture.tic.x_source);              state.texture_units[current_bindpoint].swizzle.g = diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 7ea07631a..352c391a9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -44,6 +44,17 @@ struct FormatTuple {      bool compressed;  }; +static void ApplyTextureDefaults(GLenum target, u32 max_mip_level) { +    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +    glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +    glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +    glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, max_mip_level - 1); +    if (max_mip_level == 1) { +        glTexParameterf(target, GL_TEXTURE_LOD_BIAS, 1000.0); +    } +} +  void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) {      auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()};      const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr_)}; @@ -532,6 +543,9 @@ CachedSurface::CachedSurface(const SurfaceParams& params)      glActiveTexture(GL_TEXTURE0);      const auto& format_tuple = GetFormatTuple(params.pixel_format, params.component_type); +    gl_internal_format = format_tuple.internal_format; +    gl_is_compressed = format_tuple.compressed; +      if (!format_tuple.compressed) {          // Only pre-create the texture for non-compressed textures.          switch (params.target) { @@ -560,15 +574,7 @@ CachedSurface::CachedSurface(const SurfaceParams& params)          }      } -    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MIN_FILTER, GL_LINEAR); -    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAG_FILTER, GL_LINEAR); -    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -    glTexParameteri(SurfaceTargetToGL(params.target), GL_TEXTURE_MAX_LEVEL, -                    params.max_mip_level - 1); -    if (params.max_mip_level == 1) { -        glTexParameterf(SurfaceTargetToGL(params.target), GL_TEXTURE_LOD_BIAS, 1000.0); -    } +    ApplyTextureDefaults(SurfaceTargetToGL(params.target), params.max_mip_level);      LabelGLObject(GL_TEXTURE, texture.handle, params.addr,                    SurfaceParams::SurfaceTargetName(params.target)); @@ -886,6 +892,31 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,      glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);  } +void CachedSurface::EnsureTextureView() { +    if (texture_view.handle != 0) +        return; +    // Compressed texture are not being created with immutable storage +    UNIMPLEMENTED_IF(gl_is_compressed); + +    const GLenum target{TargetLayer()}; + +    texture_view.Create(); +    glTextureView(texture_view.handle, target, texture.handle, gl_internal_format, 0, +                  params.max_mip_level, 0, 1); + +    OpenGLState cur_state = OpenGLState::GetCurState(); +    const auto& old_tex = cur_state.texture_units[0]; +    SCOPE_EXIT({ +        cur_state.texture_units[0] = old_tex; +        cur_state.Apply(); +    }); +    cur_state.texture_units[0].texture = texture_view.handle; +    cur_state.texture_units[0].target = target; +    cur_state.Apply(); + +    ApplyTextureDefaults(target, params.max_mip_level); +} +  MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64));  void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) {      if (params.type == SurfaceType::Fill) diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index c710aa245..7223700c4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -293,10 +293,31 @@ public:          return texture;      } +    const OGLTexture& TextureLayer() { +        if (params.is_layered) { +            return Texture(); +        } +        EnsureTextureView(); +        return texture_view; +    } +      GLenum Target() const {          return gl_target;      } +    GLenum TargetLayer() const { +        using VideoCore::Surface::SurfaceTarget; +        switch (params.target) { +        case SurfaceTarget::Texture1D: +            return GL_TEXTURE_1D_ARRAY; +        case SurfaceTarget::Texture2D: +            return GL_TEXTURE_2D_ARRAY; +        case SurfaceTarget::TextureCubemap: +            return GL_TEXTURE_CUBE_MAP_ARRAY; +        } +        return Target(); +    } +      const SurfaceParams& GetSurfaceParams() const {          return params;      } @@ -311,11 +332,16 @@ public:  private:      void UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, GLuint draw_fb_handle); +    void EnsureTextureView(); +      OGLTexture texture; +    OGLTexture texture_view;      std::vector<std::vector<u8>> gl_buffer; -    SurfaceParams params; -    GLenum gl_target; -    std::size_t cached_size_in_bytes; +    SurfaceParams params{}; +    GLenum gl_target{}; +    GLenum gl_internal_format{}; +    bool gl_is_compressed{}; +    std::size_t cached_size_in_bytes{};  };  class RasterizerCacheOpenGL final : public RasterizerCache<Surface> { | 
