VarAction2: Implement register tracking for rail station adv tile layouts
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include "debug_settings.h"
|
||||
#include "core/y_combinator.hpp"
|
||||
#include "scope.h"
|
||||
#include "newgrf_station.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
@@ -2444,6 +2445,36 @@ static void OptimiseVarAction2CheckInliningCandidate(DeterministicSpriteGroup *g
|
||||
*(_cur.GetInlinableGroupAdjusts(group, true)) = std::move(saved_adjusts);
|
||||
}
|
||||
|
||||
static void PopulateRegistersUsedByNewGRFSpriteLayout(const NewGRFSpriteLayout &dts, std::bitset<256> &bits)
|
||||
{
|
||||
const TileLayoutRegisters *registers = dts.registers;
|
||||
|
||||
auto process_registers = [&](uint i, bool is_parent) {
|
||||
const TileLayoutRegisters *reg = registers + i;
|
||||
if (reg->flags & TLF_DODRAW) bits.set(reg->dodraw, true);
|
||||
if (reg->flags & TLF_SPRITE) bits.set(reg->sprite, true);
|
||||
if (reg->flags & TLF_PALETTE) bits.set(reg->palette, true);
|
||||
if (is_parent) {
|
||||
if (reg->flags & TLF_BB_XY_OFFSET) {
|
||||
bits.set(reg->delta.parent[0], true);
|
||||
bits.set(reg->delta.parent[1], true);
|
||||
}
|
||||
if (reg->flags & TLF_BB_Z_OFFSET) bits.set(reg->delta.parent[2], true);
|
||||
} else {
|
||||
if (reg->flags & TLF_CHILD_X_OFFSET) bits.set(reg->delta.child[0], true);
|
||||
if (reg->flags & TLF_CHILD_Y_OFFSET) bits.set(reg->delta.child[1], true);
|
||||
}
|
||||
};
|
||||
process_registers(0, false);
|
||||
|
||||
uint offset = 0; // offset 0 is the ground sprite
|
||||
const DrawTileSeqStruct *element;
|
||||
foreach_draw_tile_seq(element, dts.seq) {
|
||||
offset++;
|
||||
process_registers(offset, element->IsParentSprite());
|
||||
}
|
||||
}
|
||||
|
||||
void OptimiseVarAction2DeterministicSpriteGroup(VarAction2OptimiseState &state, const GrfSpecFeature feature, const byte varsize, DeterministicSpriteGroup *group, std::vector<DeterministicSpriteGroupAdjust> &saved_adjusts)
|
||||
{
|
||||
if (unlikely(HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2))) return;
|
||||
@@ -2529,32 +2560,7 @@ void OptimiseVarAction2DeterministicSpriteGroup(VarAction2OptimiseState &state,
|
||||
if (sg != nullptr && sg->type == SGT_TILELAYOUT) {
|
||||
const TileLayoutSpriteGroup *tlsg = (const TileLayoutSpriteGroup*)sg;
|
||||
if (tlsg->dts.registers != nullptr) {
|
||||
const TileLayoutRegisters *registers = tlsg->dts.registers;
|
||||
|
||||
auto process_registers = [&](uint i, bool is_parent) {
|
||||
const TileLayoutRegisters *reg = registers + i;
|
||||
if (reg->flags & TLF_DODRAW) bits.set(reg->dodraw, true);
|
||||
if (reg->flags & TLF_SPRITE) bits.set(reg->sprite, true);
|
||||
if (reg->flags & TLF_PALETTE) bits.set(reg->palette, true);
|
||||
if (is_parent) {
|
||||
if (reg->flags & TLF_BB_XY_OFFSET) {
|
||||
bits.set(reg->delta.parent[0], true);
|
||||
bits.set(reg->delta.parent[1], true);
|
||||
}
|
||||
if (reg->flags & TLF_BB_Z_OFFSET) bits.set(reg->delta.parent[2], true);
|
||||
} else {
|
||||
if (reg->flags & TLF_CHILD_X_OFFSET) bits.set(reg->delta.child[0], true);
|
||||
if (reg->flags & TLF_CHILD_Y_OFFSET) bits.set(reg->delta.child[1], true);
|
||||
}
|
||||
};
|
||||
process_registers(0, false);
|
||||
|
||||
uint offset = 0; // offset 0 is the ground sprite
|
||||
const DrawTileSeqStruct *element;
|
||||
foreach_draw_tile_seq(element, tlsg->dts.seq) {
|
||||
offset++;
|
||||
process_registers(offset, element->IsParentSprite());
|
||||
}
|
||||
PopulateRegistersUsedByNewGRFSpriteLayout(tlsg->dts, bits);
|
||||
}
|
||||
}
|
||||
if (sg != nullptr && sg->type == SGT_INDUSTRY_PRODUCTION) {
|
||||
@@ -2980,10 +2986,40 @@ static std::bitset<256> HandleVarAction2DeadStoreElimination(DeterministicSprite
|
||||
return propagate_bits;
|
||||
}
|
||||
|
||||
static void PopulateRailStationAdvancedLayoutVariableUsage()
|
||||
{
|
||||
for (uint i = 0; StationClass::IsClassIDValid((StationClassID)i); i++) {
|
||||
StationClass *stclass = StationClass::Get((StationClassID)i);
|
||||
|
||||
for (uint j = 0; j < stclass->GetSpecCount(); j++) {
|
||||
const StationSpec *statspec = stclass->GetSpec(j);
|
||||
if (statspec == nullptr) continue;
|
||||
|
||||
std::bitset<256> bits;
|
||||
for (const NewGRFSpriteLayout &dts : statspec->renderdata) {
|
||||
if (dts.registers != nullptr) {
|
||||
PopulateRegistersUsedByNewGRFSpriteLayout(dts, bits);
|
||||
}
|
||||
}
|
||||
if (bits.any()) {
|
||||
/* Simulate a procedure call on each of the root sprite groups which requires the bits used in the tile layouts */
|
||||
CheckDeterministicSpriteGroupOutputVarBitsProcedureHandler proc_handler(bits);
|
||||
for (uint k = 0; k < NUM_CARGO + 3; k++) {
|
||||
if (statspec->grf_prop.spritegroup[k] != nullptr) {
|
||||
proc_handler.ProcessGroup(statspec->grf_prop.spritegroup[k], nullptr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleVarAction2OptimisationPasses()
|
||||
{
|
||||
if (unlikely(HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2))) return;
|
||||
|
||||
PopulateRailStationAdvancedLayoutVariableUsage();
|
||||
|
||||
for (DeterministicSpriteGroup *group : _cur.dead_store_elimination_candidates) {
|
||||
VarAction2GroupVariableTracking *var_tracking = _cur.GetVarAction2GroupVariableTracking(group, false);
|
||||
if (!group->calculated_result) {
|
||||
|
Reference in New Issue
Block a user