Skip to content

Commit c008e39

Browse files
committed
REMIX-2941: Go directly from Slang to SPIRV rather than via GLSL
1 parent aa6cc79 commit c008e39

File tree

17 files changed

+287
-158
lines changed

17 files changed

+287
-158
lines changed

packman-external.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<package name="rtx-remix-glslangvalidator" version="main-tot-2bfc7ca" />
2525
</dependency>
2626
<dependency name="slang" linkPath="external/slang">
27-
<package name="rtx-remix-slang" version="slang-9542fd72-win64-remix" />
27+
<package name="rtx-remix-slang" version="slang-2025.10.4-39-g496fab196-win64-remix" />
2828
</dependency>
2929
<dependency name="nv_xxd" linkPath="external/nv_xxd">
3030
<package name="rtx-remix-nv_xxd" version="1" />
@@ -38,4 +38,7 @@
3838
<dependency name="nrd" linkPath="external/nrd">
3939
<package name="rtx-remix-nrd" version="4.13" />
4040
</dependency>
41+
<dependency name="spirv_tools" linkPath="external/spirv_tools">
42+
<package name="rtx-remix-spirv_tools" version="spirv_tools-vulkan-sdk-1.4.313" />
43+
</dependency>
4144
</project>

scripts-common/compile_shaders.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -224,22 +224,27 @@ def createSlangTask(inputFile, variantSpec):
224224
if variantName != inputName:
225225
task.customName = f'{os.path.basename(inputFile)} ({variantName})'
226226

227-
variableName = '' if args.binary else f'--vn {variantName}'
227+
variableArg = '' if args.binary else f'-source-embed-name {variantName} -source-embed-style u32'
228228

229-
command1 = f'{args.slangc} -entry main -target glsl -verbose-paths {includePaths} -o {glslFile} ' \
229+
command1 = f'{args.slangc} -entry main -target spirv -zero-initialize -emit-spirv-directly -verbose-paths {includePaths} ' \
230230
+ f'-depfile {depFile} {inputFile} -D__SLANG__ {variantDefines} ' \
231-
+ f'-matrix-layout-column-major -line-directive-mode none ' \
232-
+ f'-Wno-30081 -zero-initialize '
233-
231+
+ f'-matrix-layout-column-major ' \
232+
+ f'-Wno-30081 {variableArg} '
233+
234234
# Force scalar block layout in shaders - buffers are required to be aligned as such by Neural Radiance Cache
235-
command1 += f'-force-glsl-scalar-layout '
235+
command1 += f'-fvk-use-scalar-layout '
236236

237237
if generateSlangRepro:
238238
reproFile = os.path.join(args.output, variantName + ".slangRepro")
239239
command1 += f'-dump-repro {reproFile}'
240240

241-
command2 = f'{args.glslang} {glslangFlags} -I. -V {variableName} -o {destFile} {glslFile}'
241+
command1 += f'-o {destFile}'
242+
243+
script_dir = os.path.dirname(os.path.realpath(__file__))
244+
validate_shader_path = os.path.join(script_dir, 'validate_shader.py')
245+
command2 = f'python {validate_shader_path} {destFile}'
242246
task.commands = [command1, command2]
247+
243248
return task
244249

245250
# Read the shader variant specifications from the source code.

scripts-common/validate_shader.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import sys
2+
import os
3+
import re
4+
import struct
5+
import subprocess
6+
7+
remove_temp_file = False
8+
9+
def create_temp_file(shader_file):
10+
with open(shader_file, 'r') as f:
11+
shader_file_data = f.read()
12+
13+
match = re.search(r'\{([^}]*)\}', shader_file_data, re.DOTALL)
14+
if not match:
15+
return ''
16+
17+
array_text = match.group(1)
18+
array_text = re.sub(r'//.*', '', array_text)
19+
array_text = re.sub(r'/\*.*?\*/', '', array_text, flags=re.DOTALL)
20+
int_strings = [s.strip() for s in array_text.split(',') if s.strip()]
21+
int_values = [int(s, 0) for s in int_strings]
22+
23+
spv_filename = shader_file + '.spv'
24+
with open(spv_filename, "wb") as out:
25+
out.write(struct.pack('<%dI' % len(int_values), *int_values))
26+
27+
return spv_filename
28+
29+
def validate_shader(path_to_shaders, shader_file):
30+
if not os.path.exists(os.path.join(path_to_shaders, shader_file)):
31+
print(os.path.join(path_to_shaders, shader_file) + ' not found')
32+
return
33+
if shader_file.endswith('.h'):
34+
spv_file = create_temp_file(os.path.join(path_to_shaders, shader_file))
35+
else:
36+
spv_file = os.path.join(path_to_shaders, shader_file)
37+
if len(spv_file) > 0 and os.path.exists(spv_file):
38+
res = subprocess.Popen([spirv_val_path, '--scalar-block-layout', '--target-env', 'vulkan1.4', spv_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
39+
stdout,stderr = res.communicate()
40+
if len(stdout) > 0 or len(stderr) > 0:
41+
print(spv_file)
42+
if len(stdout) > 0:
43+
print('SPIRV-val: ' + stdout)
44+
if len(stderr) > 0:
45+
print('SPIRV-val: ' + stderr)
46+
exit(1)
47+
if remove_temp_file:
48+
os.remove(spv_file)
49+
50+
if len(sys.argv) != 2:
51+
print(sys.argv[0] + ' <path to spv files>')
52+
exit(1)
53+
54+
# path to spirv-val provided by a build of spirv-tools in packman
55+
spirv_val_path = os.path.join('..', 'external', 'spirv_tools', 'spirv-val.exe')
56+
if not os.path.exists(spirv_val_path):
57+
print('spirv-val not found at ' + spirv_val_path)
58+
exit(1)
59+
60+
if sys.argv[1].endswith('.h') or sys.argv[1].endswith('.spv'):
61+
validate_shader('', sys.argv[1])

src/dxvk/shaders/rtx/algorithm/nee_cache_light.slangh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ struct NEECacheUtils
296296
static void calculateTriangleLightIntensity(int surfaceIndex, int primitiveIndex, out vec3 triangleCenter, out f16vec3 triangleNormal, out vec3 lightIntensity)
297297
{
298298
const Surface surface = surfaces[uint(surfaceIndex)];
299-
RayInteraction rayInteracton = {};
299+
RayInteraction rayInteracton = RayInteraction();
300300
rayInteracton.frontHit = true;
301301
rayInteracton.barycentricCoordinates = barycentricsToUint(uvToBarycentrics(vec2(1.0 / 3.0)));
302302
rayInteracton.primitiveIndex = primitiveIndex;
@@ -410,7 +410,7 @@ struct NEECacheUtils
410410
return 1.0;
411411
}
412412

413-
RayInteraction rayInteraction = {};
413+
RayInteraction rayInteraction = RayInteraction();
414414
rayInteraction.coneRadius = 0;
415415
rayInteraction.viewDirection = viewDirection;
416416

src/dxvk/shaders/rtx/algorithm/resolve_expanded.slangh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ void TraceRayCustom<payload_t : IBasePayloadState>(
231231
topLevelAS, \
232232
flags, uint(payload.rayMask), \
233233
sbtRecordOffset, /* sbtRecordOffset */ \
234-
0, /* sbtRecordStride */ \
235-
0, /* missIndex */ \
234+
0u, /* sbtRecordStride */ \
235+
0u, /* missIndex */ \
236236
currentRay, \
237237
payload \
238238
); \

src/dxvk/shaders/rtx/algorithm/visibility.slangh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ float16_t getRayPortalTransparency(
226226
surface.spriteSheetCols = portal.spriteSheetCols;
227227
surface.spriteSheetFPS = portal.spriteSheetFPS;
228228

229-
SurfaceInteraction surfaceInteraction = (SurfaceInteraction)0;
229+
SurfaceInteraction surfaceInteraction = SurfaceInteraction();
230230
surfaceInteraction.textureCoordinates = uv * 0.5f + 0.5f;
231231
surfaceInteraction.textureGradientX = vec2(0.0f);
232232
surfaceInteraction.textureGradientY = vec2(0.0f);

src/dxvk/shaders/rtx/concept/ray/ray.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
#ifndef RAY_H
2323
#define RAY_H
2424

25+
// Disable Slang warning about deprecation of inheritance in favor of composition
26+
// struct Base { int a; };
27+
// struct Inherited : public Base { int b; }; <- no more this
28+
// struct Composed { Base base; int b; }; <- only this
29+
#pragma warning(disable:30816)
30+
2531
#ifndef USE_32BIT_RAY_DIRECTION
2632
#define USE_32BIT_RAY_DIRECTION 0
2733
#endif
@@ -54,35 +60,35 @@ RayDesc rayToRayDesc(Ray ray)
5460

5561
struct GBufferMemoryMinimalRay
5662
{
57-
float16_t spreadAngle;
63+
float16_t spreadAngle = 0.h;
5864
};
5965

6066
struct MinimalRay
6167
{
62-
float16_t spreadAngle;
68+
float16_t spreadAngle = 0.h;
6369
};
6470

6571
// Note: Minimal version of typical Ray Interaction for transmission across passes.
6672
struct MinimalRayInteraction
6773
{
6874
// Note: Cone radius at the hit point (after spreading over a distance from the view ray)
69-
float16_t coneRadius;
75+
float16_t coneRadius = 0.h;
7076
// Note: Do not use direction for anything highly precise (e.g. hit position derivation) as it is only
7177
// 16 bit and will lack enough precision to get highly accurate results. Generally acceptable for lighting
7278
// however unless significant artifacting is seen, in which case it may be justifiable to bump the precision
7379
// up (for primary rays mainly the concern exists).
74-
f16vec3 viewDirection;
80+
f16vec3 viewDirection = 0.h;
7581
};
7682

7783
struct RayInteraction : MinimalRayInteraction
7884
{
79-
float hitDistance;
80-
uint barycentricCoordinates;
81-
uint primitiveIndex;
82-
uint customIndex;
83-
uint16_t surfaceIndex;
84-
uint8_t materialType;
85-
uint8_t frontHit; // Todo: Pack this into some other value to not take up extra space
85+
float hitDistance = 0.f;
86+
uint barycentricCoordinates = 0u;
87+
uint primitiveIndex = 0u;
88+
uint customIndex = 0u;
89+
uint16_t surfaceIndex = 0u;
90+
uint8_t materialType = 0u;
91+
uint8_t frontHit = 0u; // Todo: Pack this into some other value to not take up extra space
8692
};
8793

8894
struct GBufferMemoryMinimalRayInteraction

src/dxvk/shaders/rtx/concept/surface/surface.h

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
*/
2222
#pragma once
2323

24+
// Disable Slang warning about deprecation of inheritance in favor of composition
25+
// struct Base { int a; };
26+
// struct Inherited : public Base { int b; }; <- no more this
27+
// struct Composed { Base base; int b; }; <- only this
28+
#pragma warning(disable:30816)
29+
2430
#include "surface_shared.h"
2531
#include "rtx/utility/packing.slangh"
2632

@@ -472,14 +478,14 @@ struct Surface
472478
// Note: Minimal version of typical Surface Interaction for transmission across passes.
473479
struct MinimalSurfaceInteraction
474480
{
475-
vec3 position;
481+
vec3 position = 0..xxx;
476482
// Floating-point error of position representation in object space or world space, whichever is larger.
477483
// Used for calculating ray offsets.
478-
float positionError;
484+
float positionError = 0.f;
479485
// TODO this could just be a `quaternion triangleTBN`
480-
f16vec3 triangleNormal;
481-
f16vec3 triangleTangent;
482-
f16vec3 triangleBitangent;
486+
f16vec3 triangleNormal = 0.h;
487+
f16vec3 triangleTangent = 0.h;
488+
f16vec3 triangleBitangent = 0.h;
483489

484490
// Surfaces created from gbuffer may not be valid (i.e. if this pixel was a ray miss)
485491
property bool isValid
@@ -490,19 +496,19 @@ struct MinimalSurfaceInteraction
490496

491497
struct SurfaceInteraction : MinimalSurfaceInteraction
492498
{
493-
vec3 motion;
494-
vec2 textureCoordinates;
495-
vec2 textureGradientX;
496-
vec2 textureGradientY;
499+
vec3 motion = 0..xxx;
500+
vec2 textureCoordinates = 0..xx;
501+
vec2 textureGradientX = 0..xx;
502+
vec2 textureGradientY = 0..xx;
497503
// Note: All normal, tangent and bitangent vectors are in world space.
498504
// TODO this could just be a `quaternion interpolatedTBN`
499-
f16vec3 interpolatedNormal;
500-
f16vec3 interpolatedTangent;
501-
f16vec3 interpolatedBitangent;
502-
f16vec3 rawTangent;
503-
f16vec3 rawBitangent;
504-
f16vec4 vertexColor;
505-
float triangleArea;
505+
f16vec3 interpolatedNormal = 0.h;
506+
f16vec3 interpolatedTangent = 0.h;
507+
f16vec3 interpolatedBitangent = 0.h;
508+
f16vec3 rawTangent = 0.h;
509+
f16vec3 rawBitangent = 0.h;
510+
f16vec4 vertexColor = 0.h;
511+
float triangleArea = 0.f;
506512
};
507513

508514
struct GBufferMemoryMinimalSurfaceInteraction

src/dxvk/shaders/rtx/external/NRC.slangh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@
2121
*/
2222
#pragma once
2323

24+
// This disables the warning about uninitialized variables in the following
25+
// pattern used in NRC
26+
// NrcStruct NrcCreateStruct()
27+
// {
28+
// NrcStruct s;
29+
// return s;
30+
// }
31+
#pragma warning(disable: 41016)
32+
2433
// Includes NRC headers
2534

2635
#include "rtx/external/NRC.h"

0 commit comments

Comments
 (0)