2022-11-07 16:25:11 +11:00
use crate ::error ::{ SemanticsErrorKind , ShaderCompileError , ShaderReflectError } ;
2024-02-11 09:47:05 +11:00
use crate ::front ::SpirvCompilation ;
2023-01-29 18:30:58 +11:00
use crate ::reflect ::semantics ::{
2024-02-06 17:32:08 +11:00
BindingMeta , BindingStage , BufferReflection , MemberOffset , ShaderReflection , ShaderSemantics ,
TextureBinding , TextureSemanticMap , TextureSemantics , TextureSizeMeta , TypeInfo ,
2023-01-29 18:30:58 +11:00
UniformMemberBlock , UniqueSemanticMap , UniqueSemantics , ValidateTypeSemantics , VariableMeta ,
MAX_BINDINGS_COUNT , MAX_PUSH_BUFFER_SIZE ,
} ;
2022-12-01 17:50:16 +11:00
use crate ::reflect ::{ align_uniform_size , ReflectShader } ;
2023-02-07 11:22:53 +11:00
use std ::ops ::Deref ;
2022-11-11 17:53:02 +11:00
2022-10-27 17:22:44 +11:00
use spirv_cross ::spirv ::{ Ast , Decoration , Module , Resource , ShaderResources , Type } ;
2022-12-22 13:39:31 +11:00
use spirv_cross ::{ glsl , hlsl , ErrorCode } ;
2022-11-01 11:29:25 +11:00
2023-02-08 10:50:26 +11:00
use crate ::back ::cross ::{ CrossGlslContext , CrossHlslContext , HlslShaderModel } ;
2022-11-11 17:44:41 +11:00
use crate ::back ::targets ::{ GLSL , HLSL } ;
2022-11-11 17:53:02 +11:00
use crate ::back ::{ CompileShader , ShaderCompilerOutput } ;
2023-01-16 10:36:38 +11:00
use crate ::reflect ::helper ::{ SemanticErrorBlame , TextureData , UboData } ;
2022-10-24 14:22:26 +11:00
2023-02-06 11:48:24 +11:00
// This is "probably" OK.
unsafe impl < T : Send + spirv_cross ::spirv ::Target > Send for CrossReflect < T > { }
2023-01-17 11:35:23 +11:00
pub ( crate ) struct CrossReflect < T >
2022-10-24 14:22:26 +11:00
where
T : spirv_cross ::spirv ::Target ,
{
vertex : Ast < T > ,
fragment : Ast < T > ,
}
2023-01-17 11:35:23 +11:00
///The output of the SPIR-V AST after compilation.
///
/// This output is immutable and can not be recompiled later.
2022-11-28 15:47:41 +11:00
pub struct CompiledAst < T : spirv_cross ::spirv ::Target > ( Ast < T > ) ;
impl < T : spirv_cross ::spirv ::Target > Deref for CompiledAst < T > {
type Target = Ast < T > ;
fn deref ( & self ) -> & Self ::Target {
& self . 0
}
}
2023-01-17 11:35:23 +11:00
/// The compiled SPIR-V program after compilation.
2022-11-28 15:47:41 +11:00
pub struct CompiledProgram < T >
2022-11-11 18:26:57 +11:00
where
2022-11-22 08:21:50 +11:00
T : spirv_cross ::spirv ::Target ,
{
2022-11-28 15:47:41 +11:00
pub vertex : CompiledAst < T > ,
pub fragment : CompiledAst < T > ,
2022-11-11 18:26:57 +11:00
}
2022-11-11 17:44:41 +11:00
pub ( crate ) type HlslReflect = CrossReflect < hlsl ::Target > ;
pub ( crate ) type GlslReflect = CrossReflect < glsl ::Target > ;
2022-11-09 17:11:25 +11:00
2022-12-01 17:50:16 +11:00
impl ValidateTypeSemantics < Type > for UniqueSemantics {
2022-10-26 16:19:04 +11:00
fn validate_type ( & self , ty : & Type ) -> Option < TypeInfo > {
2023-07-20 15:13:22 +10:00
let ( Type ::Float {
ref array ,
vecsize ,
columns ,
..
}
| Type ::Int {
ref array ,
vecsize ,
columns ,
..
}
| Type ::UInt {
ref array ,
vecsize ,
columns ,
..
} ) = * ty
else {
return None ;
2022-10-26 16:19:04 +11:00
} ;
if ! array . is_empty ( ) {
2022-10-27 17:22:44 +11:00
return None ;
2022-10-26 16:19:04 +11:00
}
let valid = match self {
2022-12-01 17:50:16 +11:00
UniqueSemantics ::MVP = > {
2022-10-28 11:39:39 +11:00
matches! ( ty , Type ::Float { .. } ) & & vecsize = = 4 & & columns = = 4
2022-10-27 17:22:44 +11:00
}
2022-12-01 17:50:16 +11:00
UniqueSemantics ::FrameCount = > {
2022-10-28 11:39:39 +11:00
matches! ( ty , Type ::UInt { .. } ) & & vecsize = = 1 & & columns = = 1
2022-10-27 17:22:44 +11:00
}
2022-12-01 17:50:16 +11:00
UniqueSemantics ::FrameDirection = > {
2022-10-28 11:39:39 +11:00
matches! ( ty , Type ::Int { .. } ) & & vecsize = = 1 & & columns = = 1
2022-10-27 17:22:44 +11:00
}
2022-12-01 17:50:16 +11:00
UniqueSemantics ::FloatParameter = > {
2022-10-28 11:39:39 +11:00
matches! ( ty , Type ::Float { .. } ) & & vecsize = = 1 & & columns = = 1
2022-10-27 17:22:44 +11:00
}
_ = > matches! ( ty , Type ::Float { .. } ) & & vecsize = = 4 & & columns = = 1 ,
2022-10-26 16:19:04 +11:00
} ;
if valid {
Some ( TypeInfo {
size : vecsize ,
2022-10-27 17:22:44 +11:00
columns ,
2022-10-26 16:19:04 +11:00
} )
} else {
None
}
}
}
impl ValidateTypeSemantics < Type > for TextureSemantics {
fn validate_type ( & self , ty : & Type ) -> Option < TypeInfo > {
2023-07-20 15:13:22 +10:00
let Type ::Float {
ref array ,
vecsize ,
columns ,
..
} = * ty
else {
return None ;
2022-10-26 16:19:04 +11:00
} ;
if ! array . is_empty ( ) {
2022-10-27 17:22:44 +11:00
return None ;
2022-10-26 16:19:04 +11:00
}
if vecsize = = 4 & & columns = = 1 {
Some ( TypeInfo {
size : vecsize ,
2022-10-27 17:22:44 +11:00
columns ,
2022-10-26 16:19:04 +11:00
} )
} else {
None
}
}
}
2024-02-11 09:47:05 +11:00
impl < T > TryFrom < & SpirvCompilation > for CrossReflect < T >
2022-11-11 17:44:41 +11:00
where
T : spirv_cross ::spirv ::Target ,
Ast < T > : spirv_cross ::spirv ::Compile < T > ,
Ast < T > : spirv_cross ::spirv ::Parse < T > ,
{
2022-11-07 16:25:11 +11:00
type Error = ShaderReflectError ;
2024-02-11 09:47:05 +11:00
fn try_from ( value : & SpirvCompilation ) -> Result < Self , Self ::Error > {
2023-02-06 11:48:24 +11:00
let vertex_module = Module ::from_words ( & value . vertex ) ;
let fragment_module = Module ::from_words ( & value . fragment ) ;
2022-11-07 16:25:11 +11:00
2022-11-11 17:53:02 +11:00
let vertex = Ast ::parse ( & vertex_module ) ? ;
let fragment = Ast ::parse ( & fragment_module ) ? ;
2022-11-07 16:25:11 +11:00
Ok ( CrossReflect { vertex , fragment } )
}
}
2022-10-27 17:22:44 +11:00
impl < T > CrossReflect < T >
where
T : spirv_cross ::spirv ::Target ,
Ast < T > : spirv_cross ::spirv ::Compile < T > ,
Ast < T > : spirv_cross ::spirv ::Parse < T > ,
2022-10-24 14:22:26 +11:00
{
2022-10-27 17:22:44 +11:00
fn validate (
& self ,
vertex_res : & ShaderResources ,
fragment_res : & ShaderResources ,
) -> Result < ( ) , ShaderReflectError > {
2022-10-24 14:22:26 +11:00
if ! vertex_res . sampled_images . is_empty ( )
| | ! vertex_res . storage_buffers . is_empty ( )
| | ! vertex_res . subpass_inputs . is_empty ( )
| | ! vertex_res . storage_images . is_empty ( )
| | ! vertex_res . atomic_counters . is_empty ( )
{
return Err ( ShaderReflectError ::VertexSemanticError (
SemanticsErrorKind ::InvalidResourceType ,
) ) ;
}
if ! fragment_res . storage_buffers . is_empty ( )
| | ! fragment_res . subpass_inputs . is_empty ( )
| | ! fragment_res . storage_images . is_empty ( )
| | ! fragment_res . atomic_counters . is_empty ( )
{
return Err ( ShaderReflectError ::FragmentSemanticError (
SemanticsErrorKind ::InvalidResourceType ,
) ) ;
}
let vert_inputs = vertex_res . stage_inputs . len ( ) ;
if vert_inputs ! = 2 {
return Err ( ShaderReflectError ::VertexSemanticError (
SemanticsErrorKind ::InvalidInputCount ( vert_inputs ) ,
) ) ;
}
let frag_outputs = fragment_res . stage_outputs . len ( ) ;
if frag_outputs ! = 1 {
return Err ( ShaderReflectError ::FragmentSemanticError (
SemanticsErrorKind ::InvalidOutputCount ( frag_outputs ) ,
) ) ;
}
2022-10-27 17:22:44 +11:00
let fragment_location = self
. fragment
. get_decoration ( fragment_res . stage_outputs [ 0 ] . id , Decoration ::Location ) ? ;
2022-10-24 14:22:26 +11:00
if fragment_location ! = 0 {
return Err ( ShaderReflectError ::FragmentSemanticError (
SemanticsErrorKind ::InvalidLocation ( fragment_location ) ,
) ) ;
}
2023-12-13 18:30:01 +11:00
// Ensure that vertex attributes use location 0 and 1
2022-11-01 11:29:25 +11:00
let vert_mask = vertex_res . stage_inputs . iter ( ) . try_fold ( 0 , | mask , input | {
2022-10-27 17:22:44 +11:00
Ok ::< u32 , ErrorCode > (
mask | 1 < < self . vertex . get_decoration ( input . id , Decoration ::Location ) ? ,
)
} ) ? ;
2022-10-24 14:22:26 +11:00
if vert_mask ! = 0x3 {
return Err ( ShaderReflectError ::VertexSemanticError (
SemanticsErrorKind ::InvalidLocation ( vert_mask ) ,
) ) ;
}
if vertex_res . uniform_buffers . len ( ) > 1 {
return Err ( ShaderReflectError ::VertexSemanticError (
2022-10-26 13:13:39 +11:00
SemanticsErrorKind ::InvalidUniformBufferCount ( vertex_res . uniform_buffers . len ( ) ) ,
2022-10-24 14:22:26 +11:00
) ) ;
}
if vertex_res . push_constant_buffers . len ( ) > 1 {
return Err ( ShaderReflectError ::VertexSemanticError (
2023-12-13 18:30:01 +11:00
SemanticsErrorKind ::InvalidPushBufferCount ( vertex_res . push_constant_buffers . len ( ) ) ,
2022-10-24 14:22:26 +11:00
) ) ;
}
if fragment_res . uniform_buffers . len ( ) > 1 {
return Err ( ShaderReflectError ::FragmentSemanticError (
2022-10-26 13:13:39 +11:00
SemanticsErrorKind ::InvalidUniformBufferCount ( fragment_res . uniform_buffers . len ( ) ) ,
2022-10-24 14:22:26 +11:00
) ) ;
}
if fragment_res . push_constant_buffers . len ( ) > 1 {
return Err ( ShaderReflectError ::FragmentSemanticError (
2023-12-13 18:30:01 +11:00
SemanticsErrorKind ::InvalidPushBufferCount (
2022-10-27 17:22:44 +11:00
fragment_res . push_constant_buffers . len ( ) ,
) ,
2022-10-24 14:22:26 +11:00
) ) ;
}
Ok ( ( ) )
}
}
2022-10-27 17:22:44 +11:00
impl < T > CrossReflect < T >
where
T : spirv_cross ::spirv ::Target ,
Ast < T > : spirv_cross ::spirv ::Compile < T > ,
Ast < T > : spirv_cross ::spirv ::Parse < T > ,
2022-10-26 13:13:39 +11:00
{
2022-10-27 17:22:44 +11:00
fn get_ubo_data (
ast : & Ast < T > ,
ubo : & Resource ,
blame : SemanticErrorBlame ,
) -> Result < UboData , ShaderReflectError > {
2022-10-26 13:13:39 +11:00
let descriptor_set = ast . get_decoration ( ubo . id , Decoration ::DescriptorSet ) ? ;
2022-10-27 17:22:44 +11:00
let binding = ast . get_decoration ( ubo . id , Decoration ::Binding ) ? ;
if binding > = MAX_BINDINGS_COUNT {
return Err ( blame . error ( SemanticsErrorKind ::InvalidBinding ( binding ) ) ) ;
2022-10-24 14:22:26 +11:00
}
2022-10-26 13:13:39 +11:00
if descriptor_set ! = 0 {
return Err ( blame . error ( SemanticsErrorKind ::InvalidDescriptorSet ( descriptor_set ) ) ) ;
}
2022-11-21 18:13:10 +11:00
2022-10-26 13:13:39 +11:00
let size = ast . get_declared_struct_size ( ubo . base_type_id ) ? ;
Ok ( UboData {
2023-01-16 06:06:38 +11:00
// descriptor_set,
// id: ubo.id,
2022-10-26 13:13:39 +11:00
binding ,
2022-10-27 17:22:44 +11:00
size ,
2022-10-26 13:13:39 +11:00
} )
}
2022-10-24 14:22:26 +11:00
2022-10-27 17:22:44 +11:00
fn get_push_size (
ast : & Ast < T > ,
push : & Resource ,
blame : SemanticErrorBlame ,
) -> Result < u32 , ShaderReflectError > {
2022-10-26 13:13:39 +11:00
let size = ast . get_declared_struct_size ( push . base_type_id ) ? ;
2023-01-29 03:58:59 +11:00
if size > MAX_PUSH_BUFFER_SIZE {
2022-10-26 13:13:39 +11:00
return Err ( blame . error ( SemanticsErrorKind ::InvalidPushBufferSize ( size ) ) ) ;
2022-10-24 14:22:26 +11:00
}
2022-10-26 13:13:39 +11:00
Ok ( size )
}
2022-10-24 14:22:26 +11:00
2022-10-27 17:22:44 +11:00
fn reflect_buffer_range_metas (
ast : & Ast < T > ,
resource : & Resource ,
2022-11-20 10:48:54 +11:00
pass_number : usize ,
2022-12-01 17:50:16 +11:00
semantics : & ShaderSemantics ,
meta : & mut BindingMeta ,
2023-01-29 17:57:09 +11:00
offset_type : UniformMemberBlock ,
2022-10-27 17:22:44 +11:00
blame : SemanticErrorBlame ,
) -> Result < ( ) , ShaderReflectError > {
2022-10-26 13:13:39 +11:00
let ranges = ast . get_active_buffer_ranges ( resource . id ) ? ;
for range in ranges {
let name = ast . get_member_name ( resource . base_type_id , range . index ) ? ;
2022-10-27 17:22:44 +11:00
let ubo_type = ast . get_type ( resource . base_type_id ) ? ;
let range_type = match ubo_type {
2022-10-26 13:13:39 +11:00
Type ::Struct { member_types , .. } = > {
2022-10-27 17:22:44 +11:00
let range_type = member_types
. get ( range . index as usize )
2022-10-26 13:13:39 +11:00
. cloned ( )
. ok_or ( blame . error ( SemanticsErrorKind ::InvalidRange ( range . index ) ) ) ? ;
ast . get_type ( range_type ) ?
}
2022-10-27 17:22:44 +11:00
_ = > return Err ( blame . error ( SemanticsErrorKind ::InvalidResourceType ) ) ,
2022-10-26 13:13:39 +11:00
} ;
2022-10-24 14:22:26 +11:00
2022-12-01 17:50:16 +11:00
if let Some ( parameter ) = semantics . uniform_semantics . get_unique_semantic ( & name ) {
2022-10-27 17:22:44 +11:00
let Some ( typeinfo ) = parameter . semantics . validate_type ( & range_type ) else {
2023-07-20 15:13:22 +10:00
return Err ( blame . error ( SemanticsErrorKind ::InvalidTypeForSemantic ( name ) ) ) ;
2022-10-27 17:22:44 +11:00
} ;
match & parameter . semantics {
2022-12-01 17:50:16 +11:00
UniqueSemantics ::FloatParameter = > {
2023-01-29 17:57:09 +11:00
let offset = range . offset ;
if let Some ( meta ) = meta . parameter_meta . get_mut ( & name ) {
if let Some ( expected ) = meta . offset . offset ( offset_type )
& & expected ! = offset
{
2022-10-27 17:22:44 +11:00
return Err ( ShaderReflectError ::MismatchedOffset {
semantic : name ,
2023-01-29 17:57:09 +11:00
expected ,
received : offset ,
ty : offset_type ,
2024-02-03 18:04:39 +11:00
pass : pass_number ,
2022-10-26 16:19:04 +11:00
} ) ;
}
2022-12-01 17:50:16 +11:00
if meta . size ! = typeinfo . size {
return Err ( ShaderReflectError ::MismatchedSize {
2022-10-27 17:22:44 +11:00
semantic : name ,
2022-12-01 17:50:16 +11:00
vertex : meta . size ,
2022-10-27 17:22:44 +11:00
fragment : typeinfo . size ,
2023-01-29 18:30:58 +11:00
pass : pass_number ,
2022-10-26 16:19:04 +11:00
} ) ;
}
2023-01-29 17:57:09 +11:00
* meta . offset . offset_mut ( offset_type ) = Some ( offset ) ;
2022-10-27 17:22:44 +11:00
} else {
meta . parameter_meta . insert (
2022-11-13 18:05:49 +11:00
name . clone ( ) ,
2022-10-27 17:22:44 +11:00
VariableMeta {
2022-11-12 17:23:49 +11:00
id : name ,
2023-01-29 17:57:09 +11:00
offset : MemberOffset ::new ( offset , offset_type ) ,
2022-12-01 17:50:16 +11:00
size : typeinfo . size ,
2022-10-27 17:22:44 +11:00
} ,
) ;
2022-10-26 13:13:39 +11:00
}
}
2022-10-27 17:22:44 +11:00
semantics = > {
2023-01-29 17:57:09 +11:00
let offset = range . offset ;
if let Some ( meta ) = meta . unique_meta . get_mut ( semantics ) {
if let Some ( expected ) = meta . offset . offset ( offset_type )
& & expected ! = offset
{
2022-10-27 17:22:44 +11:00
return Err ( ShaderReflectError ::MismatchedOffset {
semantic : name ,
2023-01-29 17:57:09 +11:00
expected ,
received : offset ,
ty : offset_type ,
2024-02-03 18:04:39 +11:00
pass : pass_number ,
2022-10-27 17:22:44 +11:00
} ) ;
}
2022-12-01 17:50:16 +11:00
if meta . size ! = typeinfo . size * typeinfo . columns {
return Err ( ShaderReflectError ::MismatchedSize {
2022-10-27 17:22:44 +11:00
semantic : name ,
2022-12-01 17:50:16 +11:00
vertex : meta . size ,
2022-10-27 17:22:44 +11:00
fragment : typeinfo . size ,
2023-01-29 18:30:58 +11:00
pass : pass_number ,
2022-10-27 17:22:44 +11:00
} ) ;
}
2023-01-29 17:57:09 +11:00
* meta . offset . offset_mut ( offset_type ) = Some ( offset ) ;
2022-10-27 17:22:44 +11:00
} else {
2022-12-01 17:50:16 +11:00
meta . unique_meta . insert (
2022-10-27 17:22:44 +11:00
* semantics ,
VariableMeta {
2022-11-12 17:23:49 +11:00
id : name ,
2023-01-29 17:57:09 +11:00
offset : MemberOffset ::new ( offset , offset_type ) ,
2022-12-01 17:50:16 +11:00
size : typeinfo . size * typeinfo . columns ,
2022-10-27 17:22:44 +11:00
} ,
) ;
2022-10-26 13:13:39 +11:00
}
}
2022-10-27 17:22:44 +11:00
}
2022-11-07 16:25:11 +11:00
} else if let Some ( texture ) = semantics . uniform_semantics . get_texture_semantic ( & name ) {
2022-10-27 17:22:44 +11:00
let Some ( _typeinfo ) = texture . semantics . validate_type ( & range_type ) else {
2023-07-20 15:13:22 +10:00
return Err ( blame . error ( SemanticsErrorKind ::InvalidTypeForSemantic ( name ) ) ) ;
2022-10-27 17:22:44 +11:00
} ;
if let TextureSemantics ::PassOutput = texture . semantics {
2022-11-07 16:25:11 +11:00
if texture . index > = pass_number {
2022-10-27 17:22:44 +11:00
return Err ( ShaderReflectError ::NonCausalFilterChain {
2022-11-07 16:25:11 +11:00
pass : pass_number ,
2022-10-27 17:22:44 +11:00
target : texture . index ,
} ) ;
}
}
2022-10-24 14:22:26 +11:00
2023-01-29 17:57:09 +11:00
let offset = range . offset ;
2022-10-27 17:22:44 +11:00
if let Some ( meta ) = meta . texture_size_meta . get_mut ( & texture ) {
2023-01-29 17:57:09 +11:00
if let Some ( expected ) = meta . offset . offset ( offset_type )
& & expected ! = offset
{
2022-10-27 17:22:44 +11:00
return Err ( ShaderReflectError ::MismatchedOffset {
semantic : name ,
2023-01-29 17:57:09 +11:00
expected ,
received : offset ,
ty : offset_type ,
2024-02-03 18:04:39 +11:00
pass : pass_number ,
2022-10-26 16:19:04 +11:00
} ) ;
}
2022-10-27 17:22:44 +11:00
meta . stage_mask . insert ( match blame {
SemanticErrorBlame ::Vertex = > BindingStage ::VERTEX ,
2022-10-28 11:39:39 +11:00
SemanticErrorBlame ::Fragment = > BindingStage ::FRAGMENT ,
2022-10-27 17:22:44 +11:00
} ) ;
2023-01-29 17:57:09 +11:00
* meta . offset . offset_mut ( offset_type ) = Some ( offset ) ;
2022-10-27 17:22:44 +11:00
} else {
meta . texture_size_meta . insert (
2022-11-01 11:29:25 +11:00
texture ,
2022-10-27 17:22:44 +11:00
TextureSizeMeta {
2023-01-29 17:57:09 +11:00
offset : MemberOffset ::new ( offset , offset_type ) ,
2022-10-27 17:22:44 +11:00
stage_mask : match blame {
SemanticErrorBlame ::Vertex = > BindingStage ::VERTEX ,
2022-10-28 11:39:39 +11:00
SemanticErrorBlame ::Fragment = > BindingStage ::FRAGMENT ,
} ,
2022-11-22 08:21:50 +11:00
id : name ,
2022-10-27 17:22:44 +11:00
} ,
) ;
2022-10-24 14:22:26 +11:00
}
2022-10-27 17:22:44 +11:00
} else {
2022-10-28 11:39:39 +11:00
return Err ( blame . error ( SemanticsErrorKind ::UnknownSemantics ( name ) ) ) ;
2022-10-24 14:22:26 +11:00
}
2022-10-26 13:13:39 +11:00
}
Ok ( ( ) )
}
2022-10-27 17:22:44 +11:00
fn reflect_ubos (
2022-11-07 16:25:11 +11:00
& mut self ,
2022-10-27 17:22:44 +11:00
vertex_ubo : Option < & Resource > ,
fragment_ubo : Option < & Resource > ,
2023-12-14 11:24:00 +11:00
) -> Result < Option < BufferReflection < u32 > > , ShaderReflectError > {
2022-11-07 16:25:11 +11:00
if let Some ( vertex_ubo ) = vertex_ubo {
2022-11-11 17:44:41 +11:00
self . vertex
. set_decoration ( vertex_ubo . id , Decoration ::Binding , 0 ) ? ;
2022-11-07 16:25:11 +11:00
}
if let Some ( fragment_ubo ) = fragment_ubo {
2022-11-11 17:44:41 +11:00
self . fragment
. set_decoration ( fragment_ubo . id , Decoration ::Binding , 0 ) ? ;
2022-11-07 16:25:11 +11:00
}
2022-10-26 13:13:39 +11:00
match ( vertex_ubo , fragment_ubo ) {
( None , None ) = > Ok ( None ) ,
( Some ( vertex_ubo ) , Some ( fragment_ubo ) ) = > {
2022-10-27 17:22:44 +11:00
let vertex_ubo =
Self ::get_ubo_data ( & self . vertex , vertex_ubo , SemanticErrorBlame ::Vertex ) ? ;
let fragment_ubo =
Self ::get_ubo_data ( & self . fragment , fragment_ubo , SemanticErrorBlame ::Fragment ) ? ;
2022-10-26 13:13:39 +11:00
if vertex_ubo . binding ! = fragment_ubo . binding {
return Err ( ShaderReflectError ::MismatchedUniformBuffer {
vertex : vertex_ubo . binding ,
2022-10-27 17:22:44 +11:00
fragment : fragment_ubo . binding ,
2022-10-26 13:13:39 +11:00
} ) ;
2022-10-24 14:22:26 +11:00
}
2022-10-26 13:13:39 +11:00
let size = std ::cmp ::max ( vertex_ubo . size , fragment_ubo . size ) ;
2023-12-14 11:24:00 +11:00
Ok ( Some ( BufferReflection {
2022-10-26 13:13:39 +11:00
binding : vertex_ubo . binding ,
2022-11-27 15:57:01 +11:00
size : align_uniform_size ( size ) ,
2022-10-27 17:22:44 +11:00
stage_mask : BindingStage ::VERTEX | BindingStage ::FRAGMENT ,
2022-10-26 13:13:39 +11:00
} ) )
2022-10-24 14:22:26 +11:00
}
2022-10-26 13:13:39 +11:00
( Some ( vertex_ubo ) , None ) = > {
2022-10-27 17:22:44 +11:00
let vertex_ubo =
Self ::get_ubo_data ( & self . vertex , vertex_ubo , SemanticErrorBlame ::Vertex ) ? ;
2023-12-14 11:24:00 +11:00
Ok ( Some ( BufferReflection {
2022-10-26 13:13:39 +11:00
binding : vertex_ubo . binding ,
2022-11-27 15:57:01 +11:00
size : align_uniform_size ( vertex_ubo . size ) ,
2022-10-27 17:22:44 +11:00
stage_mask : BindingStage ::VERTEX ,
2022-10-26 13:13:39 +11:00
} ) )
}
( None , Some ( fragment_ubo ) ) = > {
2022-10-27 17:22:44 +11:00
let fragment_ubo =
Self ::get_ubo_data ( & self . fragment , fragment_ubo , SemanticErrorBlame ::Fragment ) ? ;
2023-12-14 11:24:00 +11:00
Ok ( Some ( BufferReflection {
2022-10-26 13:13:39 +11:00
binding : fragment_ubo . binding ,
2022-11-30 17:38:05 +11:00
size : align_uniform_size ( fragment_ubo . size ) ,
2022-10-27 17:22:44 +11:00
stage_mask : BindingStage ::FRAGMENT ,
2022-10-26 13:13:39 +11:00
} ) )
}
}
}
2022-10-27 17:22:44 +11:00
fn reflect_texture_metas (
& self ,
texture : TextureData ,
2022-11-20 10:48:54 +11:00
pass_number : usize ,
2022-12-01 17:50:16 +11:00
semantics : & ShaderSemantics ,
meta : & mut BindingMeta ,
2022-10-27 17:22:44 +11:00
) -> Result < ( ) , ShaderReflectError > {
2023-07-20 15:13:22 +10:00
let Some ( semantic ) = semantics
. texture_semantics
. get_texture_semantic ( texture . name )
else {
return Err (
SemanticErrorBlame ::Fragment . error ( SemanticsErrorKind ::UnknownSemantics (
texture . name . to_string ( ) ,
) ) ,
) ;
2022-10-27 17:22:44 +11:00
} ;
2022-11-11 17:44:41 +11:00
if semantic . semantics = = TextureSemantics ::PassOutput & & semantic . index > = pass_number {
2022-10-28 11:39:39 +11:00
return Err ( ShaderReflectError ::NonCausalFilterChain {
2022-11-07 16:25:11 +11:00
pass : pass_number ,
2022-10-28 11:39:39 +11:00
target : semantic . index ,
} ) ;
2022-10-27 17:22:44 +11:00
}
2022-10-28 11:39:39 +11:00
meta . texture_meta . insert (
semantic ,
2022-11-24 17:37:16 +11:00
TextureBinding {
2022-10-28 11:39:39 +11:00
binding : texture . binding ,
} ,
) ;
2022-10-27 17:22:44 +11:00
Ok ( ( ) )
}
fn reflect_texture < ' a > (
& ' a self ,
texture : & ' a Resource ,
) -> Result < TextureData < ' a > , ShaderReflectError > {
let descriptor_set = self
. fragment
. get_decoration ( texture . id , Decoration ::DescriptorSet ) ? ;
let binding = self
. fragment
. get_decoration ( texture . id , Decoration ::Binding ) ? ;
if descriptor_set ! = 0 {
return Err ( ShaderReflectError ::FragmentSemanticError (
SemanticsErrorKind ::InvalidDescriptorSet ( descriptor_set ) ,
) ) ;
}
if binding > = MAX_BINDINGS_COUNT {
return Err ( ShaderReflectError ::FragmentSemanticError (
SemanticsErrorKind ::InvalidBinding ( binding ) ,
) ) ;
}
2022-12-06 17:38:21 +11:00
2022-10-27 17:22:44 +11:00
Ok ( TextureData {
2023-01-16 06:06:38 +11:00
// id: texture.id,
// descriptor_set,
2022-10-27 17:22:44 +11:00
name : & texture . name ,
binding ,
} )
}
fn reflect_push_constant_buffer (
2022-11-07 16:25:11 +11:00
& mut self ,
2022-10-27 17:22:44 +11:00
vertex_pcb : Option < & Resource > ,
fragment_pcb : Option < & Resource > ,
2023-12-14 11:24:00 +11:00
) -> Result < Option < BufferReflection < Option < u32 > > > , ShaderReflectError > {
2022-11-07 16:25:11 +11:00
if let Some ( vertex_pcb ) = vertex_pcb {
2022-11-11 17:44:41 +11:00
self . vertex
. set_decoration ( vertex_pcb . id , Decoration ::Binding , 1 ) ? ;
2022-11-07 16:25:11 +11:00
}
if let Some ( fragment_pcb ) = fragment_pcb {
2022-11-11 17:44:41 +11:00
self . fragment
. set_decoration ( fragment_pcb . id , Decoration ::Binding , 1 ) ? ;
2022-11-07 16:25:11 +11:00
}
2022-10-26 13:13:39 +11:00
match ( vertex_pcb , fragment_pcb ) {
( None , None ) = > Ok ( None ) ,
( Some ( vertex_push ) , Some ( fragment_push ) ) = > {
2022-10-27 17:22:44 +11:00
let vertex_size =
Self ::get_push_size ( & self . vertex , vertex_push , SemanticErrorBlame ::Vertex ) ? ;
let fragment_size = Self ::get_push_size (
& self . fragment ,
fragment_push ,
SemanticErrorBlame ::Fragment ,
) ? ;
2022-10-26 13:13:39 +11:00
let size = std ::cmp ::max ( vertex_size , fragment_size ) ;
2023-12-14 11:24:00 +11:00
Ok ( Some ( BufferReflection {
binding : None ,
2022-11-27 15:57:01 +11:00
size : align_uniform_size ( size ) ,
2022-10-27 17:22:44 +11:00
stage_mask : BindingStage ::VERTEX | BindingStage ::FRAGMENT ,
2022-10-26 13:13:39 +11:00
} ) )
}
( Some ( vertex_push ) , None ) = > {
2022-10-27 17:22:44 +11:00
let vertex_size =
Self ::get_push_size ( & self . vertex , vertex_push , SemanticErrorBlame ::Vertex ) ? ;
2023-12-14 11:24:00 +11:00
Ok ( Some ( BufferReflection {
binding : None ,
2022-11-27 15:57:01 +11:00
size : align_uniform_size ( vertex_size ) ,
2022-10-27 17:22:44 +11:00
stage_mask : BindingStage ::VERTEX ,
2022-10-26 13:13:39 +11:00
} ) )
}
( None , Some ( fragment_push ) ) = > {
2022-10-27 17:22:44 +11:00
let fragment_size = Self ::get_push_size (
& self . fragment ,
fragment_push ,
SemanticErrorBlame ::Fragment ,
) ? ;
2023-12-14 11:24:00 +11:00
Ok ( Some ( BufferReflection {
binding : None ,
2022-11-27 15:57:01 +11:00
size : align_uniform_size ( fragment_size ) ,
2022-10-27 17:22:44 +11:00
stage_mask : BindingStage ::FRAGMENT ,
2022-10-26 13:13:39 +11:00
} ) )
2022-10-24 14:22:26 +11:00
}
}
2022-10-26 13:13:39 +11:00
}
}
impl < T > ReflectShader for CrossReflect < T >
where
T : spirv_cross ::spirv ::Target ,
Ast < T > : spirv_cross ::spirv ::Compile < T > ,
Ast < T > : spirv_cross ::spirv ::Parse < T > ,
{
2022-11-11 17:44:41 +11:00
fn reflect (
& mut self ,
2022-11-20 10:48:54 +11:00
pass_number : usize ,
2022-12-01 17:50:16 +11:00
semantics : & ShaderSemantics ,
2022-11-11 17:44:41 +11:00
) -> Result < ShaderReflection , ShaderReflectError > {
2022-10-26 13:13:39 +11:00
let vertex_res = self . vertex . get_shader_resources ( ) ? ;
let fragment_res = self . fragment . get_shader_resources ( ) ? ;
self . validate ( & vertex_res , & fragment_res ) ? ;
2022-11-01 11:29:25 +11:00
let vertex_ubo = vertex_res . uniform_buffers . first ( ) ;
let fragment_ubo = fragment_res . uniform_buffers . first ( ) ;
2022-10-26 13:13:39 +11:00
let ubo = self . reflect_ubos ( vertex_ubo , fragment_ubo ) ? ;
2022-11-01 11:29:25 +11:00
let vertex_push = vertex_res . push_constant_buffers . first ( ) ;
let fragment_push = fragment_res . push_constant_buffers . first ( ) ;
2022-10-26 13:13:39 +11:00
let push_constant = self . reflect_push_constant_buffer ( vertex_push , fragment_push ) ? ;
2022-10-24 14:22:26 +11:00
2022-12-01 17:50:16 +11:00
let mut meta = BindingMeta ::default ( ) ;
2022-10-26 16:19:04 +11:00
if let Some ( ubo ) = vertex_ubo {
2022-10-27 17:22:44 +11:00
Self ::reflect_buffer_range_metas (
& self . vertex ,
ubo ,
2022-11-07 16:25:11 +11:00
pass_number ,
semantics ,
2022-10-27 17:22:44 +11:00
& mut meta ,
2023-01-29 17:57:09 +11:00
UniformMemberBlock ::Ubo ,
2022-10-27 17:22:44 +11:00
SemanticErrorBlame ::Vertex ,
) ? ;
2022-10-26 16:19:04 +11:00
}
if let Some ( ubo ) = fragment_ubo {
2022-10-27 17:22:44 +11:00
Self ::reflect_buffer_range_metas (
& self . fragment ,
ubo ,
2022-11-07 16:25:11 +11:00
pass_number ,
semantics ,
2022-10-27 17:22:44 +11:00
& mut meta ,
2023-01-29 17:57:09 +11:00
UniformMemberBlock ::Ubo ,
2022-10-27 17:22:44 +11:00
SemanticErrorBlame ::Fragment ,
) ? ;
2022-10-26 16:19:04 +11:00
}
if let Some ( push ) = vertex_push {
2022-10-27 17:22:44 +11:00
Self ::reflect_buffer_range_metas (
& self . vertex ,
push ,
2022-11-07 16:25:11 +11:00
pass_number ,
semantics ,
2022-10-27 17:22:44 +11:00
& mut meta ,
2023-01-29 17:57:09 +11:00
UniformMemberBlock ::PushConstant ,
2022-10-27 17:22:44 +11:00
SemanticErrorBlame ::Vertex ,
) ? ;
2022-10-26 16:19:04 +11:00
}
if let Some ( push ) = fragment_push {
2022-10-27 17:22:44 +11:00
Self ::reflect_buffer_range_metas (
& self . fragment ,
push ,
2022-11-07 16:25:11 +11:00
pass_number ,
semantics ,
2022-10-27 17:22:44 +11:00
& mut meta ,
2023-01-29 17:57:09 +11:00
UniformMemberBlock ::PushConstant ,
2022-10-27 17:22:44 +11:00
SemanticErrorBlame ::Fragment ,
) ? ;
2022-10-26 16:19:04 +11:00
}
2022-10-27 17:22:44 +11:00
let mut ubo_bindings = 0 u16 ;
if vertex_ubo . is_some ( ) | | fragment_ubo . is_some ( ) {
ubo_bindings = 1 < < ubo . as_ref ( ) . expect ( " UBOs should be present " ) . binding ;
}
for sampled_image in & fragment_res . sampled_images {
let texture_data = self . reflect_texture ( sampled_image ) ? ;
if ubo_bindings & ( 1 < < texture_data . binding ) ! = 0 {
return Err ( ShaderReflectError ::BindingInUse ( texture_data . binding ) ) ;
}
2022-11-01 11:29:25 +11:00
ubo_bindings | = 1 < < texture_data . binding ;
2022-10-27 17:22:44 +11:00
2022-11-07 16:25:11 +11:00
self . reflect_texture_metas ( texture_data , pass_number , semantics , & mut meta ) ? ;
2022-10-27 17:22:44 +11:00
}
2022-10-26 13:13:39 +11:00
Ok ( ShaderReflection {
ubo ,
2022-10-26 16:19:04 +11:00
push_constant ,
2022-10-27 17:22:44 +11:00
meta ,
2022-10-26 13:13:39 +11:00
} )
2022-10-24 14:22:26 +11:00
}
}
2022-11-11 17:44:41 +11:00
impl CompileShader < GLSL > for CrossReflect < glsl ::Target > {
type Options = glsl ::Version ;
2022-12-01 17:50:16 +11:00
type Context = CrossGlslContext ;
2022-11-07 16:25:11 +11:00
2022-11-11 17:44:41 +11:00
fn compile (
2022-11-11 18:26:57 +11:00
mut self ,
2022-11-11 17:44:41 +11:00
version : Self ::Options ,
2022-11-11 18:26:57 +11:00
) -> Result < ShaderCompilerOutput < String , Self ::Context > , ShaderCompileError > {
2022-11-11 17:44:41 +11:00
let mut options : glsl ::CompilerOptions = Default ::default ( ) ;
options . version = version ;
options . fragment . default_float_precision = glsl ::Precision ::High ;
options . fragment . default_int_precision = glsl ::Precision ::High ;
2022-11-09 17:51:10 +11:00
options . enable_420_pack_extension = false ;
self . vertex . set_compiler_options ( & options ) ? ;
self . fragment . set_compiler_options ( & options ) ? ;
2022-11-07 16:25:11 +11:00
2022-11-09 17:11:25 +11:00
let vertex_resources = self . vertex . get_shader_resources ( ) ? ;
let fragment_resources = self . fragment . get_shader_resources ( ) ? ;
for res in & vertex_resources . stage_inputs {
self . vertex . unset_decoration ( res . id , Decoration ::Location ) ? ;
}
for res in & vertex_resources . stage_outputs {
2022-11-24 18:24:05 +11:00
// let location = self.vertex.get_decoration(res.id, Decoration::Location)?;
// self.vertex
// .set_name(res.id, &format!("LIBRA_VARYING_{location}"))?;
2022-11-09 17:11:25 +11:00
self . vertex . unset_decoration ( res . id , Decoration ::Location ) ? ;
}
for res in & fragment_resources . stage_inputs {
2022-11-24 18:24:05 +11:00
// let location = self.fragment.get_decoration(res.id, Decoration::Location)?;
// self.fragment
// .set_name(res.id, &format!("LIBRA_VARYING_{location}"))?;
2022-11-11 17:44:41 +11:00
self . fragment
. unset_decoration ( res . id , Decoration ::Location ) ? ;
2022-11-09 17:11:25 +11:00
}
if vertex_resources . push_constant_buffers . len ( ) > 1 {
2022-11-11 17:44:41 +11:00
return Err ( ShaderCompileError ::SpirvCrossCompileError (
ErrorCode ::CompilationError ( String ::from (
" Cannot have more than one push constant buffer " ,
) ) ,
) ) ;
2022-11-09 17:11:25 +11:00
}
for res in & vertex_resources . push_constant_buffers {
2022-11-20 10:48:54 +11:00
self . vertex . set_name ( res . id , " LIBRA_PUSH_VERTEX_INSTANCE " ) ? ;
2022-11-11 17:44:41 +11:00
self . vertex
2022-11-20 10:48:54 +11:00
. set_name ( res . base_type_id , " LIBRA_PUSH_VERTEX " ) ? ;
2022-11-09 17:11:25 +11:00
}
// todo: options
2022-11-22 08:21:50 +11:00
let _flatten = false ;
2022-11-09 17:11:25 +11:00
if vertex_resources . uniform_buffers . len ( ) > 1 {
2022-11-11 17:44:41 +11:00
return Err ( ShaderCompileError ::SpirvCrossCompileError (
ErrorCode ::CompilationError ( String ::from (
" Cannot have more than one uniform buffer " ,
) ) ,
) ) ;
2022-11-09 17:11:25 +11:00
}
for res in & vertex_resources . uniform_buffers {
2022-11-12 17:23:49 +11:00
// if flatten {
// self.vertex.flatten_buffer_block(res.id)?;
// }
2022-11-20 10:48:54 +11:00
self . vertex . set_name ( res . id , " LIBRA_UBO_VERTEX_INSTANCE " ) ? ;
self . vertex . set_name ( res . base_type_id , " LIBRA_UBO_VERTEX " ) ? ;
2022-11-11 17:44:41 +11:00
self . vertex
. unset_decoration ( res . id , Decoration ::DescriptorSet ) ? ;
2022-11-09 17:11:25 +11:00
self . vertex . unset_decoration ( res . id , Decoration ::Binding ) ? ;
}
if fragment_resources . push_constant_buffers . len ( ) > 1 {
2022-11-11 17:44:41 +11:00
return Err ( ShaderCompileError ::SpirvCrossCompileError (
ErrorCode ::CompilationError ( String ::from (
" Cannot have more than one push constant buffer " ,
) ) ,
) ) ;
2022-11-09 17:11:25 +11:00
}
for res in & fragment_resources . push_constant_buffers {
2022-11-11 17:44:41 +11:00
self . fragment
2022-11-20 10:48:54 +11:00
. set_name ( res . id , " LIBRA_PUSH_FRAGMENT_INSTANCE " ) ? ;
2022-11-11 17:44:41 +11:00
self . fragment
2022-11-20 10:48:54 +11:00
. set_name ( res . base_type_id , " LIBRA_PUSH_FRAGMENT " ) ? ;
2022-11-09 17:11:25 +11:00
}
if fragment_resources . uniform_buffers . len ( ) > 1 {
2022-11-11 17:44:41 +11:00
return Err ( ShaderCompileError ::SpirvCrossCompileError (
ErrorCode ::CompilationError ( String ::from (
" Cannot have more than one uniform buffer " ,
) ) ,
) ) ;
2022-11-09 17:11:25 +11:00
}
for res in & fragment_resources . uniform_buffers {
2022-11-12 17:23:49 +11:00
// if flatten {
// self.fragment.flatten_buffer_block(res.id)?;
// }
2022-11-11 17:44:41 +11:00
self . fragment
2022-11-20 10:48:54 +11:00
. set_name ( res . id , " LIBRA_UBO_FRAGMENT_INSTANCE " ) ? ;
2022-11-11 17:44:41 +11:00
self . fragment
2022-11-20 10:48:54 +11:00
. set_name ( res . base_type_id , " LIBRA_UBO_FRAGMENT " ) ? ;
2022-11-11 17:44:41 +11:00
self . fragment
. unset_decoration ( res . id , Decoration ::DescriptorSet ) ? ;
self . fragment
. unset_decoration ( res . id , Decoration ::Binding ) ? ;
2022-11-09 17:11:25 +11:00
}
let mut texture_fixups = Vec ::new ( ) ;
2022-11-24 18:08:58 +11:00
for res in fragment_resources . sampled_images {
2022-11-09 17:11:25 +11:00
let binding = self . fragment . get_decoration ( res . id , Decoration ::Binding ) ? ;
2022-11-11 17:44:41 +11:00
self . fragment
. unset_decoration ( res . id , Decoration ::DescriptorSet ) ? ;
self . fragment
. unset_decoration ( res . id , Decoration ::Binding ) ? ;
2022-11-24 18:08:58 +11:00
let mut name = res . name ;
name . push ( '\0' ) ;
texture_fixups . push ( ( name , binding ) ) ;
2022-11-09 17:11:25 +11:00
}
2022-11-11 17:53:02 +11:00
Ok ( ShaderCompilerOutput {
2022-11-07 16:25:11 +11:00
vertex : self . vertex . compile ( ) ? ,
2022-11-09 17:11:25 +11:00
fragment : self . fragment . compile ( ) ? ,
2022-12-01 17:50:16 +11:00
context : CrossGlslContext {
2022-11-20 14:03:58 +11:00
sampler_bindings : texture_fixups ,
2022-12-01 17:50:16 +11:00
artifact : CompiledProgram {
2022-11-28 15:47:41 +11:00
vertex : CompiledAst ( self . vertex ) ,
fragment : CompiledAst ( self . fragment ) ,
2022-11-22 08:21:50 +11:00
} ,
2022-11-11 18:26:57 +11:00
} ,
2022-11-07 16:25:11 +11:00
} )
}
}
2022-11-11 17:44:41 +11:00
impl CompileShader < HLSL > for CrossReflect < hlsl ::Target > {
2023-02-08 10:50:26 +11:00
type Options = Option < HlslShaderModel > ;
2022-12-01 17:50:16 +11:00
type Context = CrossHlslContext ;
2022-11-07 16:25:11 +11:00
2022-11-11 17:44:41 +11:00
fn compile (
2022-11-11 18:26:57 +11:00
mut self ,
2023-02-02 10:58:21 +11:00
options : Self ::Options ,
2022-12-01 17:50:16 +11:00
) -> Result < ShaderCompilerOutput < String , CrossHlslContext > , ShaderCompileError > {
2023-02-08 10:50:26 +11:00
let sm = options . unwrap_or ( HlslShaderModel ::V5_0 ) ;
2022-11-09 17:51:10 +11:00
let mut options = hlsl ::CompilerOptions ::default ( ) ;
2023-02-02 10:58:21 +11:00
options . shader_model = sm ;
2022-11-09 17:51:10 +11:00
self . vertex . set_compiler_options ( & options ) ? ;
self . fragment . set_compiler_options ( & options ) ? ;
2022-11-07 16:25:11 +11:00
2022-11-11 17:53:02 +11:00
Ok ( ShaderCompilerOutput {
2022-11-07 16:25:11 +11:00
vertex : self . vertex . compile ( ) ? ,
2022-11-09 17:11:25 +11:00
fragment : self . fragment . compile ( ) ? ,
2022-12-01 17:50:16 +11:00
context : CrossHlslContext {
2023-01-17 11:35:23 +11:00
artifact : CompiledProgram {
2022-11-28 15:47:41 +11:00
vertex : CompiledAst ( self . vertex ) ,
2022-11-30 17:38:05 +11:00
fragment : CompiledAst ( self . fragment ) ,
} ,
2022-11-24 17:37:16 +11:00
} ,
2022-11-07 16:25:11 +11:00
} )
}
}
2022-10-24 14:22:26 +11:00
#[ cfg(test) ]
mod test {
use crate ::reflect ::cross ::CrossReflect ;
2022-11-22 08:53:36 +11:00
use crate ::reflect ::ReflectShader ;
2022-11-11 17:44:41 +11:00
use rustc_hash ::FxHashMap ;
use crate ::back ::CompileShader ;
2024-02-11 09:47:05 +11:00
use crate ::front ::{ Glslang , ShaderInputCompiler , SpirvCompilation } ;
2022-12-22 13:39:31 +11:00
use crate ::reflect ::semantics ::{ Semantic , ShaderSemantics , UniformSemantic , UniqueSemantics } ;
2022-11-22 08:21:50 +11:00
use librashader_preprocess ::ShaderSource ;
use spirv_cross ::glsl ;
2022-11-11 17:44:41 +11:00
use spirv_cross ::glsl ::{ CompilerOptions , Version } ;
2022-10-24 14:22:26 +11:00
#[ test ]
pub fn test_into ( ) {
2022-11-22 08:21:50 +11:00
let result = ShaderSource ::load ( " ../test/basic.slang " ) . unwrap ( ) ;
2022-11-07 16:25:11 +11:00
let mut uniform_semantics : FxHashMap < String , UniformSemantic > = Default ::default ( ) ;
2022-11-11 17:44:41 +11:00
2022-11-22 08:21:50 +11:00
for ( _index , param ) in result . parameters . iter ( ) . enumerate ( ) {
2022-11-11 17:44:41 +11:00
uniform_semantics . insert (
2023-01-16 10:36:38 +11:00
param . 1. id . clone ( ) ,
2022-12-01 17:50:16 +11:00
UniformSemantic ::Unique ( Semantic {
semantics : UniqueSemantics ::FloatParameter ,
2022-11-13 18:05:49 +11:00
index : ( ) ,
2022-11-11 17:44:41 +11:00
} ) ,
) ;
2022-11-07 16:25:11 +11:00
}
2024-02-11 09:47:05 +11:00
let spirv = Glslang ::compile ( & result ) . unwrap ( ) ;
2023-02-06 11:48:24 +11:00
let mut reflect = CrossReflect ::< glsl ::Target > ::try_from ( & spirv ) . unwrap ( ) ;
2022-11-22 08:21:50 +11:00
let _shader_reflection = reflect
2022-11-11 17:44:41 +11:00
. reflect (
0 ,
2022-12-01 17:50:16 +11:00
& ShaderSemantics {
2022-11-11 17:44:41 +11:00
uniform_semantics ,
2022-11-28 15:11:21 +11:00
texture_semantics : Default ::default ( ) ,
2022-11-11 17:44:41 +11:00
} ,
)
2022-10-27 17:22:44 +11:00
. unwrap ( ) ;
2022-11-07 16:25:11 +11:00
let mut opts = CompilerOptions ::default ( ) ;
opts . version = Version ::V4_60 ;
opts . enable_420_pack_extension = false ;
2023-12-13 11:02:49 +11:00
// let compiled: ShaderCompilerOutput<String, CrossWgslContext> = <CrossReflect<glsl::Target> as CompileShader<WGSL>>::compile(reflect, Version::V3_30).unwrap();
// // eprintln!("{shader_reflection:#?}");
// eprintln!("{}", compiled.fragment)
2022-10-24 14:22:26 +11:00
// let mut loader = rspirv::dr::Loader::new();
// rspirv::binary::parse_words(spirv.fragment.as_binary(), &mut loader).unwrap();
// let module = loader.module();
// println!("{:#}", module.disassemble());
}
}