Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/dxc/Support/HLSLOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,8 @@ def fvk_bind_sampler_heap : MultiArg<["-"], "fvk-bind-sampler-heap", 2>, MetaVar
HelpText<"Specify Vulkan binding number and set number for the sampler heap.">;
def fvk_bind_counter_heap : MultiArg<["-"], "fvk-bind-counter-heap", 2>, MetaVarName<"<binding> <set>">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
HelpText<"Specify Vulkan binding number and set number for the counter heap.">;
def fvk_disable_depth_hint: Flag<["-"], "fvk-disable-depth-hint">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
HelpText<"Disable the depth hint when generating OpTypeImage (driver issues)">;
// SPIRV Change Ends

//////////////////////////////////////////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions include/dxc/Support/SPIRVOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct SpirvCodeGenOptions {
bool useScalarLayout = false;
bool flattenResourceArrays = false;
bool reduceLoadSize = false;
bool disableImageTypeDepthHint = false; // Disable depth hint for OpTypeImage because some mobile drivers crash.
bool autoShiftBindings = false;
bool supportNonzeroBaseInstance = false;
bool supportNonzeroBaseVertex = false;
Expand Down
26 changes: 26 additions & 0 deletions include/llvm/Bitcode/BitstreamWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
#include "llvm/Support/Endian.h"
#include <vector>

// O3DE change start
#include "llvm/Bitcode/LLVMBitCodes.h"
#include <functional>
// O3DE change end

namespace llvm {

class BitstreamWriter {
Expand Down Expand Up @@ -88,6 +93,11 @@ class BitstreamWriter {
}

public:
// O3DE change start
typedef std::function<void(uint64_t, uint64_t)> ConstantHandlerFn;
ConstantHandlerFn WriteConstantCallback = nullptr;
// O3DE change end

explicit BitstreamWriter(SmallVectorImpl<char> &O)
: Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}

Expand Down Expand Up @@ -370,6 +380,22 @@ class BitstreamWriter {
WriteByte(0);
} else { // Single scalar field.
assert(RecordIdx < Vals.size() && "Invalid abbrev/record");

// O3DE Change Start
if (WriteConstantCallback &&
Vals[0] == bitc::CST_CODE_INTEGER &&
Op.getEncoding() == BitCodeAbbrevOp::VBR) {
uint64_t SCBitOffset = (uint64_t)Out.size_in_bytes() * 8 + CurBit;
uint64_t SCVal = Vals[RecordIdx];
if (Vals[RecordIdx] & 1) {
SCVal = -(SCVal >> 1);
} else {
SCVal = SCVal >> 1;
}

WriteConstantCallback(SCVal, SCBitOffset);
}
// O3DE Change End
EmitAbbreviatedField(Op, Vals[RecordIdx]);
++RecordIdx;
}
Expand Down
7 changes: 5 additions & 2 deletions include/llvm/Bitcode/ReaderWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
// O3DE change start
#include "llvm/Bitcode/BitstreamWriter.h"
// O3DE change end
#include <memory>
#include <string>

namespace llvm {
class BitstreamWriter;
class DataStreamer;
class LLVMContext;
class Module;
Expand Down Expand Up @@ -69,7 +71,8 @@ namespace llvm {
/// Value in \c M. These will be reconstructed exactly when \a M is
/// deserialized.
void WriteBitcodeToFile(const Module *M, raw_ostream &Out,
bool ShouldPreserveUseListOrder = false);
bool ShouldPreserveUseListOrder = false,
BitstreamWriter::ConstantHandlerFn WriteCallback = nullptr); // O3DE change

/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
/// for an LLVM IR bitcode wrapper.
Expand Down
6 changes: 5 additions & 1 deletion lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2494,7 +2494,8 @@ static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer,
/// WriteBitcodeToFile - Write the specified module to the specified output
/// stream.
void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
bool ShouldPreserveUseListOrder) {
bool ShouldPreserveUseListOrder,
BitstreamWriter::ConstantHandlerFn WriteCallback) { // O3DE change
SmallVector<char, 0> Buffer;
Buffer.reserve(256*1024);

Expand All @@ -2507,6 +2508,9 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
// Emit the module into the buffer.
{
BitstreamWriter Stream(Buffer);
// O3DE change start
Stream.WriteConstantCallback = WriteCallback;
// O3DE change end

// Emit the file header.
Stream.Emit((unsigned)'B', 8);
Expand Down
2 changes: 2 additions & 0 deletions lib/DxcSupport/HLSLOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,8 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
Args.hasFlag(OPT_fspv_reduce_load_size, OPT_INVALID, false);
opts.SpirvOptions.fixFuncCallArguments =
Args.hasFlag(OPT_fspv_fix_func_call_arguments, OPT_INVALID, false);
opts.SpirvOptions.disableImageTypeDepthHint =
Args.hasFlag(OPT_fvk_disable_depth_hint, OPT_INVALID, false);
opts.SpirvOptions.autoShiftBindings =
Args.hasFlag(OPT_fvk_auto_shift_bindings, OPT_INVALID, false);
opts.SpirvOptions.finiteMathOnly =
Expand Down
2 changes: 1 addition & 1 deletion tools/clang/include/clang/Lex/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ class Token {
is(tok::kw_sizeof) || is(tok::kw_static_cast) ||
is(tok::kw_template) || is(tok::kw_throw) || is(tok::kw_try) ||
is(tok::kw_typename) || is(tok::kw_union) || is(tok::kw_using) ||
is(tok::kw_virtual) || is(tok::kw_volatile);
is(tok::kw_virtual);
}
// HLSL Change Starts

Expand Down
4 changes: 0 additions & 4 deletions tools/clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4197,10 +4197,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
getLangOpts());
break;
case tok::kw_volatile:
// HLSL Change - volatile is reserved for HLSL
if (getLangOpts().HLSL)
goto HLSLReservedKeyword;
// HLSL Change Ends
isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
getLangOpts());
break;
Expand Down
6 changes: 5 additions & 1 deletion tools/clang/lib/SPIRV/LowerTypeVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,10 @@ LowerTypeVisitor::lowerResourceType(QualType type, SpirvLayoutRule rule,
{ // Texture types
spv::Dim dim = {};
bool isArray = {};
// Disable depth hint because of driver issues
ImageType::WithDepth depth = spvOptions.disableImageTypeDepthHint
? ImageType::WithDepth::No
: ImageType::WithDepth::Unknown;
if ((dim = spv::Dim::Dim1D, isArray = false, name == "Texture1D") ||
(dim = spv::Dim::Dim2D, isArray = false, name == "Texture2D") ||
(dim = spv::Dim::Dim3D, isArray = false, name == "Texture3D") ||
Expand Down Expand Up @@ -950,7 +954,7 @@ LowerTypeVisitor::lowerResourceType(QualType type, SpirvLayoutRule rule,
return spvContext.getImageType(
lowerType(getElementType(astContext, sampledType), rule,
/*isRowMajor*/ llvm::None, srcLoc),
dim, ImageType::WithDepth::Unknown, isArray,
dim, depth, isArray,
/*isMultiSampled=*/false, /*sampled=*/ImageType::WithSampler::No,
format);
}
Expand Down
8 changes: 8 additions & 0 deletions tools/clang/lib/SPIRV/SpirvBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1678,6 +1678,14 @@ SpirvVariable *SpirvBuilder::addStageBuiltinVar(QualType type,
loc, var, spv::Decoration::BuiltIn, {static_cast<uint32_t>(builtin)});
mod->addDecoration(decor);

// If precise is enabled, Position is additionally decorated with Invariant.
if (isPrecise && builtin == spv::BuiltIn::Position)
{
auto *invariantDecor = new (context) SpirvDecoration(
loc, var, spv::Decoration::Invariant);
mod->addDecoration(invariantDecor);
}

// Add variable to cache.
builtinVars.emplace_back(storageClass, builtin, var);

Expand Down
2 changes: 1 addition & 1 deletion tools/clang/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ endif()

# HLSL Change Begin
# Explicitly overriding check-clang dependencies for HLSL
set(CLANG_TEST_DEPS dxc dxa dxopt dxl dxv dxr dxcompiler clang-tblgen llvm-config opt FileCheck count not ClangUnitTests)
set(CLANG_TEST_DEPS dxc dxsc dxa dxopt dxl dxv dxr dxcompiler clang-tblgen llvm-config opt FileCheck count not ClangUnitTests)
if (WIN32)
list(APPEND CLANG_TEST_DEPS
dxc_batch ExecHLSLTests dxildll
Expand Down
18 changes: 18 additions & 0 deletions tools/clang/test/CodeGenSPIRV/o3de.disable-depth-hint.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %dxc -T ps_6_0 -E main -spirv -fcgl %s | FileCheck %s --check-prefix=DEFAULT
// RUN: %dxc -T ps_6_0 -E main -spirv -fcgl -fvk-disable-depth-hint %s | FileCheck %s --check-prefix=DISABLED

// DEFAULT-DAG: OpTypeImage %float 2D 2 0 0 2 Rgba32f
// DEFAULT-DAG: OpTypeImage %float 2D 2 0 0 1 Unknown

// DISABLED-DAG: OpTypeImage %float 2D 0 0 0 2 Rgba32f
// DISABLED-DAG: OpTypeImage %float 2D 2 0 0 1 Unknown

RWTexture2D<float4> outputTexture : register(u0);
Texture2D<float4> inputTexture : register(t0);

float4 main(float2 uv : TEXCOORD) : SV_Target {
const uint2 location = uint2(uv);
const float4 value = inputTexture.Load(int3(location, 0));
outputTexture[location] = value;
return value;
}
21 changes: 21 additions & 0 deletions tools/clang/test/CodeGenSPIRV/o3de.precise-position-invariant.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %dxc -T vs_6_0 -E main -spirv -fcgl -DPRECISE_POSITION %s | FileCheck %s --check-prefix=PRECISE
// RUN: %dxc -T vs_6_0 -E main -spirv -fcgl %s | FileCheck %s --check-prefix=DEFAULT

// PRECISE: OpDecorate %gl_Position BuiltIn Position
// PRECISE-NEXT: OpDecorate %gl_Position Invariant

// DEFAULT: OpDecorate %gl_Position BuiltIn Position
// DEFAULT-NOT: OpDecorate %gl_Position Invariant

struct VertexOutput {
#ifdef PRECISE_POSITION
precise
#endif
float4 position : SV_Position;
};

VertexOutput main(float3 position : POSITION) {
VertexOutput output;
output.position = float4(position, 1.0);
return output;
}
93 changes: 93 additions & 0 deletions tools/clang/test/DXC/Inputs/verify_dxsc_offsets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env python3

import json
import pathlib
import sys


BITS_PER_GROUP = 8
PAYLOAD_BITS_PER_GROUP = 7
VBR_GROUP_COUNT = 5


def get_bit(data, bit_offset):
return (data[bit_offset // 8] >> (bit_offset % 8)) & 1


def set_bit(data, bit_offset, value):
mask = 1 << (bit_offset % 8)
byte_offset = bit_offset // 8
if value:
data[byte_offset] |= mask
else:
data[byte_offset] &= ~mask


def read_vbr32(data, bit_offset):
encoded = 0
encoded_bit = 0
current = bit_offset
for group in range(VBR_GROUP_COUNT):
for _ in range(PAYLOAD_BITS_PER_GROUP):
encoded |= get_bit(data, current) << encoded_bit
current += 1
encoded_bit += 1
continuation = get_bit(data, current)
current += 1
expected_continuation = group != VBR_GROUP_COUNT - 1
if continuation != expected_continuation:
raise ValueError(
"unexpected VBR continuation bit at group {}".format(group))
return encoded >> 1


def write_vbr32(data, bit_offset, value):
encoded = value << 1
current = bit_offset
for group in range(VBR_GROUP_COUNT):
for _ in range(PAYLOAD_BITS_PER_GROUP):
set_bit(data, current, encoded & 1)
encoded >>= 1
current += 1
set_bit(data, current, group != VBR_GROUP_COUNT - 1)
current += 1


def main():
if len(sys.argv) < 6:
raise ValueError(
"usage: verify_dxsc_offsets.py INPUT OFFSETS OUTPUT SENTINEL "
"ID=VALUE ID=VALUE [ID=VALUE ...]")

input_path = pathlib.Path(sys.argv[1])
offsets_path = pathlib.Path(sys.argv[2])
output_path = pathlib.Path(sys.argv[3])
sentinel = int(sys.argv[4], 0)
patches = {
int(shader_id): int(value, 0)
for shader_id, value in (item.split("=", 1) for item in sys.argv[5:])
}

offsets_json = json.loads(offsets_path.read_text(encoding="utf-8"))
offsets = {int(shader_id): int(offset) for shader_id, offset in offsets_json.items()}
if set(offsets) != set(patches):
raise ValueError(
"expected specialization IDs {}, found {}".format(
sorted(patches), sorted(offsets)))

bytecode = bytearray(input_path.read_bytes())
for shader_id, replacement in patches.items():
bit_offset = offsets[shader_id]
original = read_vbr32(bytecode, bit_offset)
expected = sentinel + shader_id
if original != expected:
raise ValueError(
"specialization ID {} points to {:#x}, expected {:#x}".format(
shader_id, original, expected))
write_vbr32(bytecode, bit_offset, replacement)

output_path.write_bytes(bytecode)


if __name__ == "__main__":
main()
45 changes: 45 additions & 0 deletions tools/clang/test/DXC/dxsc-specialization-constants.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// RUN: %dxc -T ps_6_0 -E main -Fo %t.dxil -Fc %t.ll %s
// RUN: FileCheck %s --check-prefix=MARKERS < %t.ll
// RUN: %dxsc -sv=1164413184 -o=%t.patched.dxil -f=%t.offsets.json %t.dxil | FileCheck %s --check-prefix=DXSC
// RUN: %dxc -dumpbin %t.patched.dxil | FileCheck %s --check-prefix=SENTINELS
// RUN: python %S/Inputs/verify_dxsc_offsets.py %t.patched.dxil %t.offsets.json %t.tampered.dxil 0x45678900 0=42 255=17
// RUN: %dxv %t.tampered.dxil -o %t.resigned.dxil | FileCheck %s --check-prefix=VALIDATED
// RUN: %dxc -dumpbin %t.resigned.dxil | FileCheck %s --check-prefix=PATCHED
// RUN: not %dxsc -sv=1164413184 -o=%t.missing-input.dxil -f=%t.missing-input.json 2>&1 | FileCheck %s --check-prefix=MISSING-INPUT
// RUN: not %dxsc -o=%t.missing-sentinel.dxil -f=%t.missing-sentinel.json %t.dxil 2>&1 | FileCheck %s --check-prefix=MISSING-SENTINEL
// RUN: %dxsc --help 2>&1 | FileCheck %s --check-prefix=HELP

// MARKERS-DAG: store volatile i32 0
// MARKERS-DAG: store volatile i32 255
// MARKERS-DAG: load volatile i32

// DXSC: Specialized Constants Patching succeeded.

// SENTINELS-DAG: i32 1164413184
// SENTINELS-DAG: i32 1164413439

// VALIDATED: Validation succeeded.

// PATCHED-DAG: i32 42
// PATCHED-DAG: i32 17

// MISSING-INPUT: dxsc: error: missing input DXIL file
// MISSING-SENTINEL: dxsc: error: missing -sv sentinel value

// HELP: OVERVIEW: dxsc patching
// HELP: -sv=<int>

int GetSpecializationConstant_Zero() {
volatile int sc_Zero = 0;
return sc_Zero;
}

int GetSpecializationConstant_Max() {
volatile int sc_Max = 255;
return sc_Max;
}

int2 main() : SV_Target {
return int2(GetSpecializationConstant_Zero(),
GetSpecializationConstant_Max());
}
2 changes: 1 addition & 1 deletion tools/clang/test/HLSL/cpp-errors-hv2015.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct s_with_friend {
};

typedef int (*fn_int_const)(int) const; // expected-error {{expected ';' after top level declarator}} expected-error {{pointers are unsupported in HLSL}} expected-warning {{declaration does not declare anything}}
typedef int (*fn_int_volatile)(int) volatile; // expected-error {{'volatile' is a reserved keyword in HLSL}} expected-error {{expected ';' after top level declarator}} expected-error {{pointers are unsupported in HLSL}} expected-warning {{declaration does not declare anything}}
typedef int (*fn_int_volatile)(int) volatile; // expected-error {{expected ';' after top level declarator}} expected-error {{pointers are unsupported in HLSL}} expected-warning {{declaration does not declare anything}}

void fn_throw() throw() { } // expected-error {{exception specification is unsupported in HLSL}}

Expand Down
3 changes: 1 addition & 2 deletions tools/clang/test/HLSL/cpp-errors.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ _Bool g_Bool; // expected-error {{unknown type name '_Bool'}}
_vector int altivec_vector; // expected-error {{expected unqualified-id}} expected-error {{unknown type name '_vector'}}

restrict int g_restrict; // expected-error {{expected unqualified-id}} expected-error {{unknown type name 'restrict'}}
volatile int g_volatile; // expected-error {{'volatile' is a reserved keyword in HLSL}}

__underlying_type(int) g_underlying_type; // expected-error {{__underlying_type is unsupported in HLSL}}
_Atomic(something) g_Atomic; // expected-error {{'_Atomic' is a reserved keyword in HLSL}} expected-error {{HLSL requires a type specifier for all declarations}}
Expand All @@ -57,7 +56,7 @@ struct s_with_friend {
};

typedef int (*fn_int_const)(int) const; // expected-error {{expected ';' after top level declarator}} expected-error {{pointers are unsupported in HLSL}} expected-warning {{declaration does not declare anything}}
typedef int (*fn_int_volatile)(int) volatile; // expected-error {{'volatile' is a reserved keyword in HLSL}} expected-error {{expected ';' after top level declarator}} expected-error {{pointers are unsupported in HLSL}} expected-warning {{declaration does not declare anything}}
typedef int (*fn_int_volatile)(int) volatile; // expected-error {{expected ';' after top level declarator}} expected-error {{pointers are unsupported in HLSL}} expected-warning {{declaration does not declare anything}}

void fn_throw() throw() { } // expected-error {{exception specification is unsupported in HLSL}}

Expand Down
Loading