mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #5279 from stenzek/compressed-custom-textures
Native compressed custom texture support
This commit is contained in:
@@ -93,6 +93,7 @@
|
||||
<ClInclude Include="GL\GLExtensions\ARB_uniform_buffer_object.h" />
|
||||
<ClInclude Include="GL\GLExtensions\ARB_vertex_array_object.h" />
|
||||
<ClInclude Include="GL\GLExtensions\ARB_viewport_array.h" />
|
||||
<ClInclude Include="GL\GLExtensions\EXT_texture_compression_s3tc.h" />
|
||||
<ClInclude Include="GL\GLExtensions\EXT_texture_filter_anisotropic.h" />
|
||||
<ClInclude Include="GL\GLExtensions\GLExtensions.h" />
|
||||
<ClInclude Include="GL\GLExtensions\gl_1_1.h" />
|
||||
@@ -225,4 +226,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -248,6 +248,9 @@
|
||||
<ClInclude Include="GL\GLExtensions\ARB_compute_shader.h">
|
||||
<Filter>GL\GLExtensions</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GL\GLExtensions\EXT_texture_compression_s3tc.h">
|
||||
<Filter>GL\GLExtensions</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CDUtils.cpp" />
|
||||
@@ -321,4 +324,4 @@
|
||||
<ItemGroup>
|
||||
<Natvis Include="BitField.natvis" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
** Copyright (c) 2013-2015 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
#include "Common/GL/GLExtensions/gl_common.h"
|
||||
|
||||
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "Common/GL/GLExtensions/ARB_uniform_buffer_object.h"
|
||||
#include "Common/GL/GLExtensions/ARB_vertex_array_object.h"
|
||||
#include "Common/GL/GLExtensions/ARB_viewport_array.h"
|
||||
#include "Common/GL/GLExtensions/EXT_texture_compression_s3tc.h"
|
||||
#include "Common/GL/GLExtensions/EXT_texture_filter_anisotropic.h"
|
||||
#include "Common/GL/GLExtensions/HP_occlusion_test.h"
|
||||
#include "Common/GL/GLExtensions/KHR_debug.h"
|
||||
|
||||
@@ -239,6 +239,19 @@ D3D_FEATURE_LEVEL GetFeatureLevel(IDXGIAdapter* adapter)
|
||||
return feat_level;
|
||||
}
|
||||
|
||||
static bool SupportsS3TCTextures(ID3D11Device* device)
|
||||
{
|
||||
UINT bc1_support, bc2_support, bc3_support;
|
||||
if (FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &bc1_support)) ||
|
||||
FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC2_UNORM, &bc2_support)) ||
|
||||
FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &bc3_support)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((bc1_support & bc2_support & bc3_support) & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
|
||||
}
|
||||
|
||||
HRESULT Create(HWND wnd)
|
||||
{
|
||||
hWnd = wnd;
|
||||
@@ -427,6 +440,7 @@ HRESULT Create(HWND wnd)
|
||||
UINT format_support;
|
||||
device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
|
||||
bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
|
||||
g_Config.backend_info.bSupportsST3CTextures = SupportsS3TCTextures(device);
|
||||
|
||||
stateman = new StateManager;
|
||||
return S_OK;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
@@ -29,6 +30,25 @@ static std::unique_ptr<PSTextureEncoder> g_encoder;
|
||||
const size_t MAX_COPY_BUFFERS = 32;
|
||||
ID3D11Buffer* efbcopycbuf[MAX_COPY_BUFFERS] = {0};
|
||||
|
||||
static DXGI_FORMAT GetDXGIFormatForHostFormat(HostTextureFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HostTextureFormat::DXT1:
|
||||
return DXGI_FORMAT_BC1_UNORM;
|
||||
|
||||
case HostTextureFormat::DXT3:
|
||||
return DXGI_FORMAT_BC2_UNORM;
|
||||
|
||||
case HostTextureFormat::DXT5:
|
||||
return DXGI_FORMAT_BC3_UNORM;
|
||||
|
||||
case HostTextureFormat::RGBA8:
|
||||
default:
|
||||
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntry::~TCacheEntry()
|
||||
{
|
||||
texture->Release();
|
||||
@@ -41,6 +61,11 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
||||
|
||||
bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level)
|
||||
{
|
||||
// We can't dump compressed textures currently (it would mean drawing them to a RGBA8
|
||||
// framebuffer, and saving that). TextureCache does not call Save for custom textures
|
||||
// anyway, so this is fine for now.
|
||||
_assert_(config.format == HostTextureFormat::RGBA8);
|
||||
|
||||
// Create a staging/readback texture with the dimensions of the specified mip level.
|
||||
u32 mip_width = std::max(config.width >> level, 1u);
|
||||
u32 mip_height = std::max(config.height >> level, 1u);
|
||||
@@ -129,28 +154,30 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase*
|
||||
g_renderer->RestoreAPIState();
|
||||
}
|
||||
|
||||
void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u32 expanded_width,
|
||||
u32 level)
|
||||
void TextureCache::TCacheEntry::Load(u32 level, u32 width, u32 height, u32 row_length,
|
||||
const u8* buffer, size_t buffer_size)
|
||||
{
|
||||
unsigned int src_pitch = 4 * expanded_width;
|
||||
D3D::context->UpdateSubresource(texture->GetTex(), level, nullptr, buffer, src_pitch, 0);
|
||||
size_t src_pitch = CalculateHostTextureLevelPitch(config.format, row_length);
|
||||
D3D::context->UpdateSubresource(texture->GetTex(), level, nullptr, buffer,
|
||||
static_cast<UINT>(src_pitch), 0);
|
||||
}
|
||||
|
||||
TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config)
|
||||
{
|
||||
DXGI_FORMAT dxgi_format = GetDXGIFormatForHostFormat(config.format);
|
||||
if (config.rendertarget)
|
||||
{
|
||||
return new TCacheEntry(
|
||||
config, D3DTexture2D::Create(
|
||||
config.width, config.height, (D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET |
|
||||
(int)D3D11_BIND_SHADER_RESOURCE),
|
||||
D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers));
|
||||
config, D3DTexture2D::Create(config.width, config.height,
|
||||
(D3D11_BIND_FLAG)((int)D3D11_BIND_RENDER_TARGET |
|
||||
(int)D3D11_BIND_SHADER_RESOURCE),
|
||||
D3D11_USAGE_DEFAULT, dxgi_format, 1, config.layers));
|
||||
}
|
||||
else
|
||||
{
|
||||
const D3D11_TEXTURE2D_DESC texdesc =
|
||||
CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, config.width, config.height, 1,
|
||||
config.levels, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0);
|
||||
CD3D11_TEXTURE2D_DESC(dxgi_format, config.width, config.height, 1, config.levels,
|
||||
D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0);
|
||||
|
||||
ID3D11Texture2D* pTexture;
|
||||
const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, nullptr, &pTexture);
|
||||
|
||||
@@ -30,7 +30,8 @@ private:
|
||||
const MathUtil::Rectangle<int>& srcrect,
|
||||
const MathUtil::Rectangle<int>& dstrect) override;
|
||||
|
||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 levels) override;
|
||||
void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
||||
size_t buffer_size) override;
|
||||
|
||||
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect, bool scaleByHalf,
|
||||
unsigned int cbufid, const float* colmat) override;
|
||||
|
||||
@@ -77,6 +77,7 @@ void VideoBackend::InitBackendInfo()
|
||||
g_Config.backend_info.bSupportsMultithreading = false;
|
||||
g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false;
|
||||
g_Config.backend_info.bSupportsGPUTextureDecoding = false;
|
||||
g_Config.backend_info.bSupportsST3CTextures = false;
|
||||
|
||||
IDXGIFactory* factory;
|
||||
IDXGIAdapter* ad;
|
||||
|
||||
@@ -262,6 +262,21 @@ std::vector<DXGI_SAMPLE_DESC> EnumAAModes(ID3D12Device* device)
|
||||
return aa_modes;
|
||||
}
|
||||
|
||||
static bool SupportsS3TCTextures(ID3D12Device* device)
|
||||
{
|
||||
auto CheckForFormat = [](ID3D12Device* device, DXGI_FORMAT format) {
|
||||
D3D12_FEATURE_DATA_FORMAT_SUPPORT data = {format};
|
||||
if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &data, sizeof(data))))
|
||||
return false;
|
||||
|
||||
return (data.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D) != 0;
|
||||
};
|
||||
|
||||
return CheckForFormat(device, DXGI_FORMAT_BC1_UNORM) &&
|
||||
CheckForFormat(device, DXGI_FORMAT_BC2_UNORM) &&
|
||||
CheckForFormat(device, DXGI_FORMAT_BC3_UNORM);
|
||||
}
|
||||
|
||||
HRESULT Create(HWND wnd)
|
||||
{
|
||||
hWnd = wnd;
|
||||
@@ -478,6 +493,8 @@ HRESULT Create(HWND wnd)
|
||||
SAFE_RELEASE(factory);
|
||||
SAFE_RELEASE(adapter);
|
||||
|
||||
g_Config.backend_info.bSupportsST3CTextures = SupportsS3TCTextures(device12);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,25 @@ static u32 s_efb_copy_last_cbuf_id = UINT_MAX;
|
||||
static ID3D12Resource* s_texture_cache_entry_readback_buffer = nullptr;
|
||||
static size_t s_texture_cache_entry_readback_buffer_size = 0;
|
||||
|
||||
static DXGI_FORMAT GetDXGIFormatForHostFormat(HostTextureFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HostTextureFormat::DXT1:
|
||||
return DXGI_FORMAT_BC1_UNORM;
|
||||
|
||||
case HostTextureFormat::DXT3:
|
||||
return DXGI_FORMAT_BC2_UNORM;
|
||||
|
||||
case HostTextureFormat::DXT5:
|
||||
return DXGI_FORMAT_BC3_UNORM;
|
||||
|
||||
case HostTextureFormat::RGBA8:
|
||||
default:
|
||||
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntry::~TCacheEntry()
|
||||
{
|
||||
m_texture->Release();
|
||||
@@ -51,6 +70,11 @@ bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int l
|
||||
Common::AlignUp(level_width * sizeof(u32), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||
size_t required_readback_buffer_size = level_pitch * level_height;
|
||||
|
||||
// We can't dump compressed textures currently (it would mean drawing them to a RGBA8
|
||||
// framebuffer, and saving that). TextureCache does not call Save for custom textures
|
||||
// anyway, so this is fine for now.
|
||||
_assert_(config.format == HostTextureFormat::RGBA8);
|
||||
|
||||
// Check if the current readback buffer is large enough
|
||||
if (required_readback_buffer_size > s_texture_cache_entry_readback_buffer_size)
|
||||
{
|
||||
@@ -175,22 +199,24 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase*
|
||||
g_renderer->RestoreAPIState();
|
||||
}
|
||||
|
||||
void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u32 expanded_width,
|
||||
u32 level)
|
||||
void TextureCache::TCacheEntry::Load(u32 level, u32 width, u32 height, u32 row_length,
|
||||
const u8* buffer, size_t buffer_size)
|
||||
{
|
||||
unsigned int src_pitch = 4 * expanded_width;
|
||||
D3D::ReplaceRGBATexture2D(m_texture->GetTex12(), buffer, width, height, src_pitch, level,
|
||||
size_t src_pitch = CalculateHostTextureLevelPitch(config.format, row_length);
|
||||
D3D::ReplaceRGBATexture2D(m_texture->GetTex12(), buffer, width, height,
|
||||
static_cast<unsigned int>(src_pitch), level,
|
||||
m_texture->GetResourceUsageState());
|
||||
}
|
||||
|
||||
TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config)
|
||||
{
|
||||
DXGI_FORMAT dxgi_format = GetDXGIFormatForHostFormat(config.format);
|
||||
if (config.rendertarget)
|
||||
{
|
||||
D3DTexture2D* texture =
|
||||
D3DTexture2D::Create(config.width, config.height,
|
||||
TEXTURE_BIND_FLAG_SHADER_RESOURCE | TEXTURE_BIND_FLAG_RENDER_TARGET,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers);
|
||||
dxgi_format, 1, config.layers);
|
||||
|
||||
TCacheEntry* entry = new TCacheEntry(config, texture);
|
||||
|
||||
@@ -204,8 +230,8 @@ TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntry
|
||||
{
|
||||
ID3D12Resource* texture_resource = nullptr;
|
||||
|
||||
D3D12_RESOURCE_DESC texture_resource_desc = CD3DX12_RESOURCE_DESC::Tex2D(
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, config.width, config.height, 1, config.levels);
|
||||
D3D12_RESOURCE_DESC texture_resource_desc =
|
||||
CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, config.width, config.height, 1, config.levels);
|
||||
|
||||
CheckHR(D3D::device12->CreateCommittedResource(
|
||||
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE,
|
||||
|
||||
@@ -39,7 +39,8 @@ private:
|
||||
const MathUtil::Rectangle<int>& src_rect,
|
||||
const MathUtil::Rectangle<int>& dst_rect) override;
|
||||
|
||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 levels) override;
|
||||
void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
||||
size_t buffer_size) override;
|
||||
|
||||
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half,
|
||||
unsigned int cbuf_id, const float* colmat) override;
|
||||
|
||||
@@ -80,6 +80,7 @@ void VideoBackend::InitBackendInfo()
|
||||
g_Config.backend_info.bSupportsMultithreading = false;
|
||||
g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false;
|
||||
g_Config.backend_info.bSupportsGPUTextureDecoding = false;
|
||||
g_Config.backend_info.bSupportsST3CTextures = false;
|
||||
|
||||
IDXGIFactory* factory;
|
||||
IDXGIAdapter* ad;
|
||||
|
||||
@@ -45,6 +45,7 @@ void VideoBackend::InitBackendInfo()
|
||||
g_Config.backend_info.bSupportsMultithreading = false;
|
||||
g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false;
|
||||
g_Config.backend_info.bSupportsGPUTextureDecoding = false;
|
||||
g_Config.backend_info.bSupportsST3CTextures = false;
|
||||
|
||||
// aamodes: We only support 1 sample, so no MSAA
|
||||
g_Config.backend_info.Adapters.clear();
|
||||
|
||||
@@ -31,7 +31,10 @@ private:
|
||||
{
|
||||
TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {}
|
||||
~TCacheEntry() {}
|
||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override {}
|
||||
void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
||||
size_t buffer_size) override
|
||||
{
|
||||
}
|
||||
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half,
|
||||
unsigned int cbufid, const float* colmat) override
|
||||
{
|
||||
|
||||
@@ -462,6 +462,8 @@ Renderer::Renderer()
|
||||
g_ogl_config.bSupportsConservativeDepth = GLExtensions::Supports("GL_ARB_conservative_depth");
|
||||
g_ogl_config.bSupportsAniso = GLExtensions::Supports("GL_EXT_texture_filter_anisotropic");
|
||||
g_Config.backend_info.bSupportsComputeShaders = GLExtensions::Supports("GL_ARB_compute_shader");
|
||||
g_Config.backend_info.bSupportsST3CTextures =
|
||||
GLExtensions::Supports("GL_EXT_texture_compression_s3tc");
|
||||
|
||||
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/GL/GLInterfaceBase.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/StringUtil.h"
|
||||
@@ -87,6 +88,48 @@ bool SaveTexture(const std::string& filename, u32 textarget, u32 tex, int virtua
|
||||
return TextureToPng(data.data(), width * 4, filename, width, height, true);
|
||||
}
|
||||
|
||||
static GLenum GetGLInternalFormatForTextureFormat(HostTextureFormat format, bool storage)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HostTextureFormat::DXT1:
|
||||
return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
case HostTextureFormat::DXT3:
|
||||
return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
case HostTextureFormat::DXT5:
|
||||
return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
case HostTextureFormat::RGBA8:
|
||||
default:
|
||||
return storage ? GL_RGBA8 : GL_RGBA;
|
||||
}
|
||||
}
|
||||
|
||||
static GLenum GetGLFormatForTextureFormat(HostTextureFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HostTextureFormat::RGBA8:
|
||||
return GL_RGBA;
|
||||
|
||||
// Compressed texture formats don't use this parameter.
|
||||
default:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
static GLenum GetGLTypeForTextureFormat(HostTextureFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case HostTextureFormat::RGBA8:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
|
||||
// Compressed texture formats don't use this parameter.
|
||||
default:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntry::~TCacheEntry()
|
||||
{
|
||||
if (texture)
|
||||
@@ -129,6 +172,11 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage)
|
||||
|
||||
bool TextureCache::TCacheEntry::Save(const std::string& filename, unsigned int level)
|
||||
{
|
||||
// We can't dump compressed textures currently (it would mean drawing them to a RGBA8
|
||||
// framebuffer, and saving that). TextureCache does not call Save for custom textures
|
||||
// anyway, so this is fine for now.
|
||||
_assert_(config.format == HostTextureFormat::RGBA8);
|
||||
|
||||
return SaveTexture(filename, GL_TEXTURE_2D_ARRAY, texture, config.width, config.height, level);
|
||||
}
|
||||
|
||||
@@ -143,12 +191,15 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConf
|
||||
|
||||
if (g_ogl_config.bSupportsTextureStorage)
|
||||
{
|
||||
glTexStorage3D(GL_TEXTURE_2D_ARRAY, config.levels, GL_RGBA8, config.width, config.height,
|
||||
config.layers);
|
||||
GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(config.format, true);
|
||||
glTexStorage3D(GL_TEXTURE_2D_ARRAY, config.levels, gl_internal_format, config.width,
|
||||
config.height, config.layers);
|
||||
}
|
||||
|
||||
if (config.rendertarget)
|
||||
{
|
||||
// We can't render to compressed formats.
|
||||
_assert_(!IsCompressedHostTextureFormat(config.format));
|
||||
if (!g_ogl_config.bSupportsTextureStorage)
|
||||
{
|
||||
for (u32 level = 0; level < config.levels; level++)
|
||||
@@ -202,8 +253,8 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase*
|
||||
g_renderer->RestoreAPIState();
|
||||
}
|
||||
|
||||
void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u32 expanded_width,
|
||||
u32 level)
|
||||
void TextureCache::TCacheEntry::Load(u32 level, u32 width, u32 height, u32 row_length,
|
||||
const u8* buffer, size_t buffer_size)
|
||||
{
|
||||
if (level >= config.levels)
|
||||
PanicAlert("Texture only has %d levels, can't update level %d", config.levels, level);
|
||||
@@ -216,21 +267,40 @@ void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u3
|
||||
glActiveTexture(GL_TEXTURE9);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
|
||||
|
||||
if (expanded_width != width)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width);
|
||||
if (row_length != width)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
|
||||
|
||||
if (g_ogl_config.bSupportsTextureStorage)
|
||||
GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(config.format, false);
|
||||
if (IsCompressedHostTextureFormat(config.format))
|
||||
{
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, 0, width, height, 1, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, buffer);
|
||||
if (g_ogl_config.bSupportsTextureStorage)
|
||||
{
|
||||
glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, 0, width, height, 1,
|
||||
gl_internal_format, static_cast<GLsizei>(buffer_size), buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, level, gl_internal_format, width, height, 1, 0,
|
||||
static_cast<GLsizei>(buffer_size), buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL_RGBA, width, height, 1, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, buffer);
|
||||
GLenum gl_format = GetGLFormatForTextureFormat(config.format);
|
||||
GLenum gl_type = GetGLTypeForTextureFormat(config.format);
|
||||
if (g_ogl_config.bSupportsTextureStorage)
|
||||
{
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, 0, width, height, 1, gl_format, gl_type,
|
||||
buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, level, gl_internal_format, width, height, 1, 0, gl_format,
|
||||
gl_type, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (expanded_width != width)
|
||||
if (row_length != width)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
TextureCache::SetStage();
|
||||
|
||||
@@ -45,7 +45,8 @@ private:
|
||||
const MathUtil::Rectangle<int>& srcrect,
|
||||
const MathUtil::Rectangle<int>& dstrect) override;
|
||||
|
||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override;
|
||||
void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
||||
size_t buffer_size) override;
|
||||
|
||||
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect, bool scaleByHalf,
|
||||
unsigned int cbufid, const float* colmat) override;
|
||||
|
||||
@@ -103,6 +103,7 @@ void VideoBackend::InitBackendInfo()
|
||||
g_Config.backend_info.bSupportsPaletteConversion = true;
|
||||
g_Config.backend_info.bSupportsClipControl = true;
|
||||
g_Config.backend_info.bSupportsDepthClamp = true;
|
||||
g_Config.backend_info.bSupportsST3CTextures = false;
|
||||
|
||||
g_Config.backend_info.Adapters.clear();
|
||||
|
||||
|
||||
@@ -65,7 +65,10 @@ private:
|
||||
{
|
||||
TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {}
|
||||
~TCacheEntry() {}
|
||||
void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override {}
|
||||
void Load(u32 level, u32 width, u32 height, u32 row_length, const u8* buffer,
|
||||
size_t buffer_size) override
|
||||
{
|
||||
}
|
||||
void FromRenderTarget(bool is_depth_copy, const EFBRectangle& srcRect, bool scaleByHalf,
|
||||
unsigned int cbufid, const float* colmat) override
|
||||
{
|
||||
@@ -134,6 +137,7 @@ void VideoSoftware::InitBackendInfo()
|
||||
g_Config.backend_info.bSupportsComputeShaders = false;
|
||||
g_Config.backend_info.bSupportsInternalResolutionFrameDumps = false;
|
||||
g_Config.backend_info.bSupportsGPUTextureDecoding = false;
|
||||
g_Config.backend_info.bSupportsST3CTextures = false;
|
||||
|
||||
// aamodes
|
||||
g_Config.backend_info.AAModes = {1};
|
||||
|
||||
@@ -109,7 +109,7 @@ constexpr size_t MAXIMUM_TEXTURE_UPLOAD_BUFFER_SIZE = 64 * 1024 * 1024;
|
||||
// streaming buffer and be blocking frequently. Games are unlikely to have textures this
|
||||
// large anyway, so it's only really an issue for HD texture packs, and memory is not
|
||||
// a limiting factor in these scenarios anyway.
|
||||
constexpr size_t STAGING_TEXTURE_UPLOAD_THRESHOLD = 1024 * 1024 * 4;
|
||||
constexpr size_t STAGING_TEXTURE_UPLOAD_THRESHOLD = 1024 * 1024 * 8;
|
||||
|
||||
// Streaming uniform buffer size
|
||||
constexpr size_t INITIAL_UNIFORM_STREAM_BUFFER_SIZE = 16 * 1024 * 1024;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user