mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 12:40:23 +00:00
Squashed 'deps/SPIRV-Cross/' changes from e59cc24495..f96c9f9fb4
f96c9f9fb4 Merge pull request #635 from KhronosGroup/fix-631 e044732896 Support OpTypeImage with depth == 2 (unknown) properly. a6814a405a Merge pull request #630 from KhronosGroup/fix-628 af2d3abd03 Fail more gracefully with some unsupported opcodes. 26107ba200 Fix os.errno issues on Travis. ee44f6027b Changed OpTypeImage to only flag depth if the op is 1 c863f53cac Merge pull request #627 from KhronosGroup/macro-namespace-fix 9ddbd5aff6 Run format_all.sh. f1752e58e1 Add basic namespace to internal macros. d67e586b2e Merge pull request #626 from billhollings/master 9bf226cb05 Fixes for code review of PR 626. 4c5142b9d3 CompilerMSL support larger texel buffers by using 2D Metal textures. 314f39a7c4 Merge pull request #621 from billhollings/master 4beefe756c Fixes from PR 621 code review. f66507a701 Merge branch 'master' of https://github.com/KhronosGroup/SPIRV-Cross 0ea5e0549e Merge pull request #615 from JustSid/master 5ac55ee735 Fixed emission of some legacy texture ops without requiring the appropriate extensions ceec708b89 Added better fallbacks for legacy textureProjLod() and textureProjLodOffset() generation 994f789465 Merge pull request #624 from KhronosGroup/fix-619 33c61d2abe Support branch/loop hints in HLSL. 327fb03677 Merge pull request #623 from KhronosGroup/fix-618 2077478651 Merge pull request #622 from KhronosGroup/fix-620 10dfaf79d5 Support globallycoherent in HLSL. ffa9133d77 Support ternary expressions in OpSpecConstantOp. e091031613 CompilerMSL pass builtin struct members into functions. 7607eb6923 Merge pull request #617 from KhronosGroup/fix-612 d94d20f4f3 Deal with some builtins being declared with wrong signedness. 0f62b5dc1e Moved check for depth texture and shadowXY emission completely to legacy_tex_op() 447a253ce7 Simplified check for depth texture 76c8e3c1c4 Merge pull request #616 from KhronosGroup/fix-614 b29629fd46 Add support to remove SPIRV_Cross_BaseInstance uniform. 809631ce21 Mention JSON backend in README. 040204d65c Fix warnings and run format_all.sh. b4c8c3b9b2 Merge branch 'reflection' of git://github.com/jherico/SPIRV-Cross f6dad78c99 Added support for shadowXY() sample instructions in legacy GLSL 9ad432463c Prefix integer types with underscore 0ad0f948e1 More PR feedback 3b30202bee Add reflection specific test cases, add reflection testing to test_shaders.sh 8d84a541ac Add specialization constant output in reflection 762040084d More feedback d0a67ba6a7 Code consolidation, const correctness, faster regression testing 3a825349bc More cleanup 6c88b0048b PR feedback ee86000529 Cleanup code 709d3c60f2 Working on reflection output 0039cb86fc Merge pull request #613 from KhronosGroup/fix-609 9d31154917 Deal with switch case labels which share a block. git-subtree-dir: deps/SPIRV-Cross git-subtree-split: f96c9f9fb4fc7d17991cecb2b2294dce06d08d9c
This commit is contained in:
parent
0328298474
commit
2da12dca58
@ -93,6 +93,10 @@ spirv_cross_add_library(spirv-cross-cpp spirv_cross_cpp STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cpp.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_cpp.cpp)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-reflect spirv_cross_reflect STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reflect.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_reflect.cpp)
|
||||
|
||||
spirv_cross_add_library(spirv-cross-msl spirv_cross_msl STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_msl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spirv_msl.cpp)
|
||||
@ -110,7 +114,7 @@ target_compile_options(spirv-cross PRIVATE ${spirv-compiler-options})
|
||||
target_compile_definitions(spirv-cross PRIVATE ${spirv-compiler-defines})
|
||||
|
||||
install(TARGETS spirv-cross RUNTIME DESTINATION bin)
|
||||
target_link_libraries(spirv-cross spirv-cross-glsl spirv-cross-hlsl spirv-cross-cpp spirv-cross-msl spirv-cross-util spirv-cross-core)
|
||||
target_link_libraries(spirv-cross spirv-cross-glsl spirv-cross-hlsl spirv-cross-cpp spirv-cross-reflect spirv-cross-msl spirv-cross-util spirv-cross-core)
|
||||
target_link_libraries(spirv-cross-util spirv-cross-core)
|
||||
target_link_libraries(spirv-cross-glsl spirv-cross-core)
|
||||
target_link_libraries(spirv-cross-msl spirv-cross-glsl)
|
||||
|
@ -11,6 +11,7 @@ SPIRV-Cross is a tool designed for parsing and converting SPIR-V to other shader
|
||||
- Convert SPIR-V to readable, usable and efficient Metal Shading Language (MSL)
|
||||
- Convert SPIR-V to readable, usable and efficient HLSL
|
||||
- Convert SPIR-V to debuggable C++ [EXPERIMENTAL]
|
||||
- Convert SPIR-V to a JSON reflection format [EXPERIMENTAL]
|
||||
- Reflection API to simplify the creation of Vulkan pipeline layouts
|
||||
- Reflection API to modify and tweak OpDecorations
|
||||
- Supports "all" of vertex, fragment, tessellation, geometry and compute shaders.
|
||||
|
41
main.cpp
41
main.cpp
@ -19,6 +19,7 @@
|
||||
#include "spirv_glsl.hpp"
|
||||
#include "spirv_hlsl.hpp"
|
||||
#include "spirv_msl.hpp"
|
||||
#include "spirv_reflect.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
@ -149,6 +150,22 @@ struct CLIParser
|
||||
return val;
|
||||
}
|
||||
|
||||
// Return a string only if it's not prefixed with `--`, otherwise return the default value
|
||||
const char *next_value_string(const char *default_value)
|
||||
{
|
||||
if (!argc)
|
||||
{
|
||||
return default_value;
|
||||
}
|
||||
|
||||
if (0 == strncmp("--", *argv, 2))
|
||||
{
|
||||
return default_value;
|
||||
}
|
||||
|
||||
return next_string();
|
||||
}
|
||||
|
||||
const char *next_string()
|
||||
{
|
||||
if (!argc)
|
||||
@ -461,6 +478,7 @@ struct CLIArguments
|
||||
bool fixup = false;
|
||||
bool yflip = false;
|
||||
bool sso = false;
|
||||
bool support_nonzero_baseinstance = true;
|
||||
vector<PLSArg> pls_in;
|
||||
vector<PLSArg> pls_out;
|
||||
vector<Remap> remaps;
|
||||
@ -481,6 +499,7 @@ struct CLIArguments
|
||||
|
||||
uint32_t iterations = 1;
|
||||
bool cpp = false;
|
||||
string reflect;
|
||||
bool msl = false;
|
||||
bool hlsl = false;
|
||||
bool hlsl_compat = false;
|
||||
@ -512,6 +531,7 @@ static void print_help()
|
||||
"\t[--msl]\n"
|
||||
"\t[--msl-version <MMmmpp>]\n"
|
||||
"\t[--hlsl]\n"
|
||||
"\t[--reflect]\n"
|
||||
"\t[--shader-model]\n"
|
||||
"\t[--hlsl-enable-compat]\n"
|
||||
"\t[--separate-shader-objects]\n"
|
||||
@ -528,7 +548,8 @@ static void print_help()
|
||||
"\t[--rename-interface-variable <in|out> <location> <new_variable_name>]\n"
|
||||
"\t[--set-hlsl-vertex-input-semantic <location> <semantic>]\n"
|
||||
"\t[--rename-entry-point <old> <new> <stage>]\n"
|
||||
"\t[--combined-samplers-inherit-bindings]"
|
||||
"\t[--combined-samplers-inherit-bindings]\n"
|
||||
"\t[--no-support-nonzero-baseinstance]\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -663,6 +684,7 @@ static int main_inner(int argc, char *argv[])
|
||||
cbs.add("--flip-vert-y", [&args](CLIParser &) { args.yflip = true; });
|
||||
cbs.add("--iterations", [&args](CLIParser &parser) { args.iterations = parser.next_uint(); });
|
||||
cbs.add("--cpp", [&args](CLIParser &) { args.cpp = true; });
|
||||
cbs.add("--reflect", [&args](CLIParser &parser) { args.reflect = parser.next_value_string("json"); });
|
||||
cbs.add("--cpp-interface-name", [&args](CLIParser &parser) { args.cpp_interface_name = parser.next_string(); });
|
||||
cbs.add("--metal", [&args](CLIParser &) { args.msl = true; }); // Legacy compatibility
|
||||
cbs.add("--msl", [&args](CLIParser &) { args.msl = true; });
|
||||
@ -737,6 +759,8 @@ static int main_inner(int argc, char *argv[])
|
||||
cbs.add("--combined-samplers-inherit-bindings",
|
||||
[&args](CLIParser &) { args.combined_samplers_inherit_bindings = true; });
|
||||
|
||||
cbs.add("--no-support-nonzero-baseinstance", [&](CLIParser &) { args.support_nonzero_baseinstance = false; });
|
||||
|
||||
cbs.default_handler = [&args](const char *value) { args.input = value; };
|
||||
cbs.error_handler = [] { print_help(); };
|
||||
|
||||
@ -757,8 +781,20 @@ static int main_inner(int argc, char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
unique_ptr<CompilerGLSL> compiler;
|
||||
// Special case reflection because it has little to do with the path followed by code-outputting compilers
|
||||
if (!args.reflect.empty())
|
||||
{
|
||||
CompilerReflection compiler(read_spirv_file(args.input));
|
||||
compiler.set_format(args.reflect);
|
||||
auto json = compiler.compile();
|
||||
if (args.output)
|
||||
write_string_to_file(args.output, json.c_str());
|
||||
else
|
||||
printf("%s", json.c_str());
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
unique_ptr<CompilerGLSL> compiler;
|
||||
bool combined_image_samplers = false;
|
||||
bool build_dummy_sampler = false;
|
||||
|
||||
@ -895,6 +931,7 @@ static int main_inner(int argc, char *argv[])
|
||||
opts.vulkan_semantics = args.vulkan_semantics;
|
||||
opts.vertex.fixup_clipspace = args.fixup;
|
||||
opts.vertex.flip_vert_y = args.yflip;
|
||||
opts.vertex.support_nonzero_base_instance = args.support_nonzero_baseinstance;
|
||||
compiler->set_common_options(opts);
|
||||
|
||||
// Set HLSL specific options.
|
||||
|
@ -127,6 +127,7 @@
|
||||
<ClCompile Include="..\spirv_cpp.cpp" />
|
||||
<ClCompile Include="..\spirv_cross.cpp" />
|
||||
<ClCompile Include="..\spirv_glsl.cpp" />
|
||||
<ClCompile Include="..\spirv_reflect.cpp" />
|
||||
<ClCompile Include="..\spirv_hlsl.cpp" />
|
||||
<ClCompile Include="..\spirv_msl.cpp" />
|
||||
<ClCompile Include="..\spirv_cfg.cpp" />
|
||||
@ -138,6 +139,7 @@
|
||||
<ClInclude Include="..\spirv_cpp.hpp" />
|
||||
<ClInclude Include="..\spirv_cross.hpp" />
|
||||
<ClInclude Include="..\spirv_glsl.hpp" />
|
||||
<ClInclude Include="..\spirv_reflect.hpp" />
|
||||
<ClInclude Include="..\spirv.hpp" />
|
||||
<ClInclude Include="..\spirv_hlsl.hpp" />
|
||||
<ClInclude Include="..\spirv_msl.hpp" />
|
||||
|
@ -24,6 +24,9 @@
|
||||
<ClCompile Include="..\spirv_glsl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\spirv_reflect.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\spirv_cpp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -50,6 +53,9 @@
|
||||
<ClInclude Include="..\spirv_glsl.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\spirv_reflect.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\spirv.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -0,0 +1,32 @@
|
||||
RWByteAddressBuffer bar : register(u0);
|
||||
RWByteAddressBuffer foo : register(u1);
|
||||
|
||||
void comp_main()
|
||||
{
|
||||
[unroll]
|
||||
for (int _135 = 0; _135 < 16; )
|
||||
{
|
||||
bar.Store4(_135 * 16 + 0, asuint(asfloat(foo.Load4(_135 * 16 + 0))));
|
||||
_135++;
|
||||
continue;
|
||||
}
|
||||
[loop]
|
||||
for (int _136 = 0; _136 < 16; )
|
||||
{
|
||||
bar.Store4((15 - _136) * 16 + 0, asuint(asfloat(foo.Load4(_136 * 16 + 0))));
|
||||
_136++;
|
||||
continue;
|
||||
}
|
||||
[branch]
|
||||
if (asfloat(bar.Load(160)) > 10.0f)
|
||||
{
|
||||
foo.Store4(320, asuint(5.0f.xxxx));
|
||||
}
|
||||
foo.Store4(320, asuint(20.0f.xxxx));
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main()
|
||||
{
|
||||
comp_main();
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
Texture2D<float4> uShadow : register(t0);
|
||||
SamplerComparisonState _uShadow_sampler : register(s0);
|
||||
Texture2D<float4> uTexture : register(t1);
|
||||
SamplerComparisonState uSampler : register(s2);
|
||||
|
||||
static float3 vUV;
|
||||
static float FragColor;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
float3 vUV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
FragColor = uShadow.SampleCmp(_uShadow_sampler, vUV.xy, vUV.z) + uTexture.SampleCmp(uSampler, vUV.xy, vUV.z);
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
vUV = stage_input.vUV;
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
static float4 gl_Position;
|
||||
static int gl_VertexIndex;
|
||||
static int gl_InstanceIndex;
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
uint gl_VertexIndex : SV_VertexID;
|
||||
uint gl_InstanceIndex : SV_InstanceID;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 gl_Position : SV_Position;
|
||||
};
|
||||
|
||||
void vert_main()
|
||||
{
|
||||
gl_Position = float(uint(gl_VertexIndex) + uint(gl_InstanceIndex)).xxxx;
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
gl_VertexIndex = int(stage_input.gl_VertexIndex);
|
||||
gl_InstanceIndex = int(stage_input.gl_InstanceIndex);
|
||||
vert_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.gl_Position = gl_Position;
|
||||
return stage_output;
|
||||
}
|
16
reference/opt/shaders-hlsl/comp/globallycoherent.comp
Normal file
16
reference/opt/shaders-hlsl/comp/globallycoherent.comp
Normal file
@ -0,0 +1,16 @@
|
||||
globallycoherent RWByteAddressBuffer _29 : register(u3);
|
||||
ByteAddressBuffer _33 : register(t2);
|
||||
RWTexture2D<float> uImageIn : register(u0);
|
||||
globallycoherent RWTexture2D<float> uImageOut : register(u1);
|
||||
|
||||
void comp_main()
|
||||
{
|
||||
uImageOut[int2(9, 7)] = uImageIn[int2(9, 7)].x;
|
||||
_29.Store(0, asuint(asfloat(_33.Load(0))));
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main()
|
||||
{
|
||||
comp_main();
|
||||
}
|
23
reference/opt/shaders-hlsl/frag/spec-constant-ternary.frag
Normal file
23
reference/opt/shaders-hlsl/frag/spec-constant-ternary.frag
Normal file
@ -0,0 +1,23 @@
|
||||
static const uint s = 10u;
|
||||
static const bool _13 = (s > 20u);
|
||||
static const uint _16 = _13 ? 30u : 50u;
|
||||
|
||||
static float FragColor;
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
FragColor = float(_16);
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main()
|
||||
{
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float3 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], depth2d<float> uShadow [[texture(0)]], depth2d<float> uTexture [[texture(1)]], sampler uShadowSmplr [[sampler(0)]], sampler uSampler [[sampler(2)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = uShadow.sample_compare(uShadowSmplr, in.vUV.xy, in.vUV.z) + uTexture.sample_compare(uSampler, in.vUV.xy, in.vUV.z);
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(uint gl_VertexIndex [[vertex_id]], uint gl_InstanceIndex [[instance_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = float4(float(gl_VertexIndex + gl_InstanceIndex));
|
||||
return out;
|
||||
}
|
||||
|
22
reference/opt/shaders-msl/frag/spec-constant-ternary.frag
Normal file
22
reference/opt/shaders-msl/frag/spec-constant-ternary.frag
Normal file
@ -0,0 +1,22 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
constant uint s_tmp [[function_constant(0)]];
|
||||
constant uint s = is_function_constant_defined(s_tmp) ? s_tmp : 10u;
|
||||
constant bool _13 = (s > 20u);
|
||||
constant uint _16 = _13 ? 30u : 50u;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0()
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = float(_16);
|
||||
return out;
|
||||
}
|
||||
|
19
reference/opt/shaders-msl/vert/set_builtin_in_func.vert
Normal file
19
reference/opt/shaders-msl/vert/set_builtin_in_func.vert
Normal file
@ -0,0 +1,19 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
float gl_PointSize [[point_size]];
|
||||
};
|
||||
|
||||
vertex main0_out main0()
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_PointSize = 1.0;
|
||||
out.gl_Position = float4(out.gl_PointSize);
|
||||
return out;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
@ -8,10 +10,16 @@ struct main0_out
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
||||
uint2 spvTexelBufferCoord(uint tc)
|
||||
{
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
vertex main0_out main0(texture2d<float> uSamp [[texture(4)]], texture2d<float> uSampo [[texture(5)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = uSamp.read(uint2(10, 0)) + uSampo.read(uint2(100, 0));
|
||||
out.gl_Position = uSamp.read(spvTexelBufferCoord(10)) + uSampo.read(spvTexelBufferCoord(100));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
layout(location = 0) flat in mediump int vIndex;
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
highp float _19;
|
||||
switch (vIndex)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
{
|
||||
_19 = 1.0;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
default:
|
||||
{
|
||||
_19 = 3.0;
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
_19 = 8.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
FragColor = _19;
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2DShadow uShadow;
|
||||
uniform sampler2DShadow SPIRV_Cross_CombineduTextureuSampler;
|
||||
|
||||
layout(location = 0) in vec3 vUV;
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(uShadow, vec3(vUV.xy, vUV.z)) + texture(SPIRV_Cross_CombineduTextureuSampler, vec3(vUV.xy, vUV.z));
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2DShadow uShadow;
|
||||
layout(set = 0, binding = 1) uniform texture2D uTexture;
|
||||
layout(set = 0, binding = 2) uniform samplerShadow uSampler;
|
||||
|
||||
layout(location = 0) in vec3 vUV;
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(uShadow, vec3(vUV.xy, vUV.z)) + texture(sampler2DShadow(uTexture, uSampler), vec3(vUV.xy, vUV.z));
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
#version 450
|
||||
layout(triangles) in;
|
||||
layout(max_vertices = 3, triangle_strip) out;
|
||||
|
||||
struct VertexOutput
|
||||
{
|
||||
vec4 pos;
|
||||
};
|
||||
|
||||
struct GeometryOutput
|
||||
{
|
||||
vec4 pos;
|
||||
uint layer;
|
||||
};
|
||||
|
||||
void _main(VertexOutput _input[3], GeometryOutput stream)
|
||||
{
|
||||
GeometryOutput _output;
|
||||
_output.layer = 1u;
|
||||
for (int v = 0; v < 3; v++)
|
||||
{
|
||||
_output.pos = _input[v].pos;
|
||||
gl_Position = _output.pos;
|
||||
gl_Layer = int(_output.layer);
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
VertexOutput _input[3];
|
||||
_input[0].pos = gl_in[0].gl_Position;
|
||||
_input[1].pos = gl_in[1].gl_Position;
|
||||
_input[2].pos = gl_in[2].gl_Position;
|
||||
VertexOutput param[3] = _input;
|
||||
GeometryOutput param_1;
|
||||
_main(param, param_1);
|
||||
GeometryOutput stream = param_1;
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
|
||||
uniform int SPIRV_Cross_BaseInstance;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(float(uint(gl_VertexID) + uint((gl_InstanceID + SPIRV_Cross_BaseInstance))));
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = float((10u > 20u) ? 30u : 50u);
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
|
||||
layout(constant_id = 0) const uint s = 10u;
|
||||
const bool _13 = (s > 20u);
|
||||
const uint _16 = _13 ? 30u : 50u;
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = float(_16);
|
||||
}
|
||||
|
41
reference/shaders-hlsl/asm/comp/control-flow-hints.asm.comp
Normal file
41
reference/shaders-hlsl/asm/comp/control-flow-hints.asm.comp
Normal file
@ -0,0 +1,41 @@
|
||||
RWByteAddressBuffer bar : register(u0);
|
||||
RWByteAddressBuffer foo : register(u1);
|
||||
|
||||
void _main()
|
||||
{
|
||||
[unroll]
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
bar.Store4(i * 16 + 0, asuint(asfloat(foo.Load4(i * 16 + 0))));
|
||||
}
|
||||
[loop]
|
||||
for (int i_1 = 0; i_1 < 16; i_1++)
|
||||
{
|
||||
bar.Store4((15 - i_1) * 16 + 0, asuint(asfloat(foo.Load4(i_1 * 16 + 0))));
|
||||
}
|
||||
float v = asfloat(bar.Load(160));
|
||||
float w = asfloat(foo.Load(160));
|
||||
[branch]
|
||||
if (v > 10.0f)
|
||||
{
|
||||
foo.Store4(320, asuint(5.0f.xxxx));
|
||||
}
|
||||
float value = 20.0f;
|
||||
[flatten]
|
||||
if (w > 40.0f)
|
||||
{
|
||||
value = 20.0f;
|
||||
}
|
||||
foo.Store4(320, asuint(value.xxxx));
|
||||
}
|
||||
|
||||
void comp_main()
|
||||
{
|
||||
_main();
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main()
|
||||
{
|
||||
comp_main();
|
||||
}
|
41
reference/shaders-hlsl/asm/frag/unknown-depth-state.asm.frag
Normal file
41
reference/shaders-hlsl/asm/frag/unknown-depth-state.asm.frag
Normal file
@ -0,0 +1,41 @@
|
||||
Texture2D<float4> uShadow : register(t0);
|
||||
SamplerComparisonState _uShadow_sampler : register(s0);
|
||||
Texture2D<float4> uTexture : register(t1);
|
||||
SamplerComparisonState uSampler : register(s2);
|
||||
|
||||
static float3 vUV;
|
||||
static float FragColor;
|
||||
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
float3 vUV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
float sample_combined()
|
||||
{
|
||||
return uShadow.SampleCmp(_uShadow_sampler, vUV.xy, vUV.z);
|
||||
}
|
||||
|
||||
float sample_separate()
|
||||
{
|
||||
return uTexture.SampleCmp(uSampler, vUV.xy, vUV.z);
|
||||
}
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
FragColor = sample_combined() + sample_separate();
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
vUV = stage_input.vUV;
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
static float4 gl_Position;
|
||||
static int gl_VertexIndex;
|
||||
static int gl_InstanceIndex;
|
||||
struct SPIRV_Cross_Input
|
||||
{
|
||||
uint gl_VertexIndex : SV_VertexID;
|
||||
uint gl_InstanceIndex : SV_InstanceID;
|
||||
};
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float4 gl_Position : SV_Position;
|
||||
};
|
||||
|
||||
float4 _main(uint vid, uint iid)
|
||||
{
|
||||
return float(vid + iid).xxxx;
|
||||
}
|
||||
|
||||
void vert_main()
|
||||
{
|
||||
uint vid = uint(gl_VertexIndex);
|
||||
uint iid = uint(gl_InstanceIndex);
|
||||
uint param = vid;
|
||||
uint param_1 = iid;
|
||||
gl_Position = _main(param, param_1);
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
|
||||
{
|
||||
gl_VertexIndex = int(stage_input.gl_VertexIndex);
|
||||
gl_InstanceIndex = int(stage_input.gl_InstanceIndex);
|
||||
vert_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.gl_Position = gl_Position;
|
||||
return stage_output;
|
||||
}
|
18
reference/shaders-hlsl/comp/globallycoherent.comp
Normal file
18
reference/shaders-hlsl/comp/globallycoherent.comp
Normal file
@ -0,0 +1,18 @@
|
||||
globallycoherent RWByteAddressBuffer _29 : register(u3);
|
||||
ByteAddressBuffer _33 : register(t2);
|
||||
RWTexture2D<float> uImageIn : register(u0);
|
||||
globallycoherent RWTexture2D<float> uImageOut : register(u1);
|
||||
|
||||
void comp_main()
|
||||
{
|
||||
int2 coord = int2(9, 7);
|
||||
float4 indata = uImageIn[coord].xxxx;
|
||||
uImageOut[coord] = indata.x;
|
||||
_29.Store(0, asuint(asfloat(_33.Load(0))));
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main()
|
||||
{
|
||||
comp_main();
|
||||
}
|
23
reference/shaders-hlsl/frag/spec-constant-ternary.frag
Normal file
23
reference/shaders-hlsl/frag/spec-constant-ternary.frag
Normal file
@ -0,0 +1,23 @@
|
||||
static const uint s = 10u;
|
||||
static const bool _13 = (s > 20u);
|
||||
static const uint _16 = _13 ? 30u : 50u;
|
||||
|
||||
static float FragColor;
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
FragColor = float(_16);
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main()
|
||||
{
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
@ -36,6 +36,12 @@ struct main0_out
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
||||
uint2 spvTexelBufferCoord(uint tc)
|
||||
{
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
attr_desc fetch_desc(thread const int& location, constant VertexBuffer& v_227)
|
||||
{
|
||||
int attribute_flags = v_227.input_attributes[location].w;
|
||||
@ -76,10 +82,10 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
|
||||
{
|
||||
int _131 = first_byte;
|
||||
first_byte = _131 + 1;
|
||||
tmp.x = input_stream.read(uint2(_131, 0)).x;
|
||||
tmp.x = input_stream.read(spvTexelBufferCoord(_131)).x;
|
||||
int _138 = first_byte;
|
||||
first_byte = _138 + 1;
|
||||
tmp.y = input_stream.read(uint2(_138, 0)).x;
|
||||
tmp.y = input_stream.read(spvTexelBufferCoord(_138)).x;
|
||||
uint4 param = tmp;
|
||||
int param_1 = desc.swap_bytes;
|
||||
result[n] = float(get_bits(param, param_1));
|
||||
@ -89,16 +95,16 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
|
||||
{
|
||||
int _156 = first_byte;
|
||||
first_byte = _156 + 1;
|
||||
tmp.x = input_stream.read(uint2(_156, 0)).x;
|
||||
tmp.x = input_stream.read(spvTexelBufferCoord(_156)).x;
|
||||
int _163 = first_byte;
|
||||
first_byte = _163 + 1;
|
||||
tmp.y = input_stream.read(uint2(_163, 0)).x;
|
||||
tmp.y = input_stream.read(spvTexelBufferCoord(_163)).x;
|
||||
int _170 = first_byte;
|
||||
first_byte = _170 + 1;
|
||||
tmp.z = input_stream.read(uint2(_170, 0)).x;
|
||||
tmp.z = input_stream.read(spvTexelBufferCoord(_170)).x;
|
||||
int _177 = first_byte;
|
||||
first_byte = _177 + 1;
|
||||
tmp.w = input_stream.read(uint2(_177, 0)).x;
|
||||
tmp.w = input_stream.read(spvTexelBufferCoord(_177)).x;
|
||||
uint4 param_2 = tmp;
|
||||
int param_3 = desc.swap_bytes;
|
||||
result[n] = as_type<float>(get_bits(param_2, param_3));
|
||||
@ -108,7 +114,7 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
|
||||
{
|
||||
int _195 = first_byte;
|
||||
first_byte = _195 + 1;
|
||||
result[n] = float(input_stream.read(uint2(_195, 0)).x);
|
||||
result[n] = float(input_stream.read(spvTexelBufferCoord(_195)).x);
|
||||
reverse_order = desc.swap_bytes != 0;
|
||||
break;
|
||||
}
|
||||
|
34
reference/shaders-msl/asm/frag/unknown-depth-state.asm.frag
Normal file
34
reference/shaders-msl/asm/frag/unknown-depth-state.asm.frag
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float3 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
float sample_combined(thread float3& vUV, thread depth2d<float> uShadow, thread const sampler uShadowSmplr)
|
||||
{
|
||||
return uShadow.sample_compare(uShadowSmplr, vUV.xy, vUV.z);
|
||||
}
|
||||
|
||||
float sample_separate(thread float3& vUV, thread depth2d<float> uTexture, thread sampler uSampler)
|
||||
{
|
||||
return uTexture.sample_compare(uSampler, vUV.xy, vUV.z);
|
||||
}
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], depth2d<float> uShadow [[texture(0)]], depth2d<float> uTexture [[texture(1)]], sampler uShadowSmplr [[sampler(0)]], sampler uSampler [[sampler(2)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = sample_combined(in.vUV, uShadow, uShadowSmplr) + sample_separate(in.vUV, uTexture, uSampler);
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
float4 _main(thread const uint& vid, thread const uint& iid)
|
||||
{
|
||||
return float4(float(vid + iid));
|
||||
}
|
||||
|
||||
vertex main0_out main0(uint gl_VertexIndex [[vertex_id]], uint gl_InstanceIndex [[instance_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
uint vid = gl_VertexIndex;
|
||||
uint iid = gl_InstanceIndex;
|
||||
uint param = vid;
|
||||
uint param_1 = iid;
|
||||
out.gl_Position = _main(param, param_1);
|
||||
return out;
|
||||
}
|
||||
|
22
reference/shaders-msl/frag/spec-constant-ternary.frag
Normal file
22
reference/shaders-msl/frag/spec-constant-ternary.frag
Normal file
@ -0,0 +1,22 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
constant uint s_tmp [[function_constant(0)]];
|
||||
constant uint s = is_function_constant_defined(s_tmp) ? s_tmp : 10u;
|
||||
constant bool _13 = (s > 20u);
|
||||
constant uint _16 = _13 ? 30u : 50u;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0()
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = float(_16);
|
||||
return out;
|
||||
}
|
||||
|
26
reference/shaders-msl/vert/set_builtin_in_func.vert
Normal file
26
reference/shaders-msl/vert/set_builtin_in_func.vert
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
float gl_PointSize [[point_size]];
|
||||
};
|
||||
|
||||
void write_outblock(thread float4& gl_Position, thread float& gl_PointSize)
|
||||
{
|
||||
gl_PointSize = 1.0;
|
||||
gl_Position = float4(gl_PointSize);
|
||||
}
|
||||
|
||||
vertex main0_out main0()
|
||||
{
|
||||
main0_out out = {};
|
||||
write_outblock(out.gl_Position, out.gl_PointSize);
|
||||
return out;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
@ -8,10 +10,16 @@ struct main0_out
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
// Returns 2D texture coords corresponding to 1D texel buffer coords
|
||||
uint2 spvTexelBufferCoord(uint tc)
|
||||
{
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
vertex main0_out main0(texture2d<float> uSamp [[texture(4)]], texture2d<float> uSampo [[texture(5)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = uSamp.read(uint2(10, 0)) + uSampo.read(uint2(100, 0));
|
||||
out.gl_Position = uSamp.read(spvTexelBufferCoord(10)) + uSampo.read(spvTexelBufferCoord(100));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,49 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "vert"
|
||||
},
|
||||
{
|
||||
"name" : "main2",
|
||||
"mode" : "vert"
|
||||
},
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
},
|
||||
{
|
||||
"name" : "main2",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"types" : {
|
||||
"_8" : {
|
||||
"name" : "_8",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "_m0",
|
||||
"type" : "vec4"
|
||||
},
|
||||
{
|
||||
"name" : "_m1",
|
||||
"type" : "float"
|
||||
},
|
||||
{
|
||||
"name" : "_m2",
|
||||
"type" : "float",
|
||||
"array" : [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "_m3",
|
||||
"type" : "float",
|
||||
"array" : [
|
||||
1
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
64
reference/shaders-reflection/comp/struct-layout.comp.json
Normal file
64
reference/shaders-reflection/comp/struct-layout.comp.json
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "comp"
|
||||
}
|
||||
],
|
||||
"types" : {
|
||||
"_19" : {
|
||||
"name" : "Foo",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "m",
|
||||
"type" : "mat4",
|
||||
"offset" : 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"_21" : {
|
||||
"name" : "SSBO2",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "out_data",
|
||||
"type" : "_19",
|
||||
"array" : [
|
||||
0
|
||||
],
|
||||
"offset" : 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"_28" : {
|
||||
"name" : "SSBO",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "in_data",
|
||||
"type" : "_19",
|
||||
"array" : [
|
||||
0
|
||||
],
|
||||
"offset" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ssbos" : [
|
||||
{
|
||||
"type" : "_21",
|
||||
"name" : "SSBO2",
|
||||
"writeonly" : true,
|
||||
"block_size" : 0,
|
||||
"set" : 0,
|
||||
"binding" : 1
|
||||
},
|
||||
{
|
||||
"type" : "_28",
|
||||
"name" : "SSBO",
|
||||
"readonly" : true,
|
||||
"block_size" : 0,
|
||||
"set" : 0,
|
||||
"binding" : 0
|
||||
}
|
||||
]
|
||||
}
|
474
reference/shaders-reflection/comp/struct-packing.comp.json
Normal file
474
reference/shaders-reflection/comp/struct-packing.comp.json
Normal file
@ -0,0 +1,474 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "comp"
|
||||
}
|
||||
],
|
||||
"types" : {
|
||||
"_11" : {
|
||||
"name" : "S0",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "a",
|
||||
"type" : "vec2",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "b",
|
||||
"type" : "float",
|
||||
"offset" : 8
|
||||
}
|
||||
]
|
||||
},
|
||||
"_14" : {
|
||||
"name" : "S1",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "a",
|
||||
"type" : "vec3",
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "b",
|
||||
"type" : "float",
|
||||
"offset" : 12
|
||||
}
|
||||
]
|
||||
},
|
||||
"_17" : {
|
||||
"name" : "S2",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "a",
|
||||
"type" : "vec3",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "b",
|
||||
"type" : "float",
|
||||
"offset" : 16
|
||||
}
|
||||
]
|
||||
},
|
||||
"_19" : {
|
||||
"name" : "S3",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "a",
|
||||
"type" : "vec2",
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "b",
|
||||
"type" : "float",
|
||||
"offset" : 8
|
||||
}
|
||||
]
|
||||
},
|
||||
"_20" : {
|
||||
"name" : "S4",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "c",
|
||||
"type" : "vec2",
|
||||
"offset" : 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"_23" : {
|
||||
"name" : "Content",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "m0s",
|
||||
"type" : "_11",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "m1s",
|
||||
"type" : "_14",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 16
|
||||
},
|
||||
{
|
||||
"name" : "m2s",
|
||||
"type" : "_17",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 32
|
||||
},
|
||||
{
|
||||
"name" : "m0",
|
||||
"type" : "_11",
|
||||
"offset" : 64
|
||||
},
|
||||
{
|
||||
"name" : "m1",
|
||||
"type" : "_14",
|
||||
"offset" : 80
|
||||
},
|
||||
{
|
||||
"name" : "m2",
|
||||
"type" : "_17",
|
||||
"offset" : 96
|
||||
},
|
||||
{
|
||||
"name" : "m3",
|
||||
"type" : "_19",
|
||||
"offset" : 128
|
||||
},
|
||||
{
|
||||
"name" : "m4",
|
||||
"type" : "float",
|
||||
"offset" : 144
|
||||
},
|
||||
{
|
||||
"name" : "m3s",
|
||||
"type" : "_20",
|
||||
"array" : [
|
||||
8
|
||||
],
|
||||
"offset" : 152
|
||||
}
|
||||
]
|
||||
},
|
||||
"_36" : {
|
||||
"name" : "SSBO1",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "content",
|
||||
"type" : "_23",
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "content1",
|
||||
"type" : "_23",
|
||||
"array" : [
|
||||
2
|
||||
],
|
||||
"offset" : 224
|
||||
},
|
||||
{
|
||||
"name" : "content2",
|
||||
"type" : "_23",
|
||||
"offset" : 672
|
||||
},
|
||||
{
|
||||
"name" : "m0",
|
||||
"type" : "mat2",
|
||||
"offset" : 896
|
||||
},
|
||||
{
|
||||
"name" : "m1",
|
||||
"type" : "mat2",
|
||||
"offset" : 912
|
||||
},
|
||||
{
|
||||
"name" : "m2",
|
||||
"type" : "mat2x3",
|
||||
"array" : [
|
||||
4
|
||||
],
|
||||
"offset" : 928
|
||||
},
|
||||
{
|
||||
"name" : "m3",
|
||||
"type" : "mat3x2",
|
||||
"offset" : 1056
|
||||
},
|
||||
{
|
||||
"name" : "m4",
|
||||
"type" : "mat2",
|
||||
"row_major" : true,
|
||||
"offset" : 1080
|
||||
},
|
||||
{
|
||||
"name" : "m5",
|
||||
"type" : "mat2",
|
||||
"row_major" : true,
|
||||
"array" : [
|
||||
9
|
||||
],
|
||||
"offset" : 1096
|
||||
},
|
||||
{
|
||||
"name" : "m6",
|
||||
"type" : "mat2x3",
|
||||
"row_major" : true,
|
||||
"array" : [
|
||||
2,
|
||||
4
|
||||
],
|
||||
"offset" : 1240
|
||||
},
|
||||
{
|
||||
"name" : "m7",
|
||||
"type" : "mat3x2",
|
||||
"row_major" : true,
|
||||
"offset" : 1440
|
||||
},
|
||||
{
|
||||
"name" : "array",
|
||||
"type" : "float",
|
||||
"array" : [
|
||||
0
|
||||
],
|
||||
"offset" : 1472
|
||||
}
|
||||
]
|
||||
},
|
||||
"_42" : {
|
||||
"name" : "S0",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "a",
|
||||
"type" : "vec2",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "b",
|
||||
"type" : "float",
|
||||
"offset" : 16
|
||||
}
|
||||
]
|
||||
},
|
||||
"_44" : {
|
||||
"name" : "S1",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "a",
|
||||
"type" : "vec3",
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "b",
|
||||
"type" : "float",
|
||||
"offset" : 12
|
||||
}
|
||||
]
|
||||
},
|
||||
"_47" : {
|
||||
"name" : "S2",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "a",
|
||||
"type" : "vec3",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "b",
|
||||
"type" : "float",
|
||||
"offset" : 16
|
||||
}
|
||||
]
|
||||
},
|
||||
"_49" : {
|
||||
"name" : "S3",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "a",
|
||||
"type" : "vec2",
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "b",
|
||||
"type" : "float",
|
||||
"offset" : 8
|
||||
}
|
||||
]
|
||||
},
|
||||
"_50" : {
|
||||
"name" : "S4",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "c",
|
||||
"type" : "vec2",
|
||||
"offset" : 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"_52" : {
|
||||
"name" : "Content",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "m0s",
|
||||
"type" : "_42",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "m1s",
|
||||
"type" : "_44",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 32
|
||||
},
|
||||
{
|
||||
"name" : "m2s",
|
||||
"type" : "_47",
|
||||
"array" : [
|
||||
1
|
||||
],
|
||||
"offset" : 48
|
||||
},
|
||||
{
|
||||
"name" : "m0",
|
||||
"type" : "_42",
|
||||
"offset" : 80
|
||||
},
|
||||
{
|
||||
"name" : "m1",
|
||||
"type" : "_44",
|
||||
"offset" : 112
|
||||
},
|
||||
{
|
||||
"name" : "m2",
|
||||
"type" : "_47",
|
||||
"offset" : 128
|
||||
},
|
||||
{
|
||||
"name" : "m3",
|
||||
"type" : "_49",
|
||||
"offset" : 160
|
||||
},
|
||||
{
|
||||
"name" : "m4",
|
||||
"type" : "float",
|
||||
"offset" : 176
|
||||
},
|
||||
{
|
||||
"name" : "m3s",
|
||||
"type" : "_50",
|
||||
"array" : [
|
||||
8
|
||||
],
|
||||
"offset" : 192
|
||||
}
|
||||
]
|
||||
},
|
||||
"_59" : {
|
||||
"name" : "SSBO0",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "content",
|
||||
"type" : "_52",
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "content1",
|
||||
"type" : "_52",
|
||||
"array" : [
|
||||
2
|
||||
],
|
||||
"offset" : 320
|
||||
},
|
||||
{
|
||||
"name" : "content2",
|
||||
"type" : "_52",
|
||||
"offset" : 960
|
||||
},
|
||||
{
|
||||
"name" : "m0",
|
||||
"type" : "mat2",
|
||||
"offset" : 1280
|
||||
},
|
||||
{
|
||||
"name" : "m1",
|
||||
"type" : "mat2",
|
||||
"offset" : 1312
|
||||
},
|
||||
{
|
||||
"name" : "m2",
|
||||
"type" : "mat2x3",
|
||||
"array" : [
|
||||
4
|
||||
],
|
||||
"offset" : 1344
|
||||
},
|
||||
{
|
||||
"name" : "m3",
|
||||
"type" : "mat3x2",
|
||||
"offset" : 1472
|
||||
},
|
||||
{
|
||||
"name" : "m4",
|
||||
"type" : "mat2",
|
||||
"row_major" : true,
|
||||
"offset" : 1520
|
||||
},
|
||||
{
|
||||
"name" : "m5",
|
||||
"type" : "mat2",
|
||||
"row_major" : true,
|
||||
"array" : [
|
||||
9
|
||||
],
|
||||
"offset" : 1552
|
||||
},
|
||||
{
|
||||
"name" : "m6",
|
||||
"type" : "mat2x3",
|
||||
"row_major" : true,
|
||||
"array" : [
|
||||
2,
|
||||
4
|
||||
],
|
||||
"offset" : 1840
|
||||
},
|
||||
{
|
||||
"name" : "m7",
|
||||
"type" : "mat3x2",
|
||||
"row_major" : true,
|
||||
"offset" : 2224
|
||||
},
|
||||
{
|
||||
"name" : "array",
|
||||
"type" : "float",
|
||||
"array" : [
|
||||
0
|
||||
],
|
||||
"offset" : 2256
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ssbos" : [
|
||||
{
|
||||
"type" : "_36",
|
||||
"name" : "SSBO1",
|
||||
"restrict" : true,
|
||||
"block_size" : 1472,
|
||||
"set" : 0,
|
||||
"binding" : 1
|
||||
},
|
||||
{
|
||||
"type" : "_59",
|
||||
"name" : "SSBO0",
|
||||
"restrict" : true,
|
||||
"block_size" : 2256,
|
||||
"set" : 0,
|
||||
"binding" : 0
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "float",
|
||||
"name" : "FragColor",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"separate_images" : [
|
||||
{
|
||||
"type" : "texture2D",
|
||||
"name" : "uDepth",
|
||||
"set" : 0,
|
||||
"binding" : 2
|
||||
}
|
||||
],
|
||||
"separate_samplers" : [
|
||||
{
|
||||
"type" : "sampler",
|
||||
"name" : "uSampler",
|
||||
"set" : 0,
|
||||
"binding" : 0
|
||||
},
|
||||
{
|
||||
"type" : "sampler",
|
||||
"name" : "uSampler1",
|
||||
"set" : 0,
|
||||
"binding" : 1
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"inputs" : [
|
||||
{
|
||||
"type" : "vec2",
|
||||
"name" : "vTex",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "FragColor",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"separate_images" : [
|
||||
{
|
||||
"type" : "texture2D",
|
||||
"name" : "uTexture0",
|
||||
"set" : 0,
|
||||
"binding" : 2
|
||||
},
|
||||
{
|
||||
"type" : "texture2D",
|
||||
"name" : "uTexture1",
|
||||
"set" : 0,
|
||||
"binding" : 3
|
||||
}
|
||||
],
|
||||
"separate_samplers" : [
|
||||
{
|
||||
"type" : "sampler",
|
||||
"name" : "uSampler0",
|
||||
"set" : 0,
|
||||
"binding" : 0
|
||||
},
|
||||
{
|
||||
"type" : "sampler",
|
||||
"name" : "uSampler1",
|
||||
"set" : 0,
|
||||
"binding" : 1
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "_entryPointOutput",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"textures" : [
|
||||
{
|
||||
"type" : "sampler2D",
|
||||
"name" : "ROIm",
|
||||
"set" : 0,
|
||||
"binding" : 1
|
||||
}
|
||||
],
|
||||
"separate_images" : [
|
||||
{
|
||||
"type" : "samplerBuffer",
|
||||
"name" : "ROBuf",
|
||||
"set" : 0,
|
||||
"binding" : 0
|
||||
}
|
||||
],
|
||||
"images" : [
|
||||
{
|
||||
"type" : "image2D",
|
||||
"name" : "RWIm",
|
||||
"set" : 0,
|
||||
"binding" : 1,
|
||||
"format" : "rgba32f"
|
||||
},
|
||||
{
|
||||
"type" : "imageBuffer",
|
||||
"name" : "RWBuf",
|
||||
"set" : 0,
|
||||
"binding" : 0,
|
||||
"format" : "rgba32f"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"subpass_inputs" : [
|
||||
{
|
||||
"type" : "subpassInputMS",
|
||||
"name" : "uSubpass0",
|
||||
"set" : 0,
|
||||
"binding" : 0,
|
||||
"input_attachment_index" : 0
|
||||
},
|
||||
{
|
||||
"type" : "subpassInputMS",
|
||||
"name" : "uSubpass1",
|
||||
"set" : 0,
|
||||
"binding" : 1,
|
||||
"input_attachment_index" : 1
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "FragColor",
|
||||
"location" : 0
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"subpass_inputs" : [
|
||||
{
|
||||
"type" : "subpassInput",
|
||||
"name" : "uSubpass0",
|
||||
"set" : 0,
|
||||
"binding" : 0,
|
||||
"input_attachment_index" : 0
|
||||
},
|
||||
{
|
||||
"type" : "subpassInput",
|
||||
"name" : "uSubpass1",
|
||||
"set" : 0,
|
||||
"binding" : 1,
|
||||
"input_attachment_index" : 1
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "FragColor",
|
||||
"location" : 0
|
||||
}
|
||||
]
|
||||
}
|
46
reference/shaders-reflection/frag/push-constant.vk.frag.json
Normal file
46
reference/shaders-reflection/frag/push-constant.vk.frag.json
Normal file
@ -0,0 +1,46 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"types" : {
|
||||
"_13" : {
|
||||
"name" : "PushConstants",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "value0",
|
||||
"type" : "vec4",
|
||||
"offset" : 0
|
||||
},
|
||||
{
|
||||
"name" : "value1",
|
||||
"type" : "vec4",
|
||||
"offset" : 16
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"inputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "vColor",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "FragColor",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"push_constants" : [
|
||||
{
|
||||
"type" : "_13",
|
||||
"name" : "push",
|
||||
"push_constant" : true
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"inputs" : [
|
||||
{
|
||||
"type" : "vec2",
|
||||
"name" : "vTex",
|
||||
"location" : 0
|
||||
},
|
||||
{
|
||||
"type" : "vec3",
|
||||
"name" : "vTex3",
|
||||
"location" : 1
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "FragColor",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"separate_images" : [
|
||||
{
|
||||
"type" : "texture2D",
|
||||
"name" : "uTexture",
|
||||
"array" : [
|
||||
4
|
||||
],
|
||||
"set" : 0,
|
||||
"binding" : 1
|
||||
},
|
||||
{
|
||||
"type" : "texture2DArray",
|
||||
"name" : "uTextureArray",
|
||||
"array" : [
|
||||
4
|
||||
],
|
||||
"set" : 0,
|
||||
"binding" : 4
|
||||
},
|
||||
{
|
||||
"type" : "textureCube",
|
||||
"name" : "uTextureCube",
|
||||
"array" : [
|
||||
4
|
||||
],
|
||||
"set" : 0,
|
||||
"binding" : 3
|
||||
},
|
||||
{
|
||||
"type" : "texture3D",
|
||||
"name" : "uTexture3D",
|
||||
"array" : [
|
||||
4
|
||||
],
|
||||
"set" : 0,
|
||||
"binding" : 2
|
||||
}
|
||||
],
|
||||
"separate_samplers" : [
|
||||
{
|
||||
"type" : "sampler",
|
||||
"name" : "uSampler",
|
||||
"set" : 0,
|
||||
"binding" : 0
|
||||
}
|
||||
]
|
||||
}
|
71
reference/shaders-reflection/frag/spec-constant.vk.frag.json
Normal file
71
reference/shaders-reflection/frag/spec-constant.vk.frag.json
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"types" : {
|
||||
"_137" : {
|
||||
"name" : "Foo",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "elems",
|
||||
"type" : "float",
|
||||
"array" : [
|
||||
135
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "FragColor",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"specialization_constants" : [
|
||||
{
|
||||
"id" : 1,
|
||||
"type" : "float",
|
||||
"default_value" : 1.5
|
||||
},
|
||||
{
|
||||
"id" : 2,
|
||||
"type" : "float",
|
||||
"default_value" : 2.5
|
||||
},
|
||||
{
|
||||
"id" : 3,
|
||||
"type" : "int",
|
||||
"default_value" : 3
|
||||
},
|
||||
{
|
||||
"id" : 4,
|
||||
"type" : "int",
|
||||
"default_value" : 4
|
||||
},
|
||||
{
|
||||
"id" : 5,
|
||||
"type" : "uint",
|
||||
"default_value" : 5
|
||||
},
|
||||
{
|
||||
"id" : 6,
|
||||
"type" : "uint",
|
||||
"default_value" : 6
|
||||
},
|
||||
{
|
||||
"id" : 7,
|
||||
"type" : "bool",
|
||||
"default_value" : false
|
||||
},
|
||||
{
|
||||
"id" : 8,
|
||||
"type" : "bool",
|
||||
"default_value" : true
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "vert"
|
||||
}
|
||||
],
|
||||
"types" : {
|
||||
"_89" : {
|
||||
"name" : "gl_PerVertex",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "gl_Position",
|
||||
"type" : "vec4"
|
||||
},
|
||||
{
|
||||
"name" : "gl_PointSize",
|
||||
"type" : "float"
|
||||
}
|
||||
]
|
||||
},
|
||||
"_102" : {
|
||||
"name" : "Block",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "var",
|
||||
"type" : "mat2x3",
|
||||
"row_major" : true,
|
||||
"array" : [
|
||||
4,
|
||||
3
|
||||
],
|
||||
"offset" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"inputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "a_position",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "float",
|
||||
"name" : "v_vtxResult",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"ubos" : [
|
||||
{
|
||||
"type" : "_102",
|
||||
"name" : "Block",
|
||||
"block_size" : 576,
|
||||
"set" : 0,
|
||||
"binding" : 0
|
||||
}
|
||||
]
|
||||
}
|
40
reference/shaders-reflection/vert/texture_buffer.vert.json
Normal file
40
reference/shaders-reflection/vert/texture_buffer.vert.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "vert"
|
||||
}
|
||||
],
|
||||
"types" : {
|
||||
"_8" : {
|
||||
"name" : "gl_PerVertex",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "gl_Position",
|
||||
"type" : "vec4"
|
||||
},
|
||||
{
|
||||
"name" : "gl_PointSize",
|
||||
"type" : "float"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"textures" : [
|
||||
{
|
||||
"type" : "samplerBuffer",
|
||||
"name" : "uSamp",
|
||||
"set" : 0,
|
||||
"binding" : 4
|
||||
}
|
||||
],
|
||||
"images" : [
|
||||
{
|
||||
"type" : "imageBuffer",
|
||||
"name" : "uSampo",
|
||||
"set" : 0,
|
||||
"binding" : 5,
|
||||
"format" : "rgba32f"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
layout(location = 0) flat in mediump int vIndex;
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
highp float _19;
|
||||
switch (vIndex)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
{
|
||||
_19 = 1.0;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
default:
|
||||
{
|
||||
_19 = 3.0;
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
_19 = 8.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
FragColor = _19;
|
||||
}
|
||||
|
23
reference/shaders/asm/frag/unknown-depth-state.asm.vk.frag
Normal file
23
reference/shaders/asm/frag/unknown-depth-state.asm.vk.frag
Normal file
@ -0,0 +1,23 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler2DShadow uShadow;
|
||||
uniform sampler2DShadow SPIRV_Cross_CombineduTextureuSampler;
|
||||
|
||||
layout(location = 0) in vec3 vUV;
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
float sample_combined()
|
||||
{
|
||||
return texture(uShadow, vec3(vUV.xy, vUV.z));
|
||||
}
|
||||
|
||||
float sample_separate()
|
||||
{
|
||||
return texture(SPIRV_Cross_CombineduTextureuSampler, vec3(vUV.xy, vUV.z));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = sample_combined() + sample_separate();
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2DShadow uShadow;
|
||||
layout(set = 0, binding = 1) uniform texture2D uTexture;
|
||||
layout(set = 0, binding = 2) uniform samplerShadow uSampler;
|
||||
|
||||
layout(location = 0) in vec3 vUV;
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
float sample_combined()
|
||||
{
|
||||
return texture(uShadow, vec3(vUV.xy, vUV.z));
|
||||
}
|
||||
|
||||
float sample_separate()
|
||||
{
|
||||
return texture(sampler2DShadow(uTexture, uSampler), vec3(vUV.xy, vUV.z));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = sample_combined() + sample_separate();
|
||||
}
|
||||
|
41
reference/shaders/asm/geom/store-uint-layer.invalid.asm.geom
Normal file
41
reference/shaders/asm/geom/store-uint-layer.invalid.asm.geom
Normal file
@ -0,0 +1,41 @@
|
||||
#version 450
|
||||
layout(triangles) in;
|
||||
layout(max_vertices = 3, triangle_strip) out;
|
||||
|
||||
struct VertexOutput
|
||||
{
|
||||
vec4 pos;
|
||||
};
|
||||
|
||||
struct GeometryOutput
|
||||
{
|
||||
vec4 pos;
|
||||
uint layer;
|
||||
};
|
||||
|
||||
void _main(VertexOutput _input[3], GeometryOutput stream)
|
||||
{
|
||||
GeometryOutput _output;
|
||||
_output.layer = 1u;
|
||||
for (int v = 0; v < 3; v++)
|
||||
{
|
||||
_output.pos = _input[v].pos;
|
||||
gl_Position = _output.pos;
|
||||
gl_Layer = int(_output.layer);
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
VertexOutput _input[3];
|
||||
_input[0].pos = gl_in[0].gl_Position;
|
||||
_input[1].pos = gl_in[1].gl_Position;
|
||||
_input[2].pos = gl_in[2].gl_Position;
|
||||
VertexOutput param[3] = _input;
|
||||
GeometryOutput param_1;
|
||||
_main(param, param_1);
|
||||
GeometryOutput stream = param_1;
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
#version 450
|
||||
|
||||
uniform int SPIRV_Cross_BaseInstance;
|
||||
|
||||
vec4 _main(uint vid, uint iid)
|
||||
{
|
||||
return vec4(float(vid + iid));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
uint vid = uint(gl_VertexID);
|
||||
uint iid = uint((gl_InstanceID + SPIRV_Cross_BaseInstance));
|
||||
uint param = vid;
|
||||
uint param_1 = iid;
|
||||
gl_Position = _main(param, param_1);
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = float((10u > 20u) ? 30u : 50u);
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
#version 450
|
||||
|
||||
layout(constant_id = 0) const uint s = 10u;
|
||||
const bool _13 = (s > 20u);
|
||||
const uint _16 = _13 ? 30u : 50u;
|
||||
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = float(_16);
|
||||
}
|
||||
|
146
shaders-hlsl/asm/comp/control-flow-hints.asm.comp
Normal file
146
shaders-hlsl/asm/comp/control-flow-hints.asm.comp
Normal file
@ -0,0 +1,146 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 85
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
OpName %_main_ "@main("
|
||||
OpName %i "i"
|
||||
OpName %bar "bar"
|
||||
OpMemberName %bar 0 "@data"
|
||||
OpName %bar_0 "bar"
|
||||
OpName %foo "foo"
|
||||
OpName %i_0 "i"
|
||||
OpName %v "v"
|
||||
OpName %w "w"
|
||||
OpName %value "value"
|
||||
OpDecorate %_runtimearr_v4float ArrayStride 16
|
||||
OpMemberDecorate %bar 0 Offset 0
|
||||
OpDecorate %bar BufferBlock
|
||||
OpDecorate %bar_0 DescriptorSet 0
|
||||
OpDecorate %bar_0 Binding 0
|
||||
OpDecorate %foo DescriptorSet 0
|
||||
OpDecorate %foo Binding 1
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_16 = OpConstant %int 16
|
||||
%bool = OpTypeBool
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%_runtimearr_v4float = OpTypeRuntimeArray %v4float
|
||||
%bar = OpTypeStruct %_runtimearr_v4float
|
||||
%_ptr_Uniform_bar = OpTypePointer Uniform %bar
|
||||
%bar_0 = OpVariable %_ptr_Uniform_bar Uniform
|
||||
%foo = OpVariable %_ptr_Uniform_bar Uniform
|
||||
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_15 = OpConstant %int 15
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%int_10 = OpConstant %int 10
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Uniform_float = OpTypePointer Uniform %float
|
||||
%float_10 = OpConstant %float 10
|
||||
%int_20 = OpConstant %int 20
|
||||
%float_5 = OpConstant %float 5
|
||||
%72 = OpConstantComposite %v4float %float_5 %float_5 %float_5 %float_5
|
||||
%float_20 = OpConstant %float 20
|
||||
%float_40 = OpConstant %float 40
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%84 = OpFunctionCall %void %_main_
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_main_ = OpFunction %void None %3
|
||||
%7 = OpLabel
|
||||
%i = OpVariable %_ptr_Function_int Function
|
||||
%i_0 = OpVariable %_ptr_Function_int Function
|
||||
%v = OpVariable %_ptr_Function_float Function
|
||||
%w = OpVariable %_ptr_Function_float Function
|
||||
%value = OpVariable %_ptr_Function_float Function
|
||||
OpStore %i %int_0
|
||||
OpBranch %12
|
||||
%12 = OpLabel
|
||||
OpLoopMerge %14 %15 Unroll
|
||||
OpBranch %16
|
||||
%16 = OpLabel
|
||||
%17 = OpLoad %int %i
|
||||
%20 = OpSLessThan %bool %17 %int_16
|
||||
OpBranchConditional %20 %13 %14
|
||||
%13 = OpLabel
|
||||
%27 = OpLoad %int %i
|
||||
%29 = OpLoad %int %i
|
||||
%31 = OpAccessChain %_ptr_Uniform_v4float %foo %int_0 %29
|
||||
%32 = OpLoad %v4float %31
|
||||
%33 = OpAccessChain %_ptr_Uniform_v4float %bar_0 %int_0 %27
|
||||
OpStore %33 %32
|
||||
OpBranch %15
|
||||
%15 = OpLabel
|
||||
%34 = OpLoad %int %i
|
||||
%36 = OpIAdd %int %34 %int_1
|
||||
OpStore %i %36
|
||||
OpBranch %12
|
||||
%14 = OpLabel
|
||||
OpStore %i_0 %int_0
|
||||
OpBranch %38
|
||||
%38 = OpLabel
|
||||
OpLoopMerge %40 %41 DontUnroll
|
||||
OpBranch %42
|
||||
%42 = OpLabel
|
||||
%43 = OpLoad %int %i_0
|
||||
%44 = OpSLessThan %bool %43 %int_16
|
||||
OpBranchConditional %44 %39 %40
|
||||
%39 = OpLabel
|
||||
%46 = OpLoad %int %i_0
|
||||
%47 = OpISub %int %int_15 %46
|
||||
%48 = OpLoad %int %i_0
|
||||
%49 = OpAccessChain %_ptr_Uniform_v4float %foo %int_0 %48
|
||||
%50 = OpLoad %v4float %49
|
||||
%51 = OpAccessChain %_ptr_Uniform_v4float %bar_0 %int_0 %47
|
||||
OpStore %51 %50
|
||||
OpBranch %41
|
||||
%41 = OpLabel
|
||||
%52 = OpLoad %int %i_0
|
||||
%53 = OpIAdd %int %52 %int_1
|
||||
OpStore %i_0 %53
|
||||
OpBranch %38
|
||||
%40 = OpLabel
|
||||
%60 = OpAccessChain %_ptr_Uniform_float %bar_0 %int_0 %int_10 %uint_0
|
||||
%61 = OpLoad %float %60
|
||||
OpStore %v %61
|
||||
%63 = OpAccessChain %_ptr_Uniform_float %foo %int_0 %int_10 %uint_0
|
||||
%64 = OpLoad %float %63
|
||||
OpStore %w %64
|
||||
%65 = OpLoad %float %v
|
||||
%67 = OpFOrdGreaterThan %bool %65 %float_10
|
||||
OpSelectionMerge %69 DontFlatten
|
||||
OpBranchConditional %67 %68 %69
|
||||
%68 = OpLabel
|
||||
%73 = OpAccessChain %_ptr_Uniform_v4float %foo %int_0 %int_20
|
||||
OpStore %73 %72
|
||||
OpBranch %69
|
||||
%69 = OpLabel
|
||||
OpStore %value %float_20
|
||||
%76 = OpLoad %float %w
|
||||
%78 = OpFOrdGreaterThan %bool %76 %float_40
|
||||
OpSelectionMerge %80 Flatten
|
||||
OpBranchConditional %78 %79 %80
|
||||
%79 = OpLabel
|
||||
OpStore %value %float_20
|
||||
OpBranch %80
|
||||
%80 = OpLabel
|
||||
%81 = OpLoad %float %value
|
||||
%82 = OpCompositeConstruct %v4float %81 %81 %81 %81
|
||||
%83 = OpAccessChain %_ptr_Uniform_v4float %foo %int_0 %int_20
|
||||
OpStore %83 %82
|
||||
OpReturn
|
||||
OpFunctionEnd
|
71
shaders-hlsl/asm/frag/unknown-depth-state.asm.frag
Normal file
71
shaders-hlsl/asm/frag/unknown-depth-state.asm.frag
Normal file
@ -0,0 +1,71 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 44
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %vUV %FragColor
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %sample_combined_ "sample_combined("
|
||||
OpName %sample_separate_ "sample_separate("
|
||||
OpName %uShadow "uShadow"
|
||||
OpName %vUV "vUV"
|
||||
OpName %uTexture "uTexture"
|
||||
OpName %uSampler "uSampler"
|
||||
OpName %FragColor "FragColor"
|
||||
OpDecorate %uShadow DescriptorSet 0
|
||||
OpDecorate %uShadow Binding 0
|
||||
OpDecorate %vUV Location 0
|
||||
OpDecorate %uTexture DescriptorSet 0
|
||||
OpDecorate %uTexture Binding 1
|
||||
OpDecorate %uSampler DescriptorSet 0
|
||||
OpDecorate %uSampler Binding 2
|
||||
OpDecorate %FragColor Location 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%7 = OpTypeFunction %float
|
||||
%12 = OpTypeImage %float 2D 2 0 0 1 Unknown
|
||||
%13 = OpTypeSampledImage %12
|
||||
%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
|
||||
%uShadow = OpVariable %_ptr_UniformConstant_13 UniformConstant
|
||||
%v3float = OpTypeVector %float 3
|
||||
%_ptr_Input_v3float = OpTypePointer Input %v3float
|
||||
%vUV = OpVariable %_ptr_Input_v3float Input
|
||||
%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %12
|
||||
%uTexture = OpVariable %_ptr_UniformConstant_25 UniformConstant
|
||||
%29 = OpTypeSampler
|
||||
%_ptr_UniformConstant_29 = OpTypePointer UniformConstant %29
|
||||
%uSampler = OpVariable %_ptr_UniformConstant_29 UniformConstant
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%FragColor = OpVariable %_ptr_Output_float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%41 = OpFunctionCall %float %sample_combined_
|
||||
%42 = OpFunctionCall %float %sample_separate_
|
||||
%43 = OpFAdd %float %41 %42
|
||||
OpStore %FragColor %43
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%sample_combined_ = OpFunction %float None %7
|
||||
%9 = OpLabel
|
||||
%16 = OpLoad %13 %uShadow
|
||||
%20 = OpLoad %v3float %vUV
|
||||
%21 = OpCompositeExtract %float %20 2
|
||||
%22 = OpImageSampleDrefImplicitLod %float %16 %20 %21
|
||||
OpReturnValue %22
|
||||
OpFunctionEnd
|
||||
%sample_separate_ = OpFunction %float None %7
|
||||
%11 = OpLabel
|
||||
%28 = OpLoad %12 %uTexture
|
||||
%32 = OpLoad %29 %uSampler
|
||||
%33 = OpSampledImage %13 %28 %32
|
||||
%34 = OpLoad %v3float %vUV
|
||||
%35 = OpCompositeExtract %float %34 2
|
||||
%36 = OpImageSampleDrefImplicitLod %float %33 %34 %35
|
||||
OpReturnValue %36
|
||||
OpFunctionEnd
|
65
shaders-hlsl/asm/vert/uint-vertex-id-instance-id.asm.vert
Normal file
65
shaders-hlsl/asm/vert/uint-vertex-id-instance-id.asm.vert
Normal file
@ -0,0 +1,65 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 36
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %main "main" %vid_1 %iid_1 %_entryPointOutput
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
OpName %_main_u1_u1_ "@main(u1;u1;"
|
||||
OpName %vid "vid"
|
||||
OpName %iid "iid"
|
||||
OpName %vid_0 "vid"
|
||||
OpName %vid_1 "vid"
|
||||
OpName %iid_0 "iid"
|
||||
OpName %iid_1 "iid"
|
||||
OpName %_entryPointOutput "@entryPointOutput"
|
||||
OpName %param "param"
|
||||
OpName %param_0 "param"
|
||||
OpDecorate %vid_1 BuiltIn VertexIndex
|
||||
OpDecorate %iid_1 BuiltIn InstanceIndex
|
||||
OpDecorate %_entryPointOutput BuiltIn Position
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%uint = OpTypeInt 32 0
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%10 = OpTypeFunction %v4float %_ptr_Function_uint %_ptr_Function_uint
|
||||
%_ptr_Input_uint = OpTypePointer Input %uint
|
||||
%vid_1 = OpVariable %_ptr_Input_uint Input
|
||||
%iid_1 = OpVariable %_ptr_Input_uint Input
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%vid_0 = OpVariable %_ptr_Function_uint Function
|
||||
%iid_0 = OpVariable %_ptr_Function_uint Function
|
||||
%param = OpVariable %_ptr_Function_uint Function
|
||||
%param_0 = OpVariable %_ptr_Function_uint Function
|
||||
%25 = OpLoad %uint %vid_1
|
||||
OpStore %vid_0 %25
|
||||
%28 = OpLoad %uint %iid_1
|
||||
OpStore %iid_0 %28
|
||||
%32 = OpLoad %uint %vid_0
|
||||
OpStore %param %32
|
||||
%34 = OpLoad %uint %iid_0
|
||||
OpStore %param_0 %34
|
||||
%35 = OpFunctionCall %v4float %_main_u1_u1_ %param %param_0
|
||||
OpStore %_entryPointOutput %35
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_main_u1_u1_ = OpFunction %v4float None %10
|
||||
%vid = OpFunctionParameter %_ptr_Function_uint
|
||||
%iid = OpFunctionParameter %_ptr_Function_uint
|
||||
%14 = OpLabel
|
||||
%15 = OpLoad %uint %vid
|
||||
%16 = OpLoad %uint %iid
|
||||
%17 = OpIAdd %uint %15 %16
|
||||
%18 = OpConvertUToF %float %17
|
||||
%19 = OpCompositeConstruct %v4float %18 %18 %18 %18
|
||||
OpReturnValue %19
|
||||
OpFunctionEnd
|
25
shaders-hlsl/comp/globallycoherent.comp
Normal file
25
shaders-hlsl/comp/globallycoherent.comp
Normal file
@ -0,0 +1,25 @@
|
||||
#version 450
|
||||
layout(local_size_x = 1) in;
|
||||
|
||||
layout(r32f, binding = 0) uniform readonly image2D uImageIn;
|
||||
layout(r32f, binding = 1) uniform coherent writeonly image2D uImageOut;
|
||||
|
||||
layout(set = 0, binding = 2) readonly buffer Foo
|
||||
{
|
||||
float foo;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 3) coherent writeonly buffer Bar
|
||||
{
|
||||
float bar;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 coord = ivec2(9, 7);
|
||||
vec4 indata = imageLoad(uImageIn, coord);
|
||||
imageStore(uImageOut, coord, indata);
|
||||
|
||||
bar = foo;
|
||||
}
|
||||
|
9
shaders-hlsl/frag/spec-constant-ternary.frag
Normal file
9
shaders-hlsl/frag/spec-constant-ternary.frag
Normal file
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
layout(location = 0) out float FragColor;
|
||||
layout(constant_id = 0) const uint s = 10u;
|
||||
const uint f = s > 20u ? 30u : 50u;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = float(f);
|
||||
}
|
71
shaders-msl/asm/frag/unknown-depth-state.asm.frag
Normal file
71
shaders-msl/asm/frag/unknown-depth-state.asm.frag
Normal file
@ -0,0 +1,71 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 44
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %vUV %FragColor
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %sample_combined_ "sample_combined("
|
||||
OpName %sample_separate_ "sample_separate("
|
||||
OpName %uShadow "uShadow"
|
||||
OpName %vUV "vUV"
|
||||
OpName %uTexture "uTexture"
|
||||
OpName %uSampler "uSampler"
|
||||
OpName %FragColor "FragColor"
|
||||
OpDecorate %uShadow DescriptorSet 0
|
||||
OpDecorate %uShadow Binding 0
|
||||
OpDecorate %vUV Location 0
|
||||
OpDecorate %uTexture DescriptorSet 0
|
||||
OpDecorate %uTexture Binding 1
|
||||
OpDecorate %uSampler DescriptorSet 0
|
||||
OpDecorate %uSampler Binding 2
|
||||
OpDecorate %FragColor Location 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%7 = OpTypeFunction %float
|
||||
%12 = OpTypeImage %float 2D 2 0 0 1 Unknown
|
||||
%13 = OpTypeSampledImage %12
|
||||
%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
|
||||
%uShadow = OpVariable %_ptr_UniformConstant_13 UniformConstant
|
||||
%v3float = OpTypeVector %float 3
|
||||
%_ptr_Input_v3float = OpTypePointer Input %v3float
|
||||
%vUV = OpVariable %_ptr_Input_v3float Input
|
||||
%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %12
|
||||
%uTexture = OpVariable %_ptr_UniformConstant_25 UniformConstant
|
||||
%29 = OpTypeSampler
|
||||
%_ptr_UniformConstant_29 = OpTypePointer UniformConstant %29
|
||||
%uSampler = OpVariable %_ptr_UniformConstant_29 UniformConstant
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%FragColor = OpVariable %_ptr_Output_float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%41 = OpFunctionCall %float %sample_combined_
|
||||
%42 = OpFunctionCall %float %sample_separate_
|
||||
%43 = OpFAdd %float %41 %42
|
||||
OpStore %FragColor %43
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%sample_combined_ = OpFunction %float None %7
|
||||
%9 = OpLabel
|
||||
%16 = OpLoad %13 %uShadow
|
||||
%20 = OpLoad %v3float %vUV
|
||||
%21 = OpCompositeExtract %float %20 2
|
||||
%22 = OpImageSampleDrefImplicitLod %float %16 %20 %21
|
||||
OpReturnValue %22
|
||||
OpFunctionEnd
|
||||
%sample_separate_ = OpFunction %float None %7
|
||||
%11 = OpLabel
|
||||
%28 = OpLoad %12 %uTexture
|
||||
%32 = OpLoad %29 %uSampler
|
||||
%33 = OpSampledImage %13 %28 %32
|
||||
%34 = OpLoad %v3float %vUV
|
||||
%35 = OpCompositeExtract %float %34 2
|
||||
%36 = OpImageSampleDrefImplicitLod %float %33 %34 %35
|
||||
OpReturnValue %36
|
||||
OpFunctionEnd
|
65
shaders-msl/asm/vert/uint-vertex-id-instance-id.asm.vert
Normal file
65
shaders-msl/asm/vert/uint-vertex-id-instance-id.asm.vert
Normal file
@ -0,0 +1,65 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 36
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %main "main" %vid_1 %iid_1 %_entryPointOutput
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
OpName %_main_u1_u1_ "@main(u1;u1;"
|
||||
OpName %vid "vid"
|
||||
OpName %iid "iid"
|
||||
OpName %vid_0 "vid"
|
||||
OpName %vid_1 "vid"
|
||||
OpName %iid_0 "iid"
|
||||
OpName %iid_1 "iid"
|
||||
OpName %_entryPointOutput "@entryPointOutput"
|
||||
OpName %param "param"
|
||||
OpName %param_0 "param"
|
||||
OpDecorate %vid_1 BuiltIn VertexIndex
|
||||
OpDecorate %iid_1 BuiltIn InstanceIndex
|
||||
OpDecorate %_entryPointOutput BuiltIn Position
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%uint = OpTypeInt 32 0
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%10 = OpTypeFunction %v4float %_ptr_Function_uint %_ptr_Function_uint
|
||||
%_ptr_Input_uint = OpTypePointer Input %uint
|
||||
%vid_1 = OpVariable %_ptr_Input_uint Input
|
||||
%iid_1 = OpVariable %_ptr_Input_uint Input
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%vid_0 = OpVariable %_ptr_Function_uint Function
|
||||
%iid_0 = OpVariable %_ptr_Function_uint Function
|
||||
%param = OpVariable %_ptr_Function_uint Function
|
||||
%param_0 = OpVariable %_ptr_Function_uint Function
|
||||
%25 = OpLoad %uint %vid_1
|
||||
OpStore %vid_0 %25
|
||||
%28 = OpLoad %uint %iid_1
|
||||
OpStore %iid_0 %28
|
||||
%32 = OpLoad %uint %vid_0
|
||||
OpStore %param %32
|
||||
%34 = OpLoad %uint %iid_0
|
||||
OpStore %param_0 %34
|
||||
%35 = OpFunctionCall %v4float %_main_u1_u1_ %param %param_0
|
||||
OpStore %_entryPointOutput %35
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_main_u1_u1_ = OpFunction %v4float None %10
|
||||
%vid = OpFunctionParameter %_ptr_Function_uint
|
||||
%iid = OpFunctionParameter %_ptr_Function_uint
|
||||
%14 = OpLabel
|
||||
%15 = OpLoad %uint %vid
|
||||
%16 = OpLoad %uint %iid
|
||||
%17 = OpIAdd %uint %15 %16
|
||||
%18 = OpConvertUToF %float %17
|
||||
%19 = OpCompositeConstruct %v4float %18 %18 %18 %18
|
||||
OpReturnValue %19
|
||||
OpFunctionEnd
|
9
shaders-msl/frag/spec-constant-ternary.frag
Normal file
9
shaders-msl/frag/spec-constant-ternary.frag
Normal file
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
layout(location = 0) out float FragColor;
|
||||
layout(constant_id = 0) const uint s = 10u;
|
||||
const uint f = s > 20u ? 30u : 50u;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = float(f);
|
||||
}
|
12
shaders-msl/vert/set_builtin_in_func.vert
Normal file
12
shaders-msl/vert/set_builtin_in_func.vert
Normal file
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
|
||||
void write_outblock()
|
||||
{
|
||||
gl_PointSize = 1.0;
|
||||
gl_Position = vec4(gl_PointSize);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
write_outblock();
|
||||
}
|
60
shaders-reflection/asm/aliased-entry-point-names.asm.multi
Normal file
60
shaders-reflection/asm/aliased-entry-point-names.asm.multi
Normal file
@ -0,0 +1,60 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 3
|
||||
; Bound: 20
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %main "main" %_
|
||||
OpEntryPoint Vertex %main2 "main2" %_
|
||||
OpEntryPoint Fragment %main3 "main" %FragColor
|
||||
OpEntryPoint Fragment %main4 "main2" %FragColor
|
||||
OpSource GLSL 450
|
||||
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
|
||||
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
|
||||
OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
|
||||
OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
|
||||
OpDecorate %FragColor Location 0
|
||||
OpDecorate %gl_PerVertex Block
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%v4floatptr = OpTypePointer Output %v4float
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_1 = OpConstant %uint 1
|
||||
%_arr_float_uint_1 = OpTypeArray %float %uint_1
|
||||
%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
|
||||
%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
|
||||
%_ = OpVariable %_ptr_Output_gl_PerVertex Output
|
||||
%FragColor = OpVariable %v4floatptr Output
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%float_1 = OpConstant %float 1
|
||||
%17 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
|
||||
%float_2 = OpConstant %float 2
|
||||
%18 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%19 = OpAccessChain %_ptr_Output_v4float %_ %int_0
|
||||
OpStore %19 %17
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%main2 = OpFunction %void None %3
|
||||
%6 = OpLabel
|
||||
%20 = OpAccessChain %_ptr_Output_v4float %_ %int_0
|
||||
OpStore %20 %18
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%main3 = OpFunction %void None %3
|
||||
%7 = OpLabel
|
||||
OpStore %FragColor %17
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%main4 = OpFunction %void None %3
|
||||
%8 = OpLabel
|
||||
OpStore %FragColor %18
|
||||
OpReturn
|
||||
OpFunctionEnd
|
24
shaders-reflection/comp/struct-layout.comp
Normal file
24
shaders-reflection/comp/struct-layout.comp
Normal file
@ -0,0 +1,24 @@
|
||||
#version 310 es
|
||||
layout(local_size_x = 1) in;
|
||||
|
||||
struct Foo
|
||||
{
|
||||
mat4 m;
|
||||
};
|
||||
|
||||
layout(std430, binding = 0) readonly buffer SSBO
|
||||
{
|
||||
Foo in_data[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 1) writeonly buffer SSBO2
|
||||
{
|
||||
Foo out_data[];
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
uint ident = gl_GlobalInvocationID.x;
|
||||
out_data[ident].m = in_data[ident].m * in_data[ident].m;
|
||||
}
|
||||
|
87
shaders-reflection/comp/struct-packing.comp
Normal file
87
shaders-reflection/comp/struct-packing.comp
Normal file
@ -0,0 +1,87 @@
|
||||
#version 450
|
||||
|
||||
layout(local_size_x = 1) in;
|
||||
|
||||
struct S0
|
||||
{
|
||||
vec2 a[1];
|
||||
float b;
|
||||
};
|
||||
|
||||
struct S1
|
||||
{
|
||||
vec3 a;
|
||||
float b;
|
||||
};
|
||||
|
||||
struct S2
|
||||
{
|
||||
vec3 a[1];
|
||||
float b;
|
||||
};
|
||||
|
||||
struct S3
|
||||
{
|
||||
vec2 a;
|
||||
float b;
|
||||
};
|
||||
|
||||
struct S4
|
||||
{
|
||||
vec2 c;
|
||||
};
|
||||
|
||||
struct Content
|
||||
{
|
||||
S0 m0s[1];
|
||||
S1 m1s[1];
|
||||
S2 m2s[1];
|
||||
S0 m0;
|
||||
S1 m1;
|
||||
S2 m2;
|
||||
S3 m3;
|
||||
float m4;
|
||||
|
||||
S4 m3s[8];
|
||||
};
|
||||
|
||||
layout(binding = 1, std430) restrict buffer SSBO1
|
||||
{
|
||||
Content content;
|
||||
Content content1[2];
|
||||
Content content2;
|
||||
|
||||
layout(column_major) mat2 m0;
|
||||
layout(column_major) mat2 m1;
|
||||
layout(column_major) mat2x3 m2[4];
|
||||
layout(column_major) mat3x2 m3;
|
||||
layout(row_major) mat2 m4;
|
||||
layout(row_major) mat2 m5[9];
|
||||
layout(row_major) mat2x3 m6[4][2];
|
||||
layout(row_major) mat3x2 m7;
|
||||
float array[];
|
||||
} ssbo_430;
|
||||
|
||||
layout(binding = 0, std140) restrict buffer SSBO0
|
||||
{
|
||||
Content content;
|
||||
Content content1[2];
|
||||
Content content2;
|
||||
|
||||
layout(column_major) mat2 m0;
|
||||
layout(column_major) mat2 m1;
|
||||
layout(column_major) mat2x3 m2[4];
|
||||
layout(column_major) mat3x2 m3;
|
||||
layout(row_major) mat2 m4;
|
||||
layout(row_major) mat2 m5[9];
|
||||
layout(row_major) mat2x3 m6[4][2];
|
||||
layout(row_major) mat3x2 m7;
|
||||
|
||||
float array[];
|
||||
} ssbo_140;
|
||||
|
||||
void main()
|
||||
{
|
||||
ssbo_430.content = ssbo_140.content;
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(set = 0, binding = 0) uniform mediump samplerShadow uSampler;
|
||||
layout(set = 0, binding = 1) uniform mediump sampler uSampler1;
|
||||
layout(set = 0, binding = 2) uniform texture2D uDepth;
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
float samp2(texture2D t, mediump samplerShadow s)
|
||||
{
|
||||
return texture(sampler2DShadow(t, s), vec3(1.0));
|
||||
}
|
||||
|
||||
float samp3(texture2D t, mediump sampler s)
|
||||
{
|
||||
return texture(sampler2D(t, s), vec2(1.0)).x;
|
||||
}
|
||||
|
||||
float samp(texture2D t, mediump samplerShadow s, mediump sampler s1)
|
||||
{
|
||||
float r0 = samp2(t, s);
|
||||
float r1 = samp3(t, s1);
|
||||
return r0 + r1;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = samp(uDepth, uSampler, uSampler1);
|
||||
}
|
47
shaders-reflection/frag/combined-texture-sampler.vk.frag
Normal file
47
shaders-reflection/frag/combined-texture-sampler.vk.frag
Normal file
@ -0,0 +1,47 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(set = 0, binding = 0) uniform mediump sampler uSampler0;
|
||||
layout(set = 0, binding = 1) uniform mediump sampler uSampler1;
|
||||
layout(set = 0, binding = 2) uniform mediump texture2D uTexture0;
|
||||
layout(set = 0, binding = 3) uniform mediump texture2D uTexture1;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) in vec2 vTex;
|
||||
|
||||
vec4 sample_dual(mediump sampler samp, mediump texture2D tex)
|
||||
{
|
||||
return texture(sampler2D(tex, samp), vTex);
|
||||
}
|
||||
|
||||
vec4 sample_global_tex(mediump sampler samp)
|
||||
{
|
||||
vec4 a = texture(sampler2D(uTexture0, samp), vTex);
|
||||
vec4 b = sample_dual(samp, uTexture1);
|
||||
return a + b;
|
||||
}
|
||||
|
||||
vec4 sample_global_sampler(mediump texture2D tex)
|
||||
{
|
||||
vec4 a = texture(sampler2D(tex, uSampler0), vTex);
|
||||
vec4 b = sample_dual(uSampler1, tex);
|
||||
return a + b;
|
||||
}
|
||||
|
||||
vec4 sample_duals()
|
||||
{
|
||||
vec4 a = sample_dual(uSampler0, uTexture0);
|
||||
vec4 b = sample_dual(uSampler1, uTexture1);
|
||||
return a + b;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c0 = sample_duals();
|
||||
vec4 c1 = sample_global_tex(uSampler0);
|
||||
vec4 c2 = sample_global_tex(uSampler1);
|
||||
vec4 c3 = sample_global_sampler(uTexture0);
|
||||
vec4 c4 = sample_global_sampler(uTexture1);
|
||||
|
||||
FragColor = c0 + c1 + c2 + c3 + c4;
|
||||
}
|
103
shaders-reflection/frag/image-load-store-uint-coord.asm.frag
Normal file
103
shaders-reflection/frag/image-load-store-uint-coord.asm.frag
Normal file
@ -0,0 +1,103 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 2
|
||||
; Bound: 63
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpCapability SampledBuffer
|
||||
OpCapability ImageBuffer
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %_entryPointOutput
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
OpName %_main_ "@main("
|
||||
OpName %storeTemp "storeTemp"
|
||||
OpName %RWIm "RWIm"
|
||||
OpName %v "v"
|
||||
OpName %RWBuf "RWBuf"
|
||||
OpName %ROIm "ROIm"
|
||||
OpName %ROBuf "ROBuf"
|
||||
OpName %_entryPointOutput "@entryPointOutput"
|
||||
OpDecorate %RWIm DescriptorSet 0
|
||||
OpDecorate %RWIm Binding 1
|
||||
OpDecorate %RWBuf DescriptorSet 0
|
||||
OpDecorate %RWBuf Binding 0
|
||||
OpDecorate %ROIm DescriptorSet 0
|
||||
OpDecorate %ROIm Binding 1
|
||||
OpDecorate %ROBuf DescriptorSet 0
|
||||
OpDecorate %ROBuf Binding 0
|
||||
OpDecorate %_entryPointOutput Location 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%8 = OpTypeFunction %v4float
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%float_10 = OpConstant %float 10
|
||||
%float_0_5 = OpConstant %float 0.5
|
||||
%float_8 = OpConstant %float 8
|
||||
%float_2 = OpConstant %float 2
|
||||
%17 = OpConstantComposite %v4float %float_10 %float_0_5 %float_8 %float_2
|
||||
%18 = OpTypeImage %float 2D 0 0 0 2 Rgba32f
|
||||
%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
|
||||
%RWIm = OpVariable %_ptr_UniformConstant_18 UniformConstant
|
||||
%uint = OpTypeInt 32 0
|
||||
%v2uint = OpTypeVector %uint 2
|
||||
%uint_10 = OpConstant %uint 10
|
||||
%25 = OpConstantComposite %v2uint %uint_10 %uint_10
|
||||
%uint_30 = OpConstant %uint 30
|
||||
%30 = OpConstantComposite %v2uint %uint_30 %uint_30
|
||||
%32 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f
|
||||
%_ptr_UniformConstant_32 = OpTypePointer UniformConstant %32
|
||||
%RWBuf = OpVariable %_ptr_UniformConstant_32 UniformConstant
|
||||
%uint_80 = OpConstant %uint 80
|
||||
%38 = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%SampledImage = OpTypeSampledImage %38
|
||||
%_ptr_UniformConstant_38 = OpTypePointer UniformConstant %SampledImage
|
||||
%ROIm = OpVariable %_ptr_UniformConstant_38 UniformConstant
|
||||
%uint_50 = OpConstant %uint 50
|
||||
%uint_60 = OpConstant %uint 60
|
||||
%44 = OpConstantComposite %v2uint %uint_50 %uint_60
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%50 = OpTypeImage %float Buffer 0 0 0 1 Rgba32f
|
||||
%_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50
|
||||
%ROBuf = OpVariable %_ptr_UniformConstant_50 UniformConstant
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%62 = OpFunctionCall %v4float %_main_
|
||||
OpStore %_entryPointOutput %62
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_main_ = OpFunction %v4float None %8
|
||||
%10 = OpLabel
|
||||
%storeTemp = OpVariable %_ptr_Function_v4float Function
|
||||
%v = OpVariable %_ptr_Function_v4float Function
|
||||
OpStore %storeTemp %17
|
||||
%21 = OpLoad %18 %RWIm
|
||||
%26 = OpLoad %v4float %storeTemp
|
||||
OpImageWrite %21 %25 %26
|
||||
%28 = OpLoad %18 %RWIm
|
||||
%31 = OpImageRead %v4float %28 %30
|
||||
OpStore %v %31
|
||||
%35 = OpLoad %32 %RWBuf
|
||||
%37 = OpLoad %v4float %v
|
||||
OpImageWrite %35 %uint_80 %37
|
||||
%41 = OpLoad %SampledImage %ROIm
|
||||
%ROImage = OpImage %38 %41
|
||||
%47 = OpImageFetch %v4float %ROImage %44 Lod %int_0
|
||||
%48 = OpLoad %v4float %v
|
||||
%49 = OpFAdd %v4float %48 %47
|
||||
OpStore %v %49
|
||||
%53 = OpLoad %50 %ROBuf
|
||||
%54 = OpImageFetch %v4float %53 %uint_80
|
||||
%55 = OpLoad %v4float %v
|
||||
%56 = OpFAdd %v4float %55 %54
|
||||
OpStore %v %56
|
||||
%57 = OpLoad %v4float %v
|
||||
OpReturnValue %57
|
||||
OpFunctionEnd
|
10
shaders-reflection/frag/input-attachment-ms.vk.frag
Normal file
10
shaders-reflection/frag/input-attachment-ms.vk.frag
Normal file
@ -0,0 +1,10 @@
|
||||
#version 450
|
||||
|
||||
layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInputMS uSubpass0;
|
||||
layout(input_attachment_index = 1, set = 0, binding = 1) uniform subpassInputMS uSubpass1;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = subpassLoad(uSubpass0, 1) + subpassLoad(uSubpass1, 2) + subpassLoad(uSubpass0, gl_SampleID);
|
||||
}
|
11
shaders-reflection/frag/input-attachment.vk.frag
Normal file
11
shaders-reflection/frag/input-attachment.vk.frag
Normal file
@ -0,0 +1,11 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(input_attachment_index = 0, set = 0, binding = 0) uniform mediump subpassInput uSubpass0;
|
||||
layout(input_attachment_index = 1, set = 0, binding = 1) uniform mediump subpassInput uSubpass1;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = subpassLoad(uSubpass0) + subpassLoad(uSubpass1);
|
||||
}
|
16
shaders-reflection/frag/push-constant.vk.frag
Normal file
16
shaders-reflection/frag/push-constant.vk.frag
Normal file
@ -0,0 +1,16 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(push_constant, std430) uniform PushConstants
|
||||
{
|
||||
vec4 value0;
|
||||
vec4 value1;
|
||||
} push;
|
||||
|
||||
layout(location = 0) in vec4 vColor;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vColor + push.value0 + push.value1;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(set = 0, binding = 0) uniform mediump sampler uSampler;
|
||||
layout(set = 0, binding = 1) uniform mediump texture2D uTexture[4];
|
||||
layout(set = 0, binding = 2) uniform mediump texture3D uTexture3D[4];
|
||||
layout(set = 0, binding = 3) uniform mediump textureCube uTextureCube[4];
|
||||
layout(set = 0, binding = 4) uniform mediump texture2DArray uTextureArray[4];
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) in vec2 vTex;
|
||||
layout(location = 1) in vec3 vTex3;
|
||||
|
||||
vec4 sample_func(mediump sampler samp, vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(uTexture[2], samp), uv);
|
||||
}
|
||||
|
||||
vec4 sample_func_dual(mediump sampler samp, mediump texture2D tex, vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(tex, samp), uv);
|
||||
}
|
||||
|
||||
vec4 sample_func_dual_array(mediump sampler samp, mediump texture2D tex[4], vec2 uv)
|
||||
{
|
||||
return texture(sampler2D(tex[1], samp), uv);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 off = 1.0 / vec2(textureSize(sampler2D(uTexture[1], uSampler), 0));
|
||||
vec2 off2 = 1.0 / vec2(textureSize(sampler2D(uTexture[2], uSampler), 1));
|
||||
|
||||
vec4 c0 = sample_func(uSampler, vTex + off + off2);
|
||||
vec4 c1 = sample_func_dual(uSampler, uTexture[1], vTex + off + off2);
|
||||
vec4 c2 = sample_func_dual_array(uSampler, uTexture, vTex + off + off2);
|
||||
vec4 c3 = texture(sampler2DArray(uTextureArray[3], uSampler), vTex3);
|
||||
vec4 c4 = texture(samplerCube(uTextureCube[1], uSampler), vTex3);
|
||||
vec4 c5 = texture(sampler3D(uTexture3D[2], uSampler), vTex3);
|
||||
|
||||
FragColor = c0 + c1 + c2 + c3 + c4 + c5;
|
||||
}
|
78
shaders-reflection/frag/spec-constant.vk.frag
Normal file
78
shaders-reflection/frag/spec-constant.vk.frag
Normal file
@ -0,0 +1,78 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(constant_id = 1) const float a = 1.5;
|
||||
layout(constant_id = 2) const float b = 2.5;
|
||||
layout(constant_id = 3) const int c = 3;
|
||||
layout(constant_id = 4) const int d = 4;
|
||||
layout(constant_id = 5) const uint e = 5u;
|
||||
layout(constant_id = 6) const uint f = 6u;
|
||||
layout(constant_id = 7) const bool g = false;
|
||||
layout(constant_id = 8) const bool h = true;
|
||||
|
||||
// glslang doesn't seem to support partial spec constants or composites yet, so only test the basics.
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float elems[d + 2];
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
float t0 = a;
|
||||
float t1 = b;
|
||||
|
||||
uint c0 = uint(c); // OpIAdd with different types.
|
||||
// FConvert, float-to-double.
|
||||
int c1 = -c; // SNegate
|
||||
int c2 = ~c; // OpNot
|
||||
int c3 = c + d; // OpIAdd
|
||||
int c4 = c - d; // OpISub
|
||||
int c5 = c * d; // OpIMul
|
||||
int c6 = c / d; // OpSDiv
|
||||
uint c7 = e / f; // OpUDiv
|
||||
int c8 = c % d; // OpSMod
|
||||
uint c9 = e % f; // OpUMod
|
||||
// TODO: OpSRem, any way to access this in GLSL?
|
||||
int c10 = c >> d; // OpShiftRightArithmetic
|
||||
uint c11 = e >> f; // OpShiftRightLogical
|
||||
int c12 = c << d; // OpShiftLeftLogical
|
||||
int c13 = c | d; // OpBitwiseOr
|
||||
int c14 = c ^ d; // OpBitwiseXor
|
||||
int c15 = c & d; // OpBitwiseAnd
|
||||
// VectorShuffle, CompositeExtract, CompositeInsert, not testable atm.
|
||||
bool c16 = g || h; // OpLogicalOr
|
||||
bool c17 = g && h; // OpLogicalAnd
|
||||
bool c18 = !g; // OpLogicalNot
|
||||
bool c19 = g == h; // OpLogicalEqual
|
||||
bool c20 = g != h; // OpLogicalNotEqual
|
||||
// OpSelect not testable atm.
|
||||
bool c21 = c == d; // OpIEqual
|
||||
bool c22 = c != d; // OpINotEqual
|
||||
bool c23 = c < d; // OpSLessThan
|
||||
bool c24 = e < f; // OpULessThan
|
||||
bool c25 = c > d; // OpSGreaterThan
|
||||
bool c26 = e > f; // OpUGreaterThan
|
||||
bool c27 = c <= d; // OpSLessThanEqual
|
||||
bool c28 = e <= f; // OpULessThanEqual
|
||||
bool c29 = c >= d; // OpSGreaterThanEqual
|
||||
bool c30 = e >= f; // OpUGreaterThanEqual
|
||||
// OpQuantizeToF16 not testable atm.
|
||||
|
||||
int c31 = c8 + c3;
|
||||
|
||||
int c32 = int(e); // OpIAdd with different types.
|
||||
bool c33 = bool(c); // int -> bool
|
||||
bool c34 = bool(e); // uint -> bool
|
||||
int c35 = int(g); // bool -> int
|
||||
uint c36 = uint(g); // bool -> uint
|
||||
float c37 = float(g); // bool -> float
|
||||
|
||||
// Flexible sized arrays with spec constants and spec constant ops.
|
||||
float vec0[c + 3][8];
|
||||
float vec1[c + 2];
|
||||
|
||||
Foo foo;
|
||||
FragColor = vec4(t0 + t1) + vec0[0][0] + vec1[0] + foo.elems[c];
|
||||
}
|
20
shaders-reflection/vert/read-from-row-major-array.vert
Normal file
20
shaders-reflection/vert/read-from-row-major-array.vert
Normal file
@ -0,0 +1,20 @@
|
||||
#version 310 es
|
||||
layout(location = 0) in highp vec4 a_position;
|
||||
layout(location = 0) out mediump float v_vtxResult;
|
||||
|
||||
layout(set = 0, binding = 0, std140, row_major) uniform Block
|
||||
{
|
||||
highp mat2x3 var[3][4];
|
||||
};
|
||||
|
||||
mediump float compare_float (highp float a, highp float b) { return abs(a - b) < 0.05 ? 1.0 : 0.0; }
|
||||
mediump float compare_vec3 (highp vec3 a, highp vec3 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z); }
|
||||
mediump float compare_mat2x3 (highp mat2x3 a, highp mat2x3 b){ return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1]); }
|
||||
|
||||
void main (void)
|
||||
{
|
||||
gl_Position = a_position;
|
||||
mediump float result = 1.0;
|
||||
result *= compare_mat2x3(var[0][0], mat2x3(2.0, 6.0, -6.0, 0.0, 5.0, 5.0));
|
||||
v_vtxResult = result;
|
||||
}
|
10
shaders-reflection/vert/texture_buffer.vert
Normal file
10
shaders-reflection/vert/texture_buffer.vert
Normal file
@ -0,0 +1,10 @@
|
||||
#version 310 es
|
||||
#extension GL_OES_texture_buffer : require
|
||||
|
||||
layout(binding = 4) uniform highp samplerBuffer uSamp;
|
||||
layout(rgba32f, binding = 5) uniform readonly highp imageBuffer uSampo;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = texelFetch(uSamp, 10) + imageLoad(uSampo, 100);
|
||||
}
|
45
shaders/asm/frag/switch-label-shared-block.asm.frag
Normal file
45
shaders/asm/frag/switch-label-shared-block.asm.frag
Normal file
@ -0,0 +1,45 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 28
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %vIndex %FragColor
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource ESSL 310
|
||||
OpName %main "main"
|
||||
OpName %vIndex "vIndex"
|
||||
OpName %FragColor "FragColor"
|
||||
OpDecorate %vIndex RelaxedPrecision
|
||||
OpDecorate %vIndex Flat
|
||||
OpDecorate %vIndex Location 0
|
||||
OpDecorate %13 RelaxedPrecision
|
||||
OpDecorate %FragColor RelaxedPrecision
|
||||
OpDecorate %FragColor Location 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%float_8 = OpConstant %float 8
|
||||
%int = OpTypeInt 32 1
|
||||
%_ptr_Input_int = OpTypePointer Input %int
|
||||
%vIndex = OpVariable %_ptr_Input_int Input
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_3 = OpConstant %float 3
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%FragColor = OpVariable %_ptr_Output_float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%13 = OpLoad %int %vIndex
|
||||
OpSelectionMerge %17 None
|
||||
OpSwitch %13 %15 0 %14 2 %14 1 %15 8 %17
|
||||
%15 = OpLabel
|
||||
OpBranch %17
|
||||
%14 = OpLabel
|
||||
OpBranch %17
|
||||
%17 = OpLabel
|
||||
%27 = OpPhi %float %float_3 %15 %float_1 %14 %float_8 %5
|
||||
OpStore %FragColor %27
|
||||
OpReturn
|
||||
OpFunctionEnd
|
71
shaders/asm/frag/unknown-depth-state.asm.vk.frag
Normal file
71
shaders/asm/frag/unknown-depth-state.asm.vk.frag
Normal file
@ -0,0 +1,71 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 44
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %vUV %FragColor
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %sample_combined_ "sample_combined("
|
||||
OpName %sample_separate_ "sample_separate("
|
||||
OpName %uShadow "uShadow"
|
||||
OpName %vUV "vUV"
|
||||
OpName %uTexture "uTexture"
|
||||
OpName %uSampler "uSampler"
|
||||
OpName %FragColor "FragColor"
|
||||
OpDecorate %uShadow DescriptorSet 0
|
||||
OpDecorate %uShadow Binding 0
|
||||
OpDecorate %vUV Location 0
|
||||
OpDecorate %uTexture DescriptorSet 0
|
||||
OpDecorate %uTexture Binding 1
|
||||
OpDecorate %uSampler DescriptorSet 0
|
||||
OpDecorate %uSampler Binding 2
|
||||
OpDecorate %FragColor Location 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%7 = OpTypeFunction %float
|
||||
%12 = OpTypeImage %float 2D 2 0 0 1 Unknown
|
||||
%13 = OpTypeSampledImage %12
|
||||
%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
|
||||
%uShadow = OpVariable %_ptr_UniformConstant_13 UniformConstant
|
||||
%v3float = OpTypeVector %float 3
|
||||
%_ptr_Input_v3float = OpTypePointer Input %v3float
|
||||
%vUV = OpVariable %_ptr_Input_v3float Input
|
||||
%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %12
|
||||
%uTexture = OpVariable %_ptr_UniformConstant_25 UniformConstant
|
||||
%29 = OpTypeSampler
|
||||
%_ptr_UniformConstant_29 = OpTypePointer UniformConstant %29
|
||||
%uSampler = OpVariable %_ptr_UniformConstant_29 UniformConstant
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%FragColor = OpVariable %_ptr_Output_float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%41 = OpFunctionCall %float %sample_combined_
|
||||
%42 = OpFunctionCall %float %sample_separate_
|
||||
%43 = OpFAdd %float %41 %42
|
||||
OpStore %FragColor %43
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%sample_combined_ = OpFunction %float None %7
|
||||
%9 = OpLabel
|
||||
%16 = OpLoad %13 %uShadow
|
||||
%20 = OpLoad %v3float %vUV
|
||||
%21 = OpCompositeExtract %float %20 2
|
||||
%22 = OpImageSampleDrefImplicitLod %float %16 %20 %21
|
||||
OpReturnValue %22
|
||||
OpFunctionEnd
|
||||
%sample_separate_ = OpFunction %float None %7
|
||||
%11 = OpLabel
|
||||
%28 = OpLoad %12 %uTexture
|
||||
%32 = OpLoad %29 %uSampler
|
||||
%33 = OpSampledImage %13 %28 %32
|
||||
%34 = OpLoad %v3float %vUV
|
||||
%35 = OpCompositeExtract %float %34 2
|
||||
%36 = OpImageSampleDrefImplicitLod %float %33 %34 %35
|
||||
OpReturnValue %36
|
||||
OpFunctionEnd
|
130
shaders/asm/geom/store-uint-layer.invalid.asm.geom
Normal file
130
shaders/asm/geom/store-uint-layer.invalid.asm.geom
Normal file
@ -0,0 +1,130 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 74
|
||||
; Schema: 0
|
||||
OpCapability Geometry
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Geometry %main "main" %stream_pos %stream_layer %input_pos
|
||||
OpExecutionMode %main Triangles
|
||||
OpExecutionMode %main Invocations 1
|
||||
OpExecutionMode %main OutputTriangleStrip
|
||||
OpExecutionMode %main OutputVertices 3
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
OpName %VertexOutput "VertexOutput"
|
||||
OpMemberName %VertexOutput 0 "pos"
|
||||
OpName %GeometryOutput "GeometryOutput"
|
||||
OpMemberName %GeometryOutput 0 "pos"
|
||||
OpMemberName %GeometryOutput 1 "layer"
|
||||
OpName %_main_struct_VertexOutput_vf41_3__struct_GeometryOutput_vf4_u11_ "@main(struct-VertexOutput-vf41[3];struct-GeometryOutput-vf4-u11;"
|
||||
OpName %input "input"
|
||||
OpName %stream "stream"
|
||||
OpName %output "output"
|
||||
OpName %v "v"
|
||||
OpName %stream_pos "stream.pos"
|
||||
OpName %stream_layer "stream.layer"
|
||||
OpName %input_0 "input"
|
||||
OpName %input_pos "input.pos"
|
||||
OpName %stream_0 "stream"
|
||||
OpName %param "param"
|
||||
OpName %param_0 "param"
|
||||
OpDecorate %stream_pos BuiltIn Position
|
||||
OpDecorate %stream_layer BuiltIn Layer
|
||||
OpDecorate %input_pos BuiltIn Position
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%VertexOutput = OpTypeStruct %v4float
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr_VertexOutput_uint_3 = OpTypeArray %VertexOutput %uint_3
|
||||
%_ptr_Function__arr_VertexOutput_uint_3 = OpTypePointer Function %_arr_VertexOutput_uint_3
|
||||
%GeometryOutput = OpTypeStruct %v4float %uint
|
||||
%_ptr_Function_GeometryOutput = OpTypePointer Function %GeometryOutput
|
||||
%15 = OpTypeFunction %void %_ptr_Function__arr_VertexOutput_uint_3 %_ptr_Function_GeometryOutput
|
||||
%int = OpTypeInt 32 1
|
||||
%int_1 = OpConstant %int 1
|
||||
%uint_1 = OpConstant %uint 1
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_3 = OpConstant %int 3
|
||||
%bool = OpTypeBool
|
||||
%_ptr_Function_v4float = OpTypePointer Function %v4float
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%stream_pos = OpVariable %_ptr_Output_v4float Output
|
||||
%_ptr_Output_uint = OpTypePointer Output %uint
|
||||
%stream_layer = OpVariable %_ptr_Output_uint Output
|
||||
%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
|
||||
%_ptr_Input__arr_v4float_uint_3 = OpTypePointer Input %_arr_v4float_uint_3
|
||||
%input_pos = OpVariable %_ptr_Input__arr_v4float_uint_3 Input
|
||||
%_ptr_Input_v4float = OpTypePointer Input %v4float
|
||||
%int_2 = OpConstant %int 2
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%input_0 = OpVariable %_ptr_Function__arr_VertexOutput_uint_3 Function
|
||||
%stream_0 = OpVariable %_ptr_Function_GeometryOutput Function
|
||||
%param = OpVariable %_ptr_Function__arr_VertexOutput_uint_3 Function
|
||||
%param_0 = OpVariable %_ptr_Function_GeometryOutput Function
|
||||
%58 = OpAccessChain %_ptr_Input_v4float %input_pos %int_0
|
||||
%59 = OpLoad %v4float %58
|
||||
%60 = OpAccessChain %_ptr_Function_v4float %input_0 %int_0 %int_0
|
||||
OpStore %60 %59
|
||||
%61 = OpAccessChain %_ptr_Input_v4float %input_pos %int_1
|
||||
%62 = OpLoad %v4float %61
|
||||
%63 = OpAccessChain %_ptr_Function_v4float %input_0 %int_1 %int_0
|
||||
OpStore %63 %62
|
||||
%65 = OpAccessChain %_ptr_Input_v4float %input_pos %int_2
|
||||
%66 = OpLoad %v4float %65
|
||||
%67 = OpAccessChain %_ptr_Function_v4float %input_0 %int_2 %int_0
|
||||
OpStore %67 %66
|
||||
%70 = OpLoad %_arr_VertexOutput_uint_3 %input_0
|
||||
OpStore %param %70
|
||||
%72 = OpFunctionCall %void %_main_struct_VertexOutput_vf41_3__struct_GeometryOutput_vf4_u11_ %param %param_0
|
||||
%73 = OpLoad %GeometryOutput %param_0
|
||||
OpStore %stream_0 %73
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_main_struct_VertexOutput_vf41_3__struct_GeometryOutput_vf4_u11_ = OpFunction %void None %15
|
||||
%input = OpFunctionParameter %_ptr_Function__arr_VertexOutput_uint_3
|
||||
%stream = OpFunctionParameter %_ptr_Function_GeometryOutput
|
||||
%19 = OpLabel
|
||||
%output = OpVariable %_ptr_Function_GeometryOutput Function
|
||||
%v = OpVariable %_ptr_Function_int Function
|
||||
%25 = OpAccessChain %_ptr_Function_uint %output %int_1
|
||||
OpStore %25 %uint_1
|
||||
OpStore %v %int_0
|
||||
OpBranch %29
|
||||
%29 = OpLabel
|
||||
OpLoopMerge %31 %32 None
|
||||
OpBranch %33
|
||||
%33 = OpLabel
|
||||
%34 = OpLoad %int %v
|
||||
%37 = OpSLessThan %bool %34 %int_3
|
||||
OpBranchConditional %37 %30 %31
|
||||
%30 = OpLabel
|
||||
%38 = OpLoad %int %v
|
||||
%40 = OpAccessChain %_ptr_Function_v4float %input %38 %int_0
|
||||
%41 = OpLoad %v4float %40
|
||||
%42 = OpAccessChain %_ptr_Function_v4float %output %int_0
|
||||
OpStore %42 %41
|
||||
%45 = OpAccessChain %_ptr_Function_v4float %output %int_0
|
||||
%46 = OpLoad %v4float %45
|
||||
OpStore %stream_pos %46
|
||||
%49 = OpAccessChain %_ptr_Function_uint %output %int_1
|
||||
%50 = OpLoad %uint %49
|
||||
OpStore %stream_layer %50
|
||||
OpEmitVertex
|
||||
OpBranch %32
|
||||
%32 = OpLabel
|
||||
%51 = OpLoad %int %v
|
||||
%52 = OpIAdd %int %51 %int_1
|
||||
OpStore %v %52
|
||||
OpBranch %29
|
||||
%31 = OpLabel
|
||||
OpEndPrimitive
|
||||
OpReturn
|
||||
OpFunctionEnd
|
65
shaders/asm/vert/uint-vertex-id-instance-id.asm.vert
Normal file
65
shaders/asm/vert/uint-vertex-id-instance-id.asm.vert
Normal file
@ -0,0 +1,65 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 6
|
||||
; Bound: 36
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %main "main" %vid_1 %iid_1 %_entryPointOutput
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
OpName %_main_u1_u1_ "@main(u1;u1;"
|
||||
OpName %vid "vid"
|
||||
OpName %iid "iid"
|
||||
OpName %vid_0 "vid"
|
||||
OpName %vid_1 "vid"
|
||||
OpName %iid_0 "iid"
|
||||
OpName %iid_1 "iid"
|
||||
OpName %_entryPointOutput "@entryPointOutput"
|
||||
OpName %param "param"
|
||||
OpName %param_0 "param"
|
||||
OpDecorate %vid_1 BuiltIn VertexIndex
|
||||
OpDecorate %iid_1 BuiltIn InstanceIndex
|
||||
OpDecorate %_entryPointOutput BuiltIn Position
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%uint = OpTypeInt 32 0
|
||||
%_ptr_Function_uint = OpTypePointer Function %uint
|
||||
%float = OpTypeFloat 32
|
||||
%v4float = OpTypeVector %float 4
|
||||
%10 = OpTypeFunction %v4float %_ptr_Function_uint %_ptr_Function_uint
|
||||
%_ptr_Input_uint = OpTypePointer Input %uint
|
||||
%vid_1 = OpVariable %_ptr_Input_uint Input
|
||||
%iid_1 = OpVariable %_ptr_Input_uint Input
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%vid_0 = OpVariable %_ptr_Function_uint Function
|
||||
%iid_0 = OpVariable %_ptr_Function_uint Function
|
||||
%param = OpVariable %_ptr_Function_uint Function
|
||||
%param_0 = OpVariable %_ptr_Function_uint Function
|
||||
%25 = OpLoad %uint %vid_1
|
||||
OpStore %vid_0 %25
|
||||
%28 = OpLoad %uint %iid_1
|
||||
OpStore %iid_0 %28
|
||||
%32 = OpLoad %uint %vid_0
|
||||
OpStore %param %32
|
||||
%34 = OpLoad %uint %iid_0
|
||||
OpStore %param_0 %34
|
||||
%35 = OpFunctionCall %v4float %_main_u1_u1_ %param %param_0
|
||||
OpStore %_entryPointOutput %35
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_main_u1_u1_ = OpFunction %v4float None %10
|
||||
%vid = OpFunctionParameter %_ptr_Function_uint
|
||||
%iid = OpFunctionParameter %_ptr_Function_uint
|
||||
%14 = OpLabel
|
||||
%15 = OpLoad %uint %vid
|
||||
%16 = OpLoad %uint %iid
|
||||
%17 = OpIAdd %uint %15 %16
|
||||
%18 = OpConvertUToF %float %17
|
||||
%19 = OpCompositeConstruct %v4float %18 %18 %18 %18
|
||||
OpReturnValue %19
|
||||
OpFunctionEnd
|
9
shaders/vulkan/frag/spec-constant-ternary.vk.frag
Normal file
9
shaders/vulkan/frag/spec-constant-ternary.vk.frag
Normal file
@ -0,0 +1,9 @@
|
||||
#version 450
|
||||
layout(location = 0) out float FragColor;
|
||||
layout(constant_id = 0) const uint s = 10u;
|
||||
const uint f = s > 20u ? 30u : 50u;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = float(f);
|
||||
}
|
@ -578,6 +578,15 @@ struct SPIRBlock : IVariant
|
||||
MergeSelection
|
||||
};
|
||||
|
||||
enum Hints
|
||||
{
|
||||
HintNone,
|
||||
HintUnroll,
|
||||
HintDontUnroll,
|
||||
HintFlatten,
|
||||
HintDontFlatten
|
||||
};
|
||||
|
||||
enum Method
|
||||
{
|
||||
MergeToSelectForLoop,
|
||||
@ -610,6 +619,7 @@ struct SPIRBlock : IVariant
|
||||
|
||||
Terminator terminator = Unknown;
|
||||
Merge merge = MergeNone;
|
||||
Hints hint = HintNone;
|
||||
uint32_t next_block = 0;
|
||||
uint32_t merge_block = 0;
|
||||
uint32_t continue_block = 0;
|
||||
|
180
spirv_cross.cpp
180
spirv_cross.cpp
@ -1063,6 +1063,34 @@ const SPIRType &Compiler::get_type_from_variable(uint32_t id) const
|
||||
return get<SPIRType>(get<SPIRVariable>(id).basetype);
|
||||
}
|
||||
|
||||
uint32_t Compiler::get_non_pointer_type_id(uint32_t type_id) const
|
||||
{
|
||||
auto *p_type = &get<SPIRType>(type_id);
|
||||
while (p_type->pointer)
|
||||
{
|
||||
assert(p_type->parent_type);
|
||||
type_id = p_type->parent_type;
|
||||
p_type = &get<SPIRType>(type_id);
|
||||
}
|
||||
return type_id;
|
||||
}
|
||||
|
||||
const SPIRType &Compiler::get_non_pointer_type(const SPIRType &type) const
|
||||
{
|
||||
auto *p_type = &type;
|
||||
while (p_type->pointer)
|
||||
{
|
||||
assert(p_type->parent_type);
|
||||
p_type = &get<SPIRType>(p_type->parent_type);
|
||||
}
|
||||
return *p_type;
|
||||
}
|
||||
|
||||
const SPIRType &Compiler::get_non_pointer_type(uint32_t type_id) const
|
||||
{
|
||||
return get_non_pointer_type(get<SPIRType>(type_id));
|
||||
}
|
||||
|
||||
void Compiler::set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,
|
||||
const std::string &argument)
|
||||
{
|
||||
@ -1814,7 +1842,7 @@ void Compiler::parse(const Instruction &instruction)
|
||||
type.basetype = SPIRType::Image;
|
||||
type.image.type = ops[1];
|
||||
type.image.dim = static_cast<Dim>(ops[2]);
|
||||
type.image.depth = ops[3] != 0;
|
||||
type.image.depth = ops[3] == 1;
|
||||
type.image.arrayed = ops[4] != 0;
|
||||
type.image.ms = ops[5] != 0;
|
||||
type.image.sampled = ops[6];
|
||||
@ -2221,6 +2249,14 @@ void Compiler::parse(const Instruction &instruction)
|
||||
current_block->next_block = ops[0];
|
||||
current_block->merge = SPIRBlock::MergeSelection;
|
||||
selection_merge_targets.insert(current_block->next_block);
|
||||
|
||||
if (length >= 2)
|
||||
{
|
||||
if (ops[1] & SelectionControlFlattenMask)
|
||||
current_block->hint = SPIRBlock::HintFlatten;
|
||||
else if (ops[1] & SelectionControlDontFlattenMask)
|
||||
current_block->hint = SPIRBlock::HintDontFlatten;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2243,6 +2279,14 @@ void Compiler::parse(const Instruction &instruction)
|
||||
// they are treated as continues.
|
||||
if (current_block->continue_block != current_block->self)
|
||||
continue_blocks.insert(current_block->continue_block);
|
||||
|
||||
if (length >= 3)
|
||||
{
|
||||
if (ops[2] & LoopControlUnrollMask)
|
||||
current_block->hint = SPIRBlock::HintUnroll;
|
||||
else if (ops[2] & LoopControlDontUnrollMask)
|
||||
current_block->hint = SPIRBlock::HintDontUnroll;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4243,14 +4287,8 @@ bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args
|
||||
// Required if we access chain into builtins like gl_GlobalInvocationID.
|
||||
add_if_builtin(args[2]);
|
||||
|
||||
auto *type = &compiler.get<SPIRType>(var->basetype);
|
||||
|
||||
// Start traversing type hierarchy at the proper non-pointer types.
|
||||
while (type->pointer)
|
||||
{
|
||||
assert(type->parent_type);
|
||||
type = &compiler.get<SPIRType>(type->parent_type);
|
||||
}
|
||||
auto *type = &compiler.get_non_pointer_type(var->basetype);
|
||||
|
||||
auto &flags =
|
||||
type->storage == StorageClassInput ? compiler.active_input_builtins : compiler.active_output_builtins;
|
||||
@ -4329,11 +4367,43 @@ bool Compiler::has_active_builtin(BuiltIn builtin, StorageClass storage)
|
||||
|
||||
void Compiler::analyze_image_and_sampler_usage()
|
||||
{
|
||||
CombinedImageSamplerUsageHandler handler(*this);
|
||||
CombinedImageSamplerDrefHandler dref_handler(*this);
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), dref_handler);
|
||||
|
||||
CombinedImageSamplerUsageHandler handler(*this, dref_handler.dref_combined_samplers);
|
||||
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
|
||||
comparison_samplers = move(handler.comparison_samplers);
|
||||
comparison_images = move(handler.comparison_images);
|
||||
comparison_ids = move(handler.comparison_ids);
|
||||
need_subpass_input = handler.need_subpass_input;
|
||||
|
||||
// Forward information from separate images and samplers into combined image samplers.
|
||||
for (auto &combined : combined_image_samplers)
|
||||
if (comparison_ids.count(combined.sampler_id))
|
||||
comparison_ids.insert(combined.combined_id);
|
||||
}
|
||||
|
||||
bool Compiler::CombinedImageSamplerDrefHandler::handle(spv::Op opcode, const uint32_t *args, uint32_t)
|
||||
{
|
||||
// Mark all sampled images which are used with Dref.
|
||||
switch (opcode)
|
||||
{
|
||||
case OpImageSampleDrefExplicitLod:
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
case OpImageSampleProjDrefExplicitLod:
|
||||
case OpImageSampleProjDrefImplicitLod:
|
||||
case OpImageSparseSampleProjDrefImplicitLod:
|
||||
case OpImageSparseSampleDrefImplicitLod:
|
||||
case OpImageSparseSampleProjDrefExplicitLod:
|
||||
case OpImageSparseSampleDrefExplicitLod:
|
||||
case OpImageDrefGather:
|
||||
case OpImageSparseDrefGather:
|
||||
dref_combined_samplers.insert(args[2]);
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compiler::CombinedImageSamplerUsageHandler::begin_function_scope(const uint32_t *args, uint32_t length)
|
||||
@ -4354,20 +4424,12 @@ bool Compiler::CombinedImageSamplerUsageHandler::begin_function_scope(const uint
|
||||
return true;
|
||||
}
|
||||
|
||||
void Compiler::CombinedImageSamplerUsageHandler::add_hierarchy_to_comparison_images(uint32_t image)
|
||||
void Compiler::CombinedImageSamplerUsageHandler::add_hierarchy_to_comparison_ids(uint32_t id)
|
||||
{
|
||||
// Traverse the variable dependency hierarchy and tag everything in its path with comparison images.
|
||||
comparison_images.insert(image);
|
||||
for (auto &img : dependency_hierarchy[image])
|
||||
add_hierarchy_to_comparison_images(img);
|
||||
}
|
||||
|
||||
void Compiler::CombinedImageSamplerUsageHandler::add_hierarchy_to_comparison_samplers(uint32_t sampler)
|
||||
{
|
||||
// Traverse the variable dependency hierarchy and tag everything in its path with comparison samplers.
|
||||
comparison_samplers.insert(sampler);
|
||||
for (auto &samp : dependency_hierarchy[sampler])
|
||||
add_hierarchy_to_comparison_samplers(samp);
|
||||
// Traverse the variable dependency hierarchy and tag everything in its path with comparison ids.
|
||||
comparison_ids.insert(id);
|
||||
for (auto &dep_id : dependency_hierarchy[id])
|
||||
add_hierarchy_to_comparison_ids(dep_id);
|
||||
}
|
||||
|
||||
bool Compiler::CombinedImageSamplerUsageHandler::handle(Op opcode, const uint32_t *args, uint32_t length)
|
||||
@ -4387,6 +4449,10 @@ bool Compiler::CombinedImageSamplerUsageHandler::handle(Op opcode, const uint32_
|
||||
auto &type = compiler.get<SPIRType>(args[0]);
|
||||
if (type.image.dim == DimSubpassData)
|
||||
need_subpass_input = true;
|
||||
|
||||
// If we load a SampledImage and it will be used with Dref, propagate the state up.
|
||||
if (dref_combined_samplers.count(args[1]) != 0)
|
||||
add_hierarchy_to_comparison_ids(args[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4396,16 +4462,20 @@ bool Compiler::CombinedImageSamplerUsageHandler::handle(Op opcode, const uint32_
|
||||
return false;
|
||||
|
||||
uint32_t result_type = args[0];
|
||||
uint32_t result_id = args[1];
|
||||
auto &type = compiler.get<SPIRType>(result_type);
|
||||
if (type.image.depth)
|
||||
if (type.image.depth || dref_combined_samplers.count(result_id) != 0)
|
||||
{
|
||||
// This image must be a depth image.
|
||||
uint32_t image = args[2];
|
||||
add_hierarchy_to_comparison_images(image);
|
||||
add_hierarchy_to_comparison_ids(image);
|
||||
|
||||
// This sampler must be a SamplerComparisionState, and not a regular SamplerState.
|
||||
// This sampler must be a SamplerComparisonState, and not a regular SamplerState.
|
||||
uint32_t sampler = args[3];
|
||||
add_hierarchy_to_comparison_samplers(sampler);
|
||||
add_hierarchy_to_comparison_ids(sampler);
|
||||
|
||||
// Mark the OpSampledImage itself as being comparison state.
|
||||
comparison_ids.insert(result_id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -4567,3 +4637,57 @@ bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &resul
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Bitset Compiler::combined_decoration_for_member(const SPIRType &type, uint32_t index) const
|
||||
{
|
||||
Bitset flags;
|
||||
auto &memb = meta[type.self].members;
|
||||
if (index >= memb.size())
|
||||
return flags;
|
||||
auto &dec = memb[index];
|
||||
|
||||
// If our type is a struct, traverse all the members as well recursively.
|
||||
flags.merge_or(dec.decoration_flags);
|
||||
for (uint32_t i = 0; i < type.member_types.size(); i++)
|
||||
flags.merge_or(combined_decoration_for_member(get<SPIRType>(type.member_types[i]), i));
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool Compiler::is_desktop_only_format(spv::ImageFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
// Desktop-only formats
|
||||
case ImageFormatR11fG11fB10f:
|
||||
case ImageFormatR16f:
|
||||
case ImageFormatRgb10A2:
|
||||
case ImageFormatR8:
|
||||
case ImageFormatRg8:
|
||||
case ImageFormatR16:
|
||||
case ImageFormatRg16:
|
||||
case ImageFormatRgba16:
|
||||
case ImageFormatR16Snorm:
|
||||
case ImageFormatRg16Snorm:
|
||||
case ImageFormatRgba16Snorm:
|
||||
case ImageFormatR8Snorm:
|
||||
case ImageFormatRg8Snorm:
|
||||
case ImageFormatR8ui:
|
||||
case ImageFormatRg8ui:
|
||||
case ImageFormatR16ui:
|
||||
case ImageFormatRgb10a2ui:
|
||||
case ImageFormatR8i:
|
||||
case ImageFormatRg8i:
|
||||
case ImageFormatR16i:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::image_is_comparison(const spirv_cross::SPIRType &type, uint32_t id) const
|
||||
{
|
||||
return type.image.depth || (comparison_ids.count(id) != 0);
|
||||
}
|
||||
|
@ -170,6 +170,15 @@ public:
|
||||
// Gets the SPIR-V type of a variable.
|
||||
const SPIRType &get_type_from_variable(uint32_t id) const;
|
||||
|
||||
// Gets the id of SPIR-V type underlying the given type_id, which might be a pointer.
|
||||
uint32_t get_non_pointer_type_id(uint32_t type_id) const;
|
||||
|
||||
// Gets the SPIR-V type underlying the given type, which might be a pointer.
|
||||
const SPIRType &get_non_pointer_type(const SPIRType &type) const;
|
||||
|
||||
// Gets the SPIR-V type underlying the given type_id, which might be a pointer.
|
||||
const SPIRType &get_non_pointer_type(uint32_t type_id) const;
|
||||
|
||||
// Gets the underlying storage class for an OpVariable.
|
||||
spv::StorageClass get_storage_class(uint32_t id) const;
|
||||
|
||||
@ -817,8 +826,7 @@ protected:
|
||||
// There might be unrelated IDs found in this set which do not correspond to actual variables.
|
||||
// This set should only be queried for the existence of samplers which are already known to be variables or parameter IDs.
|
||||
// Similar is implemented for images, as well as if subpass inputs are needed.
|
||||
std::unordered_set<uint32_t> comparison_samplers;
|
||||
std::unordered_set<uint32_t> comparison_images;
|
||||
std::unordered_set<uint32_t> comparison_ids;
|
||||
bool need_subpass_input = false;
|
||||
|
||||
// In certain backends, we will need to use a dummy sampler to be able to emit code.
|
||||
@ -827,23 +835,37 @@ protected:
|
||||
uint32_t dummy_sampler_id = 0;
|
||||
|
||||
void analyze_image_and_sampler_usage();
|
||||
|
||||
struct CombinedImageSamplerDrefHandler : OpcodeHandler
|
||||
{
|
||||
CombinedImageSamplerDrefHandler(Compiler &compiler_)
|
||||
: compiler(compiler_)
|
||||
{
|
||||
}
|
||||
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
|
||||
|
||||
Compiler &compiler;
|
||||
std::unordered_set<uint32_t> dref_combined_samplers;
|
||||
};
|
||||
|
||||
struct CombinedImageSamplerUsageHandler : OpcodeHandler
|
||||
{
|
||||
CombinedImageSamplerUsageHandler(Compiler &compiler_)
|
||||
CombinedImageSamplerUsageHandler(Compiler &compiler_,
|
||||
const std::unordered_set<uint32_t> &dref_combined_samplers_)
|
||||
: compiler(compiler_)
|
||||
, dref_combined_samplers(dref_combined_samplers_)
|
||||
{
|
||||
}
|
||||
|
||||
bool begin_function_scope(const uint32_t *args, uint32_t length) override;
|
||||
bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
|
||||
Compiler &compiler;
|
||||
const std::unordered_set<uint32_t> &dref_combined_samplers;
|
||||
|
||||
std::unordered_map<uint32_t, std::unordered_set<uint32_t>> dependency_hierarchy;
|
||||
std::unordered_set<uint32_t> comparison_images;
|
||||
std::unordered_set<uint32_t> comparison_samplers;
|
||||
std::unordered_set<uint32_t> comparison_ids;
|
||||
|
||||
void add_hierarchy_to_comparison_samplers(uint32_t sampler);
|
||||
void add_hierarchy_to_comparison_images(uint32_t sampler);
|
||||
void add_hierarchy_to_comparison_ids(uint32_t ids);
|
||||
bool need_subpass_input = false;
|
||||
};
|
||||
|
||||
@ -856,6 +878,11 @@ protected:
|
||||
bool instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op, const uint32_t *args,
|
||||
uint32_t length);
|
||||
|
||||
Bitset combined_decoration_for_member(const SPIRType &type, uint32_t index) const;
|
||||
static bool is_desktop_only_format(spv::ImageFormat format);
|
||||
|
||||
bool image_is_comparison(const SPIRType &type, uint32_t id) const;
|
||||
|
||||
private:
|
||||
// Used only to implement the old deprecated get_entry_point() interface.
|
||||
const SPIREntryPoint &get_first_entry_point(const std::string &name) const;
|
||||
|
699
spirv_glsl.cpp
699
spirv_glsl.cpp
File diff suppressed because it is too large
Load Diff
@ -105,6 +105,11 @@ public:
|
||||
|
||||
// Inverts gl_Position.y or equivalent.
|
||||
bool flip_vert_y = false;
|
||||
|
||||
// If true, the backend will assume that InstanceIndex will need to apply
|
||||
// a base instance offset. Set to false if you know you will never use base instance
|
||||
// functionality as it might remove some internal uniforms.
|
||||
bool support_nonzero_base_instance = true;
|
||||
} vertex;
|
||||
|
||||
struct
|
||||
@ -276,7 +281,6 @@ protected:
|
||||
{
|
||||
for (uint32_t i = 0; i < indent; i++)
|
||||
(*buffer) << " ";
|
||||
|
||||
statement_inner(std::forward<Ts>(ts)...);
|
||||
(*buffer) << '\n';
|
||||
}
|
||||
@ -404,6 +408,9 @@ protected:
|
||||
SPIRType binary_op_bitcast_helper(std::string &cast_op0, std::string &cast_op1, SPIRType::BaseType &input_type,
|
||||
uint32_t op0, uint32_t op1, bool skip_cast_if_equal_type);
|
||||
|
||||
std::string to_ternary_expression(const SPIRType &result_type, uint32_t select, uint32_t true_value,
|
||||
uint32_t false_value);
|
||||
|
||||
void emit_unary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op);
|
||||
bool expression_is_forwarded(uint32_t id);
|
||||
SPIRExpression &emit_op(uint32_t result_type, uint32_t result_id, const std::string &rhs, bool forward_rhs,
|
||||
@ -451,11 +458,11 @@ protected:
|
||||
const char *format_to_glsl(spv::ImageFormat format);
|
||||
virtual std::string layout_for_member(const SPIRType &type, uint32_t index);
|
||||
virtual std::string to_interpolation_qualifiers(const Bitset &flags);
|
||||
Bitset combined_decoration_for_member(const SPIRType &type, uint32_t index);
|
||||
std::string layout_for_variable(const SPIRVariable &variable);
|
||||
std::string to_combined_image_sampler(uint32_t image_id, uint32_t samp_id);
|
||||
virtual bool skip_argument(uint32_t id) const;
|
||||
virtual void emit_array_copy(const std::string &lhs, uint32_t rhs_id);
|
||||
virtual void emit_block_hints(const SPIRBlock &block);
|
||||
|
||||
bool buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing, uint32_t start_offset = 0,
|
||||
uint32_t end_offset = std::numeric_limits<uint32_t>::max());
|
||||
@ -484,7 +491,7 @@ protected:
|
||||
void replace_fragment_output(SPIRVariable &var);
|
||||
void replace_fragment_outputs();
|
||||
bool check_explicit_lod_allowed(uint32_t lod);
|
||||
std::string legacy_tex_op(const std::string &op, const SPIRType &imgtype, uint32_t lod);
|
||||
std::string legacy_tex_op(const std::string &op, const SPIRType &imgtype, uint32_t lod, uint32_t id);
|
||||
|
||||
uint32_t indent = 0;
|
||||
|
||||
@ -562,6 +569,12 @@ protected:
|
||||
|
||||
std::string convert_separate_image_to_combined(uint32_t id);
|
||||
|
||||
// Builtins in GLSL are always specific signedness, but the SPIR-V can declare them
|
||||
// as either unsigned or signed.
|
||||
// Sometimes we will need to automatically perform bitcasts on load and store to make this work.
|
||||
virtual void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type);
|
||||
virtual void bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type);
|
||||
|
||||
private:
|
||||
void init()
|
||||
{
|
||||
|
162
spirv_hlsl.cpp
162
spirv_hlsl.cpp
@ -224,7 +224,7 @@ static bool hlsl_opcode_is_sign_invariant(Op opcode)
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type)
|
||||
string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type, uint32_t)
|
||||
{
|
||||
auto &imagetype = get<SPIRType>(type.image.type);
|
||||
const char *dim = nullptr;
|
||||
@ -275,7 +275,7 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type)
|
||||
">");
|
||||
}
|
||||
|
||||
string CompilerHLSL::image_type_hlsl_legacy(const SPIRType &type)
|
||||
string CompilerHLSL::image_type_hlsl_legacy(const SPIRType &type, uint32_t id)
|
||||
{
|
||||
auto &imagetype = get<SPIRType>(type.image.type);
|
||||
string res;
|
||||
@ -338,18 +338,18 @@ string CompilerHLSL::image_type_hlsl_legacy(const SPIRType &type)
|
||||
res += "MS";
|
||||
if (type.image.arrayed)
|
||||
res += "Array";
|
||||
if (type.image.depth)
|
||||
if (image_is_comparison(type, id))
|
||||
res += "Shadow";
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
string CompilerHLSL::image_type_hlsl(const SPIRType &type)
|
||||
string CompilerHLSL::image_type_hlsl(const SPIRType &type, uint32_t id)
|
||||
{
|
||||
if (hlsl_options.shader_model <= 30)
|
||||
return image_type_hlsl_legacy(type);
|
||||
return image_type_hlsl_legacy(type, id);
|
||||
else
|
||||
return image_type_hlsl_modern(type);
|
||||
return image_type_hlsl_modern(type, id);
|
||||
}
|
||||
|
||||
// The optional id parameter indicates the object whose type we are trying
|
||||
@ -370,10 +370,10 @@ string CompilerHLSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
||||
|
||||
case SPIRType::Image:
|
||||
case SPIRType::SampledImage:
|
||||
return image_type_hlsl(type);
|
||||
return image_type_hlsl(type, id);
|
||||
|
||||
case SPIRType::Sampler:
|
||||
return comparison_samplers.count(id) ? "SamplerComparisonState" : "SamplerState";
|
||||
return comparison_ids.count(id) ? "SamplerComparisonState" : "SamplerState";
|
||||
|
||||
case SPIRType::Void:
|
||||
return "void";
|
||||
@ -1838,9 +1838,10 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
|
||||
{
|
||||
Bitset flags = get_buffer_block_flags(var);
|
||||
bool is_readonly = flags.get(DecorationNonWritable);
|
||||
bool is_coherent = flags.get(DecorationCoherent);
|
||||
add_resource_name(var.self);
|
||||
statement(is_readonly ? "ByteAddressBuffer " : "RWByteAddressBuffer ", to_name(var.self),
|
||||
type_to_array_glsl(type), to_resource_binding(var), ";");
|
||||
statement(is_coherent ? "globallycoherent " : "", is_readonly ? "ByteAddressBuffer " : "RWByteAddressBuffer ",
|
||||
to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2059,7 +2060,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret
|
||||
{
|
||||
// Manufacture automatic sampler arg for SampledImage texture
|
||||
decl += ", ";
|
||||
decl += join(arg_type.image.depth ? "SamplerComparisonState " : "SamplerState ",
|
||||
decl += join(image_is_comparison(arg_type, arg.id) ? "SamplerComparisonState " : "SamplerState ",
|
||||
to_sampler_expression(arg.id), type_to_array_glsl(arg_type));
|
||||
}
|
||||
|
||||
@ -2574,7 +2575,7 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
|
||||
{
|
||||
texop += img_expr;
|
||||
|
||||
if (imgtype.image.depth)
|
||||
if (image_is_comparison(imgtype, img))
|
||||
{
|
||||
if (gather)
|
||||
{
|
||||
@ -2922,13 +2923,17 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
|
||||
case SPIRType::SampledImage:
|
||||
case SPIRType::Image:
|
||||
{
|
||||
statement(image_type_hlsl_modern(type), " ", to_name(var.self), type_to_array_glsl(type),
|
||||
to_resource_binding(var), ";");
|
||||
bool is_coherent = false;
|
||||
if (type.basetype == SPIRType::Image && type.image.sampled == 2)
|
||||
is_coherent = has_decoration(var.self, DecorationCoherent);
|
||||
|
||||
statement(is_coherent ? "globallycoherent " : "", image_type_hlsl_modern(type, var.self), " ",
|
||||
to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";");
|
||||
|
||||
if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer)
|
||||
{
|
||||
// For combined image samplers, also emit a combined image sampler.
|
||||
if (type.image.depth)
|
||||
if (image_is_comparison(type, var.self))
|
||||
statement("SamplerComparisonState ", to_sampler_expression(var.self), type_to_array_glsl(type),
|
||||
to_resource_binding_sampler(var), ";");
|
||||
else
|
||||
@ -2939,7 +2944,7 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
|
||||
}
|
||||
|
||||
case SPIRType::Sampler:
|
||||
if (comparison_samplers.count(var.self))
|
||||
if (comparison_ids.count(var.self))
|
||||
statement("SamplerComparisonState ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var),
|
||||
";");
|
||||
else
|
||||
@ -3524,14 +3529,8 @@ void CompilerHLSL::emit_access_chain(const Instruction &instruction)
|
||||
else
|
||||
base = to_expression(ops[2]);
|
||||
|
||||
auto *basetype = &type;
|
||||
|
||||
// Start traversing type hierarchy at the proper non-pointer types.
|
||||
while (basetype->pointer)
|
||||
{
|
||||
assert(basetype->parent_type);
|
||||
basetype = &get<SPIRType>(basetype->parent_type);
|
||||
}
|
||||
auto *basetype = &get_non_pointer_type(type);
|
||||
|
||||
// Traverse the type hierarchy down to the actual buffer types.
|
||||
for (uint32_t i = 0; i < to_plain_buffer_length; i++)
|
||||
@ -3767,7 +3766,7 @@ void CompilerHLSL::emit_subgroup_op(const Instruction &i)
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
#define GROUP_OP(op, hlsl_op, supports_scan) \
|
||||
#define HLSL_GROUP_OP(op, hlsl_op, supports_scan) \
|
||||
case OpGroupNonUniform##op: \
|
||||
{ \
|
||||
auto operation = static_cast<GroupOperation>(ops[3]); \
|
||||
@ -3787,20 +3786,20 @@ case OpGroupNonUniform##op: \
|
||||
SPIRV_CROSS_THROW("Invalid group operation."); \
|
||||
break; \
|
||||
}
|
||||
GROUP_OP(FAdd, Sum, true)
|
||||
GROUP_OP(FMul, Product, true)
|
||||
GROUP_OP(FMin, Min, false)
|
||||
GROUP_OP(FMax, Max, false)
|
||||
GROUP_OP(IAdd, Sum, true)
|
||||
GROUP_OP(IMul, Product, true)
|
||||
GROUP_OP(SMin, Min, false)
|
||||
GROUP_OP(SMax, Max, false)
|
||||
GROUP_OP(UMin, Min, false)
|
||||
GROUP_OP(UMax, Max, false)
|
||||
GROUP_OP(BitwiseAnd, BitAnd, false)
|
||||
GROUP_OP(BitwiseOr, BitOr, false)
|
||||
GROUP_OP(BitwiseXor, BitXor, false)
|
||||
#undef GROUP_OP
|
||||
HLSL_GROUP_OP(FAdd, Sum, true)
|
||||
HLSL_GROUP_OP(FMul, Product, true)
|
||||
HLSL_GROUP_OP(FMin, Min, false)
|
||||
HLSL_GROUP_OP(FMax, Max, false)
|
||||
HLSL_GROUP_OP(IAdd, Sum, true)
|
||||
HLSL_GROUP_OP(IMul, Product, true)
|
||||
HLSL_GROUP_OP(SMin, Min, false)
|
||||
HLSL_GROUP_OP(SMax, Max, false)
|
||||
HLSL_GROUP_OP(UMin, Min, false)
|
||||
HLSL_GROUP_OP(UMax, Max, false)
|
||||
HLSL_GROUP_OP(BitwiseAnd, BitAnd, false)
|
||||
HLSL_GROUP_OP(BitwiseOr, BitOr, false)
|
||||
HLSL_GROUP_OP(BitwiseXor, BitXor, false)
|
||||
#undef HLSL_GROUP_OP
|
||||
// clang-format on
|
||||
|
||||
case OpGroupNonUniformQuadSwap:
|
||||
@ -3835,17 +3834,17 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
auto ops = stream(instruction);
|
||||
auto opcode = static_cast<Op>(instruction.op);
|
||||
|
||||
#define BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define BOP_CAST(op, type) \
|
||||
#define HLSL_BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define HLSL_BOP_CAST(op, type) \
|
||||
emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, hlsl_opcode_is_sign_invariant(opcode))
|
||||
#define UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op)
|
||||
#define QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op)
|
||||
#define TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op)
|
||||
#define BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define BFOP_CAST(op, type) \
|
||||
#define HLSL_UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op)
|
||||
#define HLSL_QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op)
|
||||
#define HLSL_TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op)
|
||||
#define HLSL_BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define HLSL_BFOP_CAST(op, type) \
|
||||
emit_binary_func_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, hlsl_opcode_is_sign_invariant(opcode))
|
||||
#define BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define UFOP(op) emit_unary_func_op(ops[0], ops[1], ops[2], #op)
|
||||
#define HLSL_BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define HLSL_UFOP(op) emit_unary_func_op(ops[0], ops[1], ops[2], #op)
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
@ -3914,39 +3913,39 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
}
|
||||
|
||||
case OpDPdx:
|
||||
UFOP(ddx);
|
||||
HLSL_UFOP(ddx);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
case OpDPdy:
|
||||
UFOP(ddy);
|
||||
HLSL_UFOP(ddy);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
case OpDPdxFine:
|
||||
UFOP(ddx_fine);
|
||||
HLSL_UFOP(ddx_fine);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
case OpDPdyFine:
|
||||
UFOP(ddy_fine);
|
||||
HLSL_UFOP(ddy_fine);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
case OpDPdxCoarse:
|
||||
UFOP(ddx_coarse);
|
||||
HLSL_UFOP(ddx_coarse);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
case OpDPdyCoarse:
|
||||
UFOP(ddy_coarse);
|
||||
HLSL_UFOP(ddy_coarse);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
case OpFwidth:
|
||||
case OpFwidthCoarse:
|
||||
case OpFwidthFine:
|
||||
UFOP(fwidth);
|
||||
HLSL_UFOP(fwidth);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
@ -3959,7 +3958,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (type.vecsize > 1)
|
||||
emit_unrolled_unary_op(result_type, id, ops[2], "!");
|
||||
else
|
||||
UOP(!);
|
||||
HLSL_UOP(!);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3971,7 +3970,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "==");
|
||||
else
|
||||
BOP_CAST(==, SPIRType::Int);
|
||||
HLSL_BOP_CAST(==, SPIRType::Int);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3984,7 +3983,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "==");
|
||||
else
|
||||
BOP(==);
|
||||
HLSL_BOP(==);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3996,7 +3995,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "!=");
|
||||
else
|
||||
BOP_CAST(!=, SPIRType::Int);
|
||||
HLSL_BOP_CAST(!=, SPIRType::Int);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4009,7 +4008,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "!=");
|
||||
else
|
||||
BOP(!=);
|
||||
HLSL_BOP(!=);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4023,7 +4022,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], ">");
|
||||
else
|
||||
BOP_CAST(>, type);
|
||||
HLSL_BOP_CAST(>, type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4035,7 +4034,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], ">");
|
||||
else
|
||||
BOP(>);
|
||||
HLSL_BOP(>);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4049,7 +4048,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], ">=");
|
||||
else
|
||||
BOP_CAST(>=, type);
|
||||
HLSL_BOP_CAST(>=, type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4061,7 +4060,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], ">=");
|
||||
else
|
||||
BOP(>=);
|
||||
HLSL_BOP(>=);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4075,7 +4074,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "<");
|
||||
else
|
||||
BOP_CAST(<, type);
|
||||
HLSL_BOP_CAST(<, type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4087,7 +4086,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "<");
|
||||
else
|
||||
BOP(<);
|
||||
HLSL_BOP(<);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4101,7 +4100,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "<=");
|
||||
else
|
||||
BOP_CAST(<=, type);
|
||||
HLSL_BOP_CAST(<=, type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4113,7 +4112,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
if (expression_type(ops[2]).vecsize > 1)
|
||||
emit_unrolled_binary_op(result_type, id, ops[2], ops[3], "<=");
|
||||
else
|
||||
BOP(<=);
|
||||
HLSL_BOP(<=);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4418,18 +4417,18 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
|
||||
}
|
||||
|
||||
if (opcode == OpBitFieldSExtract)
|
||||
TFOP(SPIRV_Cross_bitfieldSExtract);
|
||||
HLSL_TFOP(SPIRV_Cross_bitfieldSExtract);
|
||||
else
|
||||
TFOP(SPIRV_Cross_bitfieldUExtract);
|
||||
HLSL_TFOP(SPIRV_Cross_bitfieldUExtract);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpBitCount:
|
||||
UFOP(countbits);
|
||||
HLSL_UFOP(countbits);
|
||||
break;
|
||||
|
||||
case OpBitReverse:
|
||||
UFOP(reversebits);
|
||||
HLSL_UFOP(reversebits);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -4605,3 +4604,24 @@ string CompilerHLSL::compile()
|
||||
|
||||
return buffer->str();
|
||||
}
|
||||
|
||||
void CompilerHLSL::emit_block_hints(const SPIRBlock &block)
|
||||
{
|
||||
switch (block.hint)
|
||||
{
|
||||
case SPIRBlock::HintFlatten:
|
||||
statement("[flatten]");
|
||||
break;
|
||||
case SPIRBlock::HintDontFlatten:
|
||||
statement("[branch]");
|
||||
break;
|
||||
case SPIRBlock::HintUnroll:
|
||||
statement("[unroll]");
|
||||
break;
|
||||
case SPIRBlock::HintDontUnroll:
|
||||
statement("[loop]");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -118,9 +118,9 @@ public:
|
||||
|
||||
private:
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string image_type_hlsl(const SPIRType &type);
|
||||
std::string image_type_hlsl_modern(const SPIRType &type);
|
||||
std::string image_type_hlsl_legacy(const SPIRType &type);
|
||||
std::string image_type_hlsl(const SPIRType &type, uint32_t id);
|
||||
std::string image_type_hlsl_modern(const SPIRType &type, uint32_t id);
|
||||
std::string image_type_hlsl_legacy(const SPIRType &type, uint32_t id);
|
||||
void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) override;
|
||||
void emit_hlsl_entry_point();
|
||||
void emit_header() override;
|
||||
@ -158,6 +158,7 @@ private:
|
||||
void emit_store(const Instruction &instruction);
|
||||
void emit_atomic(const uint32_t *ops, uint32_t length, spv::Op op);
|
||||
void emit_subgroup_op(const Instruction &i) override;
|
||||
void emit_block_hints(const SPIRBlock &block) override;
|
||||
|
||||
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier,
|
||||
uint32_t base_offset = 0) override;
|
||||
|
186
spirv_msl.cpp
186
spirv_msl.cpp
@ -534,19 +534,44 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::
|
||||
// Add the global variables as arguments to the function
|
||||
if (func_id != entry_point)
|
||||
{
|
||||
uint32_t next_id = increase_bound_by(uint32_t(added_arg_ids.size()));
|
||||
for (uint32_t arg_id : added_arg_ids)
|
||||
{
|
||||
auto var = get<SPIRVariable>(arg_id);
|
||||
auto &var = get<SPIRVariable>(arg_id);
|
||||
uint32_t type_id = var.basetype;
|
||||
func.add_parameter(type_id, next_id, true);
|
||||
set<SPIRVariable>(next_id, type_id, StorageClassFunction, 0, arg_id);
|
||||
auto *p_type = &get<SPIRType>(type_id);
|
||||
|
||||
// Ensure the existing variable has a valid name and the new variable has all the same meta info
|
||||
set_name(arg_id, ensure_valid_name(to_name(arg_id), "v"));
|
||||
meta[next_id] = meta[arg_id];
|
||||
if (is_builtin_variable(var) && p_type->basetype == SPIRType::Struct)
|
||||
{
|
||||
// Get the non-pointer type
|
||||
type_id = get_non_pointer_type_id(type_id);
|
||||
p_type = &get<SPIRType>(type_id);
|
||||
|
||||
next_id++;
|
||||
uint32_t mbr_idx = 0;
|
||||
for (auto &mbr_type_id : p_type->member_types)
|
||||
{
|
||||
BuiltIn builtin;
|
||||
bool is_builtin = is_member_builtin(*p_type, mbr_idx, &builtin);
|
||||
if (is_builtin && has_active_builtin(builtin, var.storage))
|
||||
{
|
||||
// Add a arg variable with the same type and decorations as the member
|
||||
uint32_t next_id = increase_bound_by(1);
|
||||
func.add_parameter(mbr_type_id, next_id, true);
|
||||
set<SPIRVariable>(next_id, mbr_type_id, StorageClassFunction);
|
||||
meta[next_id].decoration = meta[type_id].members[mbr_idx];
|
||||
}
|
||||
mbr_idx++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t next_id = increase_bound_by(1);
|
||||
func.add_parameter(type_id, next_id, true);
|
||||
set<SPIRVariable>(next_id, type_id, StorageClassFunction, 0, arg_id);
|
||||
|
||||
// Ensure the existing variable has a valid name and the new variable has all the same meta info
|
||||
set_name(arg_id, ensure_valid_name(to_name(arg_id), "v"));
|
||||
meta[next_id] = meta[arg_id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1148,6 +1173,18 @@ void CompilerMSL::emit_custom_functions()
|
||||
statement("");
|
||||
break;
|
||||
|
||||
case SPVFuncImplTexelBufferCoords:
|
||||
{
|
||||
string tex_width_str = convert_to_string(msl_options.texel_buffer_texture_width);
|
||||
statement("// Returns 2D texture coords corresponding to 1D texel buffer coords");
|
||||
statement("uint2 spvTexelBufferCoord(uint tc)");
|
||||
begin_scope();
|
||||
statement(join("return uint2(tc % ", tex_width_str, ", tc / ", tex_width_str, ");"));
|
||||
end_scope();
|
||||
statement("");
|
||||
break;
|
||||
}
|
||||
|
||||
case SPVFuncImplInverse4x4:
|
||||
statement("// Returns the determinant of a 2x2 matrix.");
|
||||
statement("inline float spvDet2x2(float a1, float a2, float b1, float b2)");
|
||||
@ -1506,16 +1543,16 @@ void CompilerMSL::emit_specialization_constants()
|
||||
void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
{
|
||||
|
||||
#define BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define BOP_CAST(op, type) \
|
||||
#define MSL_BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define MSL_BOP_CAST(op, type) \
|
||||
emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode))
|
||||
#define UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op)
|
||||
#define QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op)
|
||||
#define TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op)
|
||||
#define BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define BFOP_CAST(op, type) \
|
||||
#define MSL_UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op)
|
||||
#define MSL_QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op)
|
||||
#define MSL_TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op)
|
||||
#define MSL_BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op)
|
||||
#define MSL_BFOP_CAST(op, type) \
|
||||
emit_binary_func_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode))
|
||||
#define UFOP(op) emit_unary_func_op(ops[0], ops[1], ops[2], #op)
|
||||
#define MSL_UFOP(op) emit_unary_func_op(ops[0], ops[1], ops[2], #op)
|
||||
|
||||
auto ops = stream(instruction);
|
||||
auto opcode = static_cast<Op>(instruction.op);
|
||||
@ -1527,81 +1564,81 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
case OpIEqual:
|
||||
case OpLogicalEqual:
|
||||
case OpFOrdEqual:
|
||||
BOP(==);
|
||||
MSL_BOP(==);
|
||||
break;
|
||||
|
||||
case OpINotEqual:
|
||||
case OpLogicalNotEqual:
|
||||
case OpFOrdNotEqual:
|
||||
BOP(!=);
|
||||
MSL_BOP(!=);
|
||||
break;
|
||||
|
||||
case OpUGreaterThan:
|
||||
case OpSGreaterThan:
|
||||
case OpFOrdGreaterThan:
|
||||
BOP(>);
|
||||
MSL_BOP(>);
|
||||
break;
|
||||
|
||||
case OpUGreaterThanEqual:
|
||||
case OpSGreaterThanEqual:
|
||||
case OpFOrdGreaterThanEqual:
|
||||
BOP(>=);
|
||||
MSL_BOP(>=);
|
||||
break;
|
||||
|
||||
case OpULessThan:
|
||||
case OpSLessThan:
|
||||
case OpFOrdLessThan:
|
||||
BOP(<);
|
||||
MSL_BOP(<);
|
||||
break;
|
||||
|
||||
case OpULessThanEqual:
|
||||
case OpSLessThanEqual:
|
||||
case OpFOrdLessThanEqual:
|
||||
BOP(<=);
|
||||
MSL_BOP(<=);
|
||||
break;
|
||||
|
||||
// Derivatives
|
||||
case OpDPdx:
|
||||
case OpDPdxFine:
|
||||
case OpDPdxCoarse:
|
||||
UFOP(dfdx);
|
||||
MSL_UFOP(dfdx);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
case OpDPdy:
|
||||
case OpDPdyFine:
|
||||
case OpDPdyCoarse:
|
||||
UFOP(dfdy);
|
||||
MSL_UFOP(dfdy);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
case OpFwidth:
|
||||
case OpFwidthCoarse:
|
||||
case OpFwidthFine:
|
||||
UFOP(fwidth);
|
||||
MSL_UFOP(fwidth);
|
||||
register_control_dependent_expression(ops[1]);
|
||||
break;
|
||||
|
||||
// Bitfield
|
||||
case OpBitFieldInsert:
|
||||
QFOP(insert_bits);
|
||||
MSL_QFOP(insert_bits);
|
||||
break;
|
||||
|
||||
case OpBitFieldSExtract:
|
||||
case OpBitFieldUExtract:
|
||||
TFOP(extract_bits);
|
||||
MSL_TFOP(extract_bits);
|
||||
break;
|
||||
|
||||
case OpBitReverse:
|
||||
UFOP(reverse_bits);
|
||||
MSL_UFOP(reverse_bits);
|
||||
break;
|
||||
|
||||
case OpBitCount:
|
||||
UFOP(popcount);
|
||||
MSL_UFOP(popcount);
|
||||
break;
|
||||
|
||||
case OpFRem:
|
||||
BFOP(fmod);
|
||||
MSL_BFOP(fmod);
|
||||
break;
|
||||
|
||||
// Atomics
|
||||
@ -1654,7 +1691,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
break;
|
||||
}
|
||||
|
||||
#define AFMOImpl(op, valsrc) \
|
||||
#define MSL_AFMO_IMPL(op, valsrc) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t result_type = ops[0]; \
|
||||
@ -1665,45 +1702,45 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
emit_atomic_func_op(result_type, id, "atomic_fetch_" #op "_explicit", mem_sem, mem_sem, false, ptr, val); \
|
||||
} while (false)
|
||||
|
||||
#define AFMO(op) AFMOImpl(op, ops[5])
|
||||
#define AFMIO(op) AFMOImpl(op, 1)
|
||||
#define MSL_AFMO(op) MSL_AFMO_IMPL(op, ops[5])
|
||||
#define MSL_AFMIO(op) MSL_AFMO_IMPL(op, 1)
|
||||
|
||||
case OpAtomicIIncrement:
|
||||
AFMIO(add);
|
||||
MSL_AFMIO(add);
|
||||
break;
|
||||
|
||||
case OpAtomicIDecrement:
|
||||
AFMIO(sub);
|
||||
MSL_AFMIO(sub);
|
||||
break;
|
||||
|
||||
case OpAtomicIAdd:
|
||||
AFMO(add);
|
||||
MSL_AFMO(add);
|
||||
break;
|
||||
|
||||
case OpAtomicISub:
|
||||
AFMO(sub);
|
||||
MSL_AFMO(sub);
|
||||
break;
|
||||
|
||||
case OpAtomicSMin:
|
||||
case OpAtomicUMin:
|
||||
AFMO(min);
|
||||
MSL_AFMO(min);
|
||||
break;
|
||||
|
||||
case OpAtomicSMax:
|
||||
case OpAtomicUMax:
|
||||
AFMO(max);
|
||||
MSL_AFMO(max);
|
||||
break;
|
||||
|
||||
case OpAtomicAnd:
|
||||
AFMO(and);
|
||||
MSL_AFMO(and);
|
||||
break;
|
||||
|
||||
case OpAtomicOr:
|
||||
AFMO(or);
|
||||
MSL_AFMO(or);
|
||||
break;
|
||||
|
||||
case OpAtomicXor:
|
||||
AFMO (xor);
|
||||
MSL_AFMO (xor);
|
||||
break;
|
||||
|
||||
// Images
|
||||
@ -1827,7 +1864,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
break;
|
||||
}
|
||||
|
||||
#define ImgQry(qrytype) \
|
||||
#define MSL_ImgQry(qrytype) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t rslt_type_id = ops[0]; \
|
||||
@ -1840,11 +1877,11 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
} while (false)
|
||||
|
||||
case OpImageQueryLevels:
|
||||
ImgQry(mip_levels);
|
||||
MSL_ImgQry(mip_levels);
|
||||
break;
|
||||
|
||||
case OpImageQuerySamples:
|
||||
ImgQry(samples);
|
||||
MSL_ImgQry(samples);
|
||||
break;
|
||||
|
||||
// Casting
|
||||
@ -1926,7 +1963,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
e->need_transpose = true;
|
||||
}
|
||||
else
|
||||
BOP(*);
|
||||
MSL_BOP(*);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2429,8 +2466,9 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
|
||||
if (coord_type.vecsize > 1)
|
||||
tex_coords += ".x";
|
||||
|
||||
// Metal texel buffer textures are 2D, so convert 1D coord to 2D.
|
||||
if (is_fetch)
|
||||
tex_coords = "uint2(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ", 0)"; // Metal textures are 2D
|
||||
tex_coords = "spvTexelBufferCoord(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")";
|
||||
|
||||
alt_coord = ".y";
|
||||
|
||||
@ -3553,17 +3591,13 @@ std::string CompilerMSL::sampler_type(const SPIRType &type)
|
||||
SPIRV_CROSS_THROW("MSL 2.0 or greater is required for arrays of samplers.");
|
||||
|
||||
// Arrays of samplers in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
||||
auto *parent = &type;
|
||||
while (parent->pointer)
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
|
||||
uint32_t array_size =
|
||||
type.array_size_literal.back() ? type.array.back() : get<SPIRConstant>(type.array.back()).scalar();
|
||||
|
||||
if (array_size == 0)
|
||||
SPIRV_CROSS_THROW("Unsized array of samplers is not supported in MSL.");
|
||||
return join("array<", sampler_type(*parent), ", ", array_size, ">");
|
||||
|
||||
auto &parent = get<SPIRType>(get_non_pointer_type(type).parent_type);
|
||||
return join("array<", sampler_type(parent), ", ", array_size, ">");
|
||||
}
|
||||
else
|
||||
return "sampler";
|
||||
@ -3586,25 +3620,20 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
SPIRV_CROSS_THROW("MSL 2.0 or greater is required for arrays of textures.");
|
||||
|
||||
// Arrays of images in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
||||
auto *parent = &type;
|
||||
while (parent->pointer)
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
|
||||
uint32_t array_size =
|
||||
type.array_size_literal.back() ? type.array.back() : get<SPIRConstant>(type.array.back()).scalar();
|
||||
if (array_size == 0)
|
||||
SPIRV_CROSS_THROW("Unsized array of images is not supported in MSL.");
|
||||
return join("array<", image_type_glsl(*parent, id), ", ", array_size, ">");
|
||||
|
||||
auto &parent = get<SPIRType>(get_non_pointer_type(type).parent_type);
|
||||
return join("array<", image_type_glsl(parent, id), ", ", array_size, ">");
|
||||
}
|
||||
|
||||
string img_type_name;
|
||||
|
||||
// Bypass pointers because we need the real image struct
|
||||
auto &img_type = get<SPIRType>(type.self).image;
|
||||
bool shadow_image = comparison_images.count(id) != 0;
|
||||
|
||||
if (img_type.depth || shadow_image)
|
||||
if (image_is_comparison(type, id))
|
||||
{
|
||||
switch (img_type.dim)
|
||||
{
|
||||
@ -4035,8 +4064,8 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
|
||||
auto &return_type = compiler.get<SPIRType>(args[0]);
|
||||
if (!return_type.array.empty())
|
||||
return SPVFuncImplArrayCopy;
|
||||
else
|
||||
return SPVFuncImplNone;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OpStore:
|
||||
@ -4054,14 +4083,24 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
|
||||
else
|
||||
{
|
||||
// Or ... an expression.
|
||||
if (result_types[id_rhs] != 0)
|
||||
type = &compiler.get<SPIRType>(result_types[id_rhs]);
|
||||
uint32_t tid = result_types[id_rhs];
|
||||
if (tid)
|
||||
type = &compiler.get<SPIRType>(tid);
|
||||
}
|
||||
|
||||
if (type && compiler.is_array(*type))
|
||||
return SPVFuncImplArrayCopy;
|
||||
else
|
||||
return SPVFuncImplNone;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case OpImageFetch:
|
||||
{
|
||||
// Retrieve the image type, and if it's a Buffer, emit a texel coordinate function
|
||||
uint32_t tid = result_types[args[2]];
|
||||
if (tid && compiler.get<SPIRType>(tid).image.dim == DimBuffer)
|
||||
return SPVFuncImplTexelBufferCoords;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4179,3 +4218,12 @@ void CompilerMSL::remap_constexpr_sampler(uint32_t id, const spirv_cross::MSLCon
|
||||
SPIRV_CROSS_THROW("Can not remap array of samplers.");
|
||||
constexpr_samplers[id] = sampler;
|
||||
}
|
||||
|
||||
// MSL always declares builtins with their SPIR-V type.
|
||||
void CompilerMSL::bitcast_from_builtin_load(uint32_t, std::string &, const spirv_cross::SPIRType &)
|
||||
{
|
||||
}
|
||||
|
||||
void CompilerMSL::bitcast_to_builtin_store(uint32_t, std::string &, const spirv_cross::SPIRType &)
|
||||
{
|
||||
}
|
||||
|
@ -152,6 +152,7 @@ public:
|
||||
|
||||
Platform platform = macOS;
|
||||
uint32_t msl_version = make_msl_version(1, 2);
|
||||
uint32_t texel_buffer_texture_width = 4096; // Width of 2D Metal textures used as 1D texel buffers
|
||||
bool enable_point_size_builtin = true;
|
||||
bool resolve_specialized_array_lengths = true;
|
||||
|
||||
@ -215,6 +216,7 @@ public:
|
||||
SPVFuncImplFindSMsb,
|
||||
SPVFuncImplFindUMsb,
|
||||
SPVFuncImplArrayCopy,
|
||||
SPVFuncImplTexelBufferCoords,
|
||||
SPVFuncImplInverse4x4,
|
||||
SPVFuncImplInverse3x3,
|
||||
SPVFuncImplInverse2x2,
|
||||
@ -356,6 +358,9 @@ protected:
|
||||
void emit_entry_point_declarations() override;
|
||||
uint32_t builtin_frag_coord_id = 0;
|
||||
|
||||
void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
void bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override;
|
||||
|
||||
Options msl_options;
|
||||
std::set<SPVFuncImpl> spv_function_implementations;
|
||||
std::unordered_map<uint32_t, MSLVertexAttr *> vtx_attrs_by_location;
|
||||
|
573
spirv_reflect.cpp
Normal file
573
spirv_reflect.cpp
Normal file
@ -0,0 +1,573 @@
|
||||
/*
|
||||
* Copyright 2018 Bradley Austin Davis
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "spirv_reflect.hpp"
|
||||
#include "spirv_glsl.hpp"
|
||||
#include <iomanip>
|
||||
|
||||
using namespace spv;
|
||||
using namespace spirv_cross;
|
||||
using namespace std;
|
||||
|
||||
namespace simple_json
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
Object,
|
||||
Array,
|
||||
};
|
||||
|
||||
using State = std::pair<Type, bool>;
|
||||
using Stack = std::stack<State>;
|
||||
|
||||
class Stream
|
||||
{
|
||||
Stack stack;
|
||||
std::ostringstream buffer;
|
||||
uint32_t indent{ 0 };
|
||||
|
||||
public:
|
||||
void begin_json_object();
|
||||
void end_json_object();
|
||||
void emit_json_key(const std::string &key);
|
||||
void emit_json_key_value(const std::string &key, const std::string &value);
|
||||
void emit_json_key_value(const std::string &key, bool value);
|
||||
void emit_json_key_value(const std::string &key, uint32_t value);
|
||||
void emit_json_key_value(const std::string &key, int32_t value);
|
||||
void emit_json_key_value(const std::string &key, float value);
|
||||
void emit_json_key_object(const std::string &key);
|
||||
void emit_json_key_array(const std::string &key);
|
||||
|
||||
void begin_json_array();
|
||||
void end_json_array();
|
||||
void emit_json_array_value(const std::string &value);
|
||||
void emit_json_array_value(uint32_t value);
|
||||
|
||||
std::string str() const
|
||||
{
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
private:
|
||||
inline void statement_indent()
|
||||
{
|
||||
for (uint32_t i = 0; i < indent; i++)
|
||||
buffer << " ";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void statement_inner(T &&t)
|
||||
{
|
||||
buffer << std::forward<T>(t);
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
inline void statement_inner(T &&t, Ts &&... ts)
|
||||
{
|
||||
buffer << std::forward<T>(t);
|
||||
statement_inner(std::forward<Ts>(ts)...);
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
inline void statement(Ts &&... ts)
|
||||
{
|
||||
statement_indent();
|
||||
statement_inner(std::forward<Ts>(ts)...);
|
||||
buffer << '\n';
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
void statement_no_return(Ts &&... ts)
|
||||
{
|
||||
statement_indent();
|
||||
statement_inner(std::forward<Ts>(ts)...);
|
||||
}
|
||||
};
|
||||
} // namespace simple_json
|
||||
|
||||
using namespace simple_json;
|
||||
|
||||
// Hackery to emit JSON without using nlohmann/json C++ library (which requires a
|
||||
// higher level of compiler compliance than is required by SPIRV-Cross
|
||||
void Stream::begin_json_array()
|
||||
{
|
||||
if (!stack.empty() && stack.top().second)
|
||||
{
|
||||
statement_inner(",\n");
|
||||
}
|
||||
statement("[");
|
||||
++indent;
|
||||
stack.emplace(Type::Array, false);
|
||||
}
|
||||
|
||||
void Stream::end_json_array()
|
||||
{
|
||||
if (stack.empty() || stack.top().first != Type::Array)
|
||||
SPIRV_CROSS_THROW("Invalid JSON state");
|
||||
if (stack.top().second)
|
||||
{
|
||||
statement_inner("\n");
|
||||
}
|
||||
--indent;
|
||||
statement_no_return("]");
|
||||
stack.pop();
|
||||
if (!stack.empty())
|
||||
{
|
||||
stack.top().second = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Stream::emit_json_array_value(const std::string &value)
|
||||
{
|
||||
if (stack.empty() || stack.top().first != Type::Array)
|
||||
SPIRV_CROSS_THROW("Invalid JSON state");
|
||||
|
||||
if (stack.top().second)
|
||||
statement_inner(",\n");
|
||||
|
||||
statement_no_return("\"", value, "\"");
|
||||
stack.top().second = true;
|
||||
}
|
||||
|
||||
void Stream::emit_json_array_value(uint32_t value)
|
||||
{
|
||||
if (stack.empty() || stack.top().first != Type::Array)
|
||||
SPIRV_CROSS_THROW("Invalid JSON state");
|
||||
if (stack.top().second)
|
||||
statement_inner(",\n");
|
||||
statement_no_return(std::to_string(value));
|
||||
stack.top().second = true;
|
||||
}
|
||||
|
||||
void Stream::begin_json_object()
|
||||
{
|
||||
if (!stack.empty() && stack.top().second)
|
||||
{
|
||||
statement_inner(",\n");
|
||||
}
|
||||
statement("{");
|
||||
++indent;
|
||||
stack.emplace(Type::Object, false);
|
||||
}
|
||||
|
||||
void Stream::end_json_object()
|
||||
{
|
||||
if (stack.empty() || stack.top().first != Type::Object)
|
||||
SPIRV_CROSS_THROW("Invalid JSON state");
|
||||
if (stack.top().second)
|
||||
{
|
||||
statement_inner("\n");
|
||||
}
|
||||
--indent;
|
||||
statement_no_return("}");
|
||||
stack.pop();
|
||||
if (!stack.empty())
|
||||
{
|
||||
stack.top().second = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Stream::emit_json_key(const std::string &key)
|
||||
{
|
||||
if (stack.empty() || stack.top().first != Type::Object)
|
||||
SPIRV_CROSS_THROW("Invalid JSON state");
|
||||
|
||||
if (stack.top().second)
|
||||
statement_inner(",\n");
|
||||
statement_no_return("\"", key, "\" : ");
|
||||
stack.top().second = true;
|
||||
}
|
||||
|
||||
void Stream::emit_json_key_value(const std::string &key, const std::string &value)
|
||||
{
|
||||
emit_json_key(key);
|
||||
statement_inner("\"", value, "\"");
|
||||
}
|
||||
|
||||
void Stream::emit_json_key_value(const std::string &key, uint32_t value)
|
||||
{
|
||||
emit_json_key(key);
|
||||
statement_inner(value);
|
||||
}
|
||||
|
||||
void Stream::emit_json_key_value(const std::string &key, int32_t value)
|
||||
{
|
||||
emit_json_key(key);
|
||||
statement_inner(value);
|
||||
}
|
||||
|
||||
void Stream::emit_json_key_value(const std::string &key, float value)
|
||||
{
|
||||
emit_json_key(key);
|
||||
statement_inner(value);
|
||||
}
|
||||
|
||||
void Stream::emit_json_key_value(const std::string &key, bool value)
|
||||
{
|
||||
emit_json_key(key);
|
||||
statement_inner(value ? "true" : "false");
|
||||
}
|
||||
|
||||
void Stream::emit_json_key_object(const std::string &key)
|
||||
{
|
||||
emit_json_key(key);
|
||||
statement_inner("{\n");
|
||||
++indent;
|
||||
stack.emplace(Type::Object, false);
|
||||
}
|
||||
|
||||
void Stream::emit_json_key_array(const std::string &key)
|
||||
{
|
||||
emit_json_key(key);
|
||||
statement_inner("[\n");
|
||||
++indent;
|
||||
stack.emplace(Type::Array, false);
|
||||
}
|
||||
|
||||
void CompilerReflection::set_format(const std::string &format)
|
||||
{
|
||||
if (format != "json")
|
||||
{
|
||||
SPIRV_CROSS_THROW("Unsupported format");
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerReflection::compile()
|
||||
{
|
||||
// Force a classic "C" locale, reverts when function returns
|
||||
ClassicLocale classic_locale;
|
||||
|
||||
// Move constructor for this type is broken on GCC 4.9 ...
|
||||
json_stream = std::make_shared<simple_json::Stream>();
|
||||
json_stream->begin_json_object();
|
||||
emit_entry_points();
|
||||
emit_types();
|
||||
emit_resources();
|
||||
emit_specialization_constants();
|
||||
json_stream->end_json_object();
|
||||
return json_stream->str();
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_types()
|
||||
{
|
||||
bool emitted_open_tag = false;
|
||||
for (auto &id : ids)
|
||||
{
|
||||
auto idType = id.get_type();
|
||||
if (idType == TypeType)
|
||||
{
|
||||
auto &type = id.get<SPIRType>();
|
||||
if (type.basetype == SPIRType::Struct && !type.pointer && type.array.empty())
|
||||
{
|
||||
emit_type(type, emitted_open_tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (emitted_open_tag)
|
||||
{
|
||||
json_stream->end_json_object();
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_type(const SPIRType &type, bool &emitted_open_tag)
|
||||
{
|
||||
auto name = type_to_glsl(type);
|
||||
|
||||
if (type.type_alias != 0)
|
||||
return;
|
||||
|
||||
if (!emitted_open_tag)
|
||||
{
|
||||
json_stream->emit_json_key_object("types");
|
||||
emitted_open_tag = true;
|
||||
}
|
||||
json_stream->emit_json_key_object("_" + std::to_string(type.self));
|
||||
json_stream->emit_json_key_value("name", name);
|
||||
json_stream->emit_json_key_array("members");
|
||||
// FIXME ideally we'd like to emit the size of a structure as a
|
||||
// convenience to people parsing the reflected JSON. The problem
|
||||
// is that there's no implicit size for a type. It's final size
|
||||
// will be determined by the top level declaration in which it's
|
||||
// included. So there might be one size for the struct if it's
|
||||
// included in a std140 uniform block and another if it's included
|
||||
// in a std430 uniform block.
|
||||
// The solution is to include *all* potential sizes as a map of
|
||||
// layout type name to integer, but that will probably require
|
||||
// some additional logic being written in this class, or in the
|
||||
// parent CompilerGLSL class.
|
||||
auto size = type.member_types.size();
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
emit_type_member(type, i);
|
||||
}
|
||||
json_stream->end_json_array();
|
||||
json_stream->end_json_object();
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_type_member(const SPIRType &type, uint32_t index)
|
||||
{
|
||||
auto &membertype = get<SPIRType>(type.member_types[index]);
|
||||
json_stream->begin_json_object();
|
||||
auto name = to_member_name(type, index);
|
||||
// FIXME we'd like to emit the offset of each member, but such offsets are
|
||||
// context dependent. See the comment above regarding structure sizes
|
||||
json_stream->emit_json_key_value("name", name);
|
||||
if (membertype.basetype == SPIRType::Struct)
|
||||
{
|
||||
json_stream->emit_json_key_value("type", "_" + std::to_string(membertype.self));
|
||||
}
|
||||
else
|
||||
{
|
||||
json_stream->emit_json_key_value("type", type_to_glsl(membertype));
|
||||
}
|
||||
emit_type_member_qualifiers(type, index);
|
||||
json_stream->end_json_object();
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_type_array(const SPIRType &type)
|
||||
{
|
||||
if (!type.array.empty())
|
||||
{
|
||||
json_stream->emit_json_key_array("array");
|
||||
// Note that we emit the zeros here as a means of identifying
|
||||
// unbounded arrays. This is necessary as otherwise there would
|
||||
// be no way of differentiating between float[4] and float[4][]
|
||||
for (const auto &value : type.array)
|
||||
json_stream->emit_json_array_value(value);
|
||||
json_stream->end_json_array();
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_type_member_qualifiers(const SPIRType &type, uint32_t index)
|
||||
{
|
||||
auto flags = combined_decoration_for_member(type, index);
|
||||
if (flags.get(DecorationRowMajor))
|
||||
json_stream->emit_json_key_value("row_major", true);
|
||||
|
||||
auto &membertype = get<SPIRType>(type.member_types[index]);
|
||||
emit_type_array(membertype);
|
||||
auto &memb = meta[type.self].members;
|
||||
if (index < memb.size())
|
||||
{
|
||||
auto &dec = memb[index];
|
||||
if (dec.decoration_flags.get(DecorationLocation))
|
||||
json_stream->emit_json_key_value("location", dec.location);
|
||||
if (dec.decoration_flags.get(DecorationOffset))
|
||||
json_stream->emit_json_key_value("offset", dec.offset);
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerReflection::execution_model_to_str(spv::ExecutionModel model)
|
||||
{
|
||||
switch (model)
|
||||
{
|
||||
case spv::ExecutionModelVertex:
|
||||
return "vert";
|
||||
case spv::ExecutionModelTessellationControl:
|
||||
return "tesc";
|
||||
case ExecutionModelTessellationEvaluation:
|
||||
return "tese";
|
||||
case ExecutionModelGeometry:
|
||||
return "geom";
|
||||
case ExecutionModelFragment:
|
||||
return "frag";
|
||||
case ExecutionModelGLCompute:
|
||||
return "comp";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME include things like the local_size dimensions, geometry output vertex count, etc
|
||||
void CompilerReflection::emit_entry_points()
|
||||
{
|
||||
auto entries = get_entry_points_and_stages();
|
||||
if (!entries.empty())
|
||||
{
|
||||
json_stream->emit_json_key_array("entryPoints");
|
||||
for (auto &e : entries)
|
||||
{
|
||||
json_stream->begin_json_object();
|
||||
json_stream->emit_json_key_value("name", e.name);
|
||||
json_stream->emit_json_key_value("mode", execution_model_to_str(e.execution_model));
|
||||
json_stream->end_json_object();
|
||||
}
|
||||
json_stream->end_json_array();
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_resources()
|
||||
{
|
||||
auto res = get_shader_resources();
|
||||
emit_resources("subpass_inputs", res.subpass_inputs);
|
||||
emit_resources("inputs", res.stage_inputs);
|
||||
emit_resources("outputs", res.stage_outputs);
|
||||
emit_resources("textures", res.sampled_images);
|
||||
emit_resources("separate_images", res.separate_images);
|
||||
emit_resources("separate_samplers", res.separate_samplers);
|
||||
emit_resources("images", res.storage_images);
|
||||
emit_resources("ssbos", res.storage_buffers);
|
||||
emit_resources("ubos", res.uniform_buffers);
|
||||
emit_resources("push_constants", res.push_constant_buffers);
|
||||
emit_resources("counters", res.atomic_counters);
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_resources(const char *tag, const vector<Resource> &resources)
|
||||
{
|
||||
if (resources.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
json_stream->emit_json_key_array(tag);
|
||||
for (auto &res : resources)
|
||||
{
|
||||
auto &type = get_type(res.type_id);
|
||||
auto typeflags = meta[type.self].decoration.decoration_flags;
|
||||
auto &mask = get_decoration_bitset(res.id);
|
||||
|
||||
// If we don't have a name, use the fallback for the type instead of the variable
|
||||
// for SSBOs and UBOs since those are the only meaningful names to use externally.
|
||||
// Push constant blocks are still accessed by name and not block name, even though they are technically Blocks.
|
||||
bool is_push_constant = get_storage_class(res.id) == StorageClassPushConstant;
|
||||
bool is_block = get_decoration_bitset(type.self).get(DecorationBlock) ||
|
||||
get_decoration_bitset(type.self).get(DecorationBufferBlock);
|
||||
|
||||
uint32_t fallback_id = !is_push_constant && is_block ? res.base_type_id : res.id;
|
||||
|
||||
json_stream->begin_json_object();
|
||||
|
||||
if (type.basetype == SPIRType::Struct)
|
||||
{
|
||||
json_stream->emit_json_key_value("type", "_" + std::to_string(res.base_type_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
json_stream->emit_json_key_value("type", type_to_glsl(type));
|
||||
}
|
||||
|
||||
json_stream->emit_json_key_value("name", !res.name.empty() ? res.name : get_fallback_name(fallback_id));
|
||||
{
|
||||
bool ssbo_block = type.storage == StorageClassStorageBuffer ||
|
||||
(type.storage == StorageClassUniform && typeflags.get(DecorationBufferBlock));
|
||||
if (ssbo_block)
|
||||
{
|
||||
auto buffer_flags = get_buffer_block_flags(res.id);
|
||||
if (buffer_flags.get(DecorationNonReadable))
|
||||
json_stream->emit_json_key_value("writeonly", true);
|
||||
if (buffer_flags.get(DecorationNonWritable))
|
||||
json_stream->emit_json_key_value("readonly", true);
|
||||
if (buffer_flags.get(DecorationRestrict))
|
||||
json_stream->emit_json_key_value("restrict", true);
|
||||
if (buffer_flags.get(DecorationCoherent))
|
||||
json_stream->emit_json_key_value("coherent", true);
|
||||
}
|
||||
}
|
||||
|
||||
emit_type_array(type);
|
||||
|
||||
{
|
||||
bool is_sized_block = is_block && (get_storage_class(res.id) == StorageClassUniform ||
|
||||
get_storage_class(res.id) == StorageClassUniformConstant);
|
||||
if (is_sized_block)
|
||||
{
|
||||
uint32_t block_size = uint32_t(get_declared_struct_size(get_type(res.base_type_id)));
|
||||
json_stream->emit_json_key_value("block_size", block_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (type.storage == StorageClassPushConstant)
|
||||
json_stream->emit_json_key_value("push_constant", true);
|
||||
if (mask.get(DecorationLocation))
|
||||
json_stream->emit_json_key_value("location", get_decoration(res.id, DecorationLocation));
|
||||
if (mask.get(DecorationRowMajor))
|
||||
json_stream->emit_json_key_value("row_major", true);
|
||||
if (mask.get(DecorationColMajor))
|
||||
json_stream->emit_json_key_value("column_major", true);
|
||||
if (mask.get(DecorationIndex))
|
||||
json_stream->emit_json_key_value("index", get_decoration(res.id, DecorationIndex));
|
||||
if (type.storage != StorageClassPushConstant && mask.get(DecorationDescriptorSet))
|
||||
json_stream->emit_json_key_value("set", get_decoration(res.id, DecorationDescriptorSet));
|
||||
if (mask.get(DecorationBinding))
|
||||
json_stream->emit_json_key_value("binding", get_decoration(res.id, DecorationBinding));
|
||||
if (mask.get(DecorationInputAttachmentIndex))
|
||||
json_stream->emit_json_key_value("input_attachment_index",
|
||||
get_decoration(res.id, DecorationInputAttachmentIndex));
|
||||
if (mask.get(DecorationOffset))
|
||||
json_stream->emit_json_key_value("offset", get_decoration(res.id, DecorationOffset));
|
||||
|
||||
// For images, the type itself adds a layout qualifer.
|
||||
// Only emit the format for storage images.
|
||||
if (type.basetype == SPIRType::Image && type.image.sampled == 2)
|
||||
{
|
||||
const char *fmt = format_to_glsl(type.image.format);
|
||||
if (fmt != nullptr)
|
||||
json_stream->emit_json_key_value("format", std::string(fmt));
|
||||
}
|
||||
json_stream->end_json_object();
|
||||
}
|
||||
json_stream->end_json_array();
|
||||
}
|
||||
|
||||
void CompilerReflection::emit_specialization_constants()
|
||||
{
|
||||
auto specialization_constants = get_specialization_constants();
|
||||
if (specialization_constants.empty())
|
||||
return;
|
||||
|
||||
json_stream->emit_json_key_array("specialization_constants");
|
||||
for (const auto spec_const : specialization_constants)
|
||||
{
|
||||
auto &c = get<SPIRConstant>(spec_const.id);
|
||||
auto type = get<SPIRType>(c.constant_type);
|
||||
json_stream->begin_json_object();
|
||||
json_stream->emit_json_key_value("id", spec_const.constant_id);
|
||||
json_stream->emit_json_key_value("type", type_to_glsl(type));
|
||||
switch (type.basetype)
|
||||
{
|
||||
case SPIRType::UInt:
|
||||
json_stream->emit_json_key_value("default_value", c.scalar());
|
||||
break;
|
||||
|
||||
case SPIRType::Int:
|
||||
json_stream->emit_json_key_value("default_value", c.scalar_i32());
|
||||
break;
|
||||
|
||||
case SPIRType::Float:
|
||||
json_stream->emit_json_key_value("default_value", c.scalar_f32());
|
||||
break;
|
||||
|
||||
case SPIRType::Boolean:
|
||||
json_stream->emit_json_key_value("default_value", c.scalar() != 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
json_stream->end_json_object();
|
||||
}
|
||||
json_stream->end_json_array();
|
||||
}
|
||||
|
||||
string CompilerReflection::to_member_name(const SPIRType &type, uint32_t index) const
|
||||
{
|
||||
auto &memb = meta[type.self].members;
|
||||
if (index < memb.size() && !memb[index].alias.empty())
|
||||
return memb[index].alias;
|
||||
else
|
||||
return join("_m", index);
|
||||
}
|
72
spirv_reflect.hpp
Normal file
72
spirv_reflect.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2018 Bradley Austin Davis
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SPIRV_CROSS_REFLECT_HPP
|
||||
#define SPIRV_CROSS_REFLECT_HPP
|
||||
|
||||
#include "spirv_glsl.hpp"
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace simple_json
|
||||
{
|
||||
class Stream;
|
||||
}
|
||||
|
||||
namespace spirv_cross
|
||||
{
|
||||
class CompilerReflection : public CompilerGLSL
|
||||
{
|
||||
using Parent = CompilerGLSL;
|
||||
|
||||
public:
|
||||
CompilerReflection(std::vector<uint32_t> spirv_)
|
||||
: Parent(move(spirv_))
|
||||
{
|
||||
options.vulkan_semantics = true;
|
||||
}
|
||||
|
||||
CompilerReflection(const uint32_t *ir, size_t word_count)
|
||||
: Parent(ir, word_count)
|
||||
{
|
||||
options.vulkan_semantics = true;
|
||||
}
|
||||
|
||||
void set_format(const std::string &format);
|
||||
std::string compile() override;
|
||||
|
||||
private:
|
||||
static std::string execution_model_to_str(spv::ExecutionModel model);
|
||||
|
||||
void emit_entry_points();
|
||||
void emit_types();
|
||||
void emit_resources();
|
||||
void emit_specialization_constants();
|
||||
|
||||
void emit_type(const SPIRType &type, bool &emitted_open_tag);
|
||||
void emit_type_member(const SPIRType &type, uint32_t index);
|
||||
void emit_type_member_qualifiers(const SPIRType &type, uint32_t index);
|
||||
void emit_type_array(const SPIRType &type);
|
||||
void emit_resources(const char *tag, const std::vector<Resource> &resources);
|
||||
|
||||
std::string to_member_name(const SPIRType &type, uint32_t index) const;
|
||||
|
||||
std::shared_ptr<simple_json::Stream> json_stream;
|
||||
};
|
||||
|
||||
} // namespace spirv_cross
|
||||
|
||||
#endif
|
163
test_shaders.py
163
test_shaders.py
@ -11,8 +11,13 @@ import hashlib
|
||||
import shutil
|
||||
import argparse
|
||||
import codecs
|
||||
import json
|
||||
import multiprocessing
|
||||
import errno
|
||||
from functools import partial
|
||||
|
||||
force_no_external_validation = False
|
||||
backend = 'glsl'
|
||||
args = {}
|
||||
|
||||
def remove_file(path):
|
||||
#print('Removing file:', path)
|
||||
@ -78,7 +83,7 @@ def print_msl_compiler_version():
|
||||
subprocess.check_call(['xcrun', '--sdk', 'iphoneos', 'metal', '--version'])
|
||||
print('...are the Metal compiler characteristics.\n') # display after so xcrun FNF is silent
|
||||
except OSError as e:
|
||||
if (e.errno != os.errno.ENOENT): # Ignore xcrun not found error
|
||||
if (e.errno != errno.ENOENT): # Ignore xcrun not found error
|
||||
raise
|
||||
|
||||
def validate_shader_msl(shader, opt):
|
||||
@ -90,7 +95,7 @@ def validate_shader_msl(shader, opt):
|
||||
subprocess.check_call(['xcrun', '--sdk', msl_os, 'metal', '-x', 'metal', '-std=osx-metal{}'.format('2.0' if msl2 else '1.2'), '-Werror', '-Wno-unused-variable', msl_path])
|
||||
print('Compiled Metal shader: ' + msl_path) # display after so xcrun FNF is silent
|
||||
except OSError as oe:
|
||||
if (oe.errno != os.errno.ENOENT): # Ignore xcrun not found error
|
||||
if (oe.errno != errno.ENOENT): # Ignore xcrun not found error
|
||||
raise
|
||||
except subprocess.CalledProcessError:
|
||||
print('Error compiling Metal shader: ' + msl_path)
|
||||
@ -140,7 +145,7 @@ def shader_to_win_path(shader):
|
||||
stdout_data, stderr_data = f.communicate()
|
||||
return stdout_data.decode('utf-8')
|
||||
except OSError as oe:
|
||||
if (oe.errno != os.errno.ENOENT): # Ignore not found errors
|
||||
if (oe.errno != errno.ENOENT): # Ignore not found errors
|
||||
return shader
|
||||
except subprocess.CalledProcessError:
|
||||
raise
|
||||
@ -152,12 +157,12 @@ def validate_shader_hlsl(shader):
|
||||
subprocess.check_call(['glslangValidator', '-e', 'main', '-D', '--target-env', 'vulkan1.1', '-V', shader])
|
||||
is_no_fxc = '.nofxc.' in shader
|
||||
global ignore_fxc
|
||||
if (not ignore_fxc) and (not force_no_external_validation) and (not is_no_fxc):
|
||||
if (not ignore_fxc) and (not args.force_no_external_validation) and (not is_no_fxc):
|
||||
try:
|
||||
win_path = shader_to_win_path(shader)
|
||||
subprocess.check_call(['fxc', '-nologo', shader_model_hlsl(shader), win_path])
|
||||
except OSError as oe:
|
||||
if (oe.errno != os.errno.ENOENT): # Ignore not found errors
|
||||
if (oe.errno != errno.ENOENT): # Ignore not found errors
|
||||
raise
|
||||
else:
|
||||
ignore_fxc = True
|
||||
@ -199,6 +204,24 @@ def cross_compile_hlsl(shader, spirv, opt):
|
||||
|
||||
return (spirv_path, hlsl_path)
|
||||
|
||||
def cross_compile_reflect(shader, spirv, opt):
|
||||
spirv_path = create_temporary()
|
||||
reflect_path = create_temporary(os.path.basename(shader))
|
||||
|
||||
if spirv:
|
||||
subprocess.check_call(['spirv-as', '-o', spirv_path, shader])
|
||||
else:
|
||||
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', '-o', spirv_path, shader])
|
||||
|
||||
if opt:
|
||||
subprocess.check_call(['spirv-opt', '-O', '-o', spirv_path, spirv_path])
|
||||
|
||||
spirv_cross_path = './spirv-cross'
|
||||
|
||||
sm = shader_to_sm(shader)
|
||||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', reflect_path, spirv_path, '--reflect'])
|
||||
return (spirv_path, reflect_path)
|
||||
|
||||
def validate_shader(shader, vulkan):
|
||||
if vulkan:
|
||||
subprocess.check_call(['glslangValidator', '--target-env', 'vulkan1.1', '-V', shader])
|
||||
@ -277,6 +300,58 @@ def reference_path(directory, relpath, opt):
|
||||
reference_dir = os.path.join(reference_dir, split_paths[1])
|
||||
return os.path.join(reference_dir, relpath)
|
||||
|
||||
def json_ordered(obj):
|
||||
if isinstance(obj, dict):
|
||||
return sorted((k, json_ordered(v)) for k, v in obj.items())
|
||||
if isinstance(obj, list):
|
||||
return sorted(json_ordered(x) for x in obj)
|
||||
else:
|
||||
return obj
|
||||
|
||||
def json_compare(json_a, json_b):
|
||||
return json_ordered(json_a) == json_ordered(json_b)
|
||||
|
||||
def regression_check_reflect(shader, json_file, update, keep, opt):
|
||||
reference = reference_path(shader[0], shader[1], opt) + '.json'
|
||||
joined_path = os.path.join(shader[0], shader[1])
|
||||
print('Reference shader reflection path:', reference)
|
||||
if os.path.exists(reference):
|
||||
actual = ''
|
||||
expected = ''
|
||||
with open(json_file) as f:
|
||||
actual_json = f.read();
|
||||
actual = json.loads(actual_json)
|
||||
with open(reference) as f:
|
||||
expected = json.load(f)
|
||||
if (json_compare(actual, expected) != True):
|
||||
if update:
|
||||
print('Generated reflection json has changed for {}!'.format(reference))
|
||||
# If we expect changes, update the reference file.
|
||||
if os.path.exists(reference):
|
||||
remove_file(reference)
|
||||
make_reference_dir(reference)
|
||||
shutil.move(json_file, reference)
|
||||
else:
|
||||
print('Generated reflection json in {} does not match reference {}!'.format(json_file, reference))
|
||||
with open(json_file, 'r') as f:
|
||||
print('')
|
||||
print('Generated:')
|
||||
print('======================')
|
||||
print(f.read())
|
||||
print('======================')
|
||||
print('')
|
||||
|
||||
# Otherwise, fail the test. Keep the shader file around so we can inspect.
|
||||
if not keep:
|
||||
remove_file(json_file)
|
||||
sys.exit(1)
|
||||
else:
|
||||
remove_file(json_file)
|
||||
else:
|
||||
print('Found new shader {}. Placing generated source code in {}'.format(joined_path, reference))
|
||||
make_reference_dir(reference)
|
||||
shutil.move(json_file, reference)
|
||||
|
||||
def regression_check(shader, glsl, update, keep, opt):
|
||||
reference = reference_path(shader[0], shader[1], opt)
|
||||
joined_path = os.path.join(shader[0], shader[1])
|
||||
@ -396,7 +471,7 @@ def test_shader_msl(stats, shader, update, keep, opt):
|
||||
# executable from Xcode using args: `--msl --entry main --output msl_path spirv_path`.
|
||||
# print('SPRIV shader: ' + spirv)
|
||||
|
||||
if not force_no_external_validation:
|
||||
if not args.force_no_external_validation:
|
||||
validate_shader_msl(shader, opt)
|
||||
|
||||
remove_file(spirv)
|
||||
@ -410,26 +485,50 @@ def test_shader_hlsl(stats, shader, update, keep, opt):
|
||||
regression_check(shader, hlsl, update, keep, opt)
|
||||
remove_file(spirv)
|
||||
|
||||
def test_shaders_helper(stats, shader_dir, update, malisc, keep, opt, backend):
|
||||
for root, dirs, files in os.walk(os.path.join(shader_dir)):
|
||||
def test_shader_reflect(stats, shader, update, keep, opt):
|
||||
joined_path = os.path.join(shader[0], shader[1])
|
||||
print('Testing shader reflection:', joined_path)
|
||||
is_spirv = shader_is_spirv(shader[1])
|
||||
noopt = shader_is_noopt(shader[1])
|
||||
spirv, reflect = cross_compile_reflect(joined_path, is_spirv, opt and (not noopt))
|
||||
regression_check_reflect(shader, reflect, update, keep, opt)
|
||||
remove_file(spirv)
|
||||
|
||||
def test_shader_file(relpath, stats, shader_dir, update, keep, opt, backend):
|
||||
if backend == 'msl':
|
||||
test_shader_msl(stats, (shader_dir, relpath), update, keep, opt)
|
||||
elif backend == 'hlsl':
|
||||
test_shader_hlsl(stats, (shader_dir, relpath), update, keep, opt)
|
||||
elif backend == 'reflect':
|
||||
test_shader_reflect(stats, (shader_dir, relpath), update, keep, opt)
|
||||
else:
|
||||
test_shader(stats, (shader_dir, relpath), update, keep, opt)
|
||||
|
||||
def test_shaders_helper(stats):
|
||||
all_files = []
|
||||
for root, dirs, files in os.walk(os.path.join(args.folder)):
|
||||
files = [ f for f in files if not f.startswith(".") ] #ignore system files (esp OSX)
|
||||
for i in files:
|
||||
path = os.path.join(root, i)
|
||||
relpath = os.path.relpath(path, shader_dir)
|
||||
if backend == 'msl':
|
||||
test_shader_msl(stats, (shader_dir, relpath), update, keep, opt)
|
||||
elif backend == 'hlsl':
|
||||
test_shader_hlsl(stats, (shader_dir, relpath), update, keep, opt)
|
||||
else:
|
||||
test_shader(stats, (shader_dir, relpath), update, keep, opt)
|
||||
relpath = os.path.relpath(path, args.folder)
|
||||
all_files.append(relpath)
|
||||
|
||||
def test_shaders(shader_dir, update, malisc, keep, opt, backend):
|
||||
if malisc:
|
||||
# The child processes in parallel execution mode don't have the proper state for the global args variable, so
|
||||
# at this point we need to switch to explicit arguments
|
||||
if args.parallel:
|
||||
pool = multiprocessing.Pool(multiprocessing.cpu_count())
|
||||
pool.map(partial(test_shader_file, stats=stats, shader_dir=args.folder, update=args.update, keep=args.keep, opt=args.opt, backend=backend), all_files)
|
||||
else:
|
||||
for i in all_files:
|
||||
test_shader_file(i, stats, args.folder, args.update, args.keep, args.opt, backend)
|
||||
|
||||
def test_shaders():
|
||||
if args.malisc:
|
||||
with open('stats.csv', 'w') as stats:
|
||||
print('Shader,OrigRegs,OrigUniRegs,OrigALUShort,OrigLSShort,OrigTEXShort,OrigALULong,OrigLSLong,OrigTEXLong,CrossRegs,CrossUniRegs,CrossALUShort,CrossLSShort,CrossTEXShort,CrossALULong,CrossLSLong,CrossTEXLong', file = stats)
|
||||
test_shaders_helper(stats, shader_dir, update, malisc, keep, backend)
|
||||
test_shaders_helper(stats)
|
||||
else:
|
||||
test_shaders_helper(None, shader_dir, update, malisc, keep, opt, backend)
|
||||
test_shaders_helper(None)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description = 'Script for regression testing.')
|
||||
@ -459,19 +558,35 @@ def main():
|
||||
parser.add_argument('--opt',
|
||||
action = 'store_true',
|
||||
help = 'Run SPIRV-Tools optimization passes as well.')
|
||||
parser.add_argument('--reflect',
|
||||
action = 'store_true',
|
||||
help = 'Test reflection backend.')
|
||||
parser.add_argument('--parallel',
|
||||
action = 'store_true',
|
||||
help = 'Execute tests in parallel. Useful for doing regression quickly, but bad for debugging and stat output.')
|
||||
|
||||
global args
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.folder:
|
||||
sys.stderr.write('Need shader folder.\n')
|
||||
sys.exit(1)
|
||||
|
||||
if (args.parallel and (args.malisc or args.force_no_external_validation or args.update)):
|
||||
sys.stderr.write('Parallel execution is disabled when using the flags --update, --malisc or --force-no-external-validation\n')
|
||||
args.parallel = False
|
||||
|
||||
if args.msl:
|
||||
print_msl_compiler_version()
|
||||
|
||||
global force_no_external_validation
|
||||
force_no_external_validation = args.force_no_external_validation
|
||||
global backend
|
||||
if (args.msl or args.metal):
|
||||
backend = 'msl'
|
||||
elif args.hlsl:
|
||||
backend = 'hlsl'
|
||||
elif args.reflect:
|
||||
backend = 'reflect'
|
||||
|
||||
test_shaders(args.folder, args.update, args.malisc, args.keep, args.opt, 'msl' if (args.msl or args.metal) else ('hlsl' if args.hlsl else 'glsl'))
|
||||
test_shaders()
|
||||
if args.malisc:
|
||||
print('Stats in stats.csv!')
|
||||
print('Tests completed!')
|
||||
|
@ -16,4 +16,5 @@ echo "Using spirv-opt in: $(which spirv-opt)."
|
||||
./test_shaders.py shaders-hlsl --hlsl || exit 1
|
||||
./test_shaders.py shaders-hlsl --hlsl --opt || exit 1
|
||||
./test_shaders.py shaders-hlsl-no-opt --hlsl || exit 1
|
||||
./test_shaders.py shaders-reflection --reflect || exit 1
|
||||
|
||||
|
@ -16,5 +16,6 @@ echo "Using spirv-opt in: $(which spirv-opt)."
|
||||
./test_shaders.py shaders-hlsl --update --hlsl || exit 1
|
||||
./test_shaders.py shaders-hlsl --update --hlsl --opt || exit 1
|
||||
./test_shaders.py shaders-hlsl-no-opt --update --hlsl || exit 1
|
||||
./test_shaders.py shaders-reflection --reflect --update || exit 1
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user