summaryrefslogtreecommitdiff
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/hlsl.meta.slang2
-rw-r--r--source/slang/slang-capabilities.capdef125
-rw-r--r--source/slang/slang-capability.cpp105
-rw-r--r--source/slang/slang-capability.h11
-rw-r--r--source/slang/slang-serialize-ast-type-info.h6
5 files changed, 161 insertions, 88 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 1458467b9..13b1f0131 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -3665,7 +3665,7 @@ struct InputPatch
};
__generic<T, let N : int>
-[require(glsl_hlsl_spirv, shader_stages_domain_hull)]
+[require(glsl_hlsl_spirv, domain_hull)]
__magic_type(HLSLOutputPatchType)
__intrinsic_type($(kIROp_HLSLOutputPatchType))
struct OutputPatch
diff --git a/source/slang/slang-capabilities.capdef b/source/slang/slang-capabilities.capdef
index 5a0df9f9b..7567dd617 100644
--- a/source/slang/slang-capabilities.capdef
+++ b/source/slang/slang-capabilities.capdef
@@ -20,10 +20,22 @@
// There are three types of capability definitions:
// - `def`: this will introduce an new capability atom. If there is an inheritance clause,
// the capability name will expand to all inherited atoms plus the newly introduced atom.
-// - `abstract`: an abstract capability does not introduce an actual atom, but it defines
-// an implicit conflict group such that two capabilities inheriting the same abstract
-// capability cannot be satisfied simultaneously. When used in an expression, `abstract`
-// capability also expands into a disjunction (or) of all inherited capabilities.
+// - `abstract`: an abstract capability does not introduce an actual atom. Primarily used to
+// make disjunctions using the following rules:
+// 1. Each type of abstract atom defines a "keyhole". `target` and `stage` are distinct "keyholes".
+// 2. Any atom immediately derived off of an abstract atom is a "key atom".
+// 3. Every conjunction may only populate each "keyhole" once, else the set is incompatible.
+// * If joining ('+') incompatible sets, an invalid capability is made.
+// * If Inclusive joining ('|') incompatible sets, a disjunction is made.
+// 4. ex: `hlsl + glsl` both populate the same "keyhole" of `target`, this is incompatible.
+// 5. ex: `hlsl + _sm_6_0` both populate same keyholes of `hlsl` and `hlsl`, this is compatible.
+// 6. ex: `hlsl | glsl` creates a disjunction of 2 sets: `hlsl` and `glsl`. This is due to the
+// 2 sets being incompatible.
+// 7. Having a not populated "keyhole" means your set is compatible with any "key atom" of
+// distinct "keyhole".
+// 8. ex: `vertex + glsl` works because 'vertex' has a unpopulated `target` "keyhole", and
+// therefore is compatible with all `target` "key atoms"
+
// - `alias`: this defines an alias and does not introduce actual atoms.
// Several capabilities represent the target formats in which we generate code.
@@ -173,27 +185,23 @@ alias tesscontrol = hull;
alias tesseval = domain;
alias amplification_mesh = amplification | mesh;
alias raytracing_stages = raygen | intersection | anyhit | closesthit | miss | callable;
-alias raytracing_stages_intersection = intersection;
-alias raytracing_stages_raygen = raygen;
-alias raytracing_stages_anyhit_closesthit = anyhit | closesthit;
-alias raytracing_stages_raygen_closesthit_miss = raygen | closesthit | miss;
-alias raytracing_stages_anyhit_closesthit_intersection = anyhit | closesthit | intersection;
-alias raytracing_stages_anyhit_closesthit_intersection_miss = anyhit | closesthit | intersection | miss;
-alias raytracing_stages_raygen_closesthit_miss_callable = raygen | closesthit | miss | callable;
-alias shader_stages_compute_tesscontrol_tesseval = compute | tesscontrol | tesseval;
-alias shader_stages_compute_fragment = compute | fragment;
-alias shader_stages_compute_fragment_geometry_vertex = compute | fragment | geometry | vertex;
-alias shader_stages_domain_hull = domain | hull;
-alias raytracing_stages_fragment = raytracing_stages | fragment;
-alias raytracing_stages_compute = raytracing_stages | compute;
-alias raytracing_stages_compute_amplification_mesh = raytracing_stages_compute | amplification_mesh;
-alias raytracing_stages_compute_fragment = raytracing_stages | shader_stages_compute_fragment;
-alias raytracing_stages_compute_fragment_geometry_vertex = raytracing_stages | shader_stages_compute_fragment_geometry_vertex;
+alias anyhit_closesthit = anyhit | closesthit;
+alias raygen_closesthit_miss = raygen | closesthit | miss;
+alias anyhit_closesthit_intersection = anyhit | closesthit | intersection;
+alias anyhit_closesthit_intersection_miss = anyhit | closesthit | intersection | miss;
+alias raygen_closesthit_miss_callable = raygen | closesthit | miss | callable;
+alias compute_tesscontrol_tesseval = compute | tesscontrol | tesseval;
+alias compute_fragment = compute | fragment;
+alias compute_fragment_geometry_vertex = compute | fragment | geometry | vertex;
+alias domain_hull = domain | hull;
+alias raytracingstages_fragment = raytracing_stages | fragment;
+alias raytracingstages_compute = raytracing_stages | compute;
+alias raytracingstages_compute_amplification_mesh = raytracingstages_compute | amplification_mesh;
+alias raytracingstages_compute_fragment = raytracing_stages | compute_fragment;
+alias raytracingstages_compute_fragment_geometry_vertex = raytracing_stages | compute_fragment_geometry_vertex;
// SPIRV extensions.
-def SOURCE_EXT_GL_NV_compute_shader_derivatives : spirv_1_0;
-
def SPV_EXT_fragment_shader_interlock : spirv_1_0;
def SPV_KHR_fragment_shader_barycentric : spirv_1_0;
def SPV_EXT_fragment_fully_covered : spirv_1_0;
@@ -342,7 +350,7 @@ alias GL_KHR_shader_subgroup_shuffle = _GL_KHR_shader_subgroup_shuffle | spvGrou
alias GL_KHR_shader_subgroup_shuffle_relative = _GL_KHR_shader_subgroup_shuffle_relative | spvGroupNonUniformShuffle;
alias GL_KHR_shader_subgroup_vote = _GL_KHR_shader_subgroup_vote | spvGroupNonUniformVote;
alias GL_KHR_shader_subgroup_quad = _GL_KHR_shader_subgroup_quad | spvGroupNonUniformQuad;
-alias GL_NV_compute_shader_derivatives = _GL_NV_compute_shader_derivatives | SOURCE_EXT_GL_NV_compute_shader_derivatives | SPV_NV_compute_shader_derivatives | _sm_6_6;
+alias GL_NV_compute_shader_derivatives = _GL_NV_compute_shader_derivatives | SPV_NV_compute_shader_derivatives | _sm_6_6;
alias GL_ARB_shader_image_size = _GL_ARB_shader_image_size | spvImageQuery | metal;
alias GL_ARB_shader_texture_image_samples = _GL_ARB_shader_texture_image_samples | spvImageQuery | metal;
alias GL_NV_shader_atomic_fp16_vector = _GL_NV_shader_atomic_fp16_vector + _GL_NV_gpu_shader5 | spirv_1_0;
@@ -364,8 +372,8 @@ alias rayquery = GL_EXT_ray_query | _sm_6_5;
alias raytracing_motionblur = raytracing + motionblur | cuda;
alias ser_motion = ser + motionblur;
alias shaderclock = GL_EXT_shader_realtime_clock | hlsl_nvapi | cpp | cuda;
-alias meshshading_internal = spvMeshShadingEXT + _sm_6_5 + _GL_EXT_mesh_shader;
-alias meshshading = amplification + meshshading_internal | mesh + meshshading_internal;
+alias meshshading_internal = GL_EXT_mesh_shader | _sm_6_5;
+alias meshshading = amplification_mesh + meshshading_internal;
alias fragmentshaderinterlock = _GL_ARB_fragment_shader_interlock | hlsl_nvapi | spvFragmentShaderPixelInterlockEXT;
alias atomic64 = GL_EXT_shader_atomic_int64 | _sm_6_6 | cpp | cuda;
alias atomicfloat = GL_EXT_shader_atomic_float | _sm_6_0 + hlsl_nvapi | cpp | cuda;
@@ -375,7 +383,7 @@ alias groupnonuniform = GL_KHR_shader_subgroup_ballot + GL_KHR_shader_subgroup_s
| _sm_6_0 | cuda;
alias fragmentshaderbarycentric = GL_EXT_fragment_shader_barycentric | _sm_6_1;
alias shadermemorycontrol = glsl | spirv_1_0 | _sm_5_0;
-alias shadermemorycontrol_compute = raytracing_stages_compute + shadermemorycontrol;
+alias shadermemorycontrol_compute = raytracingstages_compute + shadermemorycontrol;
alias subpass = fragment + any_gfx_target;
alias waveprefix = _sm_6_5 | _cuda_sm_7_0 | GL_KHR_shader_subgroup_arithmetic;
alias bufferreference = GL_EXT_buffer_reference;
@@ -564,7 +572,7 @@ alias GLSL_460 = _GLSL_460
| cpp
;
-alias GLSL_410_SPIRV_1_0 = _GLSL_410 + GLSL_400 | GLSL_400;
+alias GLSL_410_SPIRV_1_0 = _GLSL_410 | spirv_1_0;
alias GLSL_420_SPIRV_1_0 = _GLSL_420 + GLSL_410_SPIRV_1_0 | GLSL_410_SPIRV_1_0;
alias GLSL_430_SPIRV_1_0 = _GLSL_430 + GLSL_420_SPIRV_1_0 | GLSL_420_SPIRV_1_0;
@@ -587,41 +595,41 @@ alias METAL_2_4 = metallib_2_4;
alias sm_2_0_GLSL_140 = _GLSL_140 + sm_4_0 | sm_4_0;
alias sm_2_0_GLSL_400 = _GLSL_400 + sm_4_0 | sm_4_0;
-alias appendstructuredbuffer = sm_5_0 + raytracing_stages_compute_fragment;
+alias appendstructuredbuffer = sm_5_0 + raytracingstages_compute_fragment;
alias atomic_hlsl = _sm_4_0;
alias atomic_hlsl_nvapi = _sm_4_0 + hlsl_nvapi;
alias atomic_hlsl_sm_6_6 = _sm_6_6;
alias byteaddressbuffer = sm_4_0;
-alias byteaddressbuffer_rw = sm_4_0 + raytracing_stages_compute_fragment;
-alias consumestructuredbuffer = sm_5_0 + raytracing_stages_compute_fragment;
+alias byteaddressbuffer_rw = sm_4_0 + raytracingstages_compute_fragment;
+alias consumestructuredbuffer = sm_5_0 + raytracingstages_compute_fragment;
alias fragmentprocessing = fragment + _sm_5_0
| fragment + glsl_spirv
- | raytracing_stages_compute_amplification_mesh + GL_NV_compute_shader_derivatives
+ | raytracingstages_compute_amplification_mesh + GL_NV_compute_shader_derivatives
;
alias fragmentprocessing_derivativecontrol = fragment + _sm_5_0
| fragment + GL_ARB_derivative_control
- | raytracing_stages_compute_amplification_mesh + GL_NV_compute_shader_derivatives
+ | raytracingstages_compute_amplification_mesh + GL_NV_compute_shader_derivatives
;
alias getattributeatvertex = fragment + _sm_6_1 | fragment + GL_EXT_fragment_shader_barycentric;
-alias memorybarrier_compute = raytracing_stages_compute + sm_5_0;
+alias memorybarrier_compute = raytracingstages_compute + sm_5_0;
alias glsl_barrier = hlsl + memorybarrier_compute
- | glsl_spirv + shader_stages_compute_tesscontrol_tesseval
+ | glsl_spirv + compute_tesscontrol_tesseval
;
alias structuredbuffer = sm_4_0;
-alias structuredbuffer_rw = sm_4_0 + raytracing_stages_compute_fragment;
+alias structuredbuffer_rw = sm_4_0 + raytracingstages_compute_fragment;
alias texture_sm_4_1 = sm_4_1
;
alias texture_sm_4_1_samplerless = cpp + texture_sm_4_1
| cuda + texture_sm_4_1
| glsl + texture_sm_4_1 + GL_EXT_samplerless_texture_functions
- | hlsl + texture_sm_4_1 + raytracing_stages_compute_fragment
+ | hlsl + texture_sm_4_1 + raytracingstages_compute_fragment
| spirv_1_0 + texture_sm_4_1 + GL_EXT_samplerless_texture_functions
| metal + texture_sm_4_1
;
alias texture_sm_4_1_compute_fragment = cpp + texture_sm_4_1
| cuda + texture_sm_4_1
| glsl + texture_sm_4_1
- | hlsl + texture_sm_4_1 + raytracing_stages_compute_fragment
+ | hlsl + texture_sm_4_1 + raytracingstages_compute_fragment
| spirv_1_0 + texture_sm_4_1
| metal + texture_sm_4_1
;
@@ -629,7 +637,7 @@ alias texture_sm_4_1_compute_fragment = cpp + texture_sm_4_1
alias texture_sm_4_1_fragment = cpp + texture_sm_4_1
| cuda + texture_sm_4_1
| glsl + texture_sm_4_1
- | hlsl + texture_sm_4_1 + raytracing_stages_compute_fragment
+ | hlsl + texture_sm_4_1 + raytracingstages_compute_fragment
| spirv_1_0 + texture_sm_4_1
| metal + texture_sm_4_1
;
@@ -637,7 +645,7 @@ alias texture_sm_4_1_clamp_fragment = texture_sm_4_1_fragment + GL_ARB_sparse_te
alias texture_sm_4_1_vertex_fragment_geometry = cpp + texture_sm_4_1
| cuda + texture_sm_4_1
| glsl + texture_sm_4_1
- | hlsl + texture_sm_4_1 + raytracing_stages_compute_fragment_geometry_vertex
+ | hlsl + texture_sm_4_1 + raytracingstages_compute_fragment_geometry_vertex
| spirv_1_0 + texture_sm_4_1
| metal + texture_sm_4_1
;
@@ -665,8 +673,8 @@ alias printf = GL_EXT_debug_printf | _sm_4_0 | _cuda_sm_2_0 | cpp;
alias texturefootprint = GL_NV_shader_texture_footprint + GLSL_450 | hlsl_nvapi + _sm_4_0;
alias texturefootprintclamp = texturefootprint + GL_ARB_sparse_texture_clamp;
-alias shader5_sm_4_0 = GL_ARB_gpu_shader5 + sm_4_0 | sm_4_0;
-alias shader5_sm_5_0 = GL_ARB_gpu_shader5 + sm_4_0 | sm_5_0;
+alias shader5_sm_4_0 = GL_ARB_gpu_shader5 + _GLSL_140 + sm_4_0 | sm_4_0;
+alias shader5_sm_5_0 = GL_ARB_gpu_shader5 + _GLSL_140 + sm_4_0 | sm_5_0;
alias subgroup_basic = GL_KHR_shader_subgroup_basic | _sm_6_0 | _cuda_sm_7_0;
alias subgroup_ballot = spirv_1_0 + GL_KHR_shader_subgroup_ballot
@@ -681,7 +689,8 @@ alias subgroup_ballot_activemask = spirv_1_0 + GL_KHR_shader_subgroup_ballot
;
alias subgroup_basic_ballot = glsl + GL_KHR_shader_subgroup_basic + subgroup_ballot
| spirv + GL_KHR_shader_subgroup_basic + subgroup_ballot
- | hlsl + subgroup_ballot | cuda + subgroup_ballot
+ | hlsl + subgroup_ballot
+ | cuda + subgroup_ballot
;
alias subgroup_vote = GL_KHR_shader_subgroup_vote | _sm_6_0 | _cuda_sm_7_0;
alias shaderinvocationgroup = subgroup_vote;
@@ -705,23 +714,23 @@ alias breakpoint = GL_EXT_debug_printf | hlsl | _cuda_sm_8_0 | cpp;
alias rayobject = raytracing | rayquery;
alias raytracing_allstages = raytracing_stages + raytracing;
alias raytracing_anyhit = anyhit + raytracing;
-alias raytracing_intersection = raytracing_stages_intersection + raytracing;
-alias raytracing_anyhit_closesthit = raytracing_stages_anyhit_closesthit + raytracing;
-alias raytracing_anyhit_closesthit_intersection = raytracing_stages_anyhit_closesthit_intersection + raytracing;
-alias raytracing_raygen_closesthit_miss = raytracing_stages_raygen_closesthit_miss + raytracing;
-alias raytracing_anyhit_closesthit_intersection_miss = raytracing_stages_anyhit_closesthit_intersection_miss + raytracing;
-alias raytracing_raygen_closesthit_miss_callable = raytracing_stages_raygen_closesthit_miss_callable + raytracing;
-alias raytracing_position = raytracing + GL_EXT_ray_tracing_position_fetch + anyhit + closesthit;
-alias raytracing_motionblur_anyhit_closesthit_intersection_miss = raytracing_stages_anyhit_closesthit_intersection_miss + raytracing_motionblur;
-alias raytracing_motionblur_raygen_closesthit_miss = raytracing_stages_raygen_closesthit_miss + raytracing_motionblur;
+alias raytracing_intersection = intersection + raytracing;
+alias raytracing_anyhit_closesthit = anyhit_closesthit + raytracing;
+alias raytracing_anyhit_closesthit_intersection = anyhit_closesthit_intersection + raytracing;
+alias raytracing_raygen_closesthit_miss = raygen_closesthit_miss + raytracing;
+alias raytracing_anyhit_closesthit_intersection_miss = anyhit_closesthit_intersection_miss + raytracing;
+alias raytracing_raygen_closesthit_miss_callable = raygen_closesthit_miss_callable + raytracing;
+alias raytracing_position = raytracing + GL_EXT_ray_tracing_position_fetch + anyhit_closesthit;
+alias raytracing_motionblur_anyhit_closesthit_intersection_miss = anyhit_closesthit_intersection_miss + raytracing_motionblur;
+alias raytracing_motionblur_raygen_closesthit_miss = raygen_closesthit_miss + raytracing_motionblur;
alias rayquery_position = rayquery + GL_EXT_ray_tracing_position_fetch;
-alias ser_raygen = raytracing_stages_raygen + ser;
-alias ser_raygen_closesthit_miss = raytracing_stages_raygen_closesthit_miss + ser;
-alias ser_any_closesthit_intersection_miss = raytracing_stages_anyhit_closesthit_intersection_miss + ser;
-alias ser_anyhit_closesthit_intersection = raytracing_stages_anyhit_closesthit_intersection + ser;
-alias ser_anyhit_closesthit = raytracing_stages_anyhit_closesthit + ser;
-alias ser_motion_raygen_closesthit_miss = raytracing_stages_raygen_closesthit_miss + ser_motion;
-alias ser_motion_raygen = raytracing_stages_raygen + ser_motion;
+alias ser_raygen = raygen + ser;
+alias ser_raygen_closesthit_miss = raygen_closesthit_miss + ser;
+alias ser_any_closesthit_intersection_miss = anyhit_closesthit_intersection_miss + ser;
+alias ser_anyhit_closesthit_intersection = anyhit_closesthit_intersection + ser;
+alias ser_anyhit_closesthit = anyhit_closesthit + ser;
+alias ser_motion_raygen_closesthit_miss = raygen_closesthit_miss + ser_motion;
+alias ser_motion_raygen = raygen + ser_motion;
alias all = _sm_6_7 + hlsl_nvapi
| glsl_spirv_1_5 + sm_6_7
diff --git a/source/slang/slang-capability.cpp b/source/slang/slang-capability.cpp
index eae04f277..e77901b5b 100644
--- a/source/slang/slang-capability.cpp
+++ b/source/slang/slang-capability.cpp
@@ -25,11 +25,11 @@ enum class CapabilityNameFlavor : int32_t
Concrete,
// An abstract capability represents a class of feature
- // where multiple different implementations might be possible.
- // For example, "ray tracing" might be an abstract feature
- // that a function can require, but a specific target will
- // only be able to provide that abstract feature via some
- // specific concrete feature (e.g., `GL_EXT_ray_tracing`).
+ // where multiple distinct implementations might be possible.
+ // 'raytracing' may be allowed with a 'raygen' "stage", but
+ // not a 'vertex' "stage"
+ // For more information (and a clearer description of the rules),
+ // read `slang-capabilities.capdef`
Abstract,
// An alias capability atom is one that is exactly equivalent
@@ -490,9 +490,6 @@ CapabilitySet CapabilitySet::getTargetsThisHasButOtherDoesNot(const CapabilitySe
return newSet;
}
-/// Join `this` with a compatble stage set of `CapabilityTargetSet other`.
-/// Return false when `other` is fully incompatible.
-/// incompatability is when `this->stage` is not a supported stage by `other.shaderStageSets`.
bool CapabilityStageSet::tryJoin(const CapabilityTargetSet& other)
{
const CapabilityStageSet* otherStageSet = other.shaderStageSets.tryGetValue(this->stage);
@@ -506,11 +503,6 @@ bool CapabilityStageSet::tryJoin(const CapabilityTargetSet& other)
return true;
}
-/// Join a compatable target set from `this` with `CapabilityTargetSet other`.
-/// Return false when `other` is fully incompatible.
-/// incompatability is when one of 2 senarios are true:
-/// 1. `this->target` is not a supported target by `other.shaderStageSets`
-/// 2. `this` has completly disjoint shader stages from other.
bool CapabilityTargetSet::tryJoin(const CapabilityTargetSets& other)
{
const CapabilityTargetSet* otherTargetSet = other.tryGetValue(this->target);
@@ -631,9 +623,6 @@ bool CapabilitySet::hasSameTargets(const CapabilitySet& other) const
#pragma warning(push)
#pragma warning(disable:4702)
#endif
-/// returns true if 'this' is a better target for 'targetCaps' than 'that'
-/// isEqual: is `this` and `that` equal
-/// isIncompatible: is `this` and `that` incompatible
bool CapabilitySet::isBetterForTarget(CapabilitySet const& that, CapabilitySet const& targetCaps, bool& isEqual) const
{
if (this->isEmpty() && (that.isEmpty() || that.isInvalid()))
@@ -882,6 +871,16 @@ int TEST_findTargetStage(
return capSet.getCapabilityTargetSets()[target].shaderStageSets.containsKey(stage);
}
+
+int TEST_targetCapSetWithSpecificAtomInStage(
+ CapabilitySet& capSet,
+ CapabilityAtom target,
+ CapabilityAtom stage,
+ CapabilityAtom atom)
+{
+ return capSet.getCapabilityTargetSets()[target].shaderStageSets[stage].atomSet->contains((UInt)atom);
+}
+
int TEST_targetCapSetWithSpecificSetInStage(
CapabilitySet& capSet,
CapabilityAtom target,
@@ -943,8 +942,8 @@ void TEST_CapabilitySet_addAtom()
testCapSet = CapabilitySet(CapabilityName::TEST_ADD_2);
CHECK_CAPS(TEST_findTargetCapSet(testCapSet, CapabilityAtom::hlsl));
- CHECK_CAPS(TEST_targetCapSetWithSpecificSetInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::vertex,
- { CapabilityAtom::textualTarget, CapabilityAtom::hlsl, CapabilityAtom::vertex,
+ CHECK_CAPS(TEST_targetCapSetWithSpecificSetInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::compute,
+ { CapabilityAtom::textualTarget, CapabilityAtom::hlsl, CapabilityAtom::compute,
CapabilityAtom::_sm_4_0, CapabilityAtom::_sm_4_1 }));
CHECK_CAPS(TEST_targetCapSetWithSpecificSetInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment,
{ CapabilityAtom::textualTarget, CapabilityAtom::hlsl, CapabilityAtom::fragment,
@@ -959,7 +958,54 @@ void TEST_CapabilitySet_addAtom()
CHECK_CAPS(TEST_targetCapSetWithSpecificSetInStage(testCapSet, CapabilityAtom::glsl, CapabilityAtom::fragment,
{ CapabilityAtom::textualTarget, CapabilityAtom::glsl, CapabilityAtom::fragment,
CapabilityAtom::_GLSL_130 }));
+
+ // ------------------------------------------------------------
+
+ testCapSet = CapabilitySet(CapabilityName::TEST_GEN_1);
+
+ CHECK_CAPS(TEST_findTargetCapSet(testCapSet, CapabilityAtom::hlsl));
+ CHECK_CAPS((int)!TEST_findTargetCapSet(testCapSet, CapabilityAtom::glsl));
+ CHECK_CAPS(TEST_findTargetStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::vertex));
+ CHECK_CAPS(TEST_findTargetStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment, CapabilityAtom::_sm_6_0));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment, CapabilityAtom::_sm_5_0));
+
+ // ------------------------------------------------------------
+
+ testCapSet = CapabilitySet(CapabilityName::TEST_GEN_2);
+
+ CHECK_CAPS(TEST_findTargetCapSet(testCapSet, CapabilityAtom::hlsl));
+ CHECK_CAPS((int)!TEST_findTargetCapSet(testCapSet, CapabilityAtom::glsl));
+ CHECK_CAPS(TEST_findTargetStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment, CapabilityAtom::_sm_6_5));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment, CapabilityAtom::_sm_5_0));
+
// ------------------------------------------------------------
+
+ testCapSet = CapabilitySet(CapabilityName::TEST_GEN_3);
+
+ CHECK_CAPS(TEST_findTargetCapSet(testCapSet, CapabilityAtom::glsl));
+ CHECK_CAPS(TEST_findTargetStage(testCapSet, CapabilityAtom::glsl, CapabilityAtom::fragment));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::glsl, CapabilityAtom::fragment, CapabilityAtom::_GL_NV_shader_texture_footprint));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::glsl, CapabilityAtom::fragment, CapabilityAtom::_GL_NV_compute_shader_derivatives));
+
+ // ------------------------------------------------------------
+
+ testCapSet = CapabilitySet(CapabilityName::TEST_GEN_4);
+
+ CHECK_CAPS(TEST_findTargetCapSet(testCapSet, CapabilityAtom::glsl));
+ CHECK_CAPS(TEST_findTargetStage(testCapSet, CapabilityAtom::glsl, CapabilityAtom::fragment));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::glsl, CapabilityAtom::fragment, CapabilityAtom::_GL_NV_shader_texture_footprint));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::glsl, CapabilityAtom::fragment, CapabilityAtom::_GL_ARB_shader_image_size));
+
+ // ------------------------------------------------------------
+
+ testCapSet = CapabilitySet(CapabilityName::TEST_GEN_5);
+
+ CHECK_CAPS(TEST_findTargetCapSet(testCapSet, CapabilityAtom::hlsl));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment, CapabilityAtom::_sm_6_5));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment, CapabilityAtom::_sm_6_4));
+ CHECK_CAPS(TEST_targetCapSetWithSpecificAtomInStage(testCapSet, CapabilityAtom::hlsl, CapabilityAtom::fragment, CapabilityAtom::_sm_6_0));
}
void TEST_CapabilitySet_join()
@@ -1034,15 +1080,15 @@ void TEST_CapabilitySet()
/*
/// Test Capabilities
-alias TEST_ADD_1 = _sm_4_1 | _GLSL_130 | spirv_1_1 | metal
- ;
-
-alias TEST_ADD_2 = _sm_4_1 | _sm_4_0 + shader_stages_compute_fragment
- ;
-
-alias TEST_ADD_3 = _GLSL_130 + shader_stages_compute_fragment_geometry_vertex;
+alias TEST_ADD_1 = _sm_4_1 | _GLSL_130 | spirv_1_1 | metal;
+alias TEST_ADD_2 = _sm_4_1 |& _sm_4_0 + compute_fragment;
+alias TEST_ADD_3 = _GLSL_130 + compute_fragment_geometry_vertex;
-//
+alias TEST_GEN_1 = _sm_6_5 + fragment | _sm_6_0 + vertex;
+alias TEST_GEN_2 = _sm_6_5 + fragment;
+alias TEST_GEN_3 = GL_NV_shader_texture_footprint + GL_NV_compute_shader_derivatives + fragment | _GL_NV_shader_texture_footprint + fragment;
+alias TEST_GEN_4 = GL_ARB_shader_image_size |& GL_NV_shader_texture_footprint + fragment;
+alias TEST_GEN_5 = sm_6_0 + compute_fragment| sm_6_5;
alias TEST_JOIN_1A = hlsl;
alias TEST_JOIN_1B = glsl;
@@ -1065,6 +1111,13 @@ alias TEST_JOIN_3B = _sm_4_1 + fragment
alias TEST_JOIN_4A = _GLSL_140 + _GL_EXT_texture_query_lod;
alias TEST_JOIN_4B = _GLSL_150 + _GL_EXT_texture_shadow_lod;
+
+// Will cause capability generator failiure
+alias TEST_ERROR_GEN_1 = GL_NV_shader_texture_footprint + GL_NV_compute_shader_derivatives + fragment | _GL_NV_shader_texture_footprint + _GL_NV_shader_atomic_fp16_vector + fragment;
+alias TEST_ERROR_GEN_2 = GL_NV_shader_texture_footprint | GL_NV_ray_tracing_motion_blur;
+alias TEST_ERROR_GEN_3 = GL_ARB_shader_image_size | GL_NV_shader_texture_footprint + fragment;
+alias TEST_ERROR_GEN_4 = _sm_6_5 + fragment + vertex + cpp;
+
///
*/
#undef CHECK_CAPS
diff --git a/source/slang/slang-capability.h b/source/slang/slang-capability.h
index 9e4bdb3a8..8bd03147e 100644
--- a/source/slang/slang-capability.h
+++ b/source/slang/slang-capability.h
@@ -73,6 +73,10 @@ struct CapabilityStageSet
else
atomSet->add(setToAdd);
}
+
+ /// Join `this` with a compatble stage set of `CapabilityTargetSet other`.
+ /// Return false when `other` is fully incompatible.
+ /// incompatability is when `this->stage` is not a supported stage by `other.shaderStageSets`.
bool tryJoin(const CapabilityTargetSet& other);
};
@@ -85,6 +89,11 @@ struct CapabilityTargetSet
CapabilityStageSets shaderStageSets{};
+ /// Join a compatable target set from `this` with `CapabilityTargetSet other`.
+ /// Return false when `other` is fully incompatible.
+ /// incompatability is when one of 2 senarios are true:
+ /// 1. `this->target` is not a supported target by `other.shaderStageSets`
+ /// 2. `this` has completly disjoint shader stages from other.
bool tryJoin(const CapabilityTargetSets& other);
void unionWith(const CapabilityTargetSet& other);
};
@@ -157,6 +166,8 @@ public:
void addCapability(List<List<CapabilityAtom>>& atomLists);
/// Calculate a list of "compacted" atoms, which excludes any atoms from the expanded list that are implies by another item in the list.
+ /// returns true if 'this' is a better target for 'targetCaps' than 'that'
+ /// isEqual: is `this` and `that` equal
bool isBetterForTarget(CapabilitySet const& that, CapabilitySet const& targetCaps, bool& isEqual) const;
/// Find any capability sets which are in 'available' but not in 'required'. Return false if this situation occurs.
diff --git a/source/slang/slang-serialize-ast-type-info.h b/source/slang/slang-serialize-ast-type-info.h
index 1d7628cd4..a8f459247 100644
--- a/source/slang/slang-serialize-ast-type-info.h
+++ b/source/slang/slang-serialize-ast-type-info.h
@@ -101,7 +101,9 @@ struct SerialTypeInfo<CapabilityAtomSet>
List<CapabilityAtomSet::Element> UIntSetBuffer;
reader->getArray(src, UIntSetBuffer);
- dst = CapabilityAtomSet(UIntSetBuffer);
+ dst = CapabilityAtomSet();
+ for(Index i = 0; i < UIntSetBuffer.getCount(); i++)
+ dst.addRawElement(UIntSetBuffer[i], i);
}
};
@@ -244,11 +246,9 @@ struct SerialTypeInfo<CapabilitySet>
auto& targetSets = dst.getCapabilityTargetSets();
targetSets.clear();
targetSets.reserve(items.getCount());
- Index iter = 0;
for (auto& i : items)
{
targetSets[i.target] = i;
- iter++;
}
}
};