From 760b5b044bc08e3686b741e44e697a368c347e91 Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Wed, 4 May 2022 17:13:13 +0200 Subject: [PATCH] [hlsl-out] use wrapped constructors when loading from storage address space --- src/back/hlsl/help.rs | 42 +++++++++++++++++++++++++++++++++++++ src/back/hlsl/storage.rs | 8 +++++-- tests/out/hlsl/globals.hlsl | 9 +++++++- tests/out/hlsl/shadow.hlsl | 10 ++++++++- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/back/hlsl/help.rs b/src/back/hlsl/help.rs index 6275248856..e79b5acebc 100644 --- a/src/back/hlsl/help.rs +++ b/src/back/hlsl/help.rs @@ -880,6 +880,48 @@ impl<'a, W: Write> super::Writer<'a, W> { self.wrapped.image_queries.insert(wiq); } } + // Write `WrappedConstructor` for structs that are loaded from `AddressSpace::Storage` + // since they will later be used by the fn `write_storage_load` + crate::Expression::Load { pointer } => { + let pointer_space = func_ctx.info[pointer] + .ty + .inner_with(&module.types) + .pointer_space(); + + if let Some(crate::AddressSpace::Storage { .. }) = pointer_space { + if let Some(ty) = func_ctx.info[handle].ty.handle() { + write_wrapped_constructor(self, ty, module, func_ctx)?; + } + } + + fn write_wrapped_constructor( + writer: &mut super::Writer<'_, W>, + ty: Handle, + module: &crate::Module, + func_ctx: &FunctionCtx, + ) -> BackendResult { + match module.types[ty].inner { + crate::TypeInner::Struct { ref members, .. } => { + for member in members { + write_wrapped_constructor(writer, member.ty, module, func_ctx)?; + } + + let constructor = WrappedConstructor { ty }; + if !writer.wrapped.constructors.contains(&constructor) { + writer + .write_wrapped_constructor_function(module, constructor)?; + writer.wrapped.constructors.insert(constructor); + } + } + crate::TypeInner::Array { base, .. } => { + write_wrapped_constructor(writer, base, module, func_ctx)?; + } + _ => {} + }; + + Ok(()) + } + } crate::Expression::Compose { ty, components: _ } => { let constructor = match module.types[ty].inner { crate::TypeInner::Struct { .. } | crate::TypeInner::Array { .. } => { diff --git a/src/back/hlsl/storage.rs b/src/back/hlsl/storage.rs index cea989deec..658090256e 100644 --- a/src/back/hlsl/storage.rs +++ b/src/back/hlsl/storage.rs @@ -156,12 +156,16 @@ impl super::Writer<'_, W> { write!(self.out, "}}")?; } crate::TypeInner::Struct { ref members, .. } => { - write!(self.out, "{{")?; + let constructor = super::help::WrappedConstructor { + ty: result_ty.handle().unwrap(), + }; + self.write_wrapped_constructor_function_name(module, constructor)?; + write!(self.out, "(")?; let iter = members .iter() .map(|m| (TypeResolution::Handle(m.ty), m.offset)); self.write_storage_load_sequence(module, var_handle, iter, func_ctx)?; - write!(self.out, "}}")?; + write!(self.out, ")")?; } _ => unreachable!(), } diff --git a/tests/out/hlsl/globals.hlsl b/tests/out/hlsl/globals.hlsl index 7b12afdf5e..2274aa4288 100644 --- a/tests/out/hlsl/globals.hlsl +++ b/tests/out/hlsl/globals.hlsl @@ -18,6 +18,13 @@ void test_msl_packed_vec3_as_arg(float3 arg) return; } +Foo ConstructFoo(float3 arg0, float arg1) { + Foo ret = (Foo)0; + ret.v3_ = arg0; + ret.v1_ = arg1; + return ret; +} + void test_msl_packed_vec3_() { int idx = 1; @@ -27,7 +34,7 @@ void test_msl_packed_vec3_() alignment.Store(0+0, asuint(2.0)); int _expr21 = idx; alignment.Store(_expr21*4+0, asuint(3.0)); - Foo data = {asfloat(alignment.Load3(0)), asfloat(alignment.Load(12))}; + Foo data = ConstructFoo(asfloat(alignment.Load3(0)), asfloat(alignment.Load(12))); float3 unnamed = data.v3_; float2 unnamed_1 = data.v3_.zx; test_msl_packed_vec3_as_arg(data.v3_); diff --git a/tests/out/hlsl/shadow.hlsl b/tests/out/hlsl/shadow.hlsl index b66713092b..fe757eaa9f 100644 --- a/tests/out/hlsl/shadow.hlsl +++ b/tests/out/hlsl/shadow.hlsl @@ -77,6 +77,14 @@ VertexOutput_vs_main vs_main(int4 position : LOC0, int4 normal : LOC1) return vertexoutput_1; } +Light ConstructLight(float4x4 arg0, float4 arg1, float4 arg2) { + Light ret = (Light)0; + ret.proj = arg0; + ret.pos = arg1; + ret.color = arg2; + return ret; +} + float4 fs_main(FragmentInput_fs_main fragmentinput_fs_main) : SV_Target0 { VertexOutput in_ = { fragmentinput_fs_main.proj_position_1, fragmentinput_fs_main.world_normal_1, fragmentinput_fs_main.world_position_1 }; @@ -98,7 +106,7 @@ float4 fs_main(FragmentInput_fs_main fragmentinput_fs_main) : SV_Target0 break; } uint _expr23 = i; - Light light = {float4x4(asfloat(s_lights.Load4(_expr23*96+0+0)), asfloat(s_lights.Load4(_expr23*96+0+16)), asfloat(s_lights.Load4(_expr23*96+0+32)), asfloat(s_lights.Load4(_expr23*96+0+48))), asfloat(s_lights.Load4(_expr23*96+64)), asfloat(s_lights.Load4(_expr23*96+80))}; + Light light = ConstructLight(float4x4(asfloat(s_lights.Load4(_expr23*96+0+0)), asfloat(s_lights.Load4(_expr23*96+0+16)), asfloat(s_lights.Load4(_expr23*96+0+32)), asfloat(s_lights.Load4(_expr23*96+0+48))), asfloat(s_lights.Load4(_expr23*96+64)), asfloat(s_lights.Load4(_expr23*96+80))); uint _expr26 = i; const float _e30 = fetch_shadow(_expr26, mul(in_.world_position, light.proj)); float3 light_dir = normalize((light.pos.xyz - in_.world_position.xyz));