summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorArielG-NV <159081215+ArielG-NV@users.noreply.github.com>2024-06-01 02:38:46 -0400
committerGitHub <noreply@github.com>2024-05-31 23:38:46 -0700
commit5799281bda2f9a174b825de4058c5e8c9aa5b27f (patch)
treea9ecfe7e9320d0722a51ba8c5c101f8ffb9fb04b /source
parenta5cdb574b391e8adce1ce71e1e7ab3a20ce15818 (diff)
Capabilities generator inclusive join and misc (#4237)
Diffstat (limited to 'source')
-rw-r--r--source/core/core.natvis82
-rw-r--r--source/core/slang-uint-set.h80
-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
7 files changed, 237 insertions, 174 deletions
diff --git a/source/core/core.natvis b/source/core/core.natvis
index 2448e2c88..f2547b3fe 100644
--- a/source/core/core.natvis
+++ b/source/core/core.natvis
@@ -55,62 +55,44 @@
</Type>
<Type Name="Slang::Dictionary&lt;*,*&gt;">
+ <DisplayString>{{ {map.m_values} }}</DisplayString>
+ <Expand>
+ <Item Name="[items]">map.m_values</Item>
+ <Item Name="map">map</Item>
+ </Expand>
+</Type>
+
+<Type Name="Slang::HashSet&lt;*&gt;">
+ <DisplayString>{{ {dict} }}</DisplayString>
+ <Expand>
+ <Item Name="dict">dict</Item>
+ </Expand>
+</Type>
+
+<Type Name="Slang::OrderedHashSet&lt;*&gt;">
+ <DisplayString>{{ size={dict._count} }}</DisplayString>
+ <Expand>
+ <LinkedListItems>
+ <Size>m_dict._count</Size>
+ <HeadPointer>m_dict.kvPairs.head</HeadPointer>
+ <NextPointer>next</NextPointer>
+ <ValueNode>value</ValueNode>
+ </LinkedListItems>
+ </Expand>
+</Type>
+
+<Type Name="Slang::OrderedDictionary&lt;*,*&gt;">
<DisplayString>{{ size={m_count} }}</DisplayString>
<Expand>
- <Item Name="[size]">m_count</Item>
- <Item Name="[capacity]">m_bucketCountMinusOne + 1</Item>
- <CustomListItems MaxItemsPerView="5000" ExcludeView="Test">
- <Variable Name="iBucket" InitialValue="0" />
- <Variable Name="pBucket" InitialValue="m_hashMap" />
- <Variable Name="isDeleted" InitialValue="0" />
- <Variable Name="isEmpty" InitialValue="0" />
+ <LinkedListItems>
<Size>m_count</Size>
- <Exec>pBucket = m_hashMap</Exec>
- <Loop>
- <If Condition="iBucket &gt;= m_bucketCountMinusOne">
- <Break/>
- </If>
- <Exec>
- isDeleted = m_marks.m_buffer.m_count &gt; (iBucket*2+1)/32
- ? ((m_marks.m_buffer.m_buffer[(iBucket*2+1)/32]&amp;(1&lt;&lt;(iBucket*2+1)%32)) != 0)
- : 0
- </Exec>
- <Exec>
- isEmpty = m_marks.m_buffer.m_count &gt; (iBucket*2)/32
- ? ((m_marks.m_buffer.m_buffer[(iBucket*2)/32]&amp;(1&lt;&lt;(iBucket*2)%32)) == 0)
- : 1
- </Exec>
- <If Condition="isDeleted+isEmpty==0">
- <Item>*(m_hashMap + iBucket)</Item>
- </If>
- <Exec>iBucket++</Exec>
- </Loop>
- </CustomListItems>
+ <HeadPointer>m_kvPairs.head</HeadPointer>
+ <NextPointer>next</NextPointer>
+ <ValueNode>value</ValueNode>
+ </LinkedListItems>
</Expand>
</Type>
- <Type Name="Slang::OrderedHashSet&lt;*&gt;">
- <DisplayString>{{ size={dict._count} }}</DisplayString>
- <Expand>
- <LinkedListItems>
- <Size>m_dict._count</Size>
- <HeadPointer>m_dict.kvPairs.head</HeadPointer>
- <NextPointer>next</NextPointer>
- <ValueNode>value</ValueNode>
- </LinkedListItems>
- </Expand>
- </Type>
- <Type Name="Slang::OrderedDictionary&lt;*,*&gt;">
- <DisplayString>{{ size={m_count} }}</DisplayString>
- <Expand>
- <LinkedListItems>
- <Size>m_count</Size>
- <HeadPointer>m_kvPairs.head</HeadPointer>
- <NextPointer>next</NextPointer>
- <ValueNode>value</ValueNode>
- </LinkedListItems>
- </Expand>
- </Type>
<Type Name="Slang::RefPtr&lt;*&gt;">
<SmartPointer Usage="Minimal">pointer</SmartPointer>
<DisplayString Condition="pointer == 0">empty</DisplayString>
diff --git a/source/core/slang-uint-set.h b/source/core/slang-uint-set.h
index 22ca457b0..7e08500fd 100644
--- a/source/core/slang-uint-set.h
+++ b/source/core/slang-uint-set.h
@@ -14,19 +14,9 @@
namespace Slang
{
-template<typename T>
-constexpr static Index computeElementShift()
+constexpr Index intLog2(unsigned x)
{
- Index currentShift = 0;
- Index currentShiftValue = 1;
-
- while (currentShiftValue != sizeof(T) * 8)
- {
- currentShift++;
- currentShiftValue *= 2;
- }
-
- return currentShift;
+ return x == 1 ? 0 : 1 + intLog2(x >> 1);
}
static inline Index bitscanForward(uint64_t in)
@@ -65,13 +55,12 @@ public:
constexpr static Index kElementSize = sizeof(Element) * 8; ///< The number of bits in an element. This also determines how many values a element can hold.
constexpr static Index kElementMask = kElementSize - 1; ///< Mask to get shift from an index
- constexpr static Index kElementShift = computeElementShift<Element>(); ///< How many bits to shift to get Element index from an index. 5 for 2^5=32 elements in a uint32_t. 6 for 2^6=64 in a uint64_t.
+ constexpr static Index kElementShift = intLog2(sizeof(Element)*8); ///< How many bits to shift to get Element index from an index. 5 for 2^5=32 elements in a uint32_t. 6 for 2^6=64 in a uint64_t.
UIntSet() {}
UIntSet(const UIntSet& other) { m_buffer = other.m_buffer; }
UIntSet(UIntSet && other) { *this = (_Move(other)); }
UIntSet(UInt maxVal) { resizeAndClear(maxVal); }
- UIntSet(List<UIntSet::Element> buffer) { m_buffer = buffer; }
UIntSet& operator=(UIntSet&& other);
UIntSet& operator=(const UIntSet& other);
@@ -81,7 +70,7 @@ public:
/// Return the count of all bits directly represented
Int getCount() const { return Int(m_buffer.getCount()) * kElementSize; }
- List<Element>& getBuffer() { return m_buffer; }
+ const List<Element>& getBuffer() const { return m_buffer; }
/// Resize such that val can be stored and clear contents
void resizeAndClear(UInt val);
@@ -101,6 +90,9 @@ public:
/// Add a value
inline void add(UInt val);
inline void add(const UIntSet& val);
+ inline void addRange(const List<UInt>& other);
+
+ inline void addRawElement(Element val, Index bitOffset);
/// Remove a value
inline void remove(UInt val);
@@ -145,37 +137,38 @@ public:
{
friend class UIntSet;
private:
- const List<Element>* context;
- Index block = 0;
- Element processedElement = 0;
- uint64_t LSB = 0;
+ const List<Element>* m_context;
+ Index m_block = 0;
+ Element m_processedElement = 0;
+ uint64_t m_LSB = 0;
void clearLSB()
{
- LSB = bitscanForward(processedElement);
- processedElement &= processedElement - 1;
+ m_LSB = bitscanForward(m_processedElement);
+ m_processedElement &= m_processedElement - 1;
}
- public:
- Iterator(const List<Element>* inContext)
+
+ Iterator(const List<Element>* context)
{
- context = inContext;
+ m_context = context;
}
+ public:
Element operator*()
{
- return Element(LSB + (kElementSize * block));
+ return Element(m_LSB + (kElementSize * m_block));
}
Iterator& operator++()
{
- while (processedElement == 0)
+ while (m_processedElement == 0)
{
- block++;
- if (block >= context->getCount())
+ m_block++;
+ if (m_block >= m_context->getCount())
{
return *this;
}
- processedElement = (*context)[block];
+ m_processedElement = (*m_context)[m_block];
}
clearLSB();
return *this;
@@ -186,8 +179,8 @@ public:
}
bool operator==(const Iterator& other) const
{
- return other.block == this->block
- && other.processedElement == this->processedElement;
+ return other.m_block == this->m_block
+ && other.m_processedElement == this->m_processedElement;
}
bool operator!=(const Iterator& other) const
{
@@ -200,19 +193,21 @@ public:
if (m_buffer.getCount() == 0)
return tmp;
- tmp.processedElement = m_buffer[0];
- if (tmp.processedElement == 0)
+ tmp.m_processedElement = m_buffer[0];
+ if (tmp.m_processedElement == 0)
+ {
tmp++;
+ return tmp;
+ }
tmp.clearLSB();
-
return tmp;
}
Iterator end() const
{
Iterator tmp(&m_buffer);
- tmp.block = m_buffer.getCount();
- tmp.processedElement = 0;
+ tmp.m_block = m_buffer.getCount();
+ tmp.m_processedElement = 0;
return tmp;
}
@@ -307,6 +302,19 @@ inline void UIntSet::add(const UIntSet& other)
m_buffer[i] |= other.m_buffer[i];
}
+inline void UIntSet::addRange(const List<UInt>& other)
+{
+ for (auto i : other)
+ add(i);
+}
+
+inline void UIntSet::addRawElement(Element other, Index elementIndex)
+{
+ if(this->m_buffer.getCount() <= elementIndex)
+ resizeBackingBufferDirectly(elementIndex+1);
+ m_buffer[elementIndex] |= other;
+}
+
template<typename T>
List<T> UIntSet::getElements() const
{
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++;
}
}
};