AbstractTexture: Move Bind() method to Renderer

This makes state tracking simpler, and enables easier porting to command
lists later on.
This commit is contained in:
Stenzek 2018-01-21 23:13:25 +10:00
parent fca56d532a
commit 38e0b6e2ab
23 changed files with 70 additions and 90 deletions

View File

@ -91,11 +91,6 @@ D3DTexture2D* DXTexture::GetRawTexIdentifier() const
return m_texture;
}
void DXTexture::Bind(unsigned int stage)
{
D3D::stateman->SetTexture(stage, m_texture->GetSRV());
}
void DXTexture::CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -19,8 +19,6 @@ public:
explicit DXTexture(const TextureConfig& tex_config);
~DXTexture();
void Bind(unsigned int stage) override;
void CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -733,11 +733,24 @@ void Renderer::SetDepthState(const DepthState& state)
m_gx_state.zmode.hex = state.hex;
}
void Renderer::SetTexture(u32 index, const AbstractTexture* texture)
{
D3D::stateman->SetTexture(
index,
texture ? static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV() : nullptr);
}
void Renderer::SetSamplerState(u32 index, const SamplerState& state)
{
m_gx_state.samplers[index].hex = state.hex;
}
void Renderer::UnbindTexture(const AbstractTexture* texture)
{
D3D::stateman->UnsetTexture(
static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV());
}
void Renderer::SetInterlacingMode()
{
// TODO

View File

@ -30,7 +30,9 @@ public:
void SetScissorRect(const EFBRectangle& rc) override;
void SetRasterizationState(const RasterizationState& state) override;
void SetDepthState(const DepthState& state) override;
void SetTexture(u32 index, const AbstractTexture* texture) override;
void SetSamplerState(u32 index, const SamplerState& state) override;
void UnbindTexture(const AbstractTexture* texture) override;
void SetInterlacingMode() override;
void SetViewport() override;
void SetFullscreen(bool enable_fullscreen) override;

View File

@ -10,10 +10,6 @@ NullTexture::NullTexture(const TextureConfig& tex_config) : AbstractTexture(tex_
{
}
void NullTexture::Bind(unsigned int stage)
{
}
void NullTexture::CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -19,8 +19,6 @@ public:
explicit NullTexture(const TextureConfig& config);
~NullTexture() = default;
void Bind(unsigned int stage) override;
void CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -19,9 +19,6 @@ namespace OGL
{
namespace
{
std::array<u32, 8> s_Textures;
u32 s_ActiveTexture;
GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool storage)
{
switch (format)
@ -120,26 +117,15 @@ OGLTexture::OGLTexture(const TextureConfig& tex_config) : AbstractTexture(tex_co
// method is in the base renderer class and can be called by VideoCommon.
FramebufferManager::SetFramebuffer(0);
}
SetStage();
}
OGLTexture::~OGLTexture()
{
if (m_texId)
{
for (auto& gtex : s_Textures)
if (gtex == m_texId)
gtex = 0;
glDeleteTextures(1, &m_texId);
m_texId = 0;
}
if (m_framebuffer)
{
glDeleteFramebuffers(1, &m_framebuffer);
m_framebuffer = 0;
}
}
GLuint OGLTexture::GetRawTexIdentifier() const
@ -152,21 +138,6 @@ GLuint OGLTexture::GetFramebuffer() const
return m_framebuffer;
}
void OGLTexture::Bind(unsigned int stage)
{
if (s_Textures[stage] != m_texId)
{
if (s_ActiveTexture != stage)
{
glActiveTexture(GL_TEXTURE0 + stage);
s_ActiveTexture = stage;
}
glBindTexture(GL_TEXTURE_2D_ARRAY, m_texId);
s_Textures[stage] = m_texId;
}
}
void OGLTexture::CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,
@ -300,19 +271,6 @@ void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8
if (row_length != width)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
SetStage();
}
void OGLTexture::DisableStage(unsigned int stage)
{
}
void OGLTexture::SetStage()
{
// -1 is the initial value as we don't know which texture should be bound
if (s_ActiveTexture != (u32)-1)
glActiveTexture(GL_TEXTURE0 + s_ActiveTexture);
}
OGLStagingTexture::OGLStagingTexture(StagingTextureType type, const TextureConfig& config,
@ -444,7 +402,6 @@ void OGLStagingTexture::CopyFromTexture(const AbstractTexture* src,
glBindTexture(GL_TEXTURE_2D_ARRAY, gltex->GetRawTexIdentifier());
glGetTexImage(GL_TEXTURE_2D_ARRAY, src_level, GetGLFormatForTextureFormat(m_config.format),
GetGLTypeForTextureFormat(m_config.format), nullptr);
OGLTexture::SetStage();
}
}
@ -507,7 +464,6 @@ void OGLStagingTexture::CopyToTexture(const MathUtil::Rectangle<int>& src_rect,
dst_rect.GetWidth(), dst_rect.GetHeight(), 1,
GetGLFormatForTextureFormat(m_config.format),
GetGLTypeForTextureFormat(m_config.format), reinterpret_cast<void*>(src_offset));
OGLTexture::SetStage();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

View File

@ -19,8 +19,6 @@ public:
explicit OGLTexture(const TextureConfig& tex_config);
~OGLTexture();
void Bind(unsigned int stage) override;
void CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,
@ -34,9 +32,6 @@ public:
GLuint GetRawTexIdentifier() const;
GLuint GetFramebuffer() const;
static void DisableStage(unsigned int stage);
static void SetStage();
private:
GLuint m_texId;
GLuint m_framebuffer = 0;

View File

@ -122,7 +122,6 @@ void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle
glBindTexture(GL_TEXTURE_2D_ARRAY, src_texture);
g_sampler_cache->BindLinearSampler(9);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
OGLTexture::SetStage();
}
void OpenGLPostProcessing::ApplyShader()

View File

@ -1571,8 +1571,6 @@ void Renderer::RestoreAPIState()
ProgramShaderCache::BindLastVertexFormat();
const VertexManager* const vm = static_cast<VertexManager*>(g_vertex_manager.get());
glBindBuffer(GL_ARRAY_BUFFER, vm->GetVertexBufferHandle());
OGLTexture::SetStage();
}
void Renderer::SetRasterizationState(const RasterizationState& state)
@ -1611,11 +1609,34 @@ void Renderer::SetDepthState(const DepthState& state)
}
}
void Renderer::SetTexture(u32 index, const AbstractTexture* texture)
{
if (m_bound_textures[index] == texture)
return;
glActiveTexture(GL_TEXTURE0 + index);
glBindTexture(GL_TEXTURE_2D_ARRAY,
texture ? static_cast<const OGLTexture*>(texture)->GetRawTexIdentifier() : 0);
m_bound_textures[index] = texture;
}
void Renderer::SetSamplerState(u32 index, const SamplerState& state)
{
g_sampler_cache->SetSamplerState(index, state);
}
void Renderer::UnbindTexture(const AbstractTexture* texture)
{
for (size_t i = 0; i < m_bound_textures.size(); i++)
{
if (m_bound_textures[i] != texture)
continue;
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + i));
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
}
}
void Renderer::SetInterlacingMode()
{
// TODO

View File

@ -4,6 +4,7 @@
#pragma once
#include <array>
#include <string>
#include "Common/GL/GLUtil.h"
@ -93,7 +94,9 @@ public:
void SetScissorRect(const EFBRectangle& rc) override;
void SetRasterizationState(const RasterizationState& state) override;
void SetDepthState(const DepthState& state) override;
void SetTexture(u32 index, const AbstractTexture* texture) override;
void SetSamplerState(u32 index, const SamplerState& state) override;
void UnbindTexture(const AbstractTexture* texture) override;
void SetInterlacingMode() override;
void SetViewport() override;
@ -128,5 +131,7 @@ private:
void BlitScreen(TargetRectangle src, TargetRectangle dst, GLuint src_texture, int src_width,
int src_height);
std::array<const AbstractTexture*, 8> m_bound_textures{};
};
}

View File

@ -476,8 +476,6 @@ void TextureCache::DecodeTextureOnGPU(TCacheEntry* entry, u32 dst_level, const u
glDispatchCompute(dispatch_groups.first, dispatch_groups.second, 1);
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
OGLTexture::SetStage();
#ifdef TIME_TEXTURE_DECODING
WARN_LOG(VIDEO, "Decode texture format %u size %ux%u took %.4fms", static_cast<u32>(format),
width, height, timer.GetTimeMilliseconds());

View File

@ -136,7 +136,6 @@ static void EncodeToRamUsingShader(GLuint srcTexture, u8* destAddr, u32 dst_line
s_encoding_readback_texture->ReadTexels(copy_rect, destAddr, writeStride);
FramebufferManager::SetFramebuffer(0);
OGLTexture::SetStage();
}
void EncodeToRamFromTexture(u8* dest_ptr, const EFBCopyParams& params, u32 native_width,

View File

@ -52,10 +52,6 @@ SWTexture::SWTexture(const TextureConfig& tex_config) : AbstractTexture(tex_conf
m_data.resize(tex_config.width * tex_config.height * 4);
}
void SWTexture::Bind(unsigned int stage)
{
}
void SWTexture::CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -19,8 +19,6 @@ public:
explicit SWTexture(const TextureConfig& tex_config);
~SWTexture() = default;
void Bind(unsigned int stage) override;
void CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -8,6 +8,7 @@
#include <string>
#include <tuple>
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
@ -848,6 +849,15 @@ void Renderer::SetBlendingState(const BlendingState& state)
StateTracker::GetInstance()->SetBlendState(state);
}
void Renderer::SetTexture(u32 index, const AbstractTexture* texture)
{
// Texture should always be in SHADER_READ_ONLY layout prior to use.
// This is so we don't need to transition during render passes.
auto* tex = texture ? static_cast<const VKTexture*>(texture)->GetRawTexIdentifier() : nullptr;
_dbg_assert_(VIDEO, !tex || tex->GetLayout() == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
StateTracker::GetInstance()->SetTexture(index, tex ? tex->GetView() : VK_NULL_HANDLE);
}
void Renderer::SetSamplerState(u32 index, const SamplerState& state)
{
// Skip lookup if the state hasn't changed.
@ -866,6 +876,12 @@ void Renderer::SetSamplerState(u32 index, const SamplerState& state)
m_sampler_states[index].hex = state.hex;
}
void Renderer::UnbindTexture(const AbstractTexture* texture)
{
StateTracker::GetInstance()->UnbindTexture(
static_cast<const VKTexture*>(texture)->GetRawTexIdentifier()->GetView());
}
void Renderer::ResetSamplerStates()
{
// Ensure none of the sampler objects are in use.

View File

@ -63,7 +63,9 @@ public:
void SetScissorRect(const EFBRectangle& rc) override;
void SetRasterizationState(const RasterizationState& state) override;
void SetDepthState(const DepthState& state) override;
void SetTexture(u32 index, const AbstractTexture* texture) override;
void SetSamplerState(u32 index, const SamplerState& state) override;
void UnbindTexture(const AbstractTexture* texture) override;
void SetInterlacingMode() override;
void SetViewport() override;

View File

@ -107,14 +107,6 @@ VkFramebuffer VKTexture::GetFramebuffer() const
return m_framebuffer;
}
void VKTexture::Bind(unsigned int stage)
{
// Texture should always be in SHADER_READ_ONLY layout prior to use.
// This is so we don't need to transition during render passes.
_assert_(m_texture->GetLayout() == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
StateTracker::GetInstance()->SetTexture(stage, m_texture->GetView());
}
void VKTexture::CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -21,8 +21,6 @@ public:
VKTexture() = delete;
~VKTexture();
void Bind(unsigned int stage) override;
void CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -15,7 +15,10 @@ AbstractTexture::AbstractTexture(const TextureConfig& c) : m_config(c)
{
}
AbstractTexture::~AbstractTexture() = default;
AbstractTexture::~AbstractTexture()
{
g_renderer->UnbindTexture(this);
}
bool AbstractTexture::Save(const std::string& filename, unsigned int level)
{

View File

@ -17,8 +17,6 @@ public:
explicit AbstractTexture(const TextureConfig& c);
virtual ~AbstractTexture();
virtual void Bind(unsigned int stage) = 0;
virtual void CopyRectangleFromTexture(const AbstractTexture* src,
const MathUtil::Rectangle<int>& src_rect, u32 src_layer,
u32 src_level, const MathUtil::Rectangle<int>& dst_rect,

View File

@ -73,7 +73,9 @@ public:
virtual void SetScissorRect(const EFBRectangle& rc) {}
virtual void SetRasterizationState(const RasterizationState& state) {}
virtual void SetDepthState(const DepthState& state) {}
virtual void SetTexture(u32 index, const AbstractTexture* texture) {}
virtual void SetSamplerState(u32 index, const SamplerState& state) {}
virtual void UnbindTexture(const AbstractTexture* texture) {}
virtual void SetInterlacingMode() {}
virtual void SetViewport() {}
virtual void SetFullscreen(bool enable_fullscreen) {}

View File

@ -470,10 +470,10 @@ static u32 CalculateLevelSize(u32 level_0_size, u32 level)
void TextureCacheBase::BindTextures()
{
for (size_t i = 0; i < bound_textures.size(); ++i)
for (u32 i = 0; i < bound_textures.size(); i++)
{
if (IsValidBindPoint(static_cast<u32>(i)) && bound_textures[i])
bound_textures[i]->texture->Bind(static_cast<u32>(i));
if (IsValidBindPoint(i) && bound_textures[i])
g_renderer->SetTexture(i, bound_textures[i]->texture.get());
}
}