HLSL 2017's enum and enum class compile to a type without an integer base.
So in this case we'll call it an unknown type for the purposes of PIX debug instrumentation.
Further work will be required to return the enumerants to PIX and to record an actual value during shader debug instrumentation.
* Refactor HLSLVersion to enum
This change converts HLSLVersion to an enum type `hlsl::LangStd`. Most
of the change is a mechanical appending `hlsl::LangStd::v` to the
integers we previously compared for version checks.
Additionally this change does the following:
* Adds a parseHLSLVersion function to unify parsing code
* Parsing code is converted to an llvm::StringSwitch over the possible
values instead of converting to integer
* Added enum value for `vLatest` so that changing the latest version is
done in one place
* Added enum value for `v202x` which parses from 202x to allow new
language features a place to land
* Updates based on PR feedback
During parsing, some properties about attributes are determined by
matching the identifier used in the source with the attribute spelling
in Attr.td. The assumption here was that attributes are all
case-sensitive. But HLSL attributes are not case-sensitive, and even
though code that matches these attributes to kind and determines
whether the attribute is valid has been adjusted to handle
case-insensitivity, the code that looks up properties had not.
One impact was that identifier arguments were not being recognized and
stored in the attributes properly (attributeHasIdentifierArg).
This change makes normalizeAttrName use lower() to force lowercase for
the incoming attribute name before it gets used in the StringSwitch.
normalizeAttrName now must return std::string instead of StringRef
since it's potentially changing the string, not just slicing it.
It would seem better to use the AttributeList::Kind in a switch instead
of matching the string used, but that would be a much more significant
change.
Note: for attributes to work now, all spellings for valid attributes
must be lower case in Attr.td (fortunately they currently are).
When replacing constant users, those users could be in functions other than the one being worked on.
The code would happily replace uses of the constant with instructions that weren't in the same function.
This would lead to bizarre consequences due to corrupt IR down the line.
This change prevents that from happenning.
* Adding /setprivate, /setrootsignature, and /Qstrip_priv to compile API calls
* Adding setprivate to initial container serialization, change warning to error
* Removed unused variable
* Adding private data blob last, because no gaurantee of aligned size
* Add error messages for conflicting private options
Since all other blob parts are expected to be aligned, make sure we always add private data at the end of the container.
Update DxcContainerBuilder to keep private data at the end as well.
- Maintain compatibility for validator version < 1.7.
- DxilContainerWriter_impl verifies size alignment for all parts, unless created with bUnaligned=true, used for backward compatibility.
- DxilValidation uses NewProgramSignatureWriter(), so bUnaligned is based on validator version in module.
* Pass compiler options to preprocessor
If we don't pass the compiler options to the preprocessor the
preprocessor doesn't get initialized correctly.
Without this change the preprocessor step identifies the shader model
version as 0.0, pipeline stage as invalid, and language version as the
default.
* Remove arugment duplication
NRVO can drop type attributes not captured into QualType, like glc. HLSL does not need NRVO, and it only poses problems in various areas, so this change turns it off globally for HLSL.
The test required an additional fix to resource return resprops merging, provided by Xiang.
Co-authored-by: Xiang Li <xiagli@microsoft.com>
These changes add a couple of new fields to the shader-access-tracking pass. The new fields are the shader kind and the instruction ordinal (from the dxil-annotate-with-virtual-regs pass). This will allow PIX to report richer feedback to the user about out-of-bounds access.
This revision adds out-of-bounds checking for SM6.6-style dynamic resources and samplers, a feature heretofore missing in PIX.
Fortunately, there was a bit spare (InstructionOrdinalndicator) that allows PIX to detect the new fields and thereby continue to operate with older versions of dxcompiler, a frequent customer scenario.
Add whole file testing for dxil2spv, starting with a simple passthrough
pixel shader. dxil2spv does not yet generate complete output for this
sample, but adding testing now will help reviewing iterations.
Modify SpirvBuilder to allow unset astContext, because astContext is
unavilable when translating from DXIL. Initialize a SpirvContext and
SpirvBuilder to generate a basic module, and output as disassembled
SPIR-V to STDOUT.
Based on Vulkan spec
> VUID-StandaloneSpirv-VulkanMemoryModel-04678
If the VulkanMemoryModel capability is not declared, the Volatile
decoration must be used on any variable declaration that includes
one of the SMIDNV, WarpIDNV, SubgroupSize, SubgroupLocalInvocationId,
SubgroupEqMask, SubgroupGeMask, SubgroupGtMask, SubgroupLeMask, or
SubgroupLtMask BuiltIn decorations when used in the ray generation,
closest hit, miss, intersection, or callable shaders, or with the
RayTmaxKHR Builtin decoration when used in an intersection shader
> VUID-StandaloneSpirv-VulkanMemoryModel-04679
If the VulkanMemoryModel capability is declared, the OpLoad
instruction must use the Volatile memory semantics when it accesses
into any variable that includes one of the SMIDNV, WarpIDNV,
SubgroupSize, SubgroupLocalInvocationId, SubgroupEqMask,
SubgroupGeMask, SubgroupGtMask, SubgroupLeMask, or SubgroupLtMask
BuiltIn decorations when used in the ray generation, closest hit,
miss, intersection, or callable shaders, or with the RayTmaxKHR
Builtin decoration when used in an intersection shader
We have to propagate the volatile semantics based on the spec. Since
adding Volatile decoration to interfaces is allowed in Vulkan 1.3 or
above, we simply add Volatile decoration for such interfaces. If it is
Vulkan 1.2 or earlier, we have to set the Volatile for OpLoad
instruction, which need the VulkanMemoryModel capability. In addition,
since Vulkan 1.1 or earlier does not have the VulkanMemoryModel
capability in the core spec, we use SPV_KHR_vulkan_memory_model.
This change modifies the RemoveBufferBlockVisitor to recurse through nested pointers to transform the storage class of inner pointers where required, as well as the fields of structs. Some uses arrays are handled by hasStorageBufferInterfaceType, but this PR leaves as a TODO further verification of the handling of of other composite types.
Fixes#4185, #4187
This fixes the OOB indexing by ending the loop early if GEP is deeper than the index list being matched.
Libraries with vectors, and intrnisics that operate on aggregate PTRs are not handled properly for precise propagation.
Some potential over/under marking is partially fixed by additional cases in PropagateOnPointerUsers:
- recurse GEP and Bitcast
- skip llvm intrinsics like lifetime
There's still some question as to how much we should really be marking precise (at function boundaries like TraceRay, for instance).
Basically, there's more to be done to improve precise propagation, potentially requiring a rewrite in the future.
But this change should improve things for now, and prevent a crash.
As a part of HLSL version of GL_EXT_spirv_intrinsics, this commit adds
`vk::ext_execution_mode_id(..)` intrinsic function. In addition, it allows users
to enable capabilites and extensions via `vk::ext_execution_mode[_id](..)`
using `[[vk::ext_capability(..)]]` and `[[vk::ext_extension(..)]]`.
Related to #3919
These were disabled at a point that the DXC CI didn't reject builds for
failing on Linux, now that they do, we can enable these tests sure in
the knowledge that any changes to them that break on Linux will be
detected and fixed quickly
Fixed *nix error code return. The previous caused an infinite loop of retries.
This definition more accurately identifies the error that has occurred as not
benefiting from repeated attempts
Skip tests and filechecker elements that entirely depend on reflection or
linker interfaces that aren't implemented on *nix yet.
Correct capitalization in a few places to satisfy a case-sensitive filesystem
Detect directories from test include handler. *nix virtual filesystem will try to
load the file using the include handler when performing stat() on a directory.
The test include handler is pretty basic and would provide the next file, leaving
it without a file to offer when the real include came along.
By detecting a name that looks like a dir and returning failure, it
correctly indicates that the file isn't found by the handler and saves
the virtual file for when its needed.
Don't mark non-debug builds as such. The DEBUG define determines which
tests get run. Some of which depend on consistencies that can only be relied
upon in debug builds. So DEBUG is disabled for all non-debug builds.
Correct free of new() memory. Incidental regex allocations were changed for
HLSL to use the global new() operator, but were still freed using the standard
free(), but replacing the default free() with regex_free() allows the default new()
operator to be paired with the default delete() operator
Correct misnamed test flag. The *nix flag was mistakenly called InputFile instead
of InputPath. By renaming it, the ManualFile test can target a specific HLSL file.
Fix misused ArrayRef in legacy GV replacement. The replacement of the GV with
the legacy form used in libraries collected the arguments into an arrayref without
an array to ref, which caused garbage in release builds. Also moved to using end
vars for loops where the elements can get deleted during the loop.
Fix *nix conversion to utf8. When an unknown codepage is found, it tries to convert
to utf16, but that isn't' actually helpful for *nix for a shader codepage derived from
the BOM, which is correctly identified as utf32
As a part of HLSL version of GL_EXT_spirv_intrinsics, this commit adds
vk::ext_result_id<T> type. We must use it for a variable definition or
a function parameter. It means we do not consider it as a physical
storage. Instead, it will be a result id of the instruction.
Related to #3919
The AST for `RayQuery` always has the initialization Expr e.g.,
```
`-VarDecl 0xba2768 <col:3, col:15> col:15 RayQ 'RayQuery<0>':'RayQuery<0>' callinit
`-CXXConstructExpr 0xba27d8 <col:15> 'RayQuery<0>':'RayQuery<0>' 'void ()'
```
Since the existing SPIR-V code gen simply uses the most recent "this" of
struct/class for CXXConstructExpr, RayQuery var defined after a struct or
class has weird initialization that results in failures.
This commit simply ignores the initialization Expr when it is
CXXConstructExpr e.g., `RayQuery<0> r = RayQuery<0>();` will not have
the initialization in SPIR-V. Note that we correctly handles the
initialization with another RayQuery var e.g.,
```
RayQuery<0> r = RayQuery<0>();
RayQuery<0> q = r;
```
Also note that the type mismatch for the initialization is handled by
AST parser e.g., parser will report an error for `RayQuery<0> r = {0};`.
When using uint64_t fields in structures, the member was not being aligned to 8-bytes in constant buffers like it should be.
Constant buffer offsets come from type annotation information, rather than raw data layout. The CBufferOffset for FieldAnnotation was not being properly aligned for u64 field types, though it was ok for i64. This was because the offset alignment code was missing ULongLong when checking the basic type.
This change fixes the issue with a minimal change by adding ULongLong to the if condition.
Modified and added tests to check this case for StructuredBuffer, cbuffer/tbuffer (both inside and outside struct member), ConstantBuffer, and TextureBuffer.
* First attempt at new changes
* Fixing the root cause of the earlier failure - the 'selfloop' check was not properly deleting the block, but disconnected it from the graph. This prevented 'FindDeadBlocks' from identifying it as a successor of the common dominator.
* Whitespace
For Vulkan 1.2 or less, we must not use HelperInvocation BuiltIn
decoration. Instread, for a variable with `[[vk::HelperInvocation]]`
attribute, we have to use `OpIsHelperInvocation` instruction:
- Create a variable (with Input storage class)
- In the module initialization, execute `OpIsHelperInvocation`
instruction and store the result in the variable