From c9d94248dc73fe41c344b0a23230e597f7b94a2c Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 13 Nov 2017 14:17:09 -0800 Subject: Parameter block work (#276) * Don't auto-enable IR use for compute tests The `COMPARE_COMPUTE` and `COMPARE_RENDER_COMPUTE` test fixtures were set up to always enable the `-use-ir` flag on Slang, which precludes having any tests that confirm functionality on the old non-IR path (which is still required by our main customer). This change adds the `-xslang -use-ir` flags explicitly to any compute test cases that left them out, and makes the fixture no longer add it by default. * Continue building out parameter block support The initial front-end logic for parameter blocks was already added, but they are still missing a bunch of functionality. This change addresses some of the known issues: - Bug fix: don't try to emit HLSL `register` bindings for variables that consume whole register spaces/sets - Overhaul type layout logic so that it can make decisions based on a given code generation target (currently passed in as a `TargetRequest`), which allows us to decide whether or not a parameter block should get its own register set on a per-target basis. - Always use a register space/set for Vulkan - Never use a register space/set for HLSL SM 5.0 and lower - By default, don't use register spaces/sets for HLSL output - Add a command-line flag and some "target flags" to enable register-space usage for D3D targets - Hackily add initial support for parameter blocks in the AST-to-AST path - This just blindly lowers `ParameterBlock` to `T`, which shouldn't quite work - A more complete overhaul will probably need to wait until the AST-to-AST legalization is changed to use the `LegalType`s from the IR legalization pass. - Add a compute-based test case to actually run code using parameter blocks - This file runs test cases both with and without the IR --- source/slang/type-layout.h | 83 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 16 deletions(-) (limited to 'source/slang/type-layout.h') diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h index 257bfa310..363b01486 100644 --- a/source/slang/type-layout.h +++ b/source/slang/type-layout.h @@ -28,11 +28,13 @@ enum class LayoutRule HLSLStructuredBuffer, }; +#if 0 enum class LayoutRulesFamily { HLSL, GLSL, }; +#endif // Layout appropriate to "just memory" scenarios, // such as laying out the members of a constant buffer. @@ -559,43 +561,92 @@ struct LayoutRulesFamilyImpl virtual MatrixLayoutMode getDefaultMatrixLayoutMode() = 0; }; -LayoutRulesImpl* GetLayoutRulesImpl(LayoutRule rule); -LayoutRulesFamilyImpl* GetLayoutRulesFamilyImpl(LayoutRulesFamily rule); -LayoutRulesFamilyImpl* GetLayoutRulesFamilyImpl(CodeGenTarget target); +struct TypeLayoutContext +{ + // The layout rules to use (e.g., we compute + // layout differently in a `cbuffer` vs. the + // parameter list of a fragment shader). + LayoutRulesImpl* rules; -SimpleLayoutInfo GetLayout(Type* type, LayoutRulesImpl* rules); + // The target request that is triggering layout + TargetRequest* targetReq; -SimpleLayoutInfo GetLayout(Type* type, LayoutRule rule = LayoutRule::Std430); + // Whether to lay out matrices column-major + // or row-major. + MatrixLayoutMode matrixLayoutMode; -RefPtr CreateTypeLayout(Type* type, LayoutRulesImpl* rules); -RefPtr CreateTypeLayout(Type* type, LayoutRulesImpl* rules, SimpleLayoutInfo offset); + LayoutRulesImpl* getRules() { return rules; } + LayoutRulesFamilyImpl* getRulesFamily() { return rules->getLayoutRulesFamily(); } -// + TypeLayoutContext with(LayoutRulesImpl* inRules) const + { + TypeLayoutContext result = *this; + result.rules = inRules; + return result; + } -struct TypeLayoutContext; + TypeLayoutContext with(MatrixLayoutMode inMatrixLayoutMode) const + { + TypeLayoutContext result = *this; + result.matrixLayoutMode = inMatrixLayoutMode; + return result; + } +}; + + +// Get an appropriate set of layout rules (packaged up +// as a `TypeLayoutContext`) to perform type layout +// for the given target. +TypeLayoutContext getInitialLayoutContextForTarget( + TargetRequest* targetReq); + +// Get the "simple" layout for a type accordinging to a given set of layout +// rules. Note that a "simple" layout can only consume one `LayoutResourceKind`, +// and so this operation may not correctly capture the full resource usage +// of a type. +SimpleLayoutInfo GetLayout( + TypeLayoutContext const& context, + Type* type); + +// Create a full type-layout object for a type, +// according to the layout rules in `context`. +RefPtr CreateTypeLayout( + TypeLayoutContext const& context, + Type* type); + +// Create a full type layout for a type, while applying the given "simple" +// layout information as an offset to any `VarLayout`s created along +// the way. +RefPtr CreateTypeLayout( + TypeLayoutContext const& context, + Type* type, + SimpleLayoutInfo offset); + +// // Create a type layout for a parameter block type. RefPtr createParameterGroupTypeLayout( - TypeLayoutContext* context, + TypeLayoutContext const& context, RefPtr parameterGroupType); RefPtr createParameterGroupTypeLayout( - TypeLayoutContext* context, + TypeLayoutContext const& context, RefPtr parameterGroupType, RefPtr elementType, LayoutRulesImpl* elementTypeRules); RefPtr createParameterGroupTypeLayout( - TypeLayoutContext* context, + TypeLayoutContext const& context, RefPtr parameterGroupType, SimpleLayoutInfo parameterGroupInfo, RefPtr elementTypeLayout); RefPtr createParameterGroupTypeLayout( + TypeLayoutContext const& context, RefPtr parameterGroupType, LayoutRulesImpl* parameterGroupRules, SimpleLayoutInfo parameterGroupInfo, @@ -604,10 +655,10 @@ createParameterGroupTypeLayout( // Create a type layout for a structured buffer type. RefPtr createStructuredBufferTypeLayout( - ShaderParameterKind kind, - RefPtr structuredBufferType, - RefPtr elementType, - LayoutRulesImpl* rules); + TypeLayoutContext const& context, + ShaderParameterKind kind, + RefPtr structuredBufferType, + RefPtr elementType); // -- cgit v1.2.3