diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 74403eed48..079132135f 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -482,19 +482,8 @@ std::vector Maxwell3D::GetStageTextures(Regs::ShaderSt return textures; } -Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, - std::size_t offset) const { - auto& shader = state.shader_stages[static_cast(stage)]; - auto& tex_info_buffer = shader.const_buffers[regs.tex_cb_index]; - ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); - - const GPUVAddr tex_info_address = - tex_info_buffer.address + offset * sizeof(Texture::TextureHandle); - - ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size); - - const Texture::TextureHandle tex_handle{memory_manager.Read(tex_info_address)}; - +Texture::FullTextureInfo Maxwell3D::GetTextureInfo(const Texture::TextureHandle tex_handle, + std::size_t offset) const { Texture::FullTextureInfo tex_info{}; tex_info.index = static_cast(offset); @@ -511,6 +500,22 @@ Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, return tex_info; } +Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, + std::size_t offset) const { + auto& shader = state.shader_stages[static_cast(stage)]; + auto& tex_info_buffer = shader.const_buffers[regs.tex_cb_index]; + ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); + + const GPUVAddr tex_info_address = + tex_info_buffer.address + offset * sizeof(Texture::TextureHandle); + + ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size); + + const Texture::TextureHandle tex_handle{memory_manager.Read(tex_info_address)}; + + return GetTextureInfo(tex_handle, offset); +} + u32 Maxwell3D::GetRegisterValue(u32 method) const { ASSERT_MSG(method < Regs::NUM_REGS, "Invalid Maxwell3D register"); return regs.reg_array[method]; diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 321af32974..fd2c35a01c 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1131,6 +1131,10 @@ public: /// Write the value to the register identified by method. void CallMethod(const GPU::MethodCall& method_call); + /// Given a Texture Handle, returns the TSC and TIC entries. + Texture::FullTextureInfo GetTextureInfo(const Texture::TextureHandle tex_handle, + std::size_t offset) const; + /// Returns a list of enabled textures for the specified shader stage. std::vector GetStageTextures(Regs::ShaderStage stage) const; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index f2ac5382d9..a20acfe8e1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -985,7 +985,15 @@ void RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, const Shader& s for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { const auto& entry = entries[bindpoint]; - const auto texture = maxwell3d.GetStageTexture(stage, entry.GetOffset()); + Tegra::Texture::FullTextureInfo texture; + if (!entry.IsBindless()) { + texture = maxwell3d.GetStageTexture(stage, entry.GetOffset()); + } else { + const auto cbuf = entry.GetBindlessCBuf(); + Tegra::Texture::TextureHandle tex_handle; + tex_handle.raw = const_buffer_accessor.access32(stage, cbuf.first, cbuf.second); + texture = maxwell3d.GetTextureInfo(tex_handle, entry.GetOffset()); + } const u32 current_bindpoint = base_bindings.sampler + bindpoint; texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 773c71fa53..ed321cfe5d 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -205,8 +205,8 @@ public: // Use this constructor for bindless Samplers explicit Sampler(u32 cbuf_index, u32 cbuf_offset, std::size_t index, Tegra::Shader::TextureType type, bool is_array, bool is_shadow) - : offset{(static_cast(cbuf_index) << 32) | cbuf_offset}, index{index}, type{type}, is_array{is_array}, - is_shadow{is_shadow}, is_bindless{true} {} + : offset{(static_cast(cbuf_index) << 32) | cbuf_offset}, index{index}, type{type}, + is_array{is_array}, is_shadow{is_shadow}, is_bindless{true} {} // Use this only for serialization/deserialization explicit Sampler(std::size_t offset, std::size_t index, Tegra::Shader::TextureType type, @@ -214,7 +214,6 @@ public: : offset{offset}, index{index}, type{type}, is_array{is_array}, is_shadow{is_shadow}, is_bindless{is_bindless} {} - std::size_t GetOffset() const { return offset; } @@ -239,7 +238,7 @@ public: return is_bindless; } - std::pair GetBindlessCBuf() { + std::pair GetBindlessCBuf() const { return {offset >> 32, offset & 0x00000000FFFFFFFFULL}; }