diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-11-13 14:17:09 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-13 14:17:09 -0800 |
| commit | c9d94248dc73fe41c344b0a23230e597f7b94a2c (patch) | |
| tree | 07330bef7fc8685f5615212de33250bb32adc918 /source/slang/emit.cpp | |
| parent | c9368fe3ec8f8d8bc58947ddb1b5fd2caa4bd70a (diff) | |
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<T>` 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
Diffstat (limited to 'source/slang/emit.cpp')
| -rw-r--r-- | source/slang/emit.cpp | 121 |
1 files changed, 65 insertions, 56 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 039aea27d..a8cd11af4 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3425,75 +3425,84 @@ struct EmitVisitor // Keyword to use in the uniform case (`register` for globals, `packoffset` inside a `cbuffer`) char const* uniformSemanticSpelling = "register") { - if( info.kind == LayoutResourceKind::Uniform ) + switch(info.kind) { - size_t offset = info.index; + case LayoutResourceKind::Uniform: + { + size_t offset = info.index; - // The HLSL `c` register space is logically grouped in 16-byte registers, - // while we try to traffic in byte offsets. That means we need to pick - // a register number, based on the starting offset in 16-byte register - // units, and then a "component" within that register, based on 4-byte - // offsets from there. We cannot support more fine-grained offsets than that. + // The HLSL `c` register space is logically grouped in 16-byte registers, + // while we try to traffic in byte offsets. That means we need to pick + // a register number, based on the starting offset in 16-byte register + // units, and then a "component" within that register, based on 4-byte + // offsets from there. We cannot support more fine-grained offsets than that. - Emit(": "); - Emit(uniformSemanticSpelling); - Emit("(c"); + Emit(": "); + Emit(uniformSemanticSpelling); + Emit("(c"); - // Size of a logical `c` register in bytes - auto registerSize = 16; + // Size of a logical `c` register in bytes + auto registerSize = 16; - // Size of each component of a logical `c` register, in bytes - auto componentSize = 4; + // Size of each component of a logical `c` register, in bytes + auto componentSize = 4; - size_t startRegister = offset / registerSize; - Emit(int(startRegister)); + size_t startRegister = offset / registerSize; + Emit(int(startRegister)); - size_t byteOffsetInRegister = offset % registerSize; + size_t byteOffsetInRegister = offset % registerSize; - // If this field doesn't start on an even register boundary, - // then we need to emit additional information to pick the - // right component to start from - if (byteOffsetInRegister != 0) - { - // The value had better occupy a whole number of components. - SLANG_RELEASE_ASSERT(byteOffsetInRegister % componentSize == 0); + // If this field doesn't start on an even register boundary, + // then we need to emit additional information to pick the + // right component to start from + if (byteOffsetInRegister != 0) + { + // The value had better occupy a whole number of components. + SLANG_RELEASE_ASSERT(byteOffsetInRegister % componentSize == 0); - size_t startComponent = byteOffsetInRegister / componentSize; + size_t startComponent = byteOffsetInRegister / componentSize; - static const char* kComponentNames[] = {"x", "y", "z", "w"}; - Emit("."); - Emit(kComponentNames[startComponent]); - } - Emit(")"); - } - else - { - Emit(": register("); - switch( info.kind ) - { - case LayoutResourceKind::ConstantBuffer: - Emit("b"); - break; - case LayoutResourceKind::ShaderResource: - Emit("t"); - break; - case LayoutResourceKind::UnorderedAccess: - Emit("u"); - break; - case LayoutResourceKind::SamplerState: - Emit("s"); - break; - default: - SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled HLSL register type"); - break; + static const char* kComponentNames[] = {"x", "y", "z", "w"}; + Emit("."); + Emit(kComponentNames[startComponent]); + } + Emit(")"); } - Emit(info.index); - if(info.space) + break; + + case LayoutResourceKind::RegisterSpace: + // ignore + break; + + default: { - Emit(", space"); - Emit(info.space); + Emit(": register("); + switch( info.kind ) + { + case LayoutResourceKind::ConstantBuffer: + Emit("b"); + break; + case LayoutResourceKind::ShaderResource: + Emit("t"); + break; + case LayoutResourceKind::UnorderedAccess: + Emit("u"); + break; + case LayoutResourceKind::SamplerState: + Emit("s"); + break; + default: + SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled HLSL register type"); + break; + } + Emit(info.index); + if(info.space) + { + Emit(", space"); + Emit(info.space); + } + Emit(")"); } - Emit(")"); } } |
