diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2024-02-03 10:14:04 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-02 18:14:04 -0800 |
| commit | a67cb0609587c230746b52567ff5775cab215220 (patch) | |
| tree | af943e2926c7279fb825ead81d74e4fe0f55795d | |
| parent | 6c8626c171a0bc40e8f2d3a15b0563d4085431c1 (diff) | |
GLSL Passthrough support for SSBO types (#3446)
* GLSL Passthrough support for SSBO types
* GLSL Passthrough support for SSBO types
* Correctly apply glsl local size layout to entry points during lowering
* Test for glsl layout correctness
* typo
* Reflect GLSL SSBO as raw buffers
* Functional test for glsl ssbo
* Allow allow glsl for render tests
* Functional test for ssbo passthrough
* Functional test for ssbo passthrough with spirv-direct
* fix windows build error
---------
Co-authored-by: Yong He <yonghe@outlook.com>
| -rw-r--r-- | source/slang/slang-ast-type.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 59 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-layout.cpp | 17 | ||||
| -rw-r--r-- | source/slang/slang-ir-layout.h | 8 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-glsl-ssbo-types.cpp | 22 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-glsl-ssbo-types.h | 11 | ||||
| -rw-r--r-- | source/slang/slang-ir-spirv-legalize.cpp | 18 | ||||
| -rw-r--r-- | source/slang/slang-reflection-api.cpp | 16 | ||||
| -rw-r--r-- | source/slang/slang-type-layout.cpp | 2 | ||||
| -rw-r--r-- | tests/glsl/compute-shader-layout.slang | 11 | ||||
| -rw-r--r-- | tests/glsl/ssbo-2.slang | 27 | ||||
| -rw-r--r-- | tests/glsl/ssbo-3.slang | 26 | ||||
| -rw-r--r-- | tests/glsl/ssbo.slang | 25 | ||||
| -rw-r--r-- | tools/render-test/options.cpp | 8 | ||||
| -rw-r--r-- | tools/render-test/options.h | 4 | ||||
| -rw-r--r-- | tools/render-test/slang-support.cpp | 2 |
19 files changed, 215 insertions, 50 deletions
diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h index 713446e93..1d2ebc566 100644 --- a/source/slang/slang-ast-type.h +++ b/source/slang/slang-ast-type.h @@ -383,7 +383,7 @@ class GLSLOutputParameterGroupType : public VaryingParameterGroupType }; -// type for GLLSL `buffer` blocks +// type for GLSL `buffer` blocks class GLSLShaderStorageBufferType : public PointerLikeType { SLANG_AST_CLASS(GLSLShaderStorageBufferType) diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 8aa550a03..05c525965 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -29,6 +29,7 @@ #include "slang-emit-source-writer.h" #include "slang-mangled-lexer.h" +#include "slang/slang-ir.h" #include <assert.h> namespace Slang { @@ -3396,7 +3397,6 @@ void CLikeSourceEmitter::emitFuncDecorationsImpl(IRFunc* func) } } - void CLikeSourceEmitter::emitStruct(IRStructType* structType) { // If the selected `struct` type is actually an intrinsic diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 0fc0c855a..3d3f9687e 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -9,6 +9,7 @@ #include "slang-legalize-types.h" #include "slang-ir-layout.h" +#include "slang/slang-ir.h" #include <assert.h> @@ -229,8 +230,7 @@ void GLSLSourceEmitter::_emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSL m_writer->emit(";\n"); } - -void GLSLSourceEmitter::_emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByteAddressBufferTypeBase* byteAddressBufferType) +void GLSLSourceEmitter::emitSSBOHeader(IRGlobalParam* varDecl, IRType* bufferType) { // TODO: A lot of this logic is copy-pasted from `emitIRStructuredBuffer_GLSL`. // It might be worthwhile to share the common code to avoid regressions sneaking @@ -247,9 +247,9 @@ void GLSLSourceEmitter::_emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByt auto layout = getVarLayout(varDecl); if (layout) { - // We can use ShaderResource/DescriptorSlot interchangably here. + // We can use ShaderResource/DescriptorSlot interchangably here. // This is possible because vk-shift-* - bool isReadOnly = (as<IRHLSLByteAddressBufferType>(byteAddressBufferType) != nullptr); + bool isReadOnly = (as<IRHLSLByteAddressBufferType>(bufferType) != nullptr); const LayoutResourceKindFlags kinds = (isReadOnly ? LayoutResourceKindFlag::ShaderResource : LayoutResourceKindFlag::UnorderedAccess) | LayoutResourceKindFlag::DescriptorTableSlot; @@ -283,12 +283,17 @@ void GLSLSourceEmitter::_emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByt HLSLRasterizerOrderedByteAddressBufferType - Allows read/write access */ - if (as<IRHLSLByteAddressBufferType>(byteAddressBufferType)) + if (as<IRHLSLByteAddressBufferType>(bufferType)) { m_writer->emit("readonly "); } m_writer->emit("buffer "); +} + +void GLSLSourceEmitter::_emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByteAddressBufferTypeBase* byteAddressBufferType) +{ + emitSSBOHeader(varDecl, byteAddressBufferType); // Generate a dummy name for the block m_writer->emit("_S"); @@ -307,6 +312,21 @@ void GLSLSourceEmitter::_emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByt m_writer->emit(";\n"); } +void GLSLSourceEmitter::_emitGLSLSSBO(IRGlobalParam* varDecl, IRGLSLShaderStorageBufferType* ssboType) +{ + emitSSBOHeader(varDecl, ssboType); + + const auto structType = cast<IRStructType>(ssboType->getOperand(0)); + m_writer->emit(getName(structType)); + m_writer->emit("_Block"); + emitStructDeclarationsBlock(structType, true); + + m_writer->emit(getName(varDecl)); + emitArrayBrackets(varDecl->getDataType()); + + m_writer->emit(";\n"); +} + void GLSLSourceEmitter::_emitGLSLParameterGroup(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) { auto varLayout = getVarLayout(varDecl); @@ -1282,6 +1302,11 @@ bool GLSLSourceEmitter::tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* v _emitGLSLByteAddressBuffer(varDecl, byteAddressBufferType); return true; } + else if (const auto glslSSBOType = as<IRGLSLShaderStorageBufferType>(unwrapArray(varType))) + { + _emitGLSLSSBO(varDecl, glslSSBOType); + return true; + } // We want to skip the declaration of any system-value variables // when outputting GLSL (well, except in the case where they @@ -1603,6 +1628,25 @@ void GLSLSourceEmitter::emitBufferPointerTypeDefinition(IRInst* ptrType) m_writer->emit("};\n"); } +// Is this type only used by SSBO declarations, if so then we don't need to +// emit it and it'll be emitted inline there. +static bool isSSBOInternalStructType(IRInst* inst) +{ + if(!as<IRStructType>(inst)) + return false; + + bool onlySSBOUses = true; + for(auto use = inst->firstUse; use; use = use->nextUse) + { + if(!as<IRGLSLShaderStorageBufferType>(use->user)) + { + onlySSBOUses = false; + break; + } + } + return onlySSBOUses; +} + void GLSLSourceEmitter::emitGlobalInstImpl(IRInst* inst) { switch (inst->getOp()) @@ -1610,6 +1654,11 @@ void GLSLSourceEmitter::emitGlobalInstImpl(IRInst* inst) case kIROp_HLSLConstBufferPointerType: emitBufferPointerTypeDefinition(inst); break; + // No need to use structs which are just taking part in a SSBO declaration + case kIROp_StructType: + if(isSSBOInternalStructType(inst)) + break; + [[fallthrough]]; default: Super::emitGlobalInstImpl(inst); break; diff --git a/source/slang/slang-emit-glsl.h b/source/slang/slang-emit-glsl.h index f15ea03b4..1a95cd346 100644 --- a/source/slang/slang-emit-glsl.h +++ b/source/slang/slang-emit-glsl.h @@ -61,6 +61,8 @@ protected: void _emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByteAddressBufferTypeBase* byteAddressBufferType); void _emitGLSLParameterGroup(IRGlobalParam* varDecl, IRUniformParameterGroupType* type); + void _emitGLSLSSBO(IRGlobalParam* varDecl, IRGLSLShaderStorageBufferType* ssboType); + void emitSSBOHeader(IRGlobalParam* varDecl, IRType* bufferType); void _emitGLSLPerVertexVaryingFragmentInput(IRGlobalParam* param, IRType* type); diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 7ad4ad5d4..311fce83d 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -242,7 +242,8 @@ Result linkAndOptimizeIR( // un-specialized IR. dumpIRIfEnabled(codeGenContext, irModule); - lowerGLSLShaderStorageBufferObjects(irModule, sink); + if(!isKhronosTarget(targetRequest)) + lowerGLSLShaderStorageBufferObjectsToStructuredBuffers(irModule, sink); translateGLSLGlobalVar(codeGenContext, irModule); diff --git a/source/slang/slang-ir-layout.cpp b/source/slang/slang-ir-layout.cpp index a6684c7b1..9bbdb1aef 100644 --- a/source/slang/slang-ir-layout.cpp +++ b/source/slang/slang-ir-layout.cpp @@ -152,10 +152,18 @@ case kIROp_##TYPE##Type: \ auto structType = cast<IRStructType>(type); IRSizeAndAlignment structLayout; IRIntegerValue offset = 0; + bool seenFinalUnsizedArrayField = false; for (auto field : structType->getFields()) { + // If we failed to catch an unsized array earlier in the pipeline, + // this will pick it up before generating nonsense results for + // subsequent offsets + SLANG_ASSERT(!seenFinalUnsizedArrayField); + IRSizeAndAlignment fieldTypeLayout; SLANG_RETURN_ON_FAIL(getSizeAndAlignment(target, rules, field->getFieldType(), &fieldTypeLayout)); + seenFinalUnsizedArrayField = fieldTypeLayout.size == IRSizeAndAlignment::kIndeterminateSize; + structLayout.size = align(offset, fieldTypeLayout.alignment); structLayout.alignment = std::max(structLayout.alignment, fieldTypeLayout.alignment); @@ -202,6 +210,15 @@ case kIROp_##TYPE##Type: \ } break; + case kIROp_UnsizedArrayType: + { + auto unsizedArrayType = cast<IRUnsizedArrayType>(type); + getSizeAndAlignment(target, rules, unsizedArrayType->getElementType(), outSizeAndAlignment); + outSizeAndAlignment->size = IRSizeAndAlignment::kIndeterminateSize; + return SLANG_OK; + } + break; + case kIROp_VectorType: { auto vecType = cast<IRVectorType>(type); diff --git a/source/slang/slang-ir-layout.h b/source/slang/slang-ir-layout.h index b5eb54497..19360aa20 100644 --- a/source/slang/slang-ir-layout.h +++ b/source/slang/slang-ir-layout.h @@ -17,6 +17,7 @@ // #include "slang-ir.h" +#include <limits> namespace Slang { @@ -40,9 +41,12 @@ struct IRSizeAndAlignment , alignment(alignment) {} - IRIntegerValue size = 0; + IRIntegerValue size = 0; - int alignment = 1; + // Used for an unsized array as a final struct member + const static IRIntegerValue kIndeterminateSize = std::numeric_limits<IRIntegerValue>::min(); + + int alignment = 1; inline IRIntegerValue getStride() { diff --git a/source/slang/slang-ir-lower-glsl-ssbo-types.cpp b/source/slang/slang-ir-lower-glsl-ssbo-types.cpp index 010c898ad..f0bdb7e83 100644 --- a/source/slang/slang-ir-lower-glsl-ssbo-types.cpp +++ b/source/slang/slang-ir-lower-glsl-ssbo-types.cpp @@ -188,6 +188,20 @@ namespace Slang } } + static void lowerSSBOsToPointers(IRModule* module) + { + IRBuilder builder{module}; + overAllInsts(module, [&](IRInst* inst){ + if(const auto ssbo = as<IRGLSLShaderStorageBufferType>(inst)) + { + builder.setInsertAfter(ssbo); + const auto ptr = builder.getPtrType(ssbo->getElementType()); + ssbo->replaceUsesWith(ptr); + ssbo->removeAndDeallocate(); + } + }); + } + static void diagnoseRemainingSSBOs(IRModule* module, DiagnosticSink* sink) { overAllInsts(module, [&](IRInst* inst){ @@ -198,10 +212,16 @@ namespace Slang }); } - void lowerGLSLShaderStorageBufferObjects(IRModule* module, DiagnosticSink* sink) + void lowerGLSLShaderStorageBufferObjectsToStructuredBuffers(IRModule* module, DiagnosticSink* sink) { lowerArrayLikeSSBOs(module); lowerStructLikeSSBOs(module); diagnoseRemainingSSBOs(module, sink); } + + void lowerGLSLShaderStorageBufferObjectsToPointers(IRModule* module, DiagnosticSink* sink) + { + lowerSSBOsToPointers(module); + diagnoseRemainingSSBOs(module, sink); + } } diff --git a/source/slang/slang-ir-lower-glsl-ssbo-types.h b/source/slang/slang-ir-lower-glsl-ssbo-types.h index fb8ea3917..532c9e115 100644 --- a/source/slang/slang-ir-lower-glsl-ssbo-types.h +++ b/source/slang/slang-ir-lower-glsl-ssbo-types.h @@ -7,8 +7,13 @@ namespace Slang struct IRModule; class DiagnosticSink; - /// Lower tuple types to ordinary `struct`s. - void lowerGLSLShaderStorageBufferObjects( + void lowerGLSLShaderStorageBufferObjectsToPointers( IRModule* module, - DiagnosticSink* sink); + DiagnosticSink* sink + ); + + void lowerGLSLShaderStorageBufferObjectsToStructuredBuffers( + IRModule* module, + DiagnosticSink* sink + ); } diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 681fb36b1..1675fe279 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -614,14 +614,18 @@ struct SPIRVLegalizationContext : public SourceEmitterBase varLayoutInst->removeAndDeallocate(); } } - else + else if (auto structuredBufferType = as<IRHLSLStructuredBufferTypeBase>(innerType)) { - if (auto structuredBufferType = as<IRHLSLStructuredBufferTypeBase>(innerType)) - { - innerType = lowerStructuredBufferType(structuredBufferType).structType; - storageClass = SpvStorageClassStorageBuffer; - needLoad = false; - } + innerType = lowerStructuredBufferType(structuredBufferType).structType; + storageClass = SpvStorageClassStorageBuffer; + needLoad = false; + } + else if (auto glslShaderStorageBufferType = as<IRGLSLShaderStorageBufferType>(innerType)) + { + innerType = glslShaderStorageBufferType->getElementType(); + builder.addDecoration(innerType, kIROp_SPIRVBlockDecoration); + storageClass = SpvStorageClassStorageBuffer; + needLoad = false; } auto innerElementType = innerType; diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp index f0540deb3..28b22b833 100644 --- a/source/slang/slang-reflection-api.cpp +++ b/source/slang/slang-reflection-api.cpp @@ -168,6 +168,11 @@ static SlangParameterCategory maybeRemapParameterCategory( return SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT; break; + case SLANG_TYPE_KIND_SHADER_STORAGE_BUFFER: + if (category == SLANG_PARAMETER_CATEGORY_UNIFORM) + return SLANG_PARAMETER_CATEGORY_DESCRIPTOR_TABLE_SLOT; + break; + // TODO: implement more helpers here default: @@ -382,6 +387,7 @@ SLANG_API SlangTypeKind spReflectionType_GetKind(SlangReflectionType* inType) CASE(HLSLRWByteAddressBufferType); CASE(HLSLRasterizerOrderedByteAddressBufferType); CASE(UntypedBufferResourceType); + CASE(GLSLShaderStorageBufferType); #undef CASE else if (const auto arrayType = as<ArrayExpressionType>(type)) @@ -668,6 +674,7 @@ SLANG_API SlangResourceShape spReflectionType_GetResourceShape(SlangReflectionTy CASE(HLSLRasterizerOrderedByteAddressBufferType, SLANG_BYTE_ADDRESS_BUFFER, SLANG_RESOURCE_ACCESS_RASTER_ORDERED); CASE(RaytracingAccelerationStructureType, SLANG_ACCELERATION_STRUCTURE, SLANG_RESOURCE_ACCESS_READ); CASE(UntypedBufferResourceType, SLANG_BYTE_ADDRESS_BUFFER, SLANG_RESOURCE_ACCESS_READ); + CASE(GLSLShaderStorageBufferType, SLANG_BYTE_ADDRESS_BUFFER, SLANG_RESOURCE_ACCESS_READ_WRITE); #undef CASE return SLANG_RESOURCE_NONE; @@ -703,9 +710,7 @@ SLANG_API SlangResourceAccess spReflectionType_GetResourceAccess(SlangReflection CASE(HLSLRWByteAddressBufferType, SLANG_BYTE_ADDRESS_BUFFER, SLANG_RESOURCE_ACCESS_READ_WRITE); CASE(HLSLRasterizerOrderedByteAddressBufferType, SLANG_BYTE_ADDRESS_BUFFER, SLANG_RESOURCE_ACCESS_RASTER_ORDERED); CASE(UntypedBufferResourceType, SLANG_BYTE_ADDRESS_BUFFER, SLANG_RESOURCE_ACCESS_READ); - - // This isn't entirely accurate, but I can live with it for now - CASE(GLSLShaderStorageBufferType, SLANG_STRUCTURED_BUFFER, SLANG_RESOURCE_ACCESS_READ_WRITE); + CASE(GLSLShaderStorageBufferType, SLANG_BYTE_ADDRESS_BUFFER, SLANG_RESOURCE_ACCESS_READ_WRITE); #undef CASE return SLANG_RESOURCE_ACCESS_NONE; @@ -1310,6 +1315,11 @@ namespace Slang return SLANG_BINDING_TYPE_MUTABLE_RAW_BUFFER; } } + else if( as<GLSLShaderStorageBufferType>(type) ) + { + // TODO Immutable buffers + return SLANG_BINDING_TYPE_MUTABLE_RAW_BUFFER; + } else if( as<ConstantBufferType>(type) ) { return SLANG_BINDING_TYPE_CONSTANT_BUFFER; diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index 074aa3350..ccd34a966 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -3905,7 +3905,7 @@ static TypeLayoutResult _createTypeLayout( // This case is mostly to allow users to add new resource types... CASE(UntypedBufferResourceType, RawBuffer); - CASE(GLSLShaderStorageBufferType, MutableBuffer); + CASE(GLSLShaderStorageBufferType, MutableRawBuffer); #undef CASE diff --git a/tests/glsl/compute-shader-layout.slang b/tests/glsl/compute-shader-layout.slang index b81a87aed..d7ff9b89c 100644 --- a/tests/glsl/compute-shader-layout.slang +++ b/tests/glsl/compute-shader-layout.slang @@ -1,5 +1,5 @@ -//TEST:SIMPLE(filecheck=CHECKGLSLANG): -target spirv -stage compute -entry main -allow-glsl -//TEST:SIMPLE(filecheck=CHECKDIRECT): -target spirv -stage compute -entry main -allow-glsl -emit-spirv-directly +//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry main -allow-glsl +//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry main -allow-glsl -emit-spirv-directly #version 430 precision highp float; precision highp int; @@ -9,12 +9,7 @@ layout(binding = 0) buffer MyBlockName vec4 data[]; } output_data; -// CHECKGLSLANG-DAG: [[x:%[^ ]+]] = OpConstant {{%[^ ]+}} 44 -// CHECKGLSLANG-DAG: [[y:%[^ ]+]] = OpConstant {{%[^ ]+}} 45 -// CHECKGLSLANG-DAG: [[z:%[^ ]+]] = OpConstant {{%[^ ]+}} 46 -// CHECKGLSLANG: %gl_WorkGroupSize = OpConstantComposite {{%[^ ]+}} [[x]] [[y]] [[z]] - -// CHECKDIRECT: OpExecutionMode %main LocalSize 44 45 46 +// CHECK: OpExecutionMode %main LocalSize 44 45 46 layout(local_size_x = 44, local_size_y = 45, local_size_z = 46) in; void main() { diff --git a/tests/glsl/ssbo-2.slang b/tests/glsl/ssbo-2.slang index 11542a539..0d6f1c1f6 100644 --- a/tests/glsl/ssbo-2.slang +++ b/tests/glsl/ssbo-2.slang @@ -1,20 +1,27 @@ -//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry main -allow-glsl +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -emit-spirv-directly #version 430 precision highp float; precision highp int; +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer layout(binding = 0) buffer MyBlockName { - vec4 a; - float b; + int a; + int b; int c; -} output_data; + int d; +} outputBuffer; -layout(local_size_x = 4) in; -void main() +layout(local_size_x = 1) in; +void computeMain() { - output_data.a = vec4(gl_GlobalInvocationID, 1); - output_data.b = 10; - output_data.c = 20; - // CHECK: OpEntryPoint + outputBuffer.a = 1; + outputBuffer.b = 2; + outputBuffer.c = 3; + outputBuffer.d = 4; + // BUF: 1 + // BUF-NEXT: 2 + // BUF-NEXT: 3 + // BUF-NEXT: 4 } diff --git a/tests/glsl/ssbo-3.slang b/tests/glsl/ssbo-3.slang new file mode 100644 index 000000000..e5d9aaddc --- /dev/null +++ b/tests/glsl/ssbo-3.slang @@ -0,0 +1,26 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -emit-spirv-directly +#version 430 +precision highp float; +precision highp int; + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +buffer MyBlockName2 +{ + uint foo; + uint bar; + uint data[]; +} outputBuffer; + +layout(local_size_x = 1) in; +void computeMain() +{ + outputBuffer.foo = 1; + outputBuffer.bar = 2; + outputBuffer.data[0] = 3; + outputBuffer.data[1] = 4; + // BUF: 1 + // BUF-NEXT: 2 + // BUF-NEXT: 3 + // BUF-NEXT: 4 +} diff --git a/tests/glsl/ssbo.slang b/tests/glsl/ssbo.slang index 47084a823..4f4db07cd 100644 --- a/tests/glsl/ssbo.slang +++ b/tests/glsl/ssbo.slang @@ -1,16 +1,27 @@ -//TEST:SIMPLE(filecheck=CHECK): -target spirv -stage compute -entry main -allow-glsl +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -allow-glsl -emit-spirv-directly #version 430 precision highp float; precision highp int; -layout(binding = 0) buffer MyBlockName +//TEST_INPUT:ubuffer(data=[2 3 5 7], stride=4):name=inputBuffer +buffer MyBlockName { - vec4 data[]; -} output_data; + uint data[]; +} inputBuffer; + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +buffer MyBlockName2 +{ + uint data[]; +} outputBuffer; layout(local_size_x = 4) in; -void main() +void computeMain() { - output_data.data[gl_GlobalInvocationID.x] = vec4(gl_GlobalInvocationID, 1); - // CHECK: OpEntryPoint + outputBuffer.data[gl_GlobalInvocationID.x] = inputBuffer.data[gl_GlobalInvocationID.x]; + // BUF: 2 + // BUF-NEXT: 3 + // BUF-NEXT: 5 + // BUF-NEXT: 7 } diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp index 0266a0c75..4b62eb60b 100644 --- a/tools/render-test/options.cpp +++ b/tools/render-test/options.cpp @@ -223,6 +223,14 @@ static gfx::DeviceType _toRenderType(Slang::RenderApiType apiType) // // TODO: At some point we could warn/error and deprecate this option. } + else if (argValue == "-allow-glsl") + { + outOptions.allowGLSL = true; + } + else if (argValue == "-entry") + { + SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.entryPointName)); + } else { // Lookup diff --git a/tools/render-test/options.h b/tools/render-test/options.h index e3b19c272..5a46c4000 100644 --- a/tools/render-test/options.h +++ b/tools/render-test/options.h @@ -71,6 +71,10 @@ struct Options bool dontAddDefaultEntryPoints = false; + bool allowGLSL = false; + + Slang::String entryPointName; + Slang::List<Slang::String> renderFeatures; /// Required render features for this test to run uint32_t computeDispatchSize[3] = { 1, 1, 1 }; diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp index 82d292cee..c598e4ea5 100644 --- a/tools/render-test/slang-support.cpp +++ b/tools/render-test/slang-support.cpp @@ -110,6 +110,8 @@ void ShaderCompilerUtil::Output::reset() if (options.generateSPIRVDirectly) spSetTargetFlags(slangRequest, 0, SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY); + slangRequest->setAllowGLSLInput(options.allowGLSL); + // Define a macro so that shader code in a test can detect what language we // are nominally working with. char const* langDefine = nullptr; |
