// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
priv struct WgslIrWriterArena {
directives : Array[String]
types : Array[WgslIrWriterTypeSlot]
constants : Array[WgslIrWriterConstantSlot]
overrides : Array[WgslIrWriterOverrideSlot]
global_variables : Array[WgslIrWriterGlobalVariableSlot]
functions : Array[WgslIrWriterFunctionSlot]
entry_points : Array[WgslIrWriterEntryPointSlot]
const_asserts : Array[WgslIrWriterConstAssertSlot]
}
///|
priv struct WgslIrWriterTypeSlot {
source_index : Int
item : Type
}
///|
priv struct WgslIrWriterConstantSlot {
source_index : Int
item : Constant
}
///|
priv struct WgslIrWriterOverrideSlot {
source_index : Int
item : Override
}
///|
priv struct WgslIrWriterGlobalVariableSlot {
source_index : Int
item : GlobalVariable
}
///|
priv struct WgslIrWriterFunctionSlot {
source_index : Int
item : Function
function_plan : WgslIrFunctionWriterPlan
}
///|
priv struct WgslIrWriterEntryPointSlot {
source_index : Int
item : EntryPoint
function_plan : WgslIrFunctionWriterPlan
}
///|
priv struct WgslIrWriterConstAssertSlot {
condition : Handle
}
///|
priv struct WgslIrWriterDeclarationArena {
types : Array[WgslIrWriterDeclarationSlot]
constants : Array[WgslIrWriterDeclarationSlot]
overrides : Array[WgslIrWriterDeclarationSlot]
global_variables : Array[WgslIrWriterDeclarationSlot]
functions : Array[WgslIrWriterDeclarationSlot]
}
///|
priv struct WgslIrWriterDeclarationSlot {
source_index : Int
}
///|
fn WgslIrWriterPlanner::writer_arena(
self : WgslIrWriterPlanner,
) -> WgslIrWriterArena {
let declarations = self.declaration_arena()
let types = self.type_slots(declarations.types)
let constants = self.constant_slots(declarations.constants)
let overrides = self.override_slots(declarations.overrides)
let global_variables = self.global_variable_slots(
declarations.global_variables,
)
let functions = self.function_slots(declarations.functions, true)
let entry_points = self.entry_point_slots(true)
let const_asserts = self.const_assert_slots()
{
directives: wgsl_ir_semantic_source_directives(self.shader_module),
types,
constants,
overrides,
global_variables,
functions,
entry_points,
const_asserts,
}
}
///|
fn WgslIrWriterPlanner::runtime_writer_arena(
self : WgslIrWriterPlanner,
) -> WgslIrWriterArena {
let declarations = self.runtime_declaration_arena()
let types = self.type_slots(declarations.types)
let constants = self.constant_slots(declarations.constants)
let overrides = self.override_slots(declarations.overrides)
let global_variables = self.global_variable_slots(
declarations.global_variables,
)
let functions = self.function_slots(declarations.functions, false)
let entry_points = self.entry_point_slots(false)
let const_asserts = self.const_assert_slots()
{
directives: wgsl_ir_semantic_source_directives(self.shader_module),
types,
constants,
overrides,
global_variables,
functions,
entry_points,
const_asserts,
}
}
///|
fn WgslIrWriterPlanner::type_slots(
self : WgslIrWriterPlanner,
declarations : Array[WgslIrWriterDeclarationSlot],
) -> Array[WgslIrWriterTypeSlot] {
let slots : Array[WgslIrWriterTypeSlot] = []
for slot in declarations {
slots.push({
source_index: slot.source_index,
item: self.shader_module.types.items[slot.source_index],
})
}
slots
}
///|
fn WgslIrWriterPlanner::constant_slots(
self : WgslIrWriterPlanner,
declarations : Array[WgslIrWriterDeclarationSlot],
) -> Array[WgslIrWriterConstantSlot] {
let slots : Array[WgslIrWriterConstantSlot] = []
for slot in declarations {
slots.push({
source_index: slot.source_index,
item: self.shader_module.constants.items[slot.source_index],
})
}
slots
}
///|
fn WgslIrWriterPlanner::override_slots(
self : WgslIrWriterPlanner,
declarations : Array[WgslIrWriterDeclarationSlot],
) -> Array[WgslIrWriterOverrideSlot] {
let slots : Array[WgslIrWriterOverrideSlot] = []
for slot in declarations {
slots.push({
source_index: slot.source_index,
item: self.shader_module.overrides.items[slot.source_index],
})
}
slots
}
///|
fn WgslIrWriterPlanner::global_variable_slots(
self : WgslIrWriterPlanner,
declarations : Array[WgslIrWriterDeclarationSlot],
) -> Array[WgslIrWriterGlobalVariableSlot] {
let slots : Array[WgslIrWriterGlobalVariableSlot] = []
for slot in declarations {
slots.push({
source_index: slot.source_index,
item: self.shader_module.global_variables.items[slot.source_index],
})
}
slots
}
///|
fn WgslIrWriterPlanner::function_slots(
self : WgslIrWriterPlanner,
declarations : Array[WgslIrWriterDeclarationSlot],
projection_aliases : Bool,
) -> Array[WgslIrWriterFunctionSlot] {
let slots : Array[WgslIrWriterFunctionSlot] = []
for slot in declarations {
let item = self.shader_module.functions.items[slot.source_index]
slots.push({
source_index: slot.source_index,
item,
function_plan: WgslIrFunctionWriterPlan::from_function(
self.shader_module,
item,
projection_aliases,
),
})
}
slots
}
///|
fn WgslIrWriterPlanner::entry_point_slots(
self : WgslIrWriterPlanner,
projection_aliases : Bool,
) -> Array[WgslIrWriterEntryPointSlot] {
let slots : Array[WgslIrWriterEntryPointSlot] = []
for source_index in self.entry_point_order() {
let item = self.shader_module.entry_points[source_index]
slots.push({
source_index,
item,
function_plan: WgslIrFunctionWriterPlan::from_function(
self.shader_module,
item.function,
projection_aliases,
),
})
}
slots
}
///|
fn WgslIrWriterPlanner::const_assert_slots(
self : WgslIrWriterPlanner,
) -> Array[WgslIrWriterConstAssertSlot] {
let slots : Array[WgslIrWriterConstAssertSlot] = []
for source_index in 0.. WgslIrWriterDeclarationArena {
let derived = self.derived_module_view()
{
types: wgsl_ir_writer_compat_declaration_slots(derived.types),
constants: wgsl_ir_writer_compat_declaration_slots(derived.constants),
overrides: wgsl_ir_writer_compat_declaration_slots(derived.overrides),
global_variables: wgsl_ir_writer_compat_declaration_slots(
derived.global_variables,
),
functions: wgsl_ir_writer_compat_declaration_slots(derived.functions),
}
}
///|
fn WgslIrWriterPlanner::runtime_declaration_arena(
self : WgslIrWriterPlanner,
) -> WgslIrWriterDeclarationArena {
let derived = self.derived_module_view()
{
types: wgsl_ir_writer_compat_declaration_slots(derived.types),
constants: wgsl_ir_writer_compat_declaration_slots(derived.constants),
overrides: wgsl_ir_writer_compat_declaration_slots(derived.overrides),
global_variables: wgsl_ir_writer_compat_declaration_slots(
derived.global_variables,
),
functions: wgsl_ir_writer_compat_declaration_slots(
self.runtime_function_order(),
),
}
}
///|
fn WgslIrWriterPlanner::runtime_function_order(
self : WgslIrWriterPlanner,
) -> Array[Int] {
let order : Array[Int] = []
for index in 0.. Bool {
if emitted.contains(index) {
return false
}
match self.filter {
Some(filter) => if !filter.contains_function(index) { return false }
None => ()
}
!wgsl_ir_function_is_entry_point_name(
self.shader_module.functions.items[index],
self.shader_module,
)
}
///|
fn wgsl_ir_writer_compat_declaration_slots(
source_order : Array[Int],
) -> Array[WgslIrWriterDeclarationSlot] {
let slots : Array[WgslIrWriterDeclarationSlot] = []
for source_index in source_order {
slots.push({ source_index, })
}
slots
}
///|
fn wgsl_ir_source_order_indices(length : Int) -> Array[Int] {
let order : Array[Int] = []
for index in 0..