Skip to content

Commit 00bd481

Browse files
authored
SPIR-V WIP (shader-slang#3064)
* Add type layout for structured buffer * Default to generating spirv directly * vk test for compute simple * Add spirv-dis as a downstream compiler * Emit Array types in SPIR-V * makevector for spirv * Dump whole spirv module on validation failure * register array types todo, use emitTypeInst * Neater formatting for unhandled inst printing * break out emitCompositeConstruct * Correct array type generation * neaten * Allow getElement for vector * Remove unused * Allow predicating target intrinsics on types * Consider functions with intrinsics to have definitions We need to specialize these if they are predicated on types * Correct array type generation * makeArray for spir-v * replace getElement with getElementPtr for spirv * Correct translation of field access for spirv * Push layouts to types for spirv * Spirv intrinsics * operator now makes a pointer * Add structured buffer of struct test * Preserve type layout in spirv structured buffer legalization * neaten * makeVectorFromScalar for SPIRV * placeholder for layouts on param groups * More type safe spirv op construction * Know that constants and types only go in one section * Remove emitTypeInst * Add todo for spirv sampling * Add links to spirv documentation on emit functions * OpTypeImage support for SPIR-V * Add simpler texture test for spirv * s/spirv_direct/spirv/g * Allow several string literals in target_intrinsic * Handle global params without a var layour for SPIR-V For example groupshared vars * uint spirv asm type * Add todo for isDefinition It is currently too broad * Some atomic op spirv intrinsics * Strip ConstantBuffer wrappers for spirv * Add todo for matrix annotations * Do not associate decorations insts with spirv counterparts * Correct entry point parameter generation * Spelling * Assert that fieldAddress is returning a pointer * Add error for existential type layout getting to spir-v emit * Add IRTupleTypeLayout Unused so far * Allow getElementPtr to work with vectors * Correct target name in test * Hide default spirv direct behind a premake option --default-spirv-direct=true * Do not insert space at start of intrinsic def * Correct asm rendering in tests * remove redundant option * Emit directly from direct test * Add source language options for spirv-dis * Add comments to spirv dis * Add dead debug print for before spirv module * Correct asm rendering in tests * s/spirv_direct/spirv/g * Only specialize intrinsic functions with predicates * regenerate vs projects * squash warnings * squash warnings * remove duplication * Silence warnings from msvc * squash warnings * Overload for zero sized array * More msvc warnings * warnings * Add spirv-tools to path for tests * Do not be specific about dxc version for diag test * Normalize line endings from spirv-dis * Correct filecheck matches * Temporarily disable two spirv tests Failing on CI, undebuggable hang :/ * Do not emit storage class more than once for spirv snippet * Do not pass spir-v to spirv-dis by stdin * Do not get spirv-dis output via stream, use file * normalize file endings in spirv-dis output
1 parent 113a257 commit 00bd481

File tree

62 files changed

+3951
-872
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+3951
-872
lines changed

.github/workflows/linux-arm64.yml

+1
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ jobs:
5353
CONFIGURATION=${{matrix.configuration}}
5454
CC=${{matrix.compiler}}
5555
ARCH=${{matrix.platform}}
56+
PATH="${PATH:+${PATH}:}$(pwd)/external/slang-binaries/spirv-tools/$(uname -m)-linux/bin"
5657
source ./github_test.sh

.github/workflows/linux.yml

+1
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,5 @@ jobs:
6969
CONFIGURATION=${{matrix.configuration}}
7070
CC=${{matrix.compiler}}
7171
ARCH=${{matrix.platform}}
72+
PATH="${PATH:+${PATH}:}$(pwd)/external/slang-binaries/spirv-tools/$(uname -m)-linux/bin"
7273
source ./github_test.sh

.github/workflows/windows-selfhosted.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@ jobs:
3939
- name: test
4040
run: |
4141
$slangTestBinDir = ".\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\";
42-
$env:Path += ";$slangTestBinDir";
42+
$spirvToolsBinDir = ".\external\slang-binaries\spirv-tools\windows-${{matrix.testPlatform}}\bin\";
43+
$env:Path += ";$slangTestBinDir;$spirvToolsBinDir";
4344
& "$slangTestBinDir\slang-test.exe" -appveyor -bindir "$slangTestBinDir\" -platform ${{matrix.testPlatform}} -configuration ${{matrix.configuration}} -category ${{matrix.testCategory}} -api all-cpu 2>&1;
44-

.github/workflows/windows.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ jobs:
6363
- name: test
6464
run: |
6565
$slangTestBinDir = ".\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\";
66-
$env:Path += ";$slangTestBinDir";
66+
$spirvToolsBinDir = ".\external\slang-binaries\spirv-tools\windows-${{matrix.testPlatform}}\bin\";
67+
$env:Path += ";$slangTestBinDir;$spirvToolsBinDir";
6768
Expand-Archive "vk_swiftshader_windows_${{matrix.testPlatform}}.zip" -DestinationPath $slangTestBinDir;
6869
& "$slangTestBinDir\slang-test.exe" -api all-dx12 -appveyor -bindir "$slangTestBinDir\" -platform ${{matrix.testPlatform}} -configuration ${{matrix.configuration}} -category ${{matrix.testCategory}} 2>&1;
69-
70+

build/visual-studio/slang/slang.vcxproj

+3
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
344344
<ClInclude Include="..\..\..\source\slang\slang-emit-hlsl.h" />
345345
<ClInclude Include="..\..\..\source\slang\slang-emit-precedence.h" />
346346
<ClInclude Include="..\..\..\source\slang\slang-emit-source-writer.h" />
347+
<ClInclude Include="..\..\..\source\slang\slang-emit-spirv-ops.h" />
347348
<ClInclude Include="..\..\..\source\slang\slang-emit-torch.h" />
348349
<ClInclude Include="..\..\..\source\slang\slang-glsl-extension-tracker.h" />
349350
<ClInclude Include="..\..\..\source\slang\slang-hlsl-to-vulkan-layout-options.h" />
@@ -396,6 +397,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
396397
<ClInclude Include="..\..\..\source\slang\slang-ir-inst-defs.h" />
397398
<ClInclude Include="..\..\..\source\slang\slang-ir-inst-pass-base.h" />
398399
<ClInclude Include="..\..\..\source\slang\slang-ir-insts.h" />
400+
<ClInclude Include="..\..\..\source\slang\slang-ir-layout-on-types.h" />
399401
<ClInclude Include="..\..\..\source\slang\slang-ir-layout.h" />
400402
<ClInclude Include="..\..\..\source\slang\slang-ir-legalize-array-return-type.h" />
401403
<ClInclude Include="..\..\..\source\slang\slang-ir-legalize-mesh-outputs.h" />
@@ -603,6 +605,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla
603605
<ClCompile Include="..\..\..\source\slang\slang-ir-glsl-liveness.cpp" />
604606
<ClCompile Include="..\..\..\source\slang\slang-ir-init-local-var.cpp" />
605607
<ClCompile Include="..\..\..\source\slang\slang-ir-inline.cpp" />
608+
<ClCompile Include="..\..\..\source\slang\slang-ir-layout-on-types.cpp" />
606609
<ClCompile Include="..\..\..\source\slang\slang-ir-layout.cpp" />
607610
<ClCompile Include="..\..\..\source\slang\slang-ir-legalize-array-return-type.cpp" />
608611
<ClCompile Include="..\..\..\source\slang\slang-ir-legalize-mesh-outputs.cpp" />

build/visual-studio/slang/slang.vcxproj.filters

+9
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@
120120
<ClInclude Include="..\..\..\source\slang\slang-emit-source-writer.h">
121121
<Filter>Header Files</Filter>
122122
</ClInclude>
123+
<ClInclude Include="..\..\..\source\slang\slang-emit-spirv-ops.h">
124+
<Filter>Header Files</Filter>
125+
</ClInclude>
123126
<ClInclude Include="..\..\..\source\slang\slang-emit-torch.h">
124127
<Filter>Header Files</Filter>
125128
</ClInclude>
@@ -276,6 +279,9 @@
276279
<ClInclude Include="..\..\..\source\slang\slang-ir-insts.h">
277280
<Filter>Header Files</Filter>
278281
</ClInclude>
282+
<ClInclude Include="..\..\..\source\slang\slang-ir-layout-on-types.h">
283+
<Filter>Header Files</Filter>
284+
</ClInclude>
279285
<ClInclude Include="..\..\..\source\slang\slang-ir-layout.h">
280286
<Filter>Header Files</Filter>
281287
</ClInclude>
@@ -893,6 +899,9 @@
893899
<ClCompile Include="..\..\..\source\slang\slang-ir-inline.cpp">
894900
<Filter>Source Files</Filter>
895901
</ClCompile>
902+
<ClCompile Include="..\..\..\source\slang\slang-ir-layout-on-types.cpp">
903+
<Filter>Source Files</Filter>
904+
</ClCompile>
896905
<ClCompile Include="..\..\..\source\slang\slang-ir-layout.cpp">
897906
<Filter>Source Files</Filter>
898907
</ClCompile>

docs/command-line-slangc-reference.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,9 @@ Verify IR in the front-end.
550550

551551
Experimental options (use at your own risk)
552552

553-
<a id="emit-spirv-directly"></a>
554-
## -emit-spirv-directly
555-
Generate SPIR-V output directly (otherwise through GLSL and using the glslang compiler)
553+
<a id="emit-spirv-via-glsl"></a>
554+
## -emit-spirv-via-glsl
555+
Generate SPIR-V output by generating and compiling GLSL using glslang
556556

557557

558558
<a id="file-system"></a>
@@ -852,7 +852,7 @@ A capability describes an optional feature that a target may or may not support.
852852
* `c`
853853
* `cpp`
854854
* `cuda`
855-
* `spirv_direct`
855+
* `spirv`
856856
* `GL_NV_ray_tracing` : enables the GL_NV_ray_tracing extension
857857
* `GL_EXT_ray_tracing` : enables the GL_EXT_ray_tracing extension
858858
* `GL_NV_fragment_shader_barycentric` : enables the GL_NV_fragment_shader_barycentric extension

docs/design/stdlib-intrinsics.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ This is a widely used and somewhat complicated intrinsic. Placed on a declaratio
7777
* cuda - CUDA
7878
* cpp - C++ output (used for exe, shared-library or host-callable)
7979

80-
* spirv_direct - Used for slangs SPIR-V direct mechanism
80+
* spirv - Used for slangs SPIR-V direct mechanism
8181

8282
A function definition can have a `target_intrinsic` *and* a body. In that case, the body will be used for targets where the `target_intrinsic` isn't defined.
8383

premake5.lua

+13
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,14 @@ newoption {
228228
allowed = { { "true", "True"}, { "false", "False" } }
229229
}
230230

231+
newoption {
232+
trigger = "default-spirv-direct",
233+
description = "(Optional) Development flag to make the default SPIR-V path generate directly rather than via GLSL",
234+
value = "bool",
235+
default = "false",
236+
allowed = { { "true", "True"}, { "false", "False" } }
237+
}
238+
231239
buildLocation = _OPTIONS["build-location"]
232240
executeBinary = (_OPTIONS["execute-binary"] == "true")
233241
buildGlslang = (_OPTIONS["build-glslang"] == "true")
@@ -245,6 +253,7 @@ fullDebugValidation = (_OPTIONS["full-debug-validation"] == "true")
245253
enableAsan = (_OPTIONS["enable-asan"] == "true")
246254
dxOnVk = (_OPTIONS["dx-on-vk"] == "true")
247255
enableAftermath = (_OPTIONS["enable-aftermath"] == "true")
256+
defaultSPIRVDirect = (_OPTIONS["default-spirv-direct"] == "true")
248257

249258
-- If stdlib embedding is enabled, disable stdlib source embedding by default
250259
disableStdlibSource = enableEmbedStdLib
@@ -435,6 +444,10 @@ workspace "slang"
435444
defines { "SLANG_CONFIG_DX_ON_VK" }
436445
end
437446

447+
if defaultSPIRVDirect then
448+
defines { "SLANG_CONFIG_DEFAULT_SPIRV_DIRECT" }
449+
end
450+
438451
function dump(o)
439452
if type(o) == 'table' then
440453
local s = '{ '

slang-gfx.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -2204,7 +2204,7 @@ class IDevice : public ISlangUnknown
22042204
const char* targetProfile = nullptr; // (optional) Target shader profile. If null this will be set to platform dependent default.
22052205
SlangFloatingPointMode floatingPointMode = SLANG_FLOATING_POINT_MODE_DEFAULT;
22062206
SlangOptimizationLevel optimizationLevel = SLANG_OPTIMIZATION_LEVEL_DEFAULT;
2207-
SlangTargetFlags targetFlags = 0;
2207+
SlangTargetFlags targetFlags = kDefaultTargetFlags;
22082208
SlangLineDirectiveMode lineDirectiveMode = SLANG_LINE_DIRECTIVE_MODE_DEFAULT;
22092209
};
22102210

slang.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -699,9 +699,14 @@ extern "C"
699699
/* When set, will dump out the IR between intermediate compilation steps.*/
700700
SLANG_TARGET_FLAG_DUMP_IR = 1 << 9,
701701

702-
/* When set, will generate SPIRV directly instead of going through glslang. */
702+
/* When set, will generate SPIRV directly rather than via glslang. */
703703
SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY = 1 << 10,
704704
};
705+
#if defined(SLANG_CONFIG_DEFAULT_SPIRV_DIRECT)
706+
constexpr static SlangTargetFlags kDefaultTargetFlags = SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY;
707+
#else
708+
constexpr static SlangTargetFlags kDefaultTargetFlags = 0;
709+
#endif
705710

706711
/*!
707712
@brief Options to control floating-point precision guarantees for a target.
@@ -737,6 +742,7 @@ extern "C"
737742
SLANG_SOURCE_LANGUAGE_C,
738743
SLANG_SOURCE_LANGUAGE_CPP,
739744
SLANG_SOURCE_LANGUAGE_CUDA,
745+
SLANG_SOURCE_LANGUAGE_SPIRV,
740746
SLANG_SOURCE_LANGUAGE_COUNT_OF,
741747
};
742748

@@ -4152,7 +4158,7 @@ namespace slang
41524158
SlangProfileID profile = SLANG_PROFILE_UNKNOWN;
41534159

41544160
/** Flags for the code generation target. Currently unused. */
4155-
SlangTargetFlags flags = 0;
4161+
SlangTargetFlags flags = kDefaultTargetFlags;
41564162

41574163
/** Default mode to use for floating-point operations on the target.
41584164
*/

source/compiler-core/slang-spirv-dis-compiler.cpp

+29-13
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
#include "slang-spirv-dis-compiler.h"
22

33
#include "../core/slang-common.h"
4+
#include "../core/slang-string-util.h"
5+
#include "../core/slang-string.h"
6+
#include "slang-artifact-desc-util.h"
47
#include "slang-artifact-representation.h"
58
#include "slang-artifact-util.h"
9+
#include "slang-artifact-representation-impl.h"
610

711
namespace Slang
812
{
@@ -39,19 +43,23 @@ SlangResult SLANG_MCALL SPIRVDisDownstreamCompiler::convert(
3943
ISlangBlob* fromBlob;
4044
SLANG_RETURN_ON_FAIL(from->loadBlob(ArtifactKeep::No, &fromBlob));
4145

46+
ComPtr<IOSFileArtifactRepresentation> fromFile;
47+
SLANG_RETURN_ON_FAIL(from->requireFile(ArtifactKeep::No, fromFile.writeRef()));
48+
49+
String toFile;
50+
File::generateTemporary(UnownedStringSlice("spv-asm"), toFile);
51+
4252
// Set up our process
4353
CommandLine commandLine;
4454
commandLine.m_executableLocation.setName("spirv-dis");
55+
commandLine.addArg("--comment");
56+
commandLine.addArg(fromFile->getPath());
57+
commandLine.addArg("-o");
58+
commandLine.addArg(toFile);
4559
RefPtr<Process> p;
4660
SLANG_RETURN_ON_FAIL(Process::create(commandLine, 0, p));
47-
const auto in = p->getStream(StdStreamType::In);
48-
const auto out = p->getStream(StdStreamType::Out);
4961
const auto err = p->getStream(StdStreamType::ErrorOut);
5062

51-
// Write the assembly
52-
SLANG_RETURN_ON_FAIL(in->write(fromBlob->getBufferPointer(), fromBlob->getBufferSize()));
53-
in->close();
54-
5563
// Wait for it to finish
5664
if(!p->waitForTermination(1000))
5765
return SLANG_FAIL;
@@ -61,18 +69,26 @@ SlangResult SLANG_MCALL SPIRVDisDownstreamCompiler::convert(
6169
SLANG_RETURN_ON_FAIL(StreamUtil::readAll(err, 0, errData));
6270
fwrite(errData.getBuffer(), errData.getCount(), 1, stderr);
6371

72+
// If spirv-dis failed, we fail
6473
const auto ret = p->getReturnValue();
6574
if(ret != 0)
6675
return SLANG_FAIL;
6776

68-
// Read the disassembly
69-
List<Byte> outData;
70-
SLANG_RETURN_ON_FAIL(StreamUtil::readAll(out, 0, outData));
71-
72-
// Wobble it into an artifact
73-
ComPtr<ISlangBlob> outBlob = RawBlob::create(outData.getBuffer(), outData.getCount());
77+
// Normalize line endings
78+
String outContents;
79+
SLANG_RETURN_ON_FAIL(File::readAllText(toFile, outContents));
80+
StringBuilder outBuilder;
81+
StringUtil::appendStandardLines(outContents.getUnownedSlice(), outBuilder);
82+
SLANG_RETURN_ON_FAIL(File::writeAllBytes(toFile, outBuilder.getBuffer(), outBuilder.getLength()));
83+
84+
// Return as a file artifact
85+
auto fileRep = OSFileArtifactRepresentation::create(
86+
IOSFileArtifactRepresentation::Kind::Owned,
87+
toFile.getUnownedSlice(),
88+
nullptr
89+
);
7490
auto artifact = ArtifactUtil::createArtifact(to);
75-
artifact->addRepresentationUnknown(outBlob.detach());
91+
artifact->addRepresentation(fileRep.detach());
7692
*outArtifact = artifact.detach();
7793

7894
return SLANG_OK;

source/core/slang-array.h

+44
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,50 @@ namespace Slang
101101
Index m_count = 0;
102102
};
103103

104+
template<typename T>
105+
class Array<T, 0>
106+
{
107+
public:
108+
T* begin() { return nullptr; }
109+
const T* begin() const { return nullptr; }
110+
111+
const T* end() const { return nullptr; }
112+
T* end() { return nullptr; }
113+
114+
inline Index getCapacity() const { return 0; }
115+
inline Index getCount() const { return 0; }
116+
inline void setCount(Index newCount)
117+
{
118+
SLANG_ASSERT(newCount == 0);
119+
}
120+
inline const T* getBuffer() const { return nullptr; }
121+
inline T* getBuffer() { return nullptr; }
122+
inline void clear() {}
123+
124+
template<typename T2>
125+
Index indexOf(const T2& val) const { return getView().indexOf(val); }
126+
template<typename T2>
127+
Index lastIndexOf(const T2& val) const { return getView().lastIndexOf(val); }
128+
template<typename Func>
129+
Index findFirstIndex(const Func& predicate) const { return getView().findFirstIndex(predicate); }
130+
template<typename Func>
131+
Index findLastIndex(const Func& predicate) const { return getView().findLastIndex(predicate); }
132+
133+
inline ConstArrayView<T> getView() const { return ConstArrayView<T>(nullptr, 0); }
134+
inline ConstArrayView<T> getView(Index start, Index count) const
135+
{
136+
SLANG_ASSERT(start == 0 && count == 0);
137+
return ConstArrayView<T>(nullptr, 0);
138+
}
139+
140+
inline ArrayView<T> getView() { return ArrayView<T>(nullptr, 0); }
141+
inline ArrayView<T> getView(Index start, Index count)
142+
{
143+
SLANG_ASSERT(start == 0 && count == 0);
144+
return ArrayView<T>(nullptr, 0);
145+
}
146+
};
147+
104148
template<typename T, typename ...TArgs>
105149
struct FirstType
106150
{

source/slang/core.meta.slang

+10
Original file line numberDiff line numberDiff line change
@@ -2078,6 +2078,16 @@ struct TextureTypeInfo
20782078

20792079
sb << "__target_intrinsic(glsl, \"$ctextureLod($p, $2, $3)$z\")\n";
20802080

2081+
// SPIR-V
2082+
{
2083+
// TODO:
2084+
// Need to:
2085+
// - Construct sampled image type OpTypeSampledImage of image type
2086+
// - Construct OpSampledImage from image and sampler
2087+
// - Call OpImageSampleExplicitLod
2088+
// test ./tests/compute/texture-simpler.slang
2089+
}
2090+
20812091
// CUDA
20822092
{
20832093
const int coordCount = base.coordCount;

0 commit comments

Comments
 (0)