Skip to content

Commit

Permalink
Add support for generating mipmaps on BC7 textures
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaldaien committed Nov 14, 2024
1 parent e505708 commit 609bf00
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 38 deletions.
1 change: 1 addition & 0 deletions include/SpecialK/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,7 @@ struct sk_config_t
bool dump = false;
bool inject = true;
bool cache = true;
bool orig_cache = true;// The initial setting when the game started
bool highlight_debug = true;
bool injection_keeps_fmt = false;
bool generate_mips = false;
Expand Down
2 changes: 2 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4627,6 +4627,8 @@ auto DeclKeybind =
texture.d3d11.inject->load (config.textures.d3d11.inject);
texture.res_root->load (config.textures.d3d11.res_root);

SK_RunOnce (config.textures.d3d11.orig_cache = config.textures.d3d11.cache);

texture.d3d11.injection_keeps_format->
load (config.textures.d3d11.injection_keeps_fmt);
texture.dump_on_load->load (config.textures.d3d11.dump);
Expand Down
21 changes: 10 additions & 11 deletions src/render/d3d11/d3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1617,9 +1617,6 @@ SK_D3D11_UpdateSubresource_Impl (
early_out = true;
}


static const bool __attempt_to_cache = config.textures.d3d11.cache;

if ( pDstBox != nullptr && ( pDstBox->left >= pDstBox->right ||
pDstBox->top >= pDstBox->bottom ||
pDstBox->front >= pDstBox->back ) )
Expand Down Expand Up @@ -1652,20 +1649,22 @@ SK_D3D11_UpdateSubresource_Impl (
_Finish ();
}

if ( __attempt_to_cache && ( (rdim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) ||
if ( config.textures.d3d11.orig_cache &&
( (rdim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) ||
SK_D3D11_IsStagingCacheable (rdim, pDstResource) ) && DstSubresource == 0 )
{
auto& textures =
SK_D3D11_Textures;

SK_ComQIPtr <ID3D11Texture2D> pTex (pDstResource);

SK_ComQIPtr <ID3D11Texture2D>
pTex (pDstResource);
if (pTex != nullptr)
{
D3D11_TEXTURE2D_DESC desc = { };
pTex->GetDesc (&desc);
D3D11_TEXTURE2D_DESC
desc = { };
pTex->GetDesc (&desc);

if (__attempt_to_cache)
if (config.textures.d3d11.orig_cache)
{
const bool skip =
( (desc.Usage == D3D11_USAGE_STAGING && (! SK_D3D11_IsStagingCacheable (rdim, pDstResource))) ||
Expand Down Expand Up @@ -2042,7 +2041,7 @@ SK_D3D11_CopySubresourceRegion_Impl (
{
SK_WRAP_AND_HOOK

// UB: If it's happening, pretend we never saw this...
// UB: If it's happening, pretend we never saw this...
if (pDstResource == nullptr || pSrcResource == nullptr)
{
return;
Expand Down Expand Up @@ -2120,7 +2119,7 @@ SK_D3D11_CopySubresourceRegion_Impl (
pSrcResource, SrcSubresource, pSrcBox );
};

bool early_out =
const bool early_out =
(! bMustNotIgnore) ||
SK_D3D11_IgnoreWrappedOrDeferred (bWrapped, bIsDevCtxDeferred, pDevCtx);

Expand Down
8 changes: 4 additions & 4 deletions src/render/d3d11/d3d11_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,10 +866,10 @@ SK_D3D11_SetShaderResources_Impl (
pDevContext, StartSlot, NumViews, ppShaderResourceViews);
};

bool early_out = shader_base == nullptr ||
( SK_D3D11_IgnoreWrappedOrDeferred (bWrapped, SK_D3D11_IsDevCtxDeferred (pDevContext),
pDevContext) ||
(! bMustNotIgnore) );
bool early_out = (! bMustNotIgnore) || shader_base == nullptr ||
SK_D3D11_IgnoreWrappedOrDeferred (bWrapped,
SK_D3D11_IsDevCtxDeferred (pDevContext),
pDevContext);

if (early_out)
{
Expand Down
2 changes: 2 additions & 0 deletions src/render/d3d11/hooks/d3d11_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,8 @@ D3D11Dev_CreateSamplerState_Override

D3D11_SAMPLER_DESC new_desc = *pSamplerDesc;



#pragma region "UglyGameHacksThatShouldNotBeHere"
static const bool bShenmue =
SK_GetCurrentGameID () == SK_GAME_ID::Shenmue;
Expand Down
122 changes: 99 additions & 23 deletions src/render/d3d11/mod_tools/d3d11_texture_mods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,48 @@ SK_D3D11_LiveTextureView (bool& can_scroll, SK_TLS* pTLS = SK_TLS_Bottom ())
entry.mipmapped = TRUE;
non_mipped--;
}

else if (skip)
{
if (DirectX::MakeTypeless (entry.desc.Format) == DXGI_FORMAT_BC7_TYPELESS)
{
SK_ScopedBool decl_tex_scope (
SK_D3D11_DeclareTexInjectScope (pTLS)
);

SK_ComPtr <ID3D11Device> pDev (rb.d3d11.device);
SK_ComPtr <ID3D11DeviceContext> pDevCtx (rb.d3d11.immediate_ctx);
DirectX::ScratchImage captured;
if (SUCCEEDED (DirectX::CaptureTexture (pDev, pDevCtx, entry.pTex, captured)))
{
DXGI_FORMAT uncompressed_fmt =
(entry.desc.Format == DXGI_FORMAT_BC7_TYPELESS) ? DXGI_FORMAT_R8G8B8A8_UNORM :
(entry.desc.Format == DXGI_FORMAT_BC7_UNORM) ? DXGI_FORMAT_R8G8B8A8_UNORM :
(entry.desc.Format == DXGI_FORMAT_BC7_UNORM_SRGB) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
: DXGI_FORMAT_UNKNOWN;
DirectX::ScratchImage converted;
DirectX::Decompress (*captured.GetImage (0,0,0), uncompressed_fmt, converted);

auto desc = entry.desc;
desc.Format = uncompressed_fmt;
desc.MipLevels = 1;

auto metadata =
converted.GetMetadata ();

metadata.mipLevels = 1;

SK_ComPtr <ID3D11Texture2D> pNewTex;
DirectX::CreateTexture (pDev, converted.GetImages (), 1, metadata, (ID3D11Resource **)&pNewTex.p);

if (SUCCEEDED (SK_D3D11_MipmapCacheTexture2D (pNewTex, entry.crc32c, pTLS)))
{
entry.mipmapped = TRUE;
non_mipped--;
}
}
}
}
}
}
}
Expand Down Expand Up @@ -1064,50 +1106,84 @@ SK_D3D11_LiveTextureView (bool& can_scroll, SK_TLS* pTLS = SK_TLS_Bottom ())
switch (entry.desc.Format)
{
// These formats take an eternity!
case DXGI_FORMAT_BC6H_TYPELESS:
case DXGI_FORMAT_BC6H_TYPELESS:
case DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT_BC6H_SF16:
case DXGI_FORMAT_BC7_TYPELESS:
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
ignore = (! bIncludeBC7andBC6H);
ignore = true;//(! bIncludeBC7andBC6H);
default:
break;
}

if (ignore) ImGui::BeginDisabled ();
//if (ignore) ImGui::BeginDisabled ();
if (ImGui::Button (" Generate Mipmaps ###GenerateMipmaps"))
{
SK_ScopedBool decl_tex_scope (
SK_D3D11_DeclareTexInjectScope (pTLS)
);

if (SUCCEEDED (SK_D3D11_MipmapCacheTexture2D (pTex, entry.crc32c, pTLS)))
if (ignore)
{
SK_ComPtr <ID3D11DeviceContext> pDevCtx (rb.d3d11.immediate_ctx);
DirectX::ScratchImage captured;
if (SUCCEEDED (DirectX::CaptureTexture (pDev, pDevCtx, pTex, captured)))
{
DXGI_FORMAT uncompressed_fmt =
(entry.desc.Format == DXGI_FORMAT_BC7_TYPELESS) ? DXGI_FORMAT_R8G8B8A8_UNORM :
(entry.desc.Format == DXGI_FORMAT_BC7_UNORM) ? DXGI_FORMAT_R8G8B8A8_UNORM :
(entry.desc.Format == DXGI_FORMAT_BC7_UNORM_SRGB) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
: DXGI_FORMAT_UNKNOWN;
DirectX::ScratchImage converted;
DirectX::Decompress (*captured.GetImage (0,0,0), uncompressed_fmt, converted);

auto desc = entry.desc;
desc.Format = uncompressed_fmt;
desc.MipLevels = 1;

auto metadata =
converted.GetMetadata ();

metadata.mipLevels = 1;

SK_ComPtr <ID3D11Texture2D> pNewTex;
DirectX::CreateTexture (pDev, converted.GetImages (), 1, metadata, (ID3D11Resource **)&pNewTex.p);

if (SUCCEEDED (SK_D3D11_MipmapCacheTexture2D (pNewTex, entry.crc32c, pTLS)))
{
entry.mipmapped = TRUE;
non_mipped--;
}
}
}

else if (SUCCEEDED (SK_D3D11_MipmapCacheTexture2D (pTex, entry.crc32c, pTLS)))
{
entry.mipmapped = TRUE;
non_mipped--;
}
}

if (ignore)
{ ImGui::EndDisabled ();
if (ImGui::IsItemHovered ())
{ ImGui::BeginTooltip ();
ImGui::TextUnformatted (
"This operation may take an EXTREMELY long time to complete!!"
);
ImGui::Separator ();
ImGui::BulletText (
"Mipmap generation must first Decompress BC7/BC6H textures");
ImGui::BulletText (
"Once decompressed, mipmap generation is simple, but...");
ImGui::BulletText (
"The mipmapped copy must be recompressed with BC7/BC6H(!!)");
ImGui::Separator ();
ImGui::TextUnformatted ("\tCompressing BC7/BC6H is SLOW!");
ImGui::EndTooltip ();
}
}
//if (ignore)
//{ ImGui::EndDisabled ();
// if (ImGui::IsItemHovered ())
// { ImGui::BeginTooltip ();
// ImGui::TextUnformatted (
// "This operation may take an EXTREMELY long time to complete!!"
// );
// ImGui::Separator ();
// ImGui::BulletText (
// "Mipmap generation must first Decompress BC7/BC6H textures");
// ImGui::BulletText (
// "Once decompressed, mipmap generation is simple, but...");
// ImGui::BulletText (
// "The mipmapped copy must be recompressed with BC7/BC6H(!!)");
// ImGui::Separator ();
// ImGui::TextUnformatted ("\tCompressing BC7/BC6H is SLOW!");
// ImGui::EndTooltip ();
// }
//}
}
}

Expand Down

0 comments on commit 609bf00

Please sign in to comment.