Граф коммитов

43 Коммитов

Автор SHA1 Сообщение Дата
Greg Roth 82422d7761
Only keep legacy struct types from resources (#3624)
When compiling a library without 16-bit support, certain struct types
containing either min precision types or matrices must be saved in
reflection data for conversion after linking. However, this is only
necessary when the types are used by a resource.

Instead of evaluating all matrix types and saving those that meet this
criteria, only the types used by resources are evaluated and possibly
preserved. This significantly shrinks the reflection size in this case.
2021-03-25 14:47:29 -07:00
Tex Riddell 6244ab8337
Validator/Dxil version error improvements (#3623)
- Move validator/dxil version checks up-front
  These should fail first rather than side effects of trying to validate
  details of a version we don't support.
- Improve message for unsupported validator or dxil version
  These errors are most likely if compiling separately from validation
  and failing to override the validator version properly, or running on
  an external validator that doesn't support a newer dxil.
- Use dxil version from metadata for DxilModule when loading,
  rather than just setting it to minimum based on shader model.
- Remove TODO from validator messages that shouldn't be there
2021-03-25 14:03:31 -07:00
Michael Haidl 1db765ea9c
DXC extension for DXR Payload Access Qualifiers (#3171)
This extension adds qualifiers for payload structures accompanied with semantic checks and code generation. This feature is opt-in for SM 6.6 libraries.  The information added by the developer is stored in the DXIL type system and a new metadata node is emitted during code generation. The metadata is not necessary for correct translation of DXIL, so it may be safely ignored, but it provides hints to unlock potential optimizations in payload storage between DXR shader stages.
2021-03-14 18:31:40 -07:00
Greg Roth b89f06578f
Consider ranges when counting UAVs for 64UAV (#3470)
The 64UAV flag is meant to indicate that 9 or more UAVs are in use.
Previously, each UAV was considered as one regardless of range. By
adding up the ranges, we get a more accurate determination.

Only use the new counting when using the latest validtor to maintain
compatibility with the old ones

Fixes: #2964
2021-02-24 19:17:30 -08:00
Tex Riddell 3b99af518d
Implement fallback path for IsHelper on SM < 6.6 (#3408) 2021-01-29 11:05:05 -08:00
Adam Yang 2b8ef5b57e
Removed source from debug module. Support slim PDB. (#3348) 2021-01-20 12:25:28 -08:00
Xiang Li 83e538ecc3
Use IsEntry when LowerStaticGlobalIntoAlloca. (#3353) 2021-01-13 16:14:09 -08:00
Greg Roth d574d27c1f
Implement Shader Model 6.6 (#3293)
This is the work of many contributors from Microsoft and our partners.
Thank you all!

Add support for 64-bit atomics, compute shader derivatives, dynamic
resources (from heap), 8-bit Packed Operations, and Wave Size.
All of these require compiling with 6_6 targets with just a few
exceptions. Each of these features include unittests and Execution
tests.

64-bit atomics add 64-bit variants of all Interlocked* intrinsic
operations. This involves changing some of the code that matches
intrinsic overloads to call instructions. Also adds a few float
intrinsics for compare and exchange interlocked ops which are available
for all shader models 6.0 and up.

Compute shader derivatives adds dd[x|y], CalculateLevelOfDetail, and
Sample operations that require derivatives to compute. QuadRead
operations have been allowed in compute from 6.0+ and tests are added
for them here.

Dynamic resources introduce global arrays that represent the resource
and sampler heaps that can be indexed without requiring root signature
representations. This involves a new way of creating and annotating
resource handles.

8-bit Packed operations introduces a set of intrinsics to pack and
unpack 8-bit values into and out of new 32-bit unsigned types that can
be trivially converted to and from uints.

WaveSize introduces a shader attribute that indicates what size the
shader depends on the wave being. If the runtime has a different wave
size, trying to create a pipeline with this size will fail.
2020-12-02 21:10:44 -08:00
rkarrenberg eaa7f95d07
Enable generation of llvm.lifetime.start/.end intrinsics (#3034)
* Enable generation of llvm.lifetime.start/.end intrinsics.

- Remove HLSL change from CGDecl.cpp::EmitLifetimeStart() that disabled
- generation of lifetime markers in the front end.
- Enable generation of lifetime intrinsics when inlining functions
- (PassManagerBuilder.cpp).
- Both of these cover a different set of situations that can lead to
- inefficient code without lifetime intrinsics (see examples below):
  - Assume a struct is created inside a loop but some or all of its
    fields are only initialized conditionally before the struct is being
    used. If the alloca of that struct does not receive lifetime intrinsics
    before being lowered to SSA its definition will effectively be hoisted
    out of the loop, which changes the original semantics: Since the
    initialization is conditional, the correct SSA form for this code
    requires a phi node in the loop header that persists the value of the
    struct field throughout different iterations because the compiler
    doesn't know anymore that the field can't be initialized in a different
    iteration than when it is used.
  - If the lifetime of an alloca in a function is the entire function it
    doesn't need lifetime intrinsics. However, when inlining that function,
    the alloca's lifetime will then suddenly span the entire caller, causing
    similar issues as described above.
- For backwards compatibility, replace lifetime.start/.end intrinsics
  with a store of undef in DxilPreparePasses.cpp, or, for validator
  version < 1.6, with a store of 0 (undef store is disallowed). This is
  slightly inconvenient but achieves the same goal as the lifetime
  intrinsics. The zero initialization is actually the current manual
  workaround for developers that hit one of the above issues.
- Allow lifetime intrinsics to pass DXIL validation.
- Allow undef stores to pass DXIL validation.
- Allow bitcast to i8* to pass DXIL validation.
- Make various places in the code aware of lifetime intrinsics and their
- related bitcasts to i8*.
- Adjust ScalarReplAggregatesHLSL so it generates new intrinsics for
  each element once a structure is broken up. Also make sure that lifetime
  intrinsics are removed when replacing one pointer by another upon seeing
  a memcpy. This is required to prevent a pointer accidentally
  "inheriting" wrong lifetimes.
- Adjust PromoteMemoryToRegister to treat an existing lifetime.start
- intrinsic as a definition.
- Since lifetime intrinsics require a cleanup, the logic in
  CGStmt.cpp:EmitBreakStmt() had to be changed: EmitHLSLCondBreak() now
  returns the generated BranchInst. That branch is then passed into
  EmitBranchThroughCleanup(), which uses it instead of creating a new one.
  This way, the cleanup is generated correctly and the wave handling also
  still works as intended.
- Adjust a number of tests that now behave slightly differently.
  memcpy_preuser.hlsl was actually exhibiting exactly the situation
  explained above and relied on the struct definition of "oStruct" to be
  hoisted out to produce the desired IR. And entry_memcpy() in
  cbuf_memcpy_replace.hlsl required an explicit initialization: With
  lifetime intrinsics, the original code correctly collapsed to returning
  undef. Without lifetime intrinsics, the compiler could not prove this.
  With proper initialization, the test now has the intended effect, even
  though the collapsing to undef could be a desireable test for lifetime
  intrinsics.

Example 1:

Original code:
for( ;; ) {
  func();
  MyStruct s;
  if( c ) {
    s.x = ...;
    ... = s.x;
  }
  ... = s.x;
}

Without lifetime intrinsics, this is equivalent to:
MyStruct s;
for( ;; ) {
  func();
  if( c ) {
    s.x = ...;
    ... = s.x;
  }
  ... = s.x;
}

After SROA, we now have a value live across the function call, which will cause a spill:
for( ;; ) {
  x_p = phi( undef, x_p2 );
  func();
  if( c ) {
    x1 = ...;
    ... = x1;
  }
  x_p2 = phi( x_p, x1 );
  ... = x_p2;
}

Example 2:

void consume(in Data data);
void expensiveComputation();

bool produce(out Data data) {
    if (condition) {
        data = ...; // <-- conditional assignment of out-qualified parameter
        return true;
    }
    return false; // <-- out-qualified parameter left uninitialized
}
void foo(int N) {
    for (int i=0; i<N; ++i) {
        Data data;
        bool valid = produce(data); // <-- generates a phi to prior iteration's value when inlined. There should be none
        if (valid)
            consume(data);
        expensiveComputation(); // <-- said phi is alive here, inflating register pressure
    }
}

* Implement lifetime intrinsic execution test.

- Test SM 6.0, 6.3, and 6.5. The 6.5 test behaves exactly the same way
  as 6.3, it is meant a placeholder for 6.6.
- Test validator versions 1.5 and 1.6.
- Abstract a few things in the ExecutionTest infrastructure to enable
  better code sharing, e.g. for lib compilation.

* Make memcpy replacement conservative by removing lifetimes of both src and dst. Add regression test for this case.

* Allow to force replacing lifetime intrinsics by zeroinitializer stores via compile option.

* Fix regression where lifetimes caused code that was not cleaned up properly.

- Add SROA and Jump Threading passes as early in the optimization
  pipeline as possible without interfering with lowering. These two are
  required to fully remove redundant code due to insertion of cleanup blocks
  for lifetimes. Previously, SROA ran much too late, and Jump Threading
  was disabled everywhere.
- A side effect of this is that we can now have unstructured control
  flow more often. This also breaks one test that was originally written
  when a part of SimplifyCFG that could also create unstructured control
  flow was disabled. That part is still disabled, but jump threading has
  the same effect. I don't know why unstructured control flow is a
  problem for the optimization pipeline.
- Add a regression test that requires the two phases to be cleaned up properly.
- Disable the simplifycfg test which now fails even though simplifycfg
  still does what it should.

* Disable lifetime intrinsics for SM < 6.6, add flag to enable explicitly.

- Add missing default value for unrelated option StructurizeLoopExitsForUnroll.
- Re-enable simplify cfg test disabled in a previous commit.
2020-11-16 15:48:05 -08:00
Minmin Gong 7e0f44fa6f
Cleanup part of compiling warnings (#2903)
Try to fix some compiler warnings produced by clang when building the dxc compiler
2020-06-25 02:57:41 -06:00
Tex Riddell e0cb412916
Add resource rename pass, dx op overload fix (#2986)
- Add method to DxilModule to rename resources based on a prefix,
  preventing resource merging during linking.
- Also one to rename by binding if desired.
- Add pass to access this resource renaming.
- Fix dxil intrinsic overload names when type disambiguation causes
  types with same name to be renamed with .0+ suffix, but intrinsic
  names remain in collision.
- Handle colliding intrinsic names with unique types in linker.
2020-06-19 15:33:58 -07:00
Tex Riddell ee442e01bc
Support instruction counts in reflection (#2930) 2020-05-29 20:09:29 -07:00
Greg Roth c207a9a8d3
Correct reflection stripping detection (#2696)
When stripping reflection data, structures are searched for any member
or submember scalars that are smaller than 32 bits. When one is found
and min precision is being used, the structure is identified as not
being able to be stripped.

In the case of a shader that has a resource that contains a struct which
contains an array which contains a struct, the struct was not being
processed as a struct, but rather as a scalar, which would cause it to
return a size of zero, which was found to be less than 32 bits. This
isn't right if the innermost struct contained a 32 bit integer. Either
way, this resulted in inconsistent results for the parent struct and the
innermost struct. As a result, the annotations were stripped from the
innermost, but left on the outermost. Because the parent struct had
annotations, validation was attempted, but ultimately hit an assert or
caused validation failures because of the innermost struct being
stripped.

By reorganizing the function that searches for 16 bit scalars to look
for a struct only after processing the arrays, the struct is properly
traversed and all annotations are stripped, avoiding the failures.

Rather than determining all aspects of keeping or stripping reflection
annotation based on the individual struct and its contents, all structs
contained in a struct are collected so that they can be excluded from
stripping should their parent struct be found needing of maintaining its
annotations.

Thanks to @tex3d for suggesting (and mostly implementing) this addition
2020-02-18 10:34:12 -07:00
Xiang Li 91fe12f0eb
Add GetResourceFromHeap. (#2691)
Add GetResourceFromHeap for hlsl.
For Dxil, add CreateHandleFromHeap and AnnotateHandle.

All handles ( createHandle, createHandleForLib, createHandleFromHeap ) must be annotated with AnnotateHandle before use.

TODO: add AnnotateHandle for pix passes.
            cleanup code about resource.
2020-02-12 21:50:02 -08:00
Tex Riddell 00c6d87f68 Switch metadata generation on shader model instead of validator version.
- MinVal[Major|Minor] tracks shader model.
- Account for reflection by special casing for version 0.0 (no validation)
- Tolerate additions to non-critical metadata for future version
- Keep track of unrecognized non-critical metadata for validation
- Update validator to detect this case.
2019-11-20 17:12:42 -08:00
Tex Riddell f4965b71dd Integrate dxcapi v2 and other changes from internal (#2575)
* Integrate changes from internal.

- dxcapi v2
- new dxc options
- DxilValueCache
- PDB and NoOpt improvements
- noop / llvm::donothing() support

* Update dxrfallbacklayer for dxcapi internal changes

* Reorder diag block based on whether pDiag is set first.

* llvm::donothing() requires dxil 1.6 / SM 6.6 for now, lib as well.

* Fixes for spir-v, non-VC compiler and non-Windows builds

- DEFINE_CROSS_PLATFORM_UUIDOF for new interfaces
- add SAL annotations
- turn output argument validation for -P into warning
- handle warnings without concatenating them to main output
- update spirv preprocessing and compilation paths
- return E_NOTIMPL from IDxcUtils::CreateReflection
- cleanup: DxcContainerBuilder back to uft8, DxcTestUtils: remove comment

* Fix some warnings from clang/gcc.

* Fix unicode conversion problems on linux, where sizeof(wchar_t) == 4

Note this is an intermediate fix.
On linux, what we are calling utf16 is actually a wide string
that's probably utf32.  This change fixes issues introduced by
the new interface changes so things are consistent and pass tests.

A future fix should correct the encodings so they are correctly labeled
on platforms where wchar_t doesn't mean UTF16.

* Return false for IsBufferNullTerminated when CP_ACP.

One test for Disassembler was crashing because it created a pinned blob
with a size of 1 << 31 + 1 without actual memory backing this.  The
IsBufferNullTerminated would attempt to see if this was null terminated,
causing AV.

This change also removes CP_UTF8 from this test when it was creating
binary blobs, not UTF8 text blobs.
2019-11-13 16:16:45 -08:00
Tex Riddell b1fea1f075
Fix Amplification Shader (AS) payload size in runtime data (#2484) 2019-09-24 13:24:39 -07:00
Tex Riddell 0f23b6946c Merge remote-tracking branch 'ms/master' into sep-reflect 2019-08-19 00:43:25 -07:00
Tex Riddell 892765cc4b Default to stripping reflection from DXIL and fix a bunch of fallout.
Two test options, -Qstrip_reflect_from_dxil and -Qkeep_reflect_in_dxil
for making tests work with reflection removed, since many tests are relying
on main module disassembly-reassembly between test phases and reflection
metadata will no longer be present there.  The strip option is for the
few cases where tests don't want the reflection kept in DXIL by default.

Validator no longer requires function annotations for no reason.

Fix places where remove global hook was not being called when functions
were removed manually from the list.

StripReflection now deletes function annotations, unless targeting lib or
old validator that required them.  Preserve global constructor list and
add annotation for 1.4 validator.  The global hook fixes were required
here, otherwise annotations would refer to dead functions during linking.
Struct annotations may not be removed in library case when they still need
translation to legacy types.

Allow missing struct annotation when not necessary to upgrade the layout.

Preserve usage in reflection by upgrading the module, emitting metadata,
cloning for reflection, then restoring validator version and re-emit
metadata.

Fix size for 16-bit type for usage and reflected size.

Make various batch reflection tests require validator 1.5, since these
tests rely on module disassembly->assembly, which will not preserve extra
usage metadata for reflection in 1.4.

Include reflection part in IDxcAssembler, but don't strip from module,
since there are no options to prevent this from breaking a lot of tests.

Don't strip reflection from offline lib target.
2019-08-19 00:39:39 -07:00
Tex Riddell 5894e7ab66 return bool changed from DxilModule::StripReflection 2019-08-12 16:15:52 -07:00
Tex Riddell e5fc71ec2f Update GetMinValidatorVersion for DXR 1_1 (1.5) and Subobjects (1.4) 2019-08-12 14:40:31 -07:00
Tex Riddell c8f7a6c970
Allow [Get/Set]NumThreads on Mesh/Amplification shaders (#2393) 2019-08-05 19:45:24 -07:00
Tex Riddell 2facceae0b
Store mesh payload in function props, fix Wave/Quad/Barrier validation (#2361)
- Compute mesh payload size before final object serialization
  - During CodeGen for MS based on payload parameter
  - During CollecShaderFlagsForModule for AS based on DispatchMesh call
- Store payload sizes in corresponding funtion properties, serializing
  these properly for HL and Dxil Modules
- Use payload sizes from function props for PSV0 data during serialization
- Validate measured and declared payload sizes, don't just fill in
  properties during validation
- Fix Wave/Quad allowed shader stages, enabling Quad* with CS-like models
- rename payloadByteSize members to payloadSizeInBytes
- Add GetMinShaderModelAndMask overload taking CallInst for additional
  detail required to produce correct SM mask for Barrier operations
2019-07-24 10:22:28 -07:00
amarpMSFT 37acf90723 add payload size to Amplification Shader metadata to mirror MS metadata (#2359) 2019-07-23 17:27:42 -07:00
Tristan Labelle 49a5dd63c2
Remove globalopt dependency on the name of the entrypoint (#2350)
GlobalOpt has an explicit test for a function called "main" (eww...) to enable an optimization. This updates the test to match the entry point, independent of its name.
2019-07-17 14:31:26 -07:00
Sahil Parmar 968fe41136 Merged PR 116: Add support for HLSL Meshlets
This PR adds support for new HLSL mesh and amplification shaders.
2019-07-11 20:19:23 +00:00
Adam Yang f240070cf1
Fixed issues that change codegen when there's debug info. (#2190) 2019-05-17 13:35:08 -07:00
Adam Yang 716a113650
Fixed a bug where necessary code gets deleted with library shaders. (#2185)
Deleted some old code where we manually delete users of resource GV's while stripping debug modules. This is normally unnecessary but harmless, because we are guaranteed to have reduced all resource variables, and any failure to do so would result in a validation failure. However, library shaders can have resource variables. Removing the instructions here would result in incorrect code.
2019-05-14 11:10:46 -07:00
Adam Yang 24e71b12e5
Fixed a validation failure with stripping reflect with library shaders. (#2182) 2019-05-14 08:00:08 -07:00
Tex Riddell 638d988e8f
Fix issues with -Qstrip_reflect and -Qstrip_debug (#2164)
-Qstrip_reflect would reserialize the root signature, leading to
validation failure #2162.  Fixed by moving root sig to writer to clear
from module and prevent re-serialization to metadata.

Fixed -Qstrip_debug with -Zi and no output location still embeding
debug module.
2019-05-03 08:06:31 -07:00
Xiang Li 58b3d23cfc
Support Qstrip_reflect. (#2139)
* Support Qstrip_reflect.
2019-04-24 12:58:25 -07:00
Tristan Labelle 685b2afa84
Added support for pre-SM5.1 resource allocation algorithm (#1687)
Added front-end `-flegacy-resource-reservation` to control behavior (added automatically for SM <= 5.0)
Added an error for unbounded resources used with `-flegacy-resource-reservation`
Added a mechanism for `DxilModule` to preserve intermediate options during its passes but not in the final DXIL
Changed `HLModule` to not remove unreferenced `DxilResources` but rather make their symbol UndefValue
Fixed assumptions of `DxilResources` having a valid `GlobalVariable`
Added reserved resource range gather pass before elimination of unused resources (if SM <= 5.0)
Changed resource allocation to account for reserved ranges
2018-11-20 12:01:08 -08:00
Tristan Labelle 80ee93547a
Fix assert following reflection changes. (#1717)
DxilModule::GetTessellatorPartitioning didn't follow the model of other methods of returning Undefined when it does not apply to the shader stage and would assert.
2018-11-16 17:05:16 -08:00
Tex Riddell fbe1371aae
Fix Validation for RDAT and other issues with Subobjects (#1706)
- re-serialize module when changed by removing either subobjects or
  root signature metadata
- improve error detection/handling for loading/creating subobjects
- load subobjects from RDAT if not in DxilModule for RDAT comparison
- fix subobjects missing from desc in DxilRuntimeReflection
- default ReducibilityAnalysis to pass so it doesn't fail when no
  functions are present
- report error on subobject if validator (< 1.4) will not accept
  them, so they will not be captured
- container validation for required/disallowed parts for libraries
2018-11-13 14:49:32 -08:00
Helena Kotas 2a7c520fcb
Fix memory allocation issues (#1679)
- DxilModule was not freed
- PragmaMatrixHandler was freed twice when the compiler execution was aborted
  prematurely by an exception
- Improve diagnostic tracing in CompilerTest::CompileWhenNoMemThenOOM
2018-11-07 12:51:37 -08:00
Tex Riddell 532368e9a1
Fix remaining HLModule/DxilModule dependencies from llvm::Module, etc. (#1656)
- Use one callback for global removal - Function and GlobalValue use this
- Share callback for HLModule and DxilModule, transfer is handled by
  setting callback on construction and checking pointer before clearing
2018-11-01 16:38:33 -07:00
Tex Riddell 254b8853be
Fix dependency on HL/DxilModule from llvm::Module (#1651)
- use function pointers for HL/DxilModule remove function callbacks
- move ReducibilityAnalysis to llvm/Analysis
2018-10-31 19:18:28 -07:00
Tex Riddell 4a942586f8
Merge pull request #1621 from tex3d/dxil-subobjects
Add Subobjects: classes, metadata, serialization, reflection, disasm
2018-10-24 11:44:51 -07:00
Tex Riddell ecb4e3b4bb Add SV_ShadingRate plus optional feature flag
- Move/fix flag collection based on signature properties to be computed
  per entry function (including for libraries)
2018-10-22 20:25:12 -07:00
Tex Riddell 9678588269 Add Subobjects: classes, metadata, serialization, reflection, disasm 2018-10-19 01:02:34 -07:00
Xiang Li 16a5f94ab2
Move DxilRootSignature to its own directory. (#1609)
* Move DxilRootSignature to its own directory.
* Move DxilContainer into its own directory.
* Move DxilLoadMetadata into DxilUtil.
2018-10-17 18:46:43 -07:00
Xiang Li 016e70532e
Move pix pass into DxilPIXPasses. (#1605)
* Move pix pass into DxilPIXPasses.
2018-10-16 21:38:33 -07:00
Xiang Li 4df08af7c0
Move DxilModule into DXIL directory. (#1599)
* Move DxilModule into DXIL directory.
2018-10-16 00:28:35 -07:00