From 8505c7ee7da1fa5ac8452903f4b32f9797c9c32c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 16 Apr 2020 23:37:22 +0200 Subject: [PATCH] - major refactor of texture upscaling control. All decisions were done deep inside the texture creation code, leaving zero options to the higher level code for controlling the feature. Changed this so that the option to upscale must be passed as a parameter to FRenderState::SetMaterial and extended all needed variables to manage the added texture variants. Still not solved: Material layers need explicit control, not only for scaling but also for filtering. --- src/common/textures/hires/hqresize.cpp | 44 +++++++++++----- src/common/textures/hw_material.cpp | 16 +++--- src/common/textures/hw_material.h | 11 ++-- src/common/textures/hw_texcontainer.h | 51 ++++++++++--------- src/common/textures/texture.cpp | 27 ++-------- src/common/textures/textures.h | 16 ++---- src/rendering/gl/renderer/gl_renderer.cpp | 2 +- src/rendering/gl/renderer/gl_renderstate.cpp | 5 +- src/rendering/gl/system/gl_framebuffer.cpp | 4 +- src/rendering/hwrenderer/models/hw_models.cpp | 2 +- src/rendering/hwrenderer/scene/hw_decal.cpp | 3 +- src/rendering/hwrenderer/scene/hw_flats.cpp | 14 +++-- src/rendering/hwrenderer/scene/hw_portal.cpp | 3 +- .../hwrenderer/scene/hw_renderstate.h | 6 +-- .../hwrenderer/scene/hw_skyportal.cpp | 21 ++++---- src/rendering/hwrenderer/scene/hw_sprites.cpp | 4 +- src/rendering/hwrenderer/scene/hw_walls.cpp | 3 +- src/rendering/hwrenderer/scene/hw_weapon.cpp | 3 +- .../hwrenderer/textures/hw_precache.cpp | 5 +- .../hwrenderer/utility/hw_draw2d.cpp | 2 +- .../polyrenderer/backend/poly_framebuffer.cpp | 6 +-- .../polyrenderer/backend/poly_hwtexture.cpp | 2 +- .../polyrenderer/backend/poly_renderstate.cpp | 2 +- src/rendering/swrenderer/r_swscene.cpp | 2 +- .../swrenderer/textures/r_swtexture.cpp | 6 ++- .../vulkan/system/vk_framebuffer.cpp | 8 +-- .../vulkan/textures/vk_hwtexture.cpp | 5 +- 27 files changed, 144 insertions(+), 129 deletions(-) diff --git a/src/common/textures/hires/hqresize.cpp b/src/common/textures/hires/hqresize.cpp index 9a4fd8b45..67e20acfb 100644 --- a/src/common/textures/hires/hqresize.cpp +++ b/src/common/textures/hires/hqresize.cpp @@ -409,22 +409,10 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA { // [BB] Make sure that inWidth and inHeight denote the size of // the returned buffer even if we don't upsample the input buffer. + int inWidth = texbuffer.mWidth; int inHeight = texbuffer.mHeight; - // [BB] Don't resample if width * height of the input texture is bigger than gl_texture_hqresize_maxinputsize squared. - const int maxInputSize = gl_texture_hqresize_maxinputsize; - if (inWidth * inHeight > maxInputSize * maxInputSize) - return; - - // [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!) - if (bHasCanvas) - return; - - // already scaled? - if (Scale.X >= 2 && Scale.Y >= 2) - return; - int type = gl_texture_hqresizemode; int mult = gl_texture_hqresizemult; #ifdef HAVE_MMX @@ -493,3 +481,33 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA contentId.scalefactor = mult; texbuffer.mContentId = contentId.id; } + +bool shouldUpscale(FGameTexture *tex, ETextureType UseType) +{ + // [BB] Don't resample if width * height of the input texture is bigger than gl_texture_hqresize_maxinputsize squared. + const int maxInputSize = gl_texture_hqresize_maxinputsize; + if (tex->GetTexelWidth() * tex->GetTexelHeight() > maxInputSize * maxInputSize) + return false; + + // [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!) + if (tex->isHardwareCanvas()) + return false; + + // already scaled? + if (tex->GetDisplayWidth() >= 2* tex->GetTexelWidth() || tex->GetDisplayHeight() >= 2*tex->GetTexelHeight()) + return false; + + switch (UseType) + { + case ETextureType::Sprite: + case ETextureType::SkinSprite: + return !!(gl_texture_hqresize_targets & 2); + + case ETextureType::FontChar: + return !!(gl_texture_hqresize_targets & 4); + + default: + return !!(gl_texture_hqresize_targets & 1); + } + +} \ No newline at end of file diff --git a/src/common/textures/hw_material.cpp b/src/common/textures/hw_material.cpp index 2aa81199f..638866a20 100644 --- a/src/common/textures/hw_material.cpp +++ b/src/common/textures/hw_material.cpp @@ -36,7 +36,7 @@ IHardwareTexture* CreateHardwareTexture(); // //=========================================================================== -FMaterial::FMaterial(FGameTexture * tx, bool expanded) +FMaterial::FMaterial(FGameTexture * tx, int scaleflags) { mShaderIndex = SHADER_Default; sourcetex = tx; @@ -122,10 +122,10 @@ FMaterial::FMaterial(FGameTexture * tx, bool expanded) } } } - mExpanded = expanded; + mScaleFlags = scaleflags; mTextureLayers.ShrinkToFit(); - imgtex->Material[expanded] = this; + imgtex->Material[scaleflags] = this; if (tx->isHardwareCanvas()) tx->SetTranslucent(false); } @@ -151,7 +151,7 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) FTexture *layer = i == 0 ? imgtex : mTextureLayers[i - 1]; if (pLayer) *pLayer = layer; - if (layer) return layer->GetHardwareTexture(translation, mExpanded); + if (layer) return layer->GetHardwareTexture(translation, mScaleFlags); return nullptr; } @@ -162,17 +162,17 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) // //========================================================================== -FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, bool expand, bool create) +FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, int scaleflags, bool create) { if (gtex && gtex->isValid()) { auto tex = gtex->GetTexture(); - if (!tex->ShouldExpandSprite()) expand = false; + if (!tex->ShouldExpandSprite()) scaleflags &= ~CTF_Expand; - FMaterial *hwtex = tex->Material[expand]; + FMaterial *hwtex = tex->Material[scaleflags]; if (hwtex == NULL && create) { - hwtex = new FMaterial(gtex, expand); + hwtex = new FMaterial(gtex, scaleflags); } return hwtex; } diff --git a/src/common/textures/hw_material.h b/src/common/textures/hw_material.h index e1e27e3db..bc9af78f0 100644 --- a/src/common/textures/hw_material.h +++ b/src/common/textures/hw_material.h @@ -20,16 +20,17 @@ class FMaterial TArray mTextureLayers; int mShaderIndex; int mLayerFlags = 0; - bool mExpanded; + int mScaleFlags; public: FGameTexture *sourcetex; // the owning texture. FTexture* imgtex; // the first layer's texture image - should be moved into the array - FMaterial(FGameTexture *tex, bool forceexpand); + FMaterial(FGameTexture *tex, int scaleflags); ~FMaterial(); int GetLayerFlags() const { return mLayerFlags; } int GetShaderIndex() const { return mShaderIndex; } + int GetScaleFlags() const { return mScaleFlags; } FGameTexture* Source() const { @@ -45,10 +46,6 @@ public: //ValidateTexture(tex, false); mTextureLayers.Push(tex); } - bool isExpanded() const - { - return mExpanded; - } int GetLayers() const { @@ -58,7 +55,7 @@ public: IHardwareTexture *GetLayer(int i, int translation, FTexture **pLayer = nullptr) const; - static FMaterial *ValidateTexture(FGameTexture * tex, bool expand, bool create = true); + static FMaterial *ValidateTexture(FGameTexture * tex, int scaleflags, bool create = true); const TArray &GetLayerArray() const { return mTextureLayers; diff --git a/src/common/textures/hw_texcontainer.h b/src/common/textures/hw_texcontainer.h index 247279fb0..f7020b5b7 100644 --- a/src/common/textures/hw_texcontainer.h +++ b/src/common/textures/hw_texcontainer.h @@ -7,6 +7,15 @@ struct FTextureBuffer; class IHardwareTexture; +enum ECreateTexBufferFlags +{ + CTF_Expand = 1, // create buffer with a one-pixel wide border + CTF_Upscale = 2, // Upscale the texture + CTF_CreateMask = 3, // Flags that are relevant for hardware texture creation. + CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. + CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures. +}; + class FHardwareTextureContainer { public: @@ -40,20 +49,20 @@ private: private: - TranslatedTexture hwDefTex[2]; + TranslatedTexture hwDefTex[4]; TArray hwTex_Translated; - TranslatedTexture * GetTexID(int translation, bool expanded) + TranslatedTexture * GetTexID(int translation, int scaleflags) { auto remap = GPalette.TranslationToTable(translation); translation = remap == nullptr ? 0 : remap->Index; - if (translation == 0) + if (translation == 0 && !(scaleflags & CTF_Upscale)) { - return &hwDefTex[expanded]; + return &hwDefTex[scaleflags]; } - if (expanded) translation = -translation; + translation |= (scaleflags << 24); // normally there aren't more than very few different // translations here so this isn't performance critical. unsigned index = hwTex_Translated.FindEx([=](auto &element) @@ -73,31 +82,28 @@ private: public: - void Clean(bool cleannormal, bool cleanexpanded) + void Clean(bool reallyclean) { - if (cleannormal) hwDefTex[0].Delete(); - if (cleanexpanded) hwDefTex[1].Delete(); hwDefTex[0].DeleteDescriptors(); hwDefTex[1].DeleteDescriptors(); - for (int i = hwTex_Translated.Size() - 1; i >= 0; i--) - { - if (cleannormal && hwTex_Translated[i].translation > 0) hwTex_Translated.Delete(i); - else if (cleanexpanded && hwTex_Translated[i].translation < 0) hwTex_Translated.Delete(i); + for (unsigned int j = 0; j < hwTex_Translated.Size(); j++) + hwTex_Translated[j].DeleteDescriptors(); - for (unsigned int j = 0; j < hwTex_Translated.Size(); j++) - hwTex_Translated[j].DeleteDescriptors(); - } + if (!reallyclean) return; + hwDefTex[0].Delete(); + hwDefTex[1].Delete(); + hwTex_Translated.Clear(); } - IHardwareTexture * GetHardwareTexture(int translation, bool expanded) + IHardwareTexture * GetHardwareTexture(int translation, int scaleflags) { - auto tt = GetTexID(translation, expanded); + auto tt = GetTexID(translation, scaleflags); return tt->hwTexture; } - void AddHardwareTexture(int translation, bool expanded, IHardwareTexture *tex) + void AddHardwareTexture(int translation, int scaleflags, IHardwareTexture *tex) { - auto tt = GetTexID(translation, expanded); + auto tt = GetTexID(translation, scaleflags); tt->Delete(); tt->hwTexture =tex; } @@ -109,16 +115,15 @@ public: // //=========================================================================== - void CleanUnused(SpriteHits &usedtranslations, bool expanded) + void CleanUnused(SpriteHits &usedtranslations, int scaleflags) { if (usedtranslations.CheckKey(0) == nullptr) { - hwDefTex[expanded].Delete(); + hwDefTex[scaleflags].Delete(); } - int fac = expanded ? -1 : 1; for (int i = hwTex_Translated.Size()-1; i>= 0; i--) { - if (usedtranslations.CheckKey(hwTex_Translated[i].translation * fac) == nullptr) + if (usedtranslations.CheckKey(hwTex_Translated[i].translation & 0xffffff) == nullptr) { hwTex_Translated.Delete(i); } diff --git a/src/common/textures/texture.cpp b/src/common/textures/texture.cpp index d51d06043..26b0f1404 100644 --- a/src/common/textures/texture.cpp +++ b/src/common/textures/texture.cpp @@ -688,27 +688,10 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) result.mWidth = W; result.mHeight = H; - bool upscale = true; - switch (UseType) - { - case ETextureType::Sprite: - case ETextureType::SkinSprite: - if (!(gl_texture_hqresize_targets & 2)) upscale = false; - break; - - case ETextureType::FontChar: - if (!(gl_texture_hqresize_targets & 4)) upscale = false; - break; - - default: - if (!(gl_texture_hqresize_targets & 1)) upscale = false; - break; - } - // Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.) if (GetImage() && flags & CTF_ProcessData) { - if (upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly); + if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly); if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); } @@ -738,7 +721,7 @@ bool FTexture::DetermineTranslucency() void FTexture::CleanHardwareTextures(bool reallyclean) { - SystemTextures.Clean(reallyclean, reallyclean); + SystemTextures.Clean(reallyclean); } //=========================================================================== @@ -964,15 +947,15 @@ void FTexture::SetSpriteRect() // //=========================================================================== -IHardwareTexture* FTexture::GetHardwareTexture(int translation, bool expanded) +IHardwareTexture* FTexture::GetHardwareTexture(int translation, int scaleflags) { if (UseType != ETextureType::Null) { - IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, expanded); + IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, scaleflags); if (hwtex == nullptr) { hwtex = CreateHardwareTexture(); - SystemTextures.AddHardwareTexture(translation, expanded, hwtex); + SystemTextures.AddHardwareTexture(translation, scaleflags, hwtex); } return hwtex; } diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index a826c06eb..65a5a7dce 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -120,15 +120,6 @@ struct FloatRect } }; -enum ECreateTexBufferFlags -{ - CTF_Expand = 2, // create buffer with a one-pixel wide border - CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. - CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures. -}; - - - class FBitmap; struct FRemapTable; struct FCopyInfo; @@ -258,7 +249,7 @@ public: SpritePositioningInfo *spi = nullptr; - IHardwareTexture* GetHardwareTexture(int translation, bool expanded); + IHardwareTexture* GetHardwareTexture(int translation, int scaleflags); static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); virtual ~FTexture (); virtual FImageSource *GetImage() const { return nullptr; } @@ -369,7 +360,7 @@ protected: int SourceLump; FTextureID id; - FMaterial *Material[2] = { nullptr, nullptr }; + FMaterial *Material[4] = { }; public: FHardwareTextureContainer SystemTextures; protected: @@ -534,7 +525,7 @@ public: FWrapperTexture(int w, int h, int bits = 1); IHardwareTexture *GetSystemTexture() { - return SystemTextures.GetHardwareTexture(0, false); + return SystemTextures.GetHardwareTexture(0, 0); } int GetColorFormat() const @@ -764,6 +755,7 @@ inline FGameTexture* MakeGameTexture(FTexture* tex) return new FGameTexture(tex); } +bool shouldUpscale(FGameTexture* tex, ETextureType UseType); #endif diff --git a/src/rendering/gl/renderer/gl_renderer.cpp b/src/rendering/gl/renderer/gl_renderer.cpp index ee5fbb09a..23380de8b 100644 --- a/src/rendering/gl/renderer/gl_renderer.cpp +++ b/src/rendering/gl/renderer/gl_renderer.cpp @@ -297,7 +297,7 @@ sector_t *FGLRenderer::RenderView(player_t* player) void FGLRenderer::BindToFrameBuffer(FTexture *tex) { - auto BaseLayer = static_cast(tex->GetHardwareTexture(0, false)); + auto BaseLayer = static_cast(tex->GetHardwareTexture(0, 0)); if (BaseLayer == nullptr) { diff --git a/src/rendering/gl/renderer/gl_renderstate.cpp b/src/rendering/gl/renderer/gl_renderstate.cpp index 73386ee10..1c60be381 100644 --- a/src/rendering/gl/renderer/gl_renderstate.cpp +++ b/src/rendering/gl/renderer/gl_renderstate.cpp @@ -323,7 +323,7 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio int usebright = false; int maxbound = 0; - int flags = mat->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); int numLayers = mat->GetLayers(); auto base = static_cast(mat->GetLayer(0, translation)); @@ -333,7 +333,8 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio { FTexture *layer; auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->BindOrCreate(layer, i, clampmode, 0, mat->isExpanded() ? CTF_Expand : 0); + // fixme: Upscale flags must be disabled for certain layers. + systex->BindOrCreate(layer, i, clampmode, 0, flags); maxbound = i; } } diff --git a/src/rendering/gl/system/gl_framebuffer.cpp b/src/rendering/gl/system/gl_framebuffer.cpp index c68ca64ca..7ea0f3df6 100644 --- a/src/rendering/gl/system/gl_framebuffer.cpp +++ b/src/rendering/gl/system/gl_framebuffer.cpp @@ -310,7 +310,7 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) { if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return; - int flags = mat->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); int numLayers = mat->GetLayers(); FTexture* layer; auto base = static_cast(mat->GetLayer(0, translation, &layer)); @@ -320,7 +320,7 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) for (int i = 1; i < numLayers; i++) { auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->BindOrCreate(layer, i, CLAMP_NONE, 0, mat->isExpanded() ? CTF_Expand : 0); + systex->BindOrCreate(layer, i, CLAMP_NONE, 0, flags); } } // unbind everything. diff --git a/src/rendering/hwrenderer/models/hw_models.cpp b/src/rendering/hwrenderer/models/hw_models.cpp index 6c76126e5..2d180126e 100644 --- a/src/rendering/hwrenderer/models/hw_models.cpp +++ b/src/rendering/hwrenderer/models/hw_models.cpp @@ -114,7 +114,7 @@ void FHWModelRenderer::SetInterpolation(double inter) void FHWModelRenderer::SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) { - state.SetMaterial(skin, false, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1); + state.SetMaterial(skin, 0, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1); state.SetLightIndex(modellightindex); } diff --git a/src/rendering/hwrenderer/scene/hw_decal.cpp b/src/rendering/hwrenderer/scene/hw_decal.cpp index e92a6c80e..3416ddfff 100644 --- a/src/rendering/hwrenderer/scene/hw_decal.cpp +++ b/src/rendering/hwrenderer/scene/hw_decal.cpp @@ -66,7 +66,8 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state) state.SetTextureMode(decal->RenderStyle); state.SetRenderStyle(decal->RenderStyle); - state.SetMaterial(texture, false, CLAMP_XY, decal->Translation, -1); + int flags = shouldUpscale(texture, ETextureType::Sprite) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_XY, decal->Translation, -1); // If srcalpha is one it looks better with a higher alpha threshold diff --git a/src/rendering/hwrenderer/scene/hw_flats.cpp b/src/rendering/hwrenderer/scene/hw_flats.cpp index a4e8d1eee..245e80a89 100644 --- a/src/rendering/hwrenderer/scene/hw_flats.cpp +++ b/src/rendering/hwrenderer/scene/hw_flats.cpp @@ -204,7 +204,8 @@ void HWFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state) void HWFlat::DrawOtherPlanes(HWDrawInfo *di, FRenderState &state) { - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); // Draw the subsectors assigned to it due to missing textures auto pNode = (renderflags&SSRF_RENDERFLOOR) ? @@ -236,7 +237,8 @@ void HWFlat::DrawFloodPlanes(HWDrawInfo *di, FRenderState &state) // This requires a stencil because the projected plane interferes with // the depth buffer - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); // Draw the subsectors assigned to it due to missing textures auto pNode = (renderflags&SSRF_RENDERFLOOR) ? @@ -322,16 +324,17 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) } else if (!translucent) { + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; if (sector->special != GLSector_Skybox) { - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); state.SetPlaneTextureRotation(&plane, texture); DrawSubsectors(di, state); state.EnableTextureMatrix(false); } else if (!hacktype) { - state.SetMaterial(texture, false, CLAMP_XY, 0, -1); + state.SetMaterial(texture, flags, CLAMP_XY, 0, -1); state.SetLightIndex(dynlightindex); state.Draw(DT_TriangleStrip,iboindex, 4); flatvertices += 4; @@ -352,7 +355,8 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) { if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); else state.AlphaFunc(Alpha_GEqual, 0.f); - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); state.SetPlaneTextureRotation(&plane, texture); DrawSubsectors(di, state); state.EnableTextureMatrix(false); diff --git a/src/rendering/hwrenderer/scene/hw_portal.cpp b/src/rendering/hwrenderer/scene/hw_portal.cpp index f3915096f..ad491217f 100644 --- a/src/rendering/hwrenderer/scene/hw_portal.cpp +++ b/src/rendering/hwrenderer/scene/hw_portal.cpp @@ -975,7 +975,8 @@ void HWHorizonPortal::DrawContents(HWDrawInfo *di, FRenderState &state) } - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); state.SetObjectColor(origin->specialcolor); state.SetPlaneTextureRotation(sp, texture); diff --git a/src/rendering/hwrenderer/scene/hw_renderstate.h b/src/rendering/hwrenderer/scene/hw_renderstate.h index e0800172c..47e08c03c 100644 --- a/src/rendering/hwrenderer/scene/hw_renderstate.h +++ b/src/rendering/hwrenderer/scene/hw_renderstate.h @@ -569,10 +569,10 @@ public: mTextureModeFlags = mat->GetLayerFlags(); } - void SetMaterial(FGameTexture* tex, bool expandmode, int clampmode, int translation, int overrideshader) + void SetMaterial(FGameTexture* tex, int scaleflags, int clampmode, int translation, int overrideshader) { - expandmode &= tex->expandSprites(); - SetMaterial(FMaterial::ValidateTexture(tex, expandmode), clampmode, translation, overrideshader); + if (!tex->expandSprites()) scaleflags &= ~CTF_Expand; + SetMaterial(FMaterial::ValidateTexture(tex, scaleflags), clampmode, translation, overrideshader); } void SetClipSplit(float bottom, float top) diff --git a/src/rendering/hwrenderer/scene/hw_skyportal.cpp b/src/rendering/hwrenderer/scene/hw_skyportal.cpp index 5b13f7371..ef2af5565 100644 --- a/src/rendering/hwrenderer/scene/hw_skyportal.cpp +++ b/src/rendering/hwrenderer/scene/hw_skyportal.cpp @@ -52,9 +52,10 @@ void HWSkyPortal::RenderRow(HWDrawInfo *di, FRenderState &state, EDrawType prim, void HWSkyPortal::RenderDome(HWDrawInfo *di, FRenderState &state, FGameTexture * tex, float x_offset, float y_offset, bool mirror, int mode) { + int flags = shouldUpscale(tex, ETextureType::Wall) ? CTF_Upscale : 0; if (tex) { - state.SetMaterial(tex, false, CLAMP_NONE, 0, -1); + state.SetMaterial(tex, flags, CLAMP_NONE, 0, -1); state.EnableModelMatrix(true); state.EnableTextureMatrix(true); @@ -106,39 +107,41 @@ void HWSkyPortal::RenderBox(HWDrawInfo *di, FRenderState &state, FTextureID texn else state.mModelMatrix.rotate(-180.0f+x_offset, di->Level->info->skyrotatevector2.X, di->Level->info->skyrotatevector2.Z, di->Level->info->skyrotatevector2.Y); - if (tex->GetSkyFace(5)) + // Only test the first face - the result here must be consistent - either all get scaled or none. + int flags = shouldUpscale(tex->GetSkyFace(0), ETextureType::Flat) ? CTF_Upscale : 0; + if (tex->GetSkyFace(5)) { faces=4; // north - state.SetMaterial(tex->GetSkyFace(0), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(0), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(0), 4); // east - state.SetMaterial(tex->GetSkyFace(1), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(1), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(1), 4); // south - state.SetMaterial(tex->GetSkyFace(2), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(2), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(2), 4); // west - state.SetMaterial(tex->GetSkyFace(3), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(3), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(3), 4); } else { faces=1; - state.SetMaterial(tex->GetSkyFace(0), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(0), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(-1), 10); } // top - state.SetMaterial(tex->GetSkyFace(faces), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(faces), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(tex->GetSkyFlip() ? 6 : 5), 4); // bottom - state.SetMaterial(tex->GetSkyFace(faces+1), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(faces+1), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(4), 4); state.EnableModelMatrix(false); diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 392d1caad..dbe44637a 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -198,7 +198,9 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) } uint32_t spritetype = (actor->renderflags & RF_SPRITETYPEMASK); - if (texture) state.SetMaterial(texture, spritetype == RF_FACESPRITE, CLAMP_XY, translation, OverrideShader); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + if (spritetype == RF_FACESPRITE) flags |= CTF_Expand; + if (texture) state.SetMaterial(texture, flags, CLAMP_XY, translation, OverrideShader); else if (!modelframe) state.EnableTexture(false); //SetColor(lightlevel, rel, Colormap, trans); diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 73c19f804..2d1235ae1 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -156,7 +156,8 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) state.SetGlowParams(topglowcolor, bottomglowcolor); state.SetGlowPlanes(frontsector->ceilingplane, frontsector->floorplane); } - state.SetMaterial(texture, false, flags & 3, 0, -1); + int uflags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, uflags, flags & 3, 0, -1); if (type == RENDERWALL_M2SNF) { diff --git a/src/rendering/hwrenderer/scene/hw_weapon.cpp b/src/rendering/hwrenderer/scene/hw_weapon.cpp index f07c667f3..6d6aaee84 100644 --- a/src/rendering/hwrenderer/scene/hw_weapon.cpp +++ b/src/rendering/hwrenderer/scene/hw_weapon.cpp @@ -96,7 +96,8 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state) { float thresh = (huds->texture->GetTranslucency() || huds->OverrideShader != -1) ? 0.f : gl_mask_sprite_threshold; state.AlphaFunc(Alpha_GEqual, thresh); - state.SetMaterial(huds->texture, true, CLAMP_XY_NOMIP, (huds->weapon->Flags & PSPF_PLAYERTRANSLATED) ? huds->owner->Translation : 0, huds->OverrideShader); + int flags = shouldUpscale(huds->texture, ETextureType::Flat) ? CTF_Upscale|CTF_Expand : CTF_Expand; + state.SetMaterial(huds->texture, flags, CLAMP_XY_NOMIP, (huds->weapon->Flags & PSPF_PLAYERTRANSLATED) ? huds->owner->Translation : 0, huds->OverrideShader); state.Draw(DT_TriangleStrip, huds->mx, 4); } diff --git a/src/rendering/hwrenderer/textures/hw_precache.cpp b/src/rendering/hwrenderer/textures/hw_precache.cpp index 5c599c491..7ce5052ca 100644 --- a/src/rendering/hwrenderer/textures/hw_precache.cpp +++ b/src/rendering/hwrenderer/textures/hw_precache.cpp @@ -62,7 +62,7 @@ static void PrecacheTexture(FGameTexture *tex, int cache) //=========================================================================== static void PrecacheList(FMaterial *gltex, SpriteHits& translations) { - gltex->BaseLayer()->SystemTextures.CleanUnused(translations, gltex->isExpanded()); + gltex->BaseLayer()->SystemTextures.CleanUnused(translations, gltex->GetScaleFlags()); SpriteHits::Iterator it(translations); SpriteHits::Pair* pair; while (it.NextPair(pair)) screen->PrecacheMaterial(gltex, pair->Key); @@ -252,7 +252,8 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl { if (texhitlist[i] & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky)) { - if (tex->GetImage() && tex->SystemTextures.GetHardwareTexture(0, false) == nullptr) + int flags = shouldUpscale(gtex, ETextureType::Wall) ? CTF_Upscale : 0; + if (tex->GetImage() && tex->SystemTextures.GetHardwareTexture(0, flags) == nullptr) { FImageSource::RegisterForPrecache(tex->GetImage(), V_IsTrueColor()); } diff --git a/src/rendering/hwrenderer/utility/hw_draw2d.cpp b/src/rendering/hwrenderer/utility/hw_draw2d.cpp index 9ea18891e..efff2852e 100644 --- a/src/rendering/hwrenderer/utility/hw_draw2d.cpp +++ b/src/rendering/hwrenderer/utility/hw_draw2d.cpp @@ -164,7 +164,7 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state) if (cmd.mTexture != nullptr && cmd.mTexture->isValid()) { - state.SetMaterial(cmd.mTexture, false, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, cmd.mTranslationId, -1); + state.SetMaterial(cmd.mTexture, 0, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, cmd.mTranslationId, -1); state.EnableTexture(true); // Canvas textures are stored upside down diff --git a/src/rendering/polyrenderer/backend/poly_framebuffer.cpp b/src/rendering/polyrenderer/backend/poly_framebuffer.cpp index e8b1c5c87..63eea8f2c 100644 --- a/src/rendering/polyrenderer/backend/poly_framebuffer.cpp +++ b/src/rendering/polyrenderer/backend/poly_framebuffer.cpp @@ -377,7 +377,7 @@ sector_t *PolyFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor * ca void PolyFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) { // This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene. - auto BaseLayer = static_cast(tex->GetHardwareTexture(0, false)); + auto BaseLayer = static_cast(tex->GetHardwareTexture(0, 0)); float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble(); DCanvas *image = BaseLayer->GetImage(tex, 0, 0); @@ -535,7 +535,7 @@ void PolyFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) { if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return; - int flags = mat->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); FTexture* layer; auto systex = static_cast(mat->GetLayer(0, translation, &layer)); systex->GetImage(layer, translation, flags); @@ -544,7 +544,7 @@ void PolyFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) for (int i = 1; i < numLayers; i++) { auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0); + systex->GetImage(layer, 0, flags); // fixme: Upscale flags must be disabled for certain layers. } } diff --git a/src/rendering/polyrenderer/backend/poly_hwtexture.cpp b/src/rendering/polyrenderer/backend/poly_hwtexture.cpp index 51a788660..55a47fca9 100644 --- a/src/rendering/polyrenderer/backend/poly_hwtexture.cpp +++ b/src/rendering/polyrenderer/backend/poly_hwtexture.cpp @@ -68,7 +68,7 @@ DCanvas *PolyHardwareTexture::GetImage(FTexture *baselayer, const FMaterialState if (!mCanvas) { - int flags = state.mMaterial->isExpanded() ? CTF_Expand : 0; + int flags = state.mMaterial->GetScaleFlags(); return GetImage(baselayer, state.mTranslation, flags); } diff --git a/src/rendering/polyrenderer/backend/poly_renderstate.cpp b/src/rendering/polyrenderer/backend/poly_renderstate.cpp index 41e2aeb4e..9119ce96d 100644 --- a/src/rendering/polyrenderer/backend/poly_renderstate.cpp +++ b/src/rendering/polyrenderer/backend/poly_renderstate.cpp @@ -327,7 +327,7 @@ void PolyRenderState::ApplyMaterial() FTexture* layer; auto systex = static_cast(mMaterial.mMaterial->GetLayer(i, 0, &layer)); - texcanvas = systex->GetImage(layer, 0, mMaterial.mMaterial->isExpanded() ? CTF_Expand : 0); + texcanvas = systex->GetImage(layer, 0, mMaterial.mMaterial->GetScaleFlags()); mDrawCommands->SetTexture(i, texcanvas->GetPixels(), texcanvas->GetWidth(), texcanvas->GetHeight(), texcanvas->IsBgra()); } } diff --git a/src/rendering/swrenderer/r_swscene.cpp b/src/rendering/swrenderer/r_swscene.cpp index ac5c382a9..2886d4575 100644 --- a/src/rendering/swrenderer/r_swscene.cpp +++ b/src/rendering/swrenderer/r_swscene.cpp @@ -94,7 +94,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) FBTextureIndex = (FBTextureIndex + 1) % 2; auto &fbtex = FBTexture[FBTextureIndex]; - auto GetSystemTexture = [&]() { return fbtex->GetTexture()->SystemTextures.GetHardwareTexture(0, false); }; + auto GetSystemTexture = [&]() { return fbtex->GetTexture()->SystemTextures.GetHardwareTexture(0, 0); }; if (fbtex == nullptr || GetSystemTexture() == nullptr || fbtex->GetTexelWidth() != screen->GetWidth() || diff --git a/src/rendering/swrenderer/textures/r_swtexture.cpp b/src/rendering/swrenderer/textures/r_swtexture.cpp index 6b9fcd7f3..ace25007e 100644 --- a/src/rendering/swrenderer/textures/r_swtexture.cpp +++ b/src/rendering/swrenderer/textures/r_swtexture.cpp @@ -54,8 +54,10 @@ FSoftwareTexture::FSoftwareTexture(FGameTexture *tex) mSource = tex->GetTexture(); mBufferFlags = CTF_ProcessData; + auto f = mBufferFlags; + if (shouldUpscale(tex, tex->GetUseType())) f |= CTF_Upscale; // calculate the real size after running the scaler. - auto info = mSource->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags); + auto info = mSource->CreateTexBuffer(0, CTF_CheckOnly| f); mPhysicalWidth = info.mWidth; mPhysicalHeight = info.mHeight; mPhysicalScale = tex->GetTexelWidth() > 0 ? mPhysicalWidth / tex->GetTexelWidth() : mPhysicalWidth; @@ -113,6 +115,8 @@ const uint8_t *FSoftwareTexture::GetPixels(int style) } else { + auto f = mBufferFlags; + if (shouldUpscale(mTexture, mTexture->GetUseType())) f |= CTF_Upscale; auto tempbuffer = mSource->CreateTexBuffer(0, mBufferFlags); Pixels.Resize(GetPhysicalWidth()*GetPhysicalHeight()); PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index dd4ef1d79..460a180db 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -515,7 +515,7 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor * void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) { - auto BaseLayer = static_cast(tex->GetHardwareTexture(0, false)); + auto BaseLayer = static_cast(tex->GetHardwareTexture(0, 0)); float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble(); VkTextureImage *image = BaseLayer->GetImage(tex, 0, 0); @@ -648,17 +648,17 @@ void VulkanFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return; // Textures that are already scaled in the texture lump will not get replaced by hires textures. - int flags = mat->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); FTexture* layer; auto systex = static_cast(mat->GetLayer(0, translation, &layer)); - systex->GetImage(layer, translation, mat->isExpanded() ? CTF_Expand : 0); + systex->GetImage(layer, translation, flags); int numLayers = mat->GetLayers(); for (int i = 1; i < numLayers; i++) { auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0); + systex->GetImage(layer, 0, flags); // fixme: Upscale flags must be disabled for certain layers. } } diff --git a/src/rendering/vulkan/textures/vk_hwtexture.cpp b/src/rendering/vulkan/textures/vk_hwtexture.cpp index 1868331fa..e3c81054c 100644 --- a/src/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/rendering/vulkan/textures/vk_hwtexture.cpp @@ -119,7 +119,7 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s clampmode = base->GetClampMode(clampmode); // Textures that are already scaled in the texture lump will not get replaced by hires textures. - int flags = state.mMaterial->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); for (auto &set : mDescriptorSets) { @@ -141,7 +141,8 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s { FTexture *layer; auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0)->View.get(), sampler, systex->mImage.Layout); + // fixme: Upscale flags must be disabled for certain layers. + update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, flags)->View.get(), sampler, systex->mImage.Layout); } auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();