From cacd8a6064e9c8feac599e1c2ffddb976268fc1e Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 3 Aug 2025 20:25:31 -0500 Subject: [PATCH 01/11] mipwork, laregly courtesy of @mmarauder2k9-torque --- Engine/source/gfx/D3D11/gfxD3D11Target.cpp | 8 +- .../gfx/D3D11/gfxD3D11TextureManager.cpp | 2 +- Engine/source/gfx/gfxTextureManager.cpp | 6 +- Engine/source/postFx/postEffect.cpp | 24 +++-- Engine/source/postFx/postEffect.h | 2 + .../core/postFX/scripts/HDR/HDRPostFX.tscript | 79 ++++++----------- .../scripts/HDR/HDR_Bloom/downSampleP.hlsl | 88 ++++++++++--------- .../scripts/HDR/HDR_Bloom/upSampleP.hlsl | 47 +++++----- 8 files changed, 128 insertions(+), 128 deletions(-) diff --git a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp index 88e91156d..63f910f05 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp @@ -151,7 +151,13 @@ void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *te mTargetSize.set( tex->getSize().x, tex->getSize().y ); mTargetFormat = tex->getFormat(); } - } + } + + if (mGenMips) + { + mTargetSRViews[slot] = d3dto->getSRView(); + mTargetSRViews[slot]->AddRef(); + } } // Update surface size diff --git a/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp b/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp index dd34b9ec5..e24a6f5dd 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp @@ -105,7 +105,7 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex, } if( !forceMips && !retTex->mProfile->isSystemMemory() && - numMipLevels == 0 && + (numMipLevels == 0 || numMipLevels > 1)&& !(depth > 0) ) { miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index b0a897501..5180a04a8 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -1414,13 +1414,13 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height, { inOutNumMips = 1; } - else if( !isPow2( width ) || !isPow2( height ) ) + else if (!isPow2(width) || !isPow2(height)) { // If a texture is not power-of-2 in size for both dimensions, it must // have only 1 mip level. - inOutNumMips = 1; + inOutNumMips = mFloor(mLog2(mMax(width, height))) + 1; } - + // Check format, and compatibility with texture profile requirements bool autoGenSupp = ( inOutNumMips == 0 ); diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index ad08b9391..0ac10a879 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -142,25 +142,23 @@ IMPLEMENT_CONOBJECT(PostEffect); GFX_ImplementTextureProfile( PostFxTextureProfile, GFXTextureProfile::DiffuseMap, - GFXTextureProfile::Static | GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap, + GFXTextureProfile::Static | GFXTextureProfile::PreserveSize, GFXTextureProfile::NONE ); GFX_ImplementTextureProfile( PostFxTextureSRGBProfile, GFXTextureProfile::DiffuseMap, - GFXTextureProfile::Static | GFXTextureProfile::PreserveSize | GFXTextureProfile::NoMipmap | GFXTextureProfile::SRGB, + GFXTextureProfile::Static | GFXTextureProfile::PreserveSize | GFXTextureProfile::SRGB, GFXTextureProfile::NONE); GFX_ImplementTextureProfile( VRTextureProfile, GFXTextureProfile::DiffuseMap, GFXTextureProfile::PreserveSize | - GFXTextureProfile::RenderTarget | - GFXTextureProfile::NoMipmap, + GFXTextureProfile::RenderTarget, GFXTextureProfile::NONE ); GFX_ImplementTextureProfile( VRDepthProfile, GFXTextureProfile::DiffuseMap, GFXTextureProfile::PreserveSize | - GFXTextureProfile::NoMipmap | GFXTextureProfile::ZTarget, GFXTextureProfile::NONE ); @@ -501,7 +499,8 @@ PostEffect::PostEffect() mInvCameraTransSC(NULL), mMatCameraToScreenSC(NULL), mMatScreenToCameraSC(NULL), - mIsCapturingSC(NULL) + mIsCapturingSC(NULL), + mMipCap(1) { dMemset( mTexSRGB, 0, sizeof(bool) * NumTextures); dMemset( mActiveTextures, 0, sizeof( GFXTextureObject* ) * NumTextures ); @@ -509,7 +508,7 @@ PostEffect::PostEffect() dMemset( mActiveTextureViewport, 0, sizeof( RectI ) * NumTextures ); dMemset( mTexSizeSC, 0, sizeof( GFXShaderConstHandle* ) * NumTextures ); dMemset( mRenderTargetParamsSC, 0, sizeof( GFXShaderConstHandle* ) * NumTextures ); - + dMemset(mMipCountSC, 0, sizeof(GFXShaderConstHandle*) * NumTextures); } PostEffect::~PostEffect() @@ -538,6 +537,9 @@ void PostEffect::initPersistFields() addField( "targetScale", TypePoint2F, Offset( mTargetScale, PostEffect ), "If targetSize is zero this is used to set a relative size from the current target." ); + + addField("mipCap", TypePoint2F, Offset(mMipCap, PostEffect), + "generate up to this many mips. 0 = all, 1 = none, >1 = as specified max."); //todo: de-stupid addField( "targetSize", TypePoint2I, Offset( mTargetSize, PostEffect ), "If non-zero this is used as the absolute target size." ); @@ -760,6 +762,7 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) { mTexSizeSC[i] = mShader->getShaderConstHandle(String::ToString("$texSize%d", i)); mRenderTargetParamsSC[i] = mShader->getShaderConstHandle(String::ToString("$rtParams%d",i)); + mMipCountSC[i] = mShader->getShaderConstHandle(String::ToString("$mipCount%d", i)); } mTargetViewportSC = mShader->getShaderConstHandle( "$targetViewport" ); @@ -843,6 +846,11 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) texSizeConst.y = (F32)mActiveTextures[i]->getHeight(); mShaderConsts->set( mTexSizeSC[i], texSizeConst ); } + + if (mMipCountSC[i]->isValid()) + { + mShaderConsts->set(mMipCountSC[i], (S32)mActiveTextures[i]->getMipLevels()); + } } for ( U32 i = 0; i < NumTextures; i++ ) @@ -1265,7 +1273,7 @@ void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarg mTargetTex.getWidthHeight() != targetSize ) { mTargetTex.set( targetSize.x, targetSize.y, mTargetFormat, - &PostFxTargetProfile, "PostEffect::_setupTarget" ); + &PostFxTargetProfile, "PostEffect::_setupTarget", mMipCap); if ( mTargetClear == PFXTargetClear_OnCreate ) *outClearTarget = true; diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index bf83812d1..101f171dc 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -133,6 +133,7 @@ protected: GFXShaderConstHandle *mTexSizeSC[NumTextures]; GFXShaderConstHandle *mRenderTargetParamsSC[NumTextures]; + GFXShaderConstHandle* mMipCountSC[NumTextures]; GFXShaderConstHandle *mViewportOffsetSC; @@ -176,6 +177,7 @@ protected: String mTargetName; GFXTexHandle mTargetTex; + S32 mMipCap; String mTargetDepthStencilName; GFXTexHandle mTargetDepthStencil; diff --git a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript index b15f48d61..ff2586d20 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript +++ b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDRPostFX.tscript @@ -117,8 +117,7 @@ singleton ShaderData( HDR_BloomUpSampleShader ) OGLVertexShaderFile= $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl"; OGLPixelShaderFile = "./HDR_Bloom/upSampleP.glsl"; - samplerNames[0] = "$nxtTex"; - samplerNames[1] = "$mipTex"; + samplerNames[0] = "$hdrbloomDown"; pixVersion = 3.0; }; @@ -292,13 +291,7 @@ function HDRPostFX::setShaderConsts( %this ) %bloom.skip = (!$PostFX::HDRPostFX::enableBloom || !$pref::PostFX::EnableHDRBloom); %bloom.setShaderConst("$threshold", $PostFX::HDRPostFX::threshold); - - for (%idx = 0; %idx < %this.mipsCount; %idx++) - { - %mip = %bloom.getObject(%this.mipsCount + %idx); - %mip.setShaderConst("$filterRadius", $PostFX::HDRPostFX::radius); - %mip.setShaderConst("$mipId", %idx); - } + %bloom-->upFX.setShaderConst("$filterRadius", $PostFX::HDRPostFX::radius); %strength = $PostFX::HDRPostFX::intensity; if (!$PostFX::HDRPostFX::enableBloom || !$pref::PostFX::EnableHDRBloom) @@ -524,50 +517,36 @@ function HDRPostFX::SetupBloomFX( %this ) shader = HDR_BloomThresholdShader; stateBlock = HDR_DownSampleStateBlock; texture[0] = "#hdrInitBloom"; - target = "#hdrbloom_0"; + target = "#hdrbloomIn"; + mipCap = "5"; targetFormat = %this.mipTexFormat; }; - - %textureName = "#hdrbloom_0"; - for (%idx = 0; %idx < %this.mipsCount; %idx++) - { - %mipName = "hdrbloom_" @ (%idx + 1); - %mipFX = new PostEffect() - { - internalName = %mipName; - allowReflectPass = false; - shader = HDR_BloomDownSampleShader; - stateBlock = HDR_DownSampleStateBlock; - texture[0] = %textureName; - target = "#" @ %mipName; - targetScale = "0.5 0.5"; - targetFormat = %this.mipTexFormat; - }; - - %bloomFX.add(%mipFX); - %textureName = "#" @ %mipName; - } - for (%idx = %this.mipsCount - 1; %idx >= 0; %idx--) + %downFX = new PostEffect() { - %nxt = "#hdrbloom_" @ %idx; - %mipName = "hdrbloom_up_" @ %idx; - - %mipFX = new PostEffect() - { - internalName = %mipName; - allowReflectPass = false; - shader = HDR_BloomUpSampleShader; - stateBlock = HDR_DownSampleStateBlock; - texture[0] = %nxt; - texture[1] = %textureName; - target = "#" @ %mipName; - targetFormat = %this.mipTexFormat; - }; - - %bloomFX.add(%mipFX); - %textureName = "#" @ %mipName; - } + internalName = "downFX"; + allowReflectPass = false; + shader = HDR_BloomDownSampleShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "#hdrbloomIn"; + target = "#hdrbloomDown"; + mipCap = "5"; + targetScale = "0.5 0.5"; + targetFormat = %this.mipTexFormat; + }; + %bloomFX.add(%downFX); + + %upFX = new PostEffect() + { + internalName = "upFX"; + allowReflectPass = false; + shader = HDR_BloomUpSampleShader; + stateBlock = HDR_DownSampleStateBlock; + texture[0] = "#hdrbloomDown"; + target = "#hdrbloomUp"; + targetFormat = %this.mipTexFormat; + }; + %bloomFX.add(%upFX); %finalFX = new PostEffect() { @@ -575,7 +554,7 @@ function HDRPostFX::SetupBloomFX( %this ) allowReflectPass = false; shader = HDR_BloomDirtShader; stateBlock = HDR_LensDirtStateBlock; - texture[0] = "#hdrbloom_up_0"; + texture[0] = "#hdrbloomUp"; target = "#hdrbloom_end"; targetFormat = %this.mipTexFormat; }; diff --git a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl index 6ac8ce668..c358087f6 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl +++ b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl @@ -25,7 +25,7 @@ TORQUE_UNIFORM_SAMPLER2D(inputTex, 0); uniform float2 oneOverTargetSize; -uniform int mipId; +uniform int mipCount0; float4 main(PFXVertToPix IN) : TORQUE_TARGET0 { @@ -33,49 +33,51 @@ float4 main(PFXVertToPix IN) : TORQUE_TARGET0 float x = oneOverTargetSize.x; float y = oneOverTargetSize.y; - float3 a = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y + 2*y)).rgb; - float3 b = TORQUE_TEX2D(inputTex, float2(IN.uv0.x , IN.uv0.y + 2*y)).rgb; - float3 c = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y + 2*y)).rgb; - - float3 d = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y)).rgb; - float3 e = TORQUE_TEX2D(inputTex, float2(IN.uv0.x , IN.uv0.y)).rgb; - float3 f = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y)).rgb; - - float3 g = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - 2 * x, IN.uv0.y - 2*y)).rgb; - float3 h = TORQUE_TEX2D(inputTex, float2(IN.uv0.x , IN.uv0.y - 2*y)).rgb; - float3 i = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + 2 * x, IN.uv0.y - 2*y)).rgb; - - float3 j = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - x, IN.uv0.y + y)).rgb; - float3 k = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + x, IN.uv0.y + y)).rgb; - float3 l = TORQUE_TEX2D(inputTex, float2(IN.uv0.x - x, IN.uv0.y - y)).rgb; - float3 m = TORQUE_TEX2D(inputTex, float2(IN.uv0.x + x, IN.uv0.y - y)).rgb; - - float3 group[5]; - switch (mipId) + for (int mipId = 0; mipId Date: Mon, 4 Aug 2025 12:48:22 -0500 Subject: [PATCH 02/11] typofix --- Engine/source/postFx/postEffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index 0ac10a879..fa5f1fa39 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -538,7 +538,7 @@ void PostEffect::initPersistFields() addField( "targetScale", TypePoint2F, Offset( mTargetScale, PostEffect ), "If targetSize is zero this is used to set a relative size from the current target." ); - addField("mipCap", TypePoint2F, Offset(mMipCap, PostEffect), + addField("mipCap", TypeS32, Offset(mMipCap, PostEffect), "generate up to this many mips. 0 = all, 1 = none, >1 = as specified max."); //todo: de-stupid addField( "targetSize", TypePoint2I, Offset( mTargetSize, PostEffect ), From 7fcdd03b50f5a50e0ba514ccfe2b5e09c0c9b230 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Mon, 4 Aug 2025 13:10:13 -0500 Subject: [PATCH 03/11] skip mip calculation for non pow2 textures if it's not for a rendertarget --- Engine/source/gfx/gfxTextureManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index 5180a04a8..100c23e9f 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -1418,7 +1418,7 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height, { // If a texture is not power-of-2 in size for both dimensions, it must // have only 1 mip level. - inOutNumMips = mFloor(mLog2(mMax(width, height))) + 1; + inOutNumMips = profile->isRenderTarget() ? mFloor(mLog2(mMax(width, height))) + 1 : 1; } // Check format, and compatibility with texture profile requirements From 3cdbd4e87e2cf2177dd6ded35e705954dee29482 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Mon, 4 Aug 2025 14:11:00 -0500 Subject: [PATCH 04/11] don't let GFXD3D11TextureTarget::deactivate() try to generate mips if we haven't told that target to do so --- Engine/source/gfx/D3D11/gfxD3D11Target.cpp | 17 ++++++++++++----- .../source/gfx/D3D11/gfxD3D11TextureManager.cpp | 1 + Engine/source/postFx/postEffect.cpp | 4 +++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp index 63f910f05..989e086e2 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp @@ -276,11 +276,18 @@ void GFXD3D11TextureTarget::deactivate() //re-gen mip maps for (U32 i = 0; i < 6; i++) { - ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i]; - if (pSRView) - D3D11DEVICECONTEXT->GenerateMips(pSRView); - } - + D3D11_TEXTURE2D_DESC desc; + if (mResolveTargets[GFXTextureTarget::Color0 + i]) + { + mResolveTargets[GFXTextureTarget::Color0 + i]->get2DTex()->GetDesc(&desc); + if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) + { + ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i]; + if (pSRView) + D3D11DEVICECONTEXT->GenerateMips(pSRView); + } + } + } } void GFXD3D11TextureTarget::resolve() diff --git a/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp b/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp index e24a6f5dd..a8cf0a2fd 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp @@ -108,6 +108,7 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex, (numMipLevels == 0 || numMipLevels > 1)&& !(depth > 0) ) { + if (numMipLevels == 5) Con::errorf("GFXD3D11TextureManager::_innerCreateTexture - numMipLevels == 5 found!"); miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; bindFlags |= D3D11_BIND_RENDER_TARGET; // in order to automatically generate mips. Resource needs to be a rendertarget and shader resource } diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index fa5f1fa39..4e2fb1990 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -849,7 +849,9 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) if (mMipCountSC[i]->isValid()) { - mShaderConsts->set(mMipCountSC[i], (S32)mActiveTextures[i]->getMipLevels()); + S32 mipLevels = (S32)mActiveTextures[i]->getMipLevels(); + mShaderConsts->set(mMipCountSC[i], mipLevels); + if (mipLevels == 5) Con::errorf("PostEffect::_setupConstants - mipLevels == 5 found!"); } } From 022f8d1732ef653edff70bf8b4a24c27643c94a7 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Mon, 4 Aug 2025 14:36:11 -0500 Subject: [PATCH 05/11] set GFXTextureManager::_validateTexParams to respect sen mipcaps also kill console spam --- Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp | 1 - Engine/source/gfx/gfxTextureManager.cpp | 14 ++++++++++++-- Engine/source/postFx/postEffect.cpp | 4 +--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp b/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp index a8cf0a2fd..e24a6f5dd 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp @@ -108,7 +108,6 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex, (numMipLevels == 0 || numMipLevels > 1)&& !(depth > 0) ) { - if (numMipLevels == 5) Con::errorf("GFXD3D11TextureManager::_innerCreateTexture - numMipLevels == 5 found!"); miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; bindFlags |= D3D11_BIND_RENDER_TARGET; // in order to automatically generate mips. Resource needs to be a rendertarget and shader resource } diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index 100c23e9f..a259caf63 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -1410,7 +1410,7 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height, U32 &inOutNumMips, GFXFormat &inOutFormat ) { // Validate mipmap parameter. If this profile requests no mips, set mips to 1. - if( profile->noMip() ) + if( profile->noMip()|| inOutNumMips == 1) { inOutNumMips = 1; } @@ -1418,7 +1418,17 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height, { // If a texture is not power-of-2 in size for both dimensions, it must // have only 1 mip level. - inOutNumMips = profile->isRenderTarget() ? mFloor(mLog2(mMax(width, height))) + 1 : 1; + if (profile->isRenderTarget()) + { + if (inOutNumMips == 0) //auto + inOutNumMips = mFloor(mLog2(mMax(width, height))) + 1; + else if (inOutNumMips > 1) //capped + inOutNumMips = mMin(inOutNumMips,mFloor(mLog2(mMax(width, height))) + 1); + } + else + { + inOutNumMips = 1; + } } // Check format, and compatibility with texture profile requirements diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index 4e2fb1990..fa5f1fa39 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -849,9 +849,7 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) if (mMipCountSC[i]->isValid()) { - S32 mipLevels = (S32)mActiveTextures[i]->getMipLevels(); - mShaderConsts->set(mMipCountSC[i], mipLevels); - if (mipLevels == 5) Con::errorf("PostEffect::_setupConstants - mipLevels == 5 found!"); + mShaderConsts->set(mMipCountSC[i], (S32)mActiveTextures[i]->getMipLevels()); } } From 36c906a72d17abdc4500d5e7ac2e41dfbd6c6188 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Mon, 4 Aug 2025 17:55:18 -0500 Subject: [PATCH 06/11] allow "null surfaces" to register mResolveTargets to at least attempt to gen mips --- Engine/source/gfx/D3D11/gfxD3D11Target.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp index 989e086e2..2e6e9fe61 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11Target.cpp +++ b/Engine/source/gfx/D3D11/gfxD3D11Target.cpp @@ -133,17 +133,14 @@ void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *te mTargets[slot] = d3dto->get2DTex(); mTargets[slot]->AddRef(); mTargetViews[slot] = d3dto->getRTView(); - mTargetViews[slot]->AddRef(); + mTargetViews[slot]->AddRef(); + mResolveTargets[slot] = d3dto; } else { mTargets[slot] = d3dto->getSurface(); mTargets[slot]->AddRef(); mTargetViews[slot]->AddRef(); - // Only assign resolve target if d3dto has a surface to give us. - // - // That usually means there is an MSAA target involved, which is why - // the resolve is needed to get the data out of the target. mResolveTargets[slot] = d3dto; if ( tex && slot == Color0 ) From 958e0d51271eb1a698e6197cdec1eff6d0fb23a6 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Mon, 4 Aug 2025 18:16:13 -0500 Subject: [PATCH 07/11] correct for mip weighting --- .../scripts/HDR/HDR_Bloom/downSampleP.hlsl | 19 ++++++++------ .../scripts/HDR/HDR_Bloom/upSampleP.hlsl | 26 ++++++++++--------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl index c358087f6..4bfa93ed0 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl +++ b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.hlsl @@ -29,12 +29,14 @@ uniform int mipCount0; float4 main(PFXVertToPix IN) : TORQUE_TARGET0 { - float4 downSample = float4(0, 0, 0, 0); - float x = oneOverTargetSize.x; - float y = oneOverTargetSize.y; + float4 downSample = float4(0, 0, 0, 0); + float4 finalOut = float4(0, 0, 0, 0); for (int mipId = 0; mipId Date: Tue, 5 Aug 2025 10:21:27 -0500 Subject: [PATCH 08/11] preliminary gl conversion --- .../scripts/HDR/HDR_Bloom/downSampleP.glsl | 99 ++++++++++--------- .../scripts/HDR/HDR_Bloom/downSampleP.hlsl | 1 + .../scripts/HDR/HDR_Bloom/upSampleP.glsl | 47 +++++---- .../scripts/HDR/HDR_Bloom/upSampleP.hlsl | 1 - 4 files changed, 80 insertions(+), 68 deletions(-) diff --git a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl index 64eeac49e..2f73d917f 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl +++ b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl @@ -28,59 +28,66 @@ #line 28 uniform sampler2D inputTex; uniform vec2 oneOverTargetSize; -uniform int mipId; +uniform int mipCount0; out vec4 OUT_col; void main() { vec4 downSample = vec4(0, 0, 0, 0); - float x = oneOverTargetSize.x; - float y = oneOverTargetSize.y; - - vec3 a = texture(inputTex, vec2(IN_uv0.x - 2 * x, IN_uv0.y + 2 * y)).rgb; - vec3 b = texture(inputTex, vec2(IN_uv0.x, IN_uv0.y + 2 * y)).rgb; - vec3 c = texture(inputTex, vec2(IN_uv0.x + 2 * x, IN_uv0.y + 2 * y)).rgb; + vec4 finalOut = float4(0, 0, 0, 0); - vec3 d = texture(inputTex, vec2(IN_uv0.x - 2 * x, IN_uv0.y)).rgb; - vec3 e = texture(inputTex, vec2(IN_uv0.x, IN_uv0.y)).rgb; - vec3 f = texture(inputTex, vec2(IN_uv0.x + 2 * x, IN_uv0.y)).rgb; - - vec3 g = texture(inputTex, vec2(IN_uv0.x - 2 * x, IN_uv0.y - 2 * y)).rgb; - vec3 h = texture(inputTex, vec2(IN_uv0.x, IN_uv0.y - 2 * y)).rgb; - vec3 i = texture(inputTex, vec2(IN_uv0.x + 2 * x, IN_uv0.y - 2 * y)).rgb; - - vec3 j = texture(inputTex, vec2(IN_uv0.x - x, IN_uv0.y + y)).rgb; - vec3 k = texture(inputTex, vec2(IN_uv0.x + x, IN_uv0.y + y)).rgb; - vec3 l = texture(inputTex, vec2(IN_uv0.x - x, IN_uv0.y - y)).rgb; - vec3 m = texture(inputTex, vec2(IN_uv0.x + x, IN_uv0.y - y)).rgb; - - vec3 group[5]; - switch (mipId) + for (int mipId = 0; mipId Date: Tue, 5 Aug 2025 14:50:30 -0500 Subject: [PATCH 09/11] typofix --- .../game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl index 2f73d917f..2ca21746f 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl +++ b/Templates/BaseGame/game/core/postFX/scripts/HDR/HDR_Bloom/downSampleP.glsl @@ -53,7 +53,7 @@ void main() vec3 f = textureLod(inputTex, vec2(IN_uv0.x + 2 * x, IN_uv0.y), mipIDf).rgb; vec3 g = textureLod(inputTex, vec2(IN_uv0.x - 2 * x, IN_uv0.y - 2 * y), mipIDf).rgb; - vec3 h = textureLod(inputTex, vec2(IN_uv0.x, IN_uv0.y - 2 * y, mipIDf)).rgb; + vec3 h = textureLod(inputTex, vec2(IN_uv0.x, IN_uv0.y - 2 * y), mipIDf).rgb; vec3 i = textureLod(inputTex, vec2(IN_uv0.x + 2 * x, IN_uv0.y - 2 * y), mipIDf).rgb; vec3 j = textureLod(inputTex, vec2(IN_uv0.x - x, IN_uv0.y + y), mipIDf).rgb; From f2ffc8bd22452d2afc584abb950524b6c26595fd Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 5 Aug 2025 14:52:31 -0500 Subject: [PATCH 10/11] rangeclamp for mip guestimates for rendertargets to keep that from getting out of hand (or try to. gls still not respecting it for some reason) --- Engine/source/gfx/gfxTextureManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index a259caf63..f9d059742 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -1424,6 +1424,7 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height, inOutNumMips = mFloor(mLog2(mMax(width, height))) + 1; else if (inOutNumMips > 1) //capped inOutNumMips = mMin(inOutNumMips,mFloor(mLog2(mMax(width, height))) + 1); + inOutNumMips = mClampF(inOutNumMips, 1, 13); } else { From 8d38fa0bc4ce228fe79656abaa0b83c5c22405e0 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Wed, 6 Aug 2025 12:57:59 -0500 Subject: [PATCH 11/11] gl side mip sanity clamps --- Engine/source/gfx/gl/gfxGLTextureManager.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Engine/source/gfx/gl/gfxGLTextureManager.cpp b/Engine/source/gfx/gl/gfxGLTextureManager.cpp index 636426240..ae6ce898c 100644 --- a/Engine/source/gfx/gl/gfxGLTextureManager.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureManager.cpp @@ -116,10 +116,18 @@ void GFXGLTextureManager::innerCreateTexture( GFXGLTextureObject *retTex, { retTex->mMipLevels = numMipLevels > 1 ? numMipLevels : 0; } - else if(profile->testFlag(GFXTextureProfile::NoMipmap) || profile->testFlag(GFXTextureProfile::RenderTarget) || numMipLevels == 1 || retTex->mIsNPoT2) + else if(profile->testFlag(GFXTextureProfile::NoMipmap) || numMipLevels == 1) { retTex->mMipLevels = 1; } + else if (profile->testFlag(GFXTextureProfile::RenderTarget)) + { + if (numMipLevels == 0) //auto + numMipLevels = mFloor(mLog2(mMax(width, height))) + 1; + else if (numMipLevels > 1) //capped + numMipLevels = mMin(numMipLevels, mFloor(mLog2(mMax(width, height))) + 1); + retTex->mMipLevels = mClampF(numMipLevels, 1, 13); + } else { retTex->mMipLevels = numMipLevels;