Skip to content
Open
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
100 changes: 100 additions & 0 deletions mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,64 @@ def DXSA_SystemValueNameAttr :
let assemblyFormat = "`<` $value `>`";
}

def DXSA_ResourceDimension_Buffer : I32EnumAttrCase<"buffer", 1>;
def DXSA_ResourceDimension_Texture1D : I32EnumAttrCase<"texture1d", 2>;
def DXSA_ResourceDimension_Texture2D : I32EnumAttrCase<"texture2d", 3>;
def DXSA_ResourceDimension_Texture2DMS : I32EnumAttrCase<"texture2dms", 4>;
def DXSA_ResourceDimension_Texture3D : I32EnumAttrCase<"texture3d", 5>;
def DXSA_ResourceDimension_TextureCube : I32EnumAttrCase<"texturecube", 6>;
def DXSA_ResourceDimension_Texture1DArray : I32EnumAttrCase<"texture1darray", 7>;
def DXSA_ResourceDimension_Texture2DArray : I32EnumAttrCase<"texture2darray", 8>;
def DXSA_ResourceDimension_Texture2DMSArray : I32EnumAttrCase<"texture2dmsarray", 9>;
def DXSA_ResourceDimension_TextureCubeArray : I32EnumAttrCase<"texturecubearray", 10>;

def DXSA_ResourceDimension : I32EnumAttr<
"ResourceDimension", "input resource dimension", [
DXSA_ResourceDimension_Buffer,
DXSA_ResourceDimension_Texture1D,
DXSA_ResourceDimension_Texture2D,
DXSA_ResourceDimension_Texture2DMS,
DXSA_ResourceDimension_Texture3D,
DXSA_ResourceDimension_TextureCube,
DXSA_ResourceDimension_Texture1DArray,
DXSA_ResourceDimension_Texture2DArray,
DXSA_ResourceDimension_Texture2DMSArray,
DXSA_ResourceDimension_TextureCubeArray
]> {
let cppNamespace = "::mlir::dxsa";
let genSpecializedAttr = 0;
}

def DXSA_ResourceDimensionAttr :
EnumAttr<DXSADialect, DXSA_ResourceDimension, "resource_dimension"> {
let assemblyFormat = "$value";
}

// `float` is a reserved C++ keyword, so the symbolic (C++ enum case) names use
// PascalCase while the printable asm form stays lowercase.
def DXSA_ResourceReturnType_Unorm : I32EnumAttrCase<"Unorm", 1, "unorm">;
def DXSA_ResourceReturnType_Snorm : I32EnumAttrCase<"Snorm", 2, "snorm">;
def DXSA_ResourceReturnType_Sint : I32EnumAttrCase<"Sint", 3, "sint">;
def DXSA_ResourceReturnType_Uint : I32EnumAttrCase<"Uint", 4, "uint">;
def DXSA_ResourceReturnType_Float : I32EnumAttrCase<"Float", 5, "float">;

def DXSA_ResourceReturnType : I32EnumAttr<
"ResourceReturnType", "input resource per-component return type", [
DXSA_ResourceReturnType_Unorm,
DXSA_ResourceReturnType_Snorm,
DXSA_ResourceReturnType_Sint,
DXSA_ResourceReturnType_Uint,
DXSA_ResourceReturnType_Float
]> {
let cppNamespace = "::mlir::dxsa";
let genSpecializedAttr = 0;
}

def DXSA_ResourceReturnTypeAttr :
EnumAttr<DXSADialect, DXSA_ResourceReturnType, "resource_return_type"> {
let assemblyFormat = "$value";
}

//===----------------------------------------------------------------------===//
// DXSA ComponentMask bit-enum (mask field of operand, normalized to bits 0..3)
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -922,4 +980,46 @@ def DXSA_DclTgsmStructured : DXSA_Op<"dcl_tgsm_structured"> {
let hasVerifier = 1;
}

def DXSA_DclResource : DXSA_Op<"dcl_resource"> {
let summary = "declares a shader input resource bound to a register";
let description = [{
The `dxsa.dcl_resource` operation declares a shader input resource
bound to a register.

Example:

```mlir
dxsa.dcl_resource <id = 0>, <dim = buffer>,
<x = unorm, y = snorm, z = sint, w = uint>
dxsa.dcl_resource <id = 5>, <dim = texture2dms, sample_count = 4>,
<x = float, y = float, z = float, w = float>
dxsa.dcl_resource <id = 0, lbound = 0, ubound = 3, space = 1>,
<dim = texture3d>, <x = float, y = float, z = float, w = float>
```
}];

let arguments = (ins
I32Attr:$id,
DXSA_ResourceDimensionAttr:$dim,
DXSA_ResourceReturnTypeAttr:$x,
DXSA_ResourceReturnTypeAttr:$y,
DXSA_ResourceReturnTypeAttr:$z,
DXSA_ResourceReturnTypeAttr:$w,
OptionalAttr<ConfinedAttr<I32Attr,
[IntPositive, IntMaxValue<127>]>>:$sample_count,
OptionalAttr<I32Attr>:$lbound,
OptionalAttr<I32Attr>:$ubound,
OptionalAttr<I32Attr>:$space);
let assemblyFormat = [{
` ` `<` `id` `=` $id
(`,` `lbound` `=` $lbound^ `,` `ubound` `=` $ubound
`,` `space` `=` $space)? `>` `,`
`<` `dim` `=` $dim
(`,` `sample_count` `=` $sample_count^)? `>` `,`
`<` `x` `=` $x `,` `y` `=` $y `,` `z` `=` $z `,` `w` `=` $w `>`
attr-dict
}];
let hasVerifier = 1;
}

#endif // DXSA_OPS
19 changes: 19 additions & 0 deletions mlir/lib/Dialect/DXSA/IR/DXSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@ LogicalResult DclTgsmStructured::verify() {
return success();
}

LogicalResult DclResource::verify() {
auto dim = getDim();
bool isMultisampled = dim == ResourceDimension::texture2dms ||
dim == ResourceDimension::texture2dmsarray;
if (isMultisampled && !getSampleCount())
return emitOpError("missing sample_count for multisampled dimension ")
<< stringifyResourceDimension(dim);
if (!isMultisampled && getSampleCount())
return emitOpError("sample_count is only valid for texture2dms and "
"texture2dmsarray, got ")
<< stringifyResourceDimension(dim);
auto lbound = getLbound();
auto ubound = getUbound();
if (lbound && ubound && *lbound > *ubound)
return emitOpError("expected lbound <= ubound, got lbound=")
<< *lbound << ", ubound=" << *ubound;
return success();
}

//===----------------------------------------------------------------------===//
// TableGen'd attribute method definitions
//===----------------------------------------------------------------------===//
Expand Down
84 changes: 84 additions & 0 deletions mlir/lib/Target/DXSA/BinaryParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,20 @@ class DXBuilder {
builder.getI32IntegerAttr(structCount));
}

Instruction buildDclResource(
uint32_t id, dxsa::ResourceDimension dim, dxsa::ResourceReturnType x,
dxsa::ResourceReturnType y, dxsa::ResourceReturnType z,
dxsa::ResourceReturnType w, std::optional<uint32_t> sampleCount,
std::optional<uint32_t> lbound, std::optional<uint32_t> ubound,
std::optional<uint32_t> space, Location loc) {
auto toAttr = [&](std::optional<uint32_t> v) -> IntegerAttr {
return v ? builder.getI32IntegerAttr(*v) : IntegerAttr();
};
return dxsa::DclResource::create(builder, loc, id, dim, x, y, z, w,
toAttr(sampleCount), toAttr(lbound),
toAttr(ubound), toAttr(space));
}

private:
MLIRContext *context;
ModuleOp module;
Expand Down Expand Up @@ -1317,6 +1331,73 @@ class Parser {
*structCount, loc);
}

FailureOr<dxsa::ResourceReturnType>
parseResourceReturnType(uint32_t returnTypeToken, uint32_t component,
Location loc) {
auto rawReturnType =
DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(returnTypeToken, component);
auto returnType = dxsa::symbolizeResourceReturnType(rawReturnType);
if (!returnType)
return emitError(loc, "unknown resource return type: ") << rawReturnType;
return *returnType;
}

FailureOr<Instruction> parseDclResource(uint32_t opcodeToken, Location loc) {
auto rawDim = DECODE_D3D10_SB_RESOURCE_DIMENSION(opcodeToken);
auto dim = dxsa::symbolizeResourceDimension(rawDim);
if (!dim)
return emitError(loc, "unknown resource dimension: ") << rawDim;

std::optional<uint32_t> sampleCount;
if (*dim == dxsa::ResourceDimension::texture2dms ||
*dim == dxsa::ResourceDimension::texture2dmsarray) {
auto rawSampleCount = DECODE_D3D10_SB_RESOURCE_SAMPLE_COUNT(opcodeToken);
if (rawSampleCount == 0)
return emitError(loc, "sample count must be non-zero for multisampled "
"dimension ")
<< dxsa::stringifyResourceDimension(*dim);
sampleCount = rawSampleCount;
}

auto operand = parseInlineOperand();
FAILURE_IF_FAILED(operand);
if (operand->getType() != dxsa::InlineOperandType::resource)
return emitError(loc, "operand must be a resource register, got ")
<< dxsa::stringifyInlineOperandType(operand->getType());
auto indexArray = operand->getIndex();
auto indexDim = indexArray ? indexArray.size() : 0;
if (indexDim != 1 && indexDim != 3)
return emitError(loc, "operand must have a 1D or 3D index, got ")
<< indexDim;
auto id = indexArray[0];
std::optional<uint32_t> lbound, ubound;
if (indexDim == 3) {
lbound = indexArray[1];
ubound = indexArray[2];
}

auto returnTypeToken = parseToken();
FAILURE_IF_FAILED(returnTypeToken);
auto x = parseResourceReturnType(*returnTypeToken, 0, loc);
FAILURE_IF_FAILED(x);
auto y = parseResourceReturnType(*returnTypeToken, 1, loc);
FAILURE_IF_FAILED(y);
auto z = parseResourceReturnType(*returnTypeToken, 2, loc);
FAILURE_IF_FAILED(z);
auto w = parseResourceReturnType(*returnTypeToken, 3, loc);
FAILURE_IF_FAILED(w);

std::optional<uint32_t> space;
if (indexDim == 3) {
auto spaceToken = parseToken();
FAILURE_IF_FAILED(spaceToken);
space = *spaceToken;
}

return builder.buildDclResource(id, *dim, *x, *y, *z, *w, sampleCount,
lbound, ubound, space, loc);
}

OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc,
Instruction &out) {
FailureOr<Instruction> result;
Expand Down Expand Up @@ -1393,6 +1474,9 @@ class Parser {
case D3D11_SB_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED:
result = parseDclTgsmStructured(loc);
break;
case D3D10_SB_OPCODE_DCL_RESOURCE:
result = parseDclResource(opcodeToken, loc);
break;
default:
return std::nullopt;
}
Expand Down
15 changes: 15 additions & 0 deletions mlir/test/Target/DXSA/dcl_resource.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_resource.bin | FileCheck %s

// CHECK: module {
// CHECK-NEXT: dxsa.dcl_resource <id = 0>, <dim = buffer>, <x = unorm, y = snorm, z = sint, w = uint>
// CHECK-NEXT: dxsa.dcl_resource <id = 1>, <dim = texture1d>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 2>, <dim = texture1darray>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 3>, <dim = texture2d>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 4>, <dim = texture2darray>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 5>, <dim = texture2dms, sample_count = 4>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 6>, <dim = texture2dmsarray, sample_count = 8>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 7>, <dim = texture3d>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 8>, <dim = texturecube>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 9>, <dim = texturecubearray>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: dxsa.dcl_resource <id = 0, lbound = 0, ubound = 3, space = 1>, <dim = texture3d>, <x = float, y = float, z = float, w = float>
// CHECK-NEXT: }
64 changes: 64 additions & 0 deletions mlir/test/Target/DXSA/dcl_resource_invalid.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// RUN: mlir-opt %s -split-input-file -verify-diagnostics

// expected-error@+1 {{'dxsa.dcl_resource' op missing sample_count for multisampled dimension texture2dms}}
dxsa.dcl_resource <id = 0>, <dim = texture2dms>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op missing sample_count for multisampled dimension texture2dmsarray}}
dxsa.dcl_resource <id = 0>, <dim = texture2dmsarray>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got buffer}}
dxsa.dcl_resource <id = 0>, <dim = buffer, sample_count = 4>, <x = unorm, y = snorm, z = sint, w = uint>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture1d}}
dxsa.dcl_resource <id = 0>, <dim = texture1d, sample_count = 4>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture1darray}}
dxsa.dcl_resource <id = 0>, <dim = texture1darray, sample_count = 4>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture2d}}
dxsa.dcl_resource <id = 0>, <dim = texture2d, sample_count = 4>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture2darray}}
dxsa.dcl_resource <id = 0>, <dim = texture2darray, sample_count = 4>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture3d}}
dxsa.dcl_resource <id = 0>, <dim = texture3d, sample_count = 4>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texturecube}}
dxsa.dcl_resource <id = 0>, <dim = texturecube, sample_count = 4>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texturecubearray}}
dxsa.dcl_resource <id = 0>, <dim = texturecubearray, sample_count = 4>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{attribute 'sample_count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 127}}
dxsa.dcl_resource <id = 0>, <dim = texture2dms, sample_count = 0>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{attribute 'sample_count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 127}}
dxsa.dcl_resource <id = 0>, <dim = texture2dms, sample_count = 128>, <x = float, y = float, z = float, w = float>

// -----

// expected-error@+1 {{'dxsa.dcl_resource' op expected lbound <= ubound, got lbound=5, ubound=3}}
dxsa.dcl_resource <id = 0, lbound = 5, ubound = 3, space = 1>, <dim = buffer>, <x = float, y = float, z = float, w = float>
Binary file added mlir/test/Target/DXSA/inputs/dcl_resource.bin
Binary file not shown.