From f9d2dc51d0ea3a37ec25cc9ba98d53927406549c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 22 Dec 2019 10:20:47 +0100 Subject: [PATCH] - cleanup of new colorization code. - profiling shows that running the code for applying the colorization and the gradients is extremely expensive, apparently this always causes a cache miss, so now the entire thing is enabled by a sidedef flag. --- src/gamedata/r_defs.h | 155 ++++++++++---------- src/maploader/udmf.cpp | 25 +++- src/maploader/udmf.h | 8 +- src/rendering/hwrenderer/scene/hw_walls.cpp | 54 +++---- 4 files changed, 135 insertions(+), 107 deletions(-) diff --git a/src/gamedata/r_defs.h b/src/gamedata/r_defs.h index 6b345692e..d9f30dd8b 100644 --- a/src/gamedata/r_defs.h +++ b/src/gamedata/r_defs.h @@ -611,12 +611,64 @@ struct TextureManipulation BlendOverlay = 3, BlendHardLight = 4, BlendMask = 7, - InvertBit = 8 + InvertBit = 8, + ActiveBit = 16, // Must be set for the shader to do something }; PalEntry AddColor; // Alpha contains the blend flags PalEntry ModulateColor; // Alpha may contain a multiplier to get higher values than 1.0 without promoting this to 4 full floats. PalEntry BlendColor; float DesaturationFactor; + + bool CheckIfEnabled() // check if this manipulation is doing something. NoOps do not need to be preserved, unless they override older setttings. + { + if (AddColor != 0 || // this includes a check for the blend mode without which BlendColor is not active + ModulateColor != 0x01ffffff || // 1 in alpha must be the default for a no-op. + DesaturationFactor != 0) + { + AddColor.a |= ActiveBit; // mark as active for the shader's benefit. + return true; + } + return false; + } + + void SetTextureModulateColor(int slot, PalEntry rgb) + { + rgb.a = ModulateColor.a; + ModulateColor = rgb; + } + + void SetTextureModulateScaleFactor(int slot, int fac) + { + ModulateColor.a = (uint8_t)fac; + } + + void SetTextureAdditiveColor(int slot, PalEntry rgb) + { + rgb.a = AddColor.a; + AddColor = rgb; + } + + void SetTextureBlendColor(int slot, PalEntry rgb) + { + BlendColor = rgb; + } + + void SetTextureDesaturationFactor(int slot, double fac) + { + DesaturationFactor = (float)fac; + } + + void SetTextureBlendMode(int slot, int mode) + { + AddColor.a = (AddColor.a & ~TextureManipulation::BlendMask) | (mode & TextureManipulation::BlendMask); + } + + void SetTextureInvert(bool on) + { + AddColor.a |= TextureManipulation::InvertBit; + AddColor.a &= ~TextureManipulation::InvertBit; + } + }; struct sector_t @@ -1047,21 +1099,32 @@ public: Flags &= ~SECF_SPECIALFLAGS; } + void CheckExColorFlag(); + + void InitAllExcolors() + { + if (SpecialColors[sector_t::wallbottom] != 0xffffffff || SpecialColors[sector_t::walltop] != 0xffffffff || AdditiveColors[sector_t::walltop] != 0xffffffff) CheckExColorFlag(); + } + void SetSpecialColor(int slot, int r, int g, int b) { SpecialColors[slot] = PalEntry(255, r, g, b); + if ((slot == sector_t::wallbottom || slot == sector_t::walltop) && SpecialColors[slot] != 0xffffffff) CheckExColorFlag(); } void SetSpecialColor(int slot, PalEntry rgb) { rgb.a = 255; SpecialColors[slot] = rgb; + if ((slot == sector_t::wallbottom || slot == sector_t::walltop) && rgb != 0xffffffff) CheckExColorFlag(); } void SetAdditiveColor(int slot, PalEntry rgb) { rgb.a = 255; AdditiveColors[slot] = rgb; + if ((slot == sector_t::walltop) && AdditiveColors[slot] != 0xffffffff) CheckExColorFlag(); // Wallbottom of this is not used. + } // TextureFX parameters @@ -1071,44 +1134,6 @@ public: planes[slot].TextureFx = tm; // this is for getting the data from a texture. } - void SetTextureModulateColor(int slot, PalEntry rgb) - { - rgb.a = planes[slot].TextureFx.ModulateColor.a; - planes[slot].TextureFx.ModulateColor = rgb; - } - - void SetTextureModulateScaleFactor(int slot, int fac) - { - planes[slot].TextureFx.ModulateColor.a = (uint8_t)fac; - } - - void SetTextureAdditiveColor(int slot, PalEntry rgb) - { - rgb.a = planes[slot].TextureFx.AddColor.a; - planes[slot].TextureFx.AddColor = rgb; - } - - void SetTextureBlendColor(int slot, PalEntry rgb) - { - planes[slot].TextureFx.BlendColor = rgb; - } - - void SetTextureDesaturationFactor(int slot, double fac) - { - planes[slot].TextureFx.DesaturationFactor = (float)fac; - } - - void SetTextureBlendMode(int slot, int mode) - { - planes[slot].TextureFx.AddColor.a = (planes[slot].TextureFx.AddColor.a & ~TextureManipulation::BlendMask) | (mode & TextureManipulation::BlendMask); - } - - void SetTextureInvert(int slot, bool on) - { - if (on) planes[slot].TextureFx.AddColor.a |= TextureManipulation::InvertBit; - else planes[slot].TextureFx.AddColor.a &= ~TextureManipulation::InvertBit; - } - inline bool PortalBlocksView(int plane); inline bool PortalBlocksSight(int plane); @@ -1194,6 +1219,7 @@ enum WALLF_WRAP_MIDTEX = 32, // Like the line counterpart, but only for this side. WALLF_POLYOBJ = 64, // This wall belongs to a polyobject. WALLF_LIGHT_FOG = 128, // This wall's Light is used even in fog. + WALLF_EXTCOLOR = 256, // enables the extended color options (flagged to allow the renderer to easily skip the relevant code) }; struct side_t @@ -1385,10 +1411,11 @@ struct side_t void EnableAdditiveColor(int which, bool enable) { - int flag = enable ? part::UseOwnAdditiveColor : 0; + const int flag = part::UseOwnAdditiveColor; if (enable) { textures[which].flags |= flag; + Flags |= WALLF_EXTCOLOR; } else { @@ -1402,42 +1429,10 @@ struct side_t textures[which].AdditiveColor = rgb; } - void SetTextureModulateColor(int slot, PalEntry rgb) + void SetTextureFx(int slot, const TextureManipulation& tm) { - rgb.a = textures[slot].TextureFx.ModulateColor.a; - textures[slot].TextureFx.ModulateColor = rgb; - } - - void SetTextureModulateScaleFactor(int slot, int fac) - { - textures[slot].TextureFx.ModulateColor.a = (uint8_t)fac; - } - - void SetTextureAdditiveColor(int slot, PalEntry rgb) - { - rgb.a = textures[slot].TextureFx.AddColor.a; - textures[slot].TextureFx.AddColor = rgb; - } - - void SetTextureBlendColor(int slot, PalEntry rgb) - { - textures[slot].TextureFx.BlendColor = rgb; - } - - void SetTextureDesaturationFactor(int slot, double fac) - { - textures[slot].TextureFx.DesaturationFactor = (float)fac; - } - - void SetTextureBlendMode(int slot, int mode) - { - textures[slot].TextureFx.AddColor.a = (textures[slot].TextureFx.AddColor.a & ~TextureManipulation::BlendMask) | (mode & TextureManipulation::BlendMask); - } - - void SetTextureInvert(int slot, bool on) - { - if (on) textures[slot].TextureFx.AddColor.a |= TextureManipulation::InvertBit; - else textures[slot].TextureFx.AddColor.a &= ~TextureManipulation::InvertBit; + textures[slot].TextureFx = tm; // this is for getting the data from a texture. + if (tm.AddColor.a) Flags |= WALLF_EXTCOLOR; } PalEntry GetAdditiveColor(int which, sector_t *frontsector) const @@ -1785,5 +1780,15 @@ inline int sector_t::GetFloorLight() const { return ::GetFloorLight(this); } inline int sector_t::GetCeilingLight() const { return ::GetCeilingLight(this); } inline double sector_t::GetFriction(int plane, double *movefac) const { return ::GetFriction(this, plane, movefac); } +inline void sector_t::CheckExColorFlag() +{ + for (auto ld : Lines) + { + if (ld->frontsector == this) ld->sidedef[0]->Flags |= WALLF_EXTCOLOR; + if (ld->backsector == this) ld->sidedef[1]->Flags |= WALLF_EXTCOLOR; + } +} + + #endif diff --git a/src/maploader/udmf.cpp b/src/maploader/udmf.cpp index 8226f525d..b1c0ba054 100644 --- a/src/maploader/udmf.cpp +++ b/src/maploader/udmf.cpp @@ -1308,7 +1308,8 @@ public: break; case NAME_useowncolors_top: - Flag(sd->textures[side_t::top].flags, side_t::part::UseOwnSpecialColors, key); + if (Flag(sd->textures[side_t::top].flags, side_t::part::UseOwnSpecialColors, key)) + sd->Flags |= WALLF_EXTCOLOR; break; case NAME_uppercolor_top: @@ -1332,7 +1333,9 @@ public: break; case NAME_useowncolors_mid: - Flag(sd->textures[side_t::mid].flags, side_t::part::UseOwnSpecialColors, key); + if (Flag(sd->textures[side_t::mid].flags, side_t::part::UseOwnSpecialColors, key)) + sd->Flags |= WALLF_EXTCOLOR; + break; case NAME_uppercolor_mid: @@ -1356,7 +1359,8 @@ public: break; case NAME_useowncolors_bottom: - Flag(sd->textures[side_t::bottom].flags, side_t::part::UseOwnSpecialColors, key); + if (Flag(sd->textures[side_t::bottom].flags, side_t::part::UseOwnSpecialColors, key)) + sd->Flags |= WALLF_EXTCOLOR; break; case NAME_uppercolor_bottom: @@ -1380,13 +1384,17 @@ public: break; case NAME_useowncoloradd_top: - sd->textures[side_t::top].flags |= side_t::part::UseOwnAdditiveColor * CheckBool(key); + Flag(sd->textures[side_t::top].flags, side_t::part::UseOwnAdditiveColor, key); + sd->Flags |= WALLF_EXTCOLOR; case NAME_useowncoloradd_mid: - sd->textures[side_t::mid].flags |= side_t::part::UseOwnAdditiveColor * CheckBool(key); + if (Flag(sd->textures[side_t::mid].flags, side_t::part::UseOwnAdditiveColor, key)) + sd->Flags |= WALLF_EXTCOLOR; case NAME_useowncoloradd_bottom: - sd->textures[side_t::bottom].flags |= side_t::part::UseOwnAdditiveColor * CheckBool(key); + if (Flag(sd->textures[side_t::bottom].flags, side_t::part::UseOwnAdditiveColor, key)) + sd->Flags |= WALLF_EXTCOLOR; + break; default: break; @@ -2284,6 +2292,11 @@ public: // Create the real linedefs and decompress the sidedefs ProcessLineDefs(); + // enable the excolor flag on all sidedefs which need it for a gradient transfer from the sector. + for (auto& sec : Level->sectors) + { + sec.CheckExColorFlag(); + } } }; diff --git a/src/maploader/udmf.h b/src/maploader/udmf.h index 8e0901755..a6f402bf1 100644 --- a/src/maploader/udmf.h +++ b/src/maploader/udmf.h @@ -23,12 +23,18 @@ protected: const char *CheckString(const char *key); template - void Flag(T &value, int mask, const char *key) + bool Flag(T &value, int mask, const char *key) { if (CheckBool(key)) + { value |= mask; + return true; + } else + { value &= ~mask; + return false; + } } }; diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 9b98bc28a..1873ce5d3 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -168,38 +168,42 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) if (type != RENDERWALL_COLOR && seg->sidedef != nullptr) { auto side = seg->sidedef; - auto tierndx = renderwalltotier[type]; - auto &tier = side->textures[tierndx]; - PalEntry color1 = side->GetSpecialColor(tierndx, side_t::walltop, frontsector); - PalEntry color2 = side->GetSpecialColor(tierndx, side_t::wallbottom, frontsector); - state.SetObjectColor(color1); - state.SetObjectColor2((color1 != color2) ? color2 : PalEntry(0)); - state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector)); - state.ApplyTextureManipulation(&side->textures[tierndx].TextureFx); - - if (color1 != color2) + if (seg->sidedef->Flags & WALLF_EXTCOLOR) // this block incurs a costly cache miss, so only process if needed. { - // Do gradient setup only if there actually is a gradient. - state.EnableGradient(true); - if ((tier.flags & side_t::part::ClampGradient) && backsector) + auto tierndx = renderwalltotier[type]; + auto& tier = side->textures[tierndx]; + PalEntry color1 = side->GetSpecialColor(tierndx, side_t::walltop, frontsector); + PalEntry color2 = side->GetSpecialColor(tierndx, side_t::wallbottom, frontsector); + state.SetObjectColor(color1); + state.SetObjectColor2((color1 != color2) ? color2 : PalEntry(0)); + state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector)); + state.ApplyTextureManipulation(&tier.TextureFx); + + if (color1 != color2) { - if (tierndx == side_t::top) + // Do gradient setup only if there actually is a gradient. + + state.EnableGradient(true); + if ((tier.flags & side_t::part::ClampGradient) && backsector) { - state.SetGradientPlanes(frontsector->ceilingplane, backsector->ceilingplane); + if (tierndx == side_t::top) + { + state.SetGradientPlanes(frontsector->ceilingplane, backsector->ceilingplane); + } + else if (tierndx == side_t::mid) + { + state.SetGradientPlanes(backsector->ceilingplane, backsector->floorplane); + } + else // side_t::bottom: + { + state.SetGradientPlanes(backsector->floorplane, frontsector->floorplane); + } } - else if (tierndx == side_t::mid) + else { - state.SetGradientPlanes(backsector->ceilingplane, backsector->floorplane); + state.SetGradientPlanes(frontsector->ceilingplane, frontsector->floorplane); } - else // side_t::bottom: - { - state.SetGradientPlanes(backsector->floorplane, frontsector->floorplane); - } - } - else - { - state.SetGradientPlanes(frontsector->ceilingplane, frontsector->floorplane); } } }