diff options
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 2 | ||||
| -rw-r--r-- | source/slang/slang-capabilities.capdef | 125 | ||||
| -rw-r--r-- | source/slang/slang-capability.cpp | 105 | ||||
| -rw-r--r-- | source/slang/slang-capability.h | 11 | ||||
| -rw-r--r-- | source/slang/slang-serialize-ast-type-info.h | 6 |
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++; } } }; |
