mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
Replace the application-specific PackPhotonSharedVec3Memory GLSL regex patch with a general DecomposeWorkgroupVec3Pass SPIR-V optimization pass. The new pass decomposes vec3/ivec3/uvec3/bvec3 Workgroup (shared) memory variables into scalar arrays (e.g. shared vec3 arr[N][M] -> shared float arr[N][M][3]), rewriting whole-vector loads/stores into per-component scalar loads/stores. Component-level accesses (e.g. arr[i].x) are unchanged since a trailing component index into a float[3] yields the same scalar pointer as it did for a vec3. Unlike the regex hack, the pass is application-agnostic: it does not match on variable names, array dimensions, or shader pack identity, and runs at the SPIR-V level before SPIRV-Cross decompilation. Registered in SanitizeAndOptimizeBinary after AggressiveDCE so dead workgroup accesses are already eliminated. Asserts on unsupported OpAtomic*/OpCopyMemory targeting vec3 workgroup pointers. Adds ProgramUtilTest.DecomposeWorkgroupVec3InSpirvPass covering array declaration, +=, whole load/store, component access, and row-copy loop.
37 lines
1.6 KiB
C++
37 lines
1.6 KiB
C++
// MobileGL - MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/DecomposeWorkgroupVec3Pass.h
|
|
// Copyright (c) 2025-2026 MobileGL-Dev
|
|
// Licensed under the GNU Lesser General Public License v3.0:
|
|
// https://www.gnu.org/licenses/gpl-3.0.txt
|
|
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
// End of Source File Header
|
|
|
|
#pragma once
|
|
#include "source/opt/pass.h"
|
|
#include "spirv-tools/optimizer.hpp"
|
|
|
|
#include <Includes.h>
|
|
|
|
namespace MobileGL {
|
|
namespace MG_Util {
|
|
namespace ShaderTranspiler {
|
|
// Decomposes vec3/ivec3/uvec3/bvec3 variables in the Workgroup storage class
|
|
// (GLSL `shared` memory) into scalar arrays (e.g. `shared vec3 arr[N]` ->
|
|
// `shared float arr[N][3]`). Whole-vector loads/stores are rewritten into
|
|
// per-component scalar loads/stores. This works around drivers (e.g.
|
|
// ANGLE/Metal) that reject `shared vec3` due to workgroup memory alignment.
|
|
//
|
|
// Component-level accesses (e.g. `arr[i].x`) require no rewriting because a
|
|
// trailing component index into a `float[3]` yields the same scalar pointer
|
|
// as it did for a `vec3`.
|
|
class DecomposeWorkgroupVec3Pass : public spvtools::opt::Pass {
|
|
public:
|
|
const char* name() const override { return "decompose-workgroup-vec3"; }
|
|
Status Process() override;
|
|
|
|
static spvtools::Optimizer::PassToken CreateDecomposeWorkgroupVec3Pass();
|
|
};
|
|
} // namespace ShaderTranspiler
|
|
} // namespace MG_Util
|
|
} // namespace MobileGL
|