diff options
30 files changed, 1843 insertions, 84 deletions
@@ -1986,12 +1986,14 @@ extern "C" SLANG_API SlangReflectionType* spReflectionTypeLayout_GetType(SlangReflectionTypeLayout* type); SLANG_API size_t spReflectionTypeLayout_GetSize(SlangReflectionTypeLayout* type, SlangParameterCategory category); + SLANG_API int32_t spReflectionTypeLayout_getAlignment(SlangReflectionTypeLayout* type, SlangParameterCategory category); SLANG_API SlangReflectionVariableLayout* spReflectionTypeLayout_GetFieldByIndex(SlangReflectionTypeLayout* type, unsigned index); SLANG_API size_t spReflectionTypeLayout_GetElementStride(SlangReflectionTypeLayout* type, SlangParameterCategory category); SLANG_API SlangReflectionTypeLayout* spReflectionTypeLayout_GetElementTypeLayout(SlangReflectionTypeLayout* type); SLANG_API SlangReflectionVariableLayout* spReflectionTypeLayout_GetElementVarLayout(SlangReflectionTypeLayout* type); + SLANG_API SlangReflectionVariableLayout* spReflectionTypeLayout_getContainerVarLayout(SlangReflectionTypeLayout* type); SLANG_API SlangParameterCategory spReflectionTypeLayout_GetParameterCategory(SlangReflectionTypeLayout* type); @@ -2072,6 +2074,9 @@ extern "C" SLANG_API SlangReflectionVariableLayout* spReflectionEntryPoint_getVarLayout( SlangReflectionEntryPoint* entryPoint); + SLANG_API SlangReflectionVariableLayout* spReflectionEntryPoint_getResultVarLayout( + SlangReflectionEntryPoint* entryPoint); + SLANG_API int spReflectionEntryPoint_hasDefaultConstantBuffer( SlangReflectionEntryPoint* entryPoint); @@ -2346,6 +2351,11 @@ namespace slang return spReflectionTypeLayout_GetSize((SlangReflectionTypeLayout*) this, category); } + int32_t getAlignment(SlangParameterCategory category = SLANG_PARAMETER_CATEGORY_UNIFORM) + { + return spReflectionTypeLayout_getAlignment((SlangReflectionTypeLayout*) this, category); + } + unsigned int getFieldCount() { return getType()->getFieldCount(); @@ -2394,6 +2404,11 @@ namespace slang return (VariableLayoutReflection*)spReflectionTypeLayout_GetElementVarLayout((SlangReflectionTypeLayout*) this); } + VariableLayoutReflection* getContainerVarLayout() + { + return (VariableLayoutReflection*)spReflectionTypeLayout_getContainerVarLayout((SlangReflectionTypeLayout*) this); + } + // How is this type supposed to be bound? ParameterCategory getParameterCategory() { @@ -2636,6 +2651,11 @@ namespace slang return getVarLayout()->getTypeLayout(); } + VariableLayoutReflection* getResultVarLayout() + { + return (VariableLayoutReflection*) spReflectionEntryPoint_getResultVarLayout((SlangReflectionEntryPoint*) this); + } + bool hasDefaultConstantBuffer() { return spReflectionEntryPoint_hasDefaultConstantBuffer((SlangReflectionEntryPoint*) this) != 0; diff --git a/source/slang/slang-reflection.cpp b/source/slang/slang-reflection.cpp index 8901f6bdd..c0c5bd72f 100644 --- a/source/slang/slang-reflection.cpp +++ b/source/slang/slang-reflection.cpp @@ -357,9 +357,9 @@ SLANG_API SlangReflectionType* spReflectionType_GetElementType(SlangReflectionTy { return (SlangReflectionType*) arrayType->baseType.Ptr(); } - else if( auto constantBufferType = as<ConstantBufferType>(type)) + else if( auto parameterGroupType = as<ParameterGroupType>(type)) { - return convert(constantBufferType->elementType.Ptr()); + return convert(parameterGroupType->elementType.Ptr()); } else if( auto vectorType = as<VectorExpressionType>(type)) { @@ -680,6 +680,21 @@ SLANG_API size_t spReflectionTypeLayout_GetSize(SlangReflectionTypeLayout* inTyp return getReflectionSize(info->count); } +SLANG_API int32_t spReflectionTypeLayout_getAlignment(SlangReflectionTypeLayout* inTypeLayout, SlangParameterCategory category) +{ + auto typeLayout = convert(inTypeLayout); + if(!typeLayout) return 0; + + if( category == SLANG_PARAMETER_CATEGORY_UNIFORM ) + { + return int32_t(typeLayout->uniformAlignment); + } + else + { + return 1; + } +} + SLANG_API SlangReflectionVariableLayout* spReflectionTypeLayout_GetFieldByIndex(SlangReflectionTypeLayout* inTypeLayout, unsigned index) { auto typeLayout = convert(inTypeLayout); @@ -758,9 +773,22 @@ SLANG_API SlangReflectionVariableLayout* spReflectionTypeLayout_GetElementVarLay auto typeLayout = convert(inTypeLayout); if(!typeLayout) return nullptr; - if( auto constantBufferTypeLayout = as<ParameterGroupTypeLayout>(typeLayout)) + if( auto parameterGroupTypeLayout = as<ParameterGroupTypeLayout>(typeLayout)) { - return convert(constantBufferTypeLayout->elementVarLayout.Ptr()); + return convert(parameterGroupTypeLayout->elementVarLayout.Ptr()); + } + + return nullptr; +} + +SLANG_API SlangReflectionVariableLayout* spReflectionTypeLayout_getContainerVarLayout(SlangReflectionTypeLayout* inTypeLayout) +{ + auto typeLayout = convert(inTypeLayout); + if(!typeLayout) return nullptr; + + if( auto parameterGroupTypeLayout = as<ParameterGroupTypeLayout>(typeLayout)) + { + return convert(parameterGroupTypeLayout->containerVarLayout.Ptr()); } return nullptr; @@ -1300,6 +1328,17 @@ SLANG_API SlangReflectionVariableLayout* spReflectionEntryPoint_getVarLayout( return convert(entryPointLayout->parametersLayout); } +SLANG_API SlangReflectionVariableLayout* spReflectionEntryPoint_getResultVarLayout( + SlangReflectionEntryPoint* inEntryPoint) +{ + auto entryPointLayout = convert(inEntryPoint); + if(!entryPointLayout) + return nullptr; + + return convert(entryPointLayout->resultLayout); +} + + static bool hasDefaultConstantBuffer(ScopeLayout* layout) { auto typeLayout = layout->parametersLayout->getTypeLayout(); diff --git a/tests/cross-compile/cpp-resource-reflection.slang.32.expected b/tests/cross-compile/cpp-resource-reflection.slang.32.expected index 7f88c134e..f40cc0fcc 100644 --- a/tests/cross-compile/cpp-resource-reflection.slang.32.expected +++ b/tests/cross-compile/cpp-resource-reflection.slang.32.expected @@ -38,6 +38,42 @@ standard output = { "binding": {"kind": "uniform", "offset": 8, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "Thing", + "fields": [ + { + "name": "a", + "type": { + "kind": "scalar", + "scalarType": "int32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "b", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 4, "size": 4} + }, + { + "name": "c", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 8, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 12} } } }, diff --git a/tests/cross-compile/cpp-resource-reflection.slang.64.expected b/tests/cross-compile/cpp-resource-reflection.slang.64.expected index a0e5241f0..2a03aaa91 100644 --- a/tests/cross-compile/cpp-resource-reflection.slang.64.expected +++ b/tests/cross-compile/cpp-resource-reflection.slang.64.expected @@ -38,6 +38,42 @@ standard output = { "binding": {"kind": "uniform", "offset": 8, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "uniform", "offset": 0, "size": 8} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "Thing", + "fields": [ + { + "name": "a", + "type": { + "kind": "scalar", + "scalarType": "int32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "b", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 4, "size": 4} + }, + { + "name": "c", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 8, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 12} } } }, diff --git a/tests/reflection/arrays.hlsl.expected b/tests/reflection/arrays.hlsl.expected index f815ea88c..2152ed0df 100644 --- a/tests/reflection/arrays.hlsl.expected +++ b/tests/reflection/arrays.hlsl.expected @@ -42,6 +42,46 @@ standard output = { "binding": {"kind": "uniform", "offset": 164, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "x", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "a", + "type": { + "kind": "array", + "elementCount": 10, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + }, + "uniformStride": 16 + }, + "binding": {"kind": "uniform", "offset": 16, "size": 148} + }, + { + "name": "y", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 164, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 168} } } }, @@ -102,7 +142,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/attribute.slang.expected b/tests/reflection/attribute.slang.expected index 4348b898f..b15c87df8 100644 --- a/tests/reflection/attribute.slang.expected +++ b/tests/reflection/attribute.slang.expected @@ -45,6 +45,49 @@ standard output = { ] } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "A", + "fields": [ + { + "name": "x", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "y", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 4, "size": 4}, + "userAttribs": [{ + "name": "DefaultValue", + "arguments": [ + 1 + ] + } + ] + } + ], + "userAttribs": [{ + "name": "MyStruct", + "arguments": [ + 0, + 1.000000 + ] + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 8} } } }, @@ -89,6 +132,49 @@ standard output = { ] } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "B", + "fields": [ + { + "name": "x", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "z", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 4, "size": 4}, + "userAttribs": [{ + "name": "DefaultValue", + "arguments": [ + 2 + ] + } + ] + } + ], + "userAttribs": [{ + "name": "MyStruct", + "arguments": [ + 0, + 2.000000 + ] + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 8} } } } diff --git a/tests/reflection/binding-gl.hlsl.expected b/tests/reflection/binding-gl.hlsl.expected index 1b5e7354f..8c2e761b5 100644 --- a/tests/reflection/binding-gl.hlsl.expected +++ b/tests/reflection/binding-gl.hlsl.expected @@ -42,6 +42,46 @@ standard output = { "binding": {"kind": "uniform", "offset": 176, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "descriptorTableSlot", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "x", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "a", + "type": { + "kind": "array", + "elementCount": 10, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + }, + "uniformStride": 16 + }, + "binding": {"kind": "uniform", "offset": 16, "size": 160} + }, + { + "name": "y", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 176, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 192} } } }, @@ -98,7 +138,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/binding-push-constant-gl.hlsl.expected b/tests/reflection/binding-push-constant-gl.hlsl.expected index ed6983364..13dfe2fcd 100644 --- a/tests/reflection/binding-push-constant-gl.hlsl.expected +++ b/tests/reflection/binding-push-constant-gl.hlsl.expected @@ -42,6 +42,46 @@ standard output = { "binding": {"kind": "uniform", "offset": 176, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "descriptorTableSlot", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "x", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "a", + "type": { + "kind": "array", + "elementCount": 10, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + }, + "uniformStride": 16 + }, + "binding": {"kind": "uniform", "offset": 16, "size": 160} + }, + { + "name": "y", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 176, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 192} } } }, @@ -71,6 +111,34 @@ standard output = { "binding": {"kind": "uniform", "offset": 4, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "pushConstantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "MyPushConstantStruct", + "fields": [ + { + "name": "pushX", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "pushY", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 4, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 16} } } }, @@ -127,7 +195,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/buffer-layout.slang.1.expected b/tests/reflection/buffer-layout.slang.1.expected index 890f31481..0b01f54a1 100644 --- a/tests/reflection/buffer-layout.slang.1.expected +++ b/tests/reflection/buffer-layout.slang.1.expected @@ -81,6 +81,85 @@ standard output = { "binding": {"kind": "uniform", "offset": 80, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "descriptorTableSlot", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "S", + "fields": [ + { + "name": "z", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "a", + "type": { + "kind": "struct", + "name": "A", + "fields": [ + { + "name": "x", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "y", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 4, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 16, "size": 16} + }, + { + "name": "b", + "type": { + "kind": "scalar", + "scalarType": "int32" + }, + "binding": {"kind": "uniform", "offset": 32, "size": 4} + }, + { + "name": "c", + "type": { + "kind": "array", + "elementCount": 2, + "elementType": { + "kind": "vector", + "elementCount": 2, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "uniformStride": 16 + }, + "binding": {"kind": "uniform", "offset": 48, "size": 32} + }, + { + "name": "d", + "type": { + "kind": "scalar", + "scalarType": "int32" + }, + "binding": {"kind": "uniform", "offset": 80, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 96} } } }, diff --git a/tests/reflection/buffer-layout.slang.expected b/tests/reflection/buffer-layout.slang.expected index 25a41bc6d..4fc7b2381 100644 --- a/tests/reflection/buffer-layout.slang.expected +++ b/tests/reflection/buffer-layout.slang.expected @@ -81,6 +81,85 @@ standard output = { "binding": {"kind": "uniform", "offset": 56, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "S", + "fields": [ + { + "name": "z", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "a", + "type": { + "kind": "struct", + "name": "A", + "fields": [ + { + "name": "x", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + }, + { + "name": "y", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 4, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 16, "size": 8} + }, + { + "name": "b", + "type": { + "kind": "scalar", + "scalarType": "int32" + }, + "binding": {"kind": "uniform", "offset": 24, "size": 4} + }, + { + "name": "c", + "type": { + "kind": "array", + "elementCount": 2, + "elementType": { + "kind": "vector", + "elementCount": 2, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "uniformStride": 16 + }, + "binding": {"kind": "uniform", "offset": 32, "size": 24} + }, + { + "name": "d", + "type": { + "kind": "scalar", + "scalarType": "int32" + }, + "binding": {"kind": "uniform", "offset": 56, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 60} } } }, diff --git a/tests/reflection/cross-compile.slang.expected b/tests/reflection/cross-compile.slang.expected index a54598d08..e3dd63095 100644 --- a/tests/reflection/cross-compile.slang.expected +++ b/tests/reflection/cross-compile.slang.expected @@ -40,6 +40,29 @@ standard output = { "binding": {"kind": "uniform", "offset": 0, "size": 12} } ] + }, + "containerVarLayout": { + "binding": {"kind": "descriptorTableSlot", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "c", + "type": { + "kind": "vector", + "elementCount": 3, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 12} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 16} } } } @@ -47,7 +70,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/default-space.slang.expected b/tests/reflection/default-space.slang.expected index 548de2be0..5ba17790c 100644 --- a/tests/reflection/default-space.slang.expected +++ b/tests/reflection/default-space.slang.expected @@ -30,6 +30,26 @@ standard output = { "binding": {"kind": "shaderResource", "index": 0} } ] + }, + "containerVarLayout": { + "binding": {"kind": "registerSpace", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "B", + "fields": [ + { + "name": "b", + "type": { + "kind": "resource", + "baseShape": "texture2D" + }, + "binding": {"kind": "shaderResource", "index": 0} + } + ] + }, + "binding": {"kind": "shaderResource", "index": 0} } } } @@ -37,7 +57,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/explicit-register-space.slang.expected b/tests/reflection/explicit-register-space.slang.expected index c9e32c4f5..0c282f5f9 100644 --- a/tests/reflection/explicit-register-space.slang.expected +++ b/tests/reflection/explicit-register-space.slang.expected @@ -16,7 +16,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/global-type-params.slang.expected b/tests/reflection/global-type-params.slang.expected index 8f6ba2838..4fb7d0279 100644 --- a/tests/reflection/global-type-params.slang.expected +++ b/tests/reflection/global-type-params.slang.expected @@ -22,6 +22,26 @@ standard output = { "binding": {"kind": "generic", "index": 0} } ] + }, + "containerVarLayout": { + + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "S", + "fields": [ + { + "name": "p", + "type": { + "kind": "GenericTypeParameter", + "name": "TParam2" + }, + "binding": {"kind": "generic", "index": 0} + } + ] + }, + "binding": {"kind": "generic", "index": 0} } } }, @@ -33,6 +53,16 @@ standard output = { "elementType": { "kind": "GenericTypeParameter", "name": "TParam" + }, + "containerVarLayout": { + + }, + "elementVarLayout": { + "type": { + "kind": "GenericTypeParameter", + "name": "TParam" + }, + "binding": {"kind": "generic", "index": 0} } } }, @@ -96,6 +126,53 @@ standard output = { "binding": {"kind": "uniform", "offset": 32, "size": 16} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "u", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 16} + }, + { + "name": "v", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 16, "size": 16} + }, + { + "name": "w", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 32, "size": 16} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 48} } } } @@ -103,7 +180,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ], "typeParams": diff --git a/tests/reflection/matrix-layout.slang.1.expected b/tests/reflection/matrix-layout.slang.1.expected index 57fd29c6d..0683a6edc 100644 --- a/tests/reflection/matrix-layout.slang.1.expected +++ b/tests/reflection/matrix-layout.slang.1.expected @@ -52,6 +52,56 @@ standard output = { "binding": {"kind": "uniform", "offset": 96, "size": 60} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "aa", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 48} + }, + { + "name": "ab", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 48, "size": 48} + }, + { + "name": "ac", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 96, "size": 60} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 156} } } }, @@ -113,6 +163,66 @@ standard output = { "binding": {"kind": "uniform", "offset": 0, "size": 156} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "b", + "type": { + "kind": "struct", + "name": "SB", + "fields": [ + { + "name": "ba", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 48} + }, + { + "name": "bb", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 48, "size": 48} + }, + { + "name": "bc", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 96, "size": 60} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 156} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 156} } } } @@ -120,7 +230,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/matrix-layout.slang.expected b/tests/reflection/matrix-layout.slang.expected index c8aeb2ae1..c81207216 100644 --- a/tests/reflection/matrix-layout.slang.expected +++ b/tests/reflection/matrix-layout.slang.expected @@ -52,6 +52,56 @@ standard output = { "binding": {"kind": "uniform", "offset": 112, "size": 60} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "aa", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 60} + }, + { + "name": "ab", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 64, "size": 48} + }, + { + "name": "ac", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 112, "size": 60} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 172} } } }, @@ -113,6 +163,66 @@ standard output = { "binding": {"kind": "uniform", "offset": 0, "size": 172} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "b", + "type": { + "kind": "struct", + "name": "SB", + "fields": [ + { + "name": "ba", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 60} + }, + { + "name": "bb", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 64, "size": 48} + }, + { + "name": "bc", + "type": { + "kind": "matrix", + "rowCount": 3, + "columnCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 112, "size": 60} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 172} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 172} } } } @@ -120,7 +230,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/multi-file.hlsl.expected b/tests/reflection/multi-file.hlsl.expected index 814c648e0..1cbc73f5c 100644 --- a/tests/reflection/multi-file.hlsl.expected +++ b/tests/reflection/multi-file.hlsl.expected @@ -72,6 +72,61 @@ standard output = { "binding": {"kind": "uniform", "offset": 32, "size": 8} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "vertexCA", + "type": { + "kind": "vector", + "elementCount": 3, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 12} + }, + { + "name": "vertexCB", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 12, "size": 4} + }, + { + "name": "vertexCC", + "type": { + "kind": "vector", + "elementCount": 3, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 16, "size": 12} + }, + { + "name": "vertexCD", + "type": { + "kind": "vector", + "elementCount": 2, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 32, "size": 8} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 40} } } }, @@ -143,6 +198,61 @@ standard output = { "binding": {"kind": "uniform", "offset": 32, "size": 8} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "fragmentCA", + "type": { + "kind": "vector", + "elementCount": 3, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 12} + }, + { + "name": "fragmentCB", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 12, "size": 4} + }, + { + "name": "fragmentCC", + "type": { + "kind": "vector", + "elementCount": 3, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 16, "size": 12} + }, + { + "name": "fragmentCD", + "type": { + "kind": "vector", + "elementCount": 2, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 32, "size": 8} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 40} } } }, @@ -214,6 +324,61 @@ standard output = { "binding": {"kind": "uniform", "offset": 32, "size": 8} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "sharedCA", + "type": { + "kind": "vector", + "elementCount": 3, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 12} + }, + { + "name": "sharedCB", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 12, "size": 4} + }, + { + "name": "sharedCC", + "type": { + "kind": "vector", + "elementCount": 3, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 16, "size": 12} + }, + { + "name": "sharedCD", + "type": { + "kind": "vector", + "elementCount": 2, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 32, "size": 8} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 40} } } }, @@ -237,11 +402,35 @@ standard output = { "entryPoints": [ { "name": "mainVS", - "stage:": "vertex" + "stage:": "vertex", + "result:": { + "semanticName": "SV_POSITION", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } }, { "name": "mainFS", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/parameter-block-explicit-space.slang.expected b/tests/reflection/parameter-block-explicit-space.slang.expected index f7944c644..a96f95961 100644 --- a/tests/reflection/parameter-block-explicit-space.slang.expected +++ b/tests/reflection/parameter-block-explicit-space.slang.expected @@ -52,6 +52,60 @@ standard output = { "binding": {"kind": "samplerState", "index": 0} } ] + }, + "containerVarLayout": { + "bindings": [ + {"kind": "constantBuffer", "index": 0}, + {"kind": "registerSpace", "index": 0} + ] + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "A", + "fields": [ + { + "name": "au", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 16} + }, + { + "name": "at1", + "type": { + "kind": "resource", + "baseShape": "texture2D" + }, + "binding": {"kind": "shaderResource", "index": 0} + }, + { + "name": "at2", + "type": { + "kind": "resource", + "baseShape": "texture2D" + }, + "binding": {"kind": "shaderResource", "index": 1} + }, + { + "name": "as", + "type": { + "kind": "samplerState" + }, + "binding": {"kind": "samplerState", "index": 0} + } + ] + }, + "bindings": [ + {"kind": "shaderResource", "index": 0, "count": 2}, + {"kind": "samplerState", "index": 0}, + {"kind": "uniform", "offset": 0, "size": 16} + ] } } }, @@ -95,6 +149,52 @@ standard output = { "binding": {"kind": "samplerState", "index": 0} } ] + }, + "containerVarLayout": { + "bindings": [ + {"kind": "constantBuffer", "index": 0}, + {"kind": "registerSpace", "index": 0} + ] + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "B", + "fields": [ + { + "name": "bu", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 16} + }, + { + "name": "bt", + "type": { + "kind": "resource", + "baseShape": "texture2D" + }, + "binding": {"kind": "shaderResource", "index": 0} + }, + { + "name": "bs", + "type": { + "kind": "samplerState" + }, + "binding": {"kind": "samplerState", "index": 0} + } + ] + }, + "bindings": [ + {"kind": "shaderResource", "index": 0}, + {"kind": "samplerState", "index": 0}, + {"kind": "uniform", "offset": 0, "size": 16} + ] } } } @@ -102,7 +202,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/parameter-block.slang.1.expected b/tests/reflection/parameter-block.slang.1.expected index bbd52a784..b8f462e60 100644 --- a/tests/reflection/parameter-block.slang.1.expected +++ b/tests/reflection/parameter-block.slang.1.expected @@ -32,6 +32,36 @@ standard output = { "binding": {"kind": "samplerState", "index": 0} } ] + }, + "containerVarLayout": { + + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "Helper", + "fields": [ + { + "name": "t", + "type": { + "kind": "resource", + "baseShape": "texture2D" + }, + "binding": {"kind": "shaderResource", "index": 0} + }, + { + "name": "s", + "type": { + "kind": "samplerState" + }, + "binding": {"kind": "samplerState", "index": 0} + } + ] + }, + "bindings": [ + {"kind": "shaderResource", "index": 0}, + {"kind": "samplerState", "index": 0} + ] } } }, @@ -47,7 +77,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/parameter-block.slang.2.expected b/tests/reflection/parameter-block.slang.2.expected index e692718e8..e4bf9b6cb 100644 --- a/tests/reflection/parameter-block.slang.2.expected +++ b/tests/reflection/parameter-block.slang.2.expected @@ -29,6 +29,36 @@ standard output = { "binding": {"kind": "samplerState", "index": 0} } ] + }, + "containerVarLayout": { + "binding": {"kind": "registerSpace", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "Helper", + "fields": [ + { + "name": "t", + "type": { + "kind": "resource", + "baseShape": "texture2D" + }, + "binding": {"kind": "shaderResource", "index": 0} + }, + { + "name": "s", + "type": { + "kind": "samplerState" + }, + "binding": {"kind": "samplerState", "index": 0} + } + ] + }, + "bindings": [ + {"kind": "shaderResource", "index": 0}, + {"kind": "samplerState", "index": 0} + ] } } }, @@ -44,7 +74,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/parameter-block.slang.expected b/tests/reflection/parameter-block.slang.expected index 58344bc12..0909dc8cf 100644 --- a/tests/reflection/parameter-block.slang.expected +++ b/tests/reflection/parameter-block.slang.expected @@ -29,6 +29,33 @@ standard output = { "binding": {"kind": "descriptorTableSlot", "index": 1} } ] + }, + "containerVarLayout": { + "binding": {"kind": "registerSpace", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "name": "Helper", + "fields": [ + { + "name": "t", + "type": { + "kind": "resource", + "baseShape": "texture2D" + }, + "binding": {"kind": "descriptorTableSlot", "index": 0} + }, + { + "name": "s", + "type": { + "kind": "samplerState" + }, + "binding": {"kind": "descriptorTableSlot", "index": 1} + } + ] + }, + "binding": {"kind": "descriptorTableSlot", "index": 0, "count": 2} } } }, @@ -44,7 +71,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/reflect-imported-code.hlsl.expected b/tests/reflection/reflect-imported-code.hlsl.expected index 78e7ce195..5d51ddb5c 100644 --- a/tests/reflection/reflect-imported-code.hlsl.expected +++ b/tests/reflection/reflect-imported-code.hlsl.expected @@ -36,6 +36,25 @@ standard output = { "binding": {"kind": "uniform", "offset": 0, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "c", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} } } }, @@ -71,6 +90,25 @@ standard output = { "binding": {"kind": "uniform", "offset": 0, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "c_i", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} } } } @@ -78,7 +116,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/reflection0.hlsl.expected b/tests/reflection/reflection0.hlsl.expected index e4d6070ca..64b8fcd85 100644 --- a/tests/reflection/reflection0.hlsl.expected +++ b/tests/reflection/reflection0.hlsl.expected @@ -36,6 +36,25 @@ standard output = { "binding": {"kind": "uniform", "offset": 0, "size": 4} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "c", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} + } + ] + }, + "binding": {"kind": "uniform", "offset": 0, "size": 4} } } } @@ -43,7 +62,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/resource-in-cbuffer.hlsl.expected b/tests/reflection/resource-in-cbuffer.hlsl.expected index d14fbe577..03299a8e0 100644 --- a/tests/reflection/resource-in-cbuffer.hlsl.expected +++ b/tests/reflection/resource-in-cbuffer.hlsl.expected @@ -48,6 +48,56 @@ standard output = { "binding": {"kind": "samplerState", "index": 0} } ] + }, + "containerVarLayout": { + "binding": {"kind": "constantBuffer", "index": 0} + }, + "elementVarLayout": { + "type": { + "kind": "struct", + "fields": [ + { + "name": "v", + "type": { + "kind": "vector", + "elementCount": 3, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + }, + "binding": {"kind": "uniform", "offset": 0, "size": 12} + }, + { + "name": "myTexture", + "type": { + "kind": "resource", + "baseShape": "texture2D" + }, + "binding": {"kind": "shaderResource", "index": 0} + }, + { + "name": "c", + "type": { + "kind": "scalar", + "scalarType": "float32" + }, + "binding": {"kind": "uniform", "offset": 12, "size": 4} + }, + { + "name": "mySampler", + "type": { + "kind": "samplerState" + }, + "binding": {"kind": "samplerState", "index": 0} + } + ] + }, + "bindings": [ + {"kind": "shaderResource", "index": 0}, + {"kind": "samplerState", "index": 0}, + {"kind": "uniform", "offset": 0, "size": 16} + ] } } } @@ -55,7 +105,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/sample-index-input.hlsl.expected b/tests/reflection/sample-index-input.hlsl.expected index 5bf5f297e..d0bc3c1b9 100644 --- a/tests/reflection/sample-index-input.hlsl.expected +++ b/tests/reflection/sample-index-input.hlsl.expected @@ -45,7 +45,20 @@ standard output = { } } ], - "usesAnySampleRateInput": true + "usesAnySampleRateInput": true, + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/sample-rate-input.hlsl.expected b/tests/reflection/sample-rate-input.hlsl.expected index 0c86ebecb..485594fae 100644 --- a/tests/reflection/sample-rate-input.hlsl.expected +++ b/tests/reflection/sample-rate-input.hlsl.expected @@ -51,7 +51,20 @@ standard output = { } } ], - "usesAnySampleRateInput": true + "usesAnySampleRateInput": true, + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/shared-modifier.hlsl.expected b/tests/reflection/shared-modifier.hlsl.expected index ddb982177..782e038de 100644 --- a/tests/reflection/shared-modifier.hlsl.expected +++ b/tests/reflection/shared-modifier.hlsl.expected @@ -40,7 +40,20 @@ standard output = { } } } - ] + ], + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/structured-buffer.slang.expected b/tests/reflection/structured-buffer.slang.expected index 3e79fd1c5..d0cb3e501 100644 --- a/tests/reflection/structured-buffer.slang.expected +++ b/tests/reflection/structured-buffer.slang.expected @@ -78,7 +78,20 @@ standard output = { "entryPoints": [ { "name": "main", - "stage:": "fragment" + "stage:": "fragment", + "result:": { + "stage": "fragment", + "binding": {"kind": "varyingOutput", "index": 0}, + "semanticName": "SV_TARGET", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tests/reflection/vertex-input-semantics.hlsl.expected b/tests/reflection/vertex-input-semantics.hlsl.expected index 06b7bc95a..e15a3a258 100644 --- a/tests/reflection/vertex-input-semantics.hlsl.expected +++ b/tests/reflection/vertex-input-semantics.hlsl.expected @@ -160,7 +160,18 @@ standard output = { ] } } - ] + ], + "result:": { + "semanticName": "SV_POSITION", + "type": { + "kind": "vector", + "elementCount": 4, + "elementType": { + "kind": "scalar", + "scalarType": "float32" + } + } + } } ] } diff --git a/tools/slang-reflection-test/slang-reflection-test-main.cpp b/tools/slang-reflection-test/slang-reflection-test-main.cpp index 7480b6ae9..6537362d7 100644 --- a/tools/slang-reflection-test/slang-reflection-test-main.cpp +++ b/tools/slang-reflection-test/slang-reflection-test-main.cpp @@ -12,8 +12,14 @@ struct PrettyWriter { + struct CommaState + { + bool needComma = false; + }; + bool startOfLine = true; int indent = 0; + CommaState* commaState = nullptr; }; static void writeRaw(PrettyWriter& writer, char const* begin, char const* end) @@ -154,6 +160,44 @@ static void write(PrettyWriter& writer, float val) Slang::StdWriters::getOut().print("%f", val); } + /// Type for tracking whether a comma is needed in a comma-separated JSON list +struct CommaTrackerRAII +{ + CommaTrackerRAII(PrettyWriter& writer) + : m_writer(&writer) + , m_previousState(writer.commaState) + { + writer.commaState = &m_state; + } + + ~CommaTrackerRAII() + { + m_writer->commaState = m_previousState; + } + +private: + PrettyWriter::CommaState m_state; + + PrettyWriter* m_writer; + PrettyWriter::CommaState* m_previousState; +}; + + /// Call before items in a comma-separated JSON list to emit the comma if/when needed +static void comma(PrettyWriter& writer) +{ + if( auto state = writer.commaState ) + { + if( !state->needComma ) + { + state->needComma = true; + return; + } + } + + write(writer, ",\n"); +} + + static void emitReflectionVarInfoJSON(PrettyWriter& writer, slang::VariableReflection* var); static void emitReflectionTypeLayoutJSON(PrettyWriter& writer, slang::TypeLayoutReflection* type); static void emitReflectionTypeJSON(PrettyWriter& writer, slang::TypeReflection* type); @@ -234,7 +278,7 @@ static void emitReflectionVarBindingInfoJSON( auto stage = var->getStage(); if (stage != SLANG_STAGE_NONE) { - write(writer, ",\n"); + comma(writer); char const* stageName = "UNKNOWN"; switch (stage) { @@ -259,7 +303,7 @@ static void emitReflectionVarBindingInfoJSON( if (categoryCount) { - write(writer, ",\n"); + comma(writer); if( categoryCount != 1 ) { write(writer,"\"bindings\": [\n"); @@ -298,14 +342,14 @@ static void emitReflectionVarBindingInfoJSON( if (auto semanticName = var->getSemanticName()) { - write(writer, ",\n"); + comma(writer); write(writer,"\"semanticName\": \""); write(writer, semanticName); write(writer, "\""); if (auto semanticIndex = var->getSemanticIndex()) { - write(writer, ",\n"); + comma(writer); write(writer,"\"semanticIndex\": "); write(writer, int(semanticIndex)); } @@ -328,7 +372,8 @@ static void emitReflectionModifierInfoJSON( { if( var->findModifier(slang::Modifier::Shared) ) { - write(writer, ",\n\"shared\": true"); + comma(writer); + write(writer, "\"shared\": true"); } } @@ -409,9 +454,15 @@ static void emitReflectionVarLayoutJSON( write(writer, "{\n"); indent(writer); - emitReflectionNameInfoJSON(writer, var->getName()); - write(writer, ",\n"); + CommaTrackerRAII commaTracker(writer); + if( auto name = var->getName() ) + { + comma(writer); + emitReflectionNameInfoJSON(writer, name); + } + + comma(writer); write(writer, "\"type\": "); emitReflectionTypeLayoutJSON(writer, var->getTypeLayout()); @@ -456,8 +507,9 @@ static void emitReflectionResourceTypeBaseInfoJSON( { auto shape = type->getResourceShape(); auto access = type->getResourceAccess(); + comma(writer); write(writer, "\"kind\": \"resource\""); - write(writer, ",\n"); + comma(writer); write(writer, "\"baseShape\": \""); switch (shape & SLANG_RESOURCE_BASE_SHAPE_MASK) { @@ -479,18 +531,19 @@ static void emitReflectionResourceTypeBaseInfoJSON( write(writer, "\""); if (shape & SLANG_TEXTURE_ARRAY_FLAG) { - write(writer, ",\n"); + comma(writer); write(writer, "\"array\": true"); } if (shape & SLANG_TEXTURE_MULTISAMPLE_FLAG) { - write(writer, ",\n"); + comma(writer); write(writer, "\"multisample\": true"); } if( access != SLANG_RESOURCE_ACCESS_READ ) { - write(writer, ",\n\"access\": \""); + comma(writer); + write(writer, "\"access\": \""); switch(access) { default: @@ -519,6 +572,7 @@ static void emitReflectionTypeInfoJSON( switch(kind) { case slang::TypeReflection::Kind::SamplerState: + comma(writer); write(writer, "\"kind\": \"samplerState\""); break; @@ -539,7 +593,7 @@ static void emitReflectionTypeInfoJSON( case SLANG_STRUCTURED_BUFFER: if( auto resultType = type->getResourceResultType() ) { - write(writer, ",\n"); + comma(writer); write(writer, "\"resultType\": "); emitReflectionTypeJSON( writer, @@ -551,8 +605,9 @@ static void emitReflectionTypeInfoJSON( break; case slang::TypeReflection::Kind::ConstantBuffer: + comma(writer); write(writer, "\"kind\": \"constantBuffer\""); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeJSON( writer, @@ -560,8 +615,9 @@ static void emitReflectionTypeInfoJSON( break; case slang::TypeReflection::Kind::ParameterBlock: + comma(writer); write(writer, "\"kind\": \"parameterBlock\""); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeJSON( writer, @@ -569,8 +625,9 @@ static void emitReflectionTypeInfoJSON( break; case slang::TypeReflection::Kind::TextureBuffer: + comma(writer); write(writer, "\"kind\": \"textureBuffer\""); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeJSON( writer, @@ -578,8 +635,9 @@ static void emitReflectionTypeInfoJSON( break; case slang::TypeReflection::Kind::ShaderStorageBuffer: + comma(writer); write(writer, "\"kind\": \"shaderStorageBuffer\""); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeJSON( writer, @@ -587,19 +645,21 @@ static void emitReflectionTypeInfoJSON( break; case slang::TypeReflection::Kind::Scalar: + comma(writer); write(writer, "\"kind\": \"scalar\""); - write(writer, ",\n"); + comma(writer); emitReflectionScalarTypeInfoJSON( writer, type->getScalarType()); break; case slang::TypeReflection::Kind::Vector: + comma(writer); write(writer, "\"kind\": \"vector\""); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementCount\": "); write(writer, int(type->getElementCount())); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeJSON( writer, @@ -607,14 +667,15 @@ static void emitReflectionTypeInfoJSON( break; case slang::TypeReflection::Kind::Matrix: + comma(writer); write(writer, "\"kind\": \"matrix\""); - write(writer, ",\n"); + comma(writer); write(writer, "\"rowCount\": "); write(writer, type->getRowCount()); - write(writer, ",\n"); + comma(writer); write(writer, "\"columnCount\": "); write(writer, type->getColumnCount()); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeJSON( writer, @@ -624,11 +685,12 @@ static void emitReflectionTypeInfoJSON( case slang::TypeReflection::Kind::Array: { auto arrayType = type; + comma(writer); write(writer, "\"kind\": \"array\""); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementCount\": "); write(writer, int(arrayType->getElementCount())); - write(writer, ",\n"); + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeJSON(writer, arrayType->getElementType()); } @@ -636,7 +698,9 @@ static void emitReflectionTypeInfoJSON( case slang::TypeReflection::Kind::Struct: { - write(writer, "\"kind\": \"struct\",\n"); + comma(writer); + write(writer, "\"kind\": \"struct\""); + comma(writer); write(writer, "\"fields\": [\n"); indent(writer); @@ -655,11 +719,15 @@ static void emitReflectionTypeInfoJSON( break; case slang::TypeReflection::Kind::GenericTypeParameter: - write(writer, "\"kind\": \"GenericTypeParameter\",\n"); + comma(writer); + write(writer, "\"kind\": \"GenericTypeParameter\""); + comma(writer); emitReflectionNameInfoJSON(writer, type->getName()); break; case slang::TypeReflection::Kind::Interface: - write(writer, "\"kind\": \"Interface\",\n"); + comma(writer); + write(writer, "\"kind\": \"Interface\""); + comma(writer); emitReflectionNameInfoJSON(writer, type->getName()); break; default: @@ -669,6 +737,66 @@ static void emitReflectionTypeInfoJSON( emitUserAttributes(writer, type); } +static void emitReflectionParameterGroupTypeLayoutInfoJSON( + PrettyWriter& writer, + slang::TypeLayoutReflection* typeLayout, + const char* kind) +{ + write(writer, "\"kind\": \""); + write(writer, kind); + write(writer, "\""); + + write(writer, ",\n\"elementType\": "); + emitReflectionTypeLayoutJSON( + writer, + typeLayout->getElementTypeLayout()); + + // Note: There is a subtle detail below when it comes to the + // container/element variable layouts that get nested inside + // a parameter group type layout. + // + // A top-level parameter group type layout like `ConstantBuffer<Foo>` + // needs to store both information about the `ConstantBuffer` part of + // things (e.g., it might consume 1 `binding`), as well as the `Foo` + // part (e.g., it might consume 4 bytes plus 1 `binding`), and there + // is offset information for each. + // + // The "element" part is easy: it is a variable layout for a variable + // of type `Foo`. The actual variable will be null, but everything else + // will be filled in as a client would expect. + // + // The "container" part is thornier: what should the type and type + // layout of the "container" variable be? The obvious answer (which + // the Slang reflection implementation uses today) is that the type + // is the type of the parameter group itself (e.g., `ConstantBuffer<Foo>`), + // and the layout is a dummy `TypeLayout` that just reflects the + // resource usage of the "container" part of things. + // + // That means that at runtime the "container var layout" will have + // a parameter group type (e.g., `TYPE_KIND_CONSTANT_BUFFER`) + // but its type layotu will be a base `TypeLayout` and not a + // `ParameterGroupLayout` (since that would introduce infinite regress). + // + // We thus have to guard here against the recursive path where + // we are emitting reflection info for the "container" part of things. + // + // TODO: We should probably + + { + CommaTrackerRAII commaTracker(writer); + + write(writer, ",\n\"containerVarLayout\": {\n"); + indent(writer); + emitReflectionVarBindingInfoJSON(writer, typeLayout->getContainerVarLayout()); + dedent(writer); + write(writer, "\n}"); + } + + write(writer, ",\n\"elementVarLayout\": "); + emitReflectionVarLayoutJSON( + writer, + typeLayout->getElementVarLayout()); +} static void emitReflectionTypeLayoutInfoJSON( PrettyWriter& writer, @@ -684,18 +812,22 @@ static void emitReflectionTypeLayoutInfoJSON( { auto arrayTypeLayout = typeLayout; auto elementTypeLayout = arrayTypeLayout->getElementTypeLayout(); + comma(writer); write(writer, "\"kind\": \"array\""); - write(writer, ",\n"); + + comma(writer); write(writer, "\"elementCount\": "); write(writer, int(arrayTypeLayout->getElementCount())); - write(writer, ",\n"); + + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeLayoutJSON( writer, elementTypeLayout); + if (arrayTypeLayout->getSize(SLANG_PARAMETER_CATEGORY_UNIFORM) != 0) { - write(writer, ",\n"); + comma(writer); write(writer, "\"uniformStride\": "); write(writer, int(arrayTypeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM))); } @@ -706,12 +838,14 @@ static void emitReflectionTypeLayoutInfoJSON( { auto structTypeLayout = typeLayout; - write(writer, "\"kind\": \"struct\",\n"); + comma(writer); + write(writer, "\"kind\": \"struct\""); if( auto name = structTypeLayout->getName() ) { + comma(writer); emitReflectionNameInfoJSON(writer, structTypeLayout->getName()); - write(writer, ",\n"); } + comma(writer); write(writer, "\"fields\": [\n"); indent(writer); @@ -731,48 +865,39 @@ static void emitReflectionTypeLayoutInfoJSON( break; case slang::TypeReflection::Kind::ConstantBuffer: - write(writer, "\"kind\": \"constantBuffer\""); - write(writer, ",\n"); - write(writer, "\"elementType\": "); - emitReflectionTypeLayoutJSON( - writer, - typeLayout->getElementTypeLayout()); + emitReflectionParameterGroupTypeLayoutInfoJSON(writer, typeLayout, "constantBuffer"); break; case slang::TypeReflection::Kind::ParameterBlock: - write(writer, "\"kind\": \"parameterBlock\""); - write(writer, ",\n"); - write(writer, "\"elementType\": "); - emitReflectionTypeLayoutJSON( - writer, - typeLayout->getElementTypeLayout()); + emitReflectionParameterGroupTypeLayoutInfoJSON(writer, typeLayout, "parameterBlock"); break; case slang::TypeReflection::Kind::TextureBuffer: - write(writer, "\"kind\": \"textureBuffer\""); - write(writer, ",\n"); - write(writer, "\"elementType\": "); - emitReflectionTypeLayoutJSON( - writer, - typeLayout->getElementTypeLayout()); + emitReflectionParameterGroupTypeLayoutInfoJSON(writer, typeLayout, "textureBuffer"); break; case slang::TypeReflection::Kind::ShaderStorageBuffer: + comma(writer); write(writer, "\"kind\": \"shaderStorageBuffer\""); - write(writer, ",\n"); + + comma(writer); write(writer, "\"elementType\": "); emitReflectionTypeLayoutJSON( writer, typeLayout->getElementTypeLayout()); break; case slang::TypeReflection::Kind::GenericTypeParameter: + comma(writer); write(writer, "\"kind\": \"GenericTypeParameter\""); - write(writer, ",\n"); + + comma(writer); emitReflectionNameInfoJSON(writer, typeLayout->getName()); break; case slang::TypeReflection::Kind::Interface: - write(writer, "\"kind\": \"Interface\",\n"); - write(writer, ",\n"); + comma(writer); + write(writer, "\"kind\": \"Interface\""); + + comma(writer); emitReflectionNameInfoJSON(writer, typeLayout->getName()); break; @@ -792,7 +917,7 @@ static void emitReflectionTypeLayoutInfoJSON( if( auto resultTypeLayout = typeLayout->getElementTypeLayout() ) { - write(writer, ",\n"); + comma(writer); write(writer, "\"resultType\": "); emitReflectionTypeLayoutJSON( writer, @@ -812,6 +937,7 @@ static void emitReflectionTypeLayoutJSON( PrettyWriter& writer, slang::TypeLayoutReflection* typeLayout) { + CommaTrackerRAII commaTracker(writer); write(writer, "{\n"); indent(writer); emitReflectionTypeLayoutInfoJSON(writer, typeLayout); @@ -823,6 +949,7 @@ static void emitReflectionTypeJSON( PrettyWriter& writer, slang::TypeReflection* type) { + CommaTrackerRAII commaTracker(writer); write(writer, "{\n"); indent(writer); emitReflectionTypeInfoJSON(writer, type); @@ -847,16 +974,25 @@ static void emitReflectionParamJSON( PrettyWriter& writer, slang::VariableLayoutReflection* param) { + // TODO: This function is likely redundant with `emitReflectionVarLayoutJSON` + // and we should try to collapse them into one. + write(writer, "{\n"); indent(writer); - emitReflectionNameInfoJSON(writer, param->getName()); + CommaTrackerRAII commaTracker(writer); + + if( auto name = param->getName() ) + { + comma(writer); + emitReflectionNameInfoJSON(writer, name); + } emitReflectionModifierInfoJSON(writer, param->getVariable()); emitReflectionVarBindingInfoJSON(writer, param); - write(writer, ",\n"); + comma(writer); write(writer, "\"type\": "); emitReflectionTypeLayoutJSON(writer, param->getTypeLayout()); @@ -931,6 +1067,7 @@ static void emitReflectionTypeParamJSON( if (ee != 0) write(writer, ",\n"); write(writer, "{\n"); indent(writer); + CommaTrackerRAII commaTracker(writer); emitReflectionTypeInfoJSON(writer, typeParam->getConstraintByIndex(ee)); dedent(writer); write(writer, "\n}"); @@ -983,6 +1120,11 @@ static void emitReflectionEntryPointJSON( { write(writer, ",\n\"usesAnySampleRateInput\": true"); } + if( auto resultVarLayout = entryPoint->getResultVarLayout() ) + { + write(writer, ",\n\"result:\": "); + emitReflectionParamJSON(writer, resultVarLayout); + } if (entryPoint->getStage() == SLANG_STAGE_COMPUTE) { |
