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
229 changes: 229 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,85 @@ 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";
}

def DXSA_UAVFlags_GloballyCoherent : I32BitEnumAttrCaseBit<"globallyCoherent", 0>;
def DXSA_UAVFlags_RasterizerOrdered : I32BitEnumAttrCaseBit<"rasterizerOrdered", 1>;
def DXSA_UAVFlags_HasOrderPreservingCounter : I32BitEnumAttrCaseBit<"hasOrderPreservingCounter", 2>;

def DXSA_UAVFlags : I32BitEnumAttr<
"UAVFlags", "UAV access flags", [
DXSA_UAVFlags_GloballyCoherent,
DXSA_UAVFlags_RasterizerOrdered,
DXSA_UAVFlags_HasOrderPreservingCounter
]> {
let separator = "|";
let cppNamespace = "::mlir::dxsa";
let genSpecializedAttr = 0;
let printBitEnumPrimaryGroups = 1;
}

def DXSA_UAVFlagsAttr :
EnumAttr<DXSADialect, DXSA_UAVFlags, "uav_flags"> {
let assemblyFormat = "$value";
}

//===----------------------------------------------------------------------===//
// DXSA ComponentMask bit-enum (mask field of operand, normalized to bits 0..3)
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -922,4 +1001,154 @@ 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;
}

def DXSA_DclUavTyped : DXSA_Op<"dcl_uav_typed"> {
let summary = "declares a typed UnorderedAccessView (UAV) for use by a shader";
let description = [{
The `dxsa.dcl_uav_typed` operation declares a typed UnorderedAccessView (UAV) for use by a shader.

Example:

```mlir
dxsa.dcl_uav_typed <id = 0, dim = buffer>,
<x = unorm, y = snorm, z = sint, w = uint>
dxsa.dcl_uav_typed <id = 1, dim = texture2d>,
<x = float, y = float, z = float, w = float>,
<flags = globallyCoherent>
dxsa.dcl_uav_typed <id = 0, dim = texture3d,
lbound = 0, ubound = 3, space = 1>,
<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<DXSA_UAVFlagsAttr>:$flags,
OptionalAttr<I32Attr>:$lbound,
OptionalAttr<I32Attr>:$ubound,
OptionalAttr<I32Attr>:$space);
let assemblyFormat = [{
` ` `<` `id` `=` $id `,` `dim` `=` $dim
(`,` `lbound` `=` $lbound^ `,` `ubound` `=` $ubound
`,` `space` `=` $space)? `>` `,`
`<` `x` `=` $x `,` `y` `=` $y `,` `z` `=` $z `,` `w` `=` $w `>`
(`,` `<` `flags` `=` $flags^ `>`)?
attr-dict
}];
let hasVerifier = 1;
}

def DXSA_DclUavRaw : DXSA_Op<"dcl_uav_raw"> {
let summary = "declares a raw UnorderedAccessView (UAV) for use by a shader";
let description = [{
The `dxsa.dcl_uav_raw` operation declares a raw UnorderedAccessView (UAV) for use by a shader.

Example:

```mlir
dxsa.dcl_uav_raw <id = 0>
dxsa.dcl_uav_raw <id = 1>, <flags = globallyCoherent>
dxsa.dcl_uav_raw <id = 0, lbound = 0, ubound = 3, space = 1>
```
}];

let arguments = (ins
I32Attr:$id,
OptionalAttr<DXSA_UAVFlagsAttr>:$flags,
OptionalAttr<I32Attr>:$lbound,
OptionalAttr<I32Attr>:$ubound,
OptionalAttr<I32Attr>:$space);
let assemblyFormat = [{
` ` `<` `id` `=` $id
(`,` `lbound` `=` $lbound^ `,` `ubound` `=` $ubound
`,` `space` `=` $space)? `>`
(`,` `<` `flags` `=` $flags^ `>`)?
attr-dict
}];
let hasVerifier = 1;
}

def DXSA_DclUavStructured : DXSA_Op<"dcl_uav_structured"> {
let summary = "declares a structured UnorderedAccessView (UAV) for use by a shader";
let description = [{
The `dxsa.dcl_uav_structured` operation declares a structured UnorderedAccessView (UAV) for use by a shader.

`$struct_byte_stride` is the structure size in bytes; it must be a
multiple of 4.

Example:

```mlir
dxsa.dcl_uav_structured <id = 0, struct_byte_stride = 16>
dxsa.dcl_uav_structured <id = 1, struct_byte_stride = 32>,
<flags = globallyCoherent|hasOrderPreservingCounter>
dxsa.dcl_uav_structured <id = 0, struct_byte_stride = 32,
lbound = 0, ubound = 3, space = 1>
```
}];

let arguments = (ins
I32Attr:$id,
ConfinedAttr<I32Attr, [IntPositive]>:$struct_byte_stride,
OptionalAttr<DXSA_UAVFlagsAttr>:$flags,
OptionalAttr<I32Attr>:$lbound,
OptionalAttr<I32Attr>:$ubound,
OptionalAttr<I32Attr>:$space);
let assemblyFormat = [{
` ` `<` `id` `=` $id
`,` `struct_byte_stride` `=` $struct_byte_stride
(`,` `lbound` `=` $lbound^ `,` `ubound` `=` $ubound
`,` `space` `=` $space)? `>`
(`,` `<` `flags` `=` $flags^ `>`)?
attr-dict
}];
let hasVerifier = 1;
}

#endif // DXSA_OPS
69 changes: 69 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,75 @@ 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();
}

static LogicalResult verifyUavRange(Operation *op,
std::optional<uint32_t> lbound,
std::optional<uint32_t> ubound) {
if (lbound && ubound && *lbound > *ubound)
return op->emitOpError("expected lbound <= ubound, got lbound=")
<< *lbound << ", ubound=" << *ubound;
return success();
}

static LogicalResult
verifyNoOrderPreservingCounter(Operation *op, std::optional<UAVFlags> flags) {
if (flags && bitEnumContainsAny(*flags, UAVFlags::hasOrderPreservingCounter))
return op->emitOpError(
"hasOrderPreservingCounter flag is only valid for dcl_uav_structured");
return success();
}

LogicalResult DclUavTyped::verify() {
auto dim = getDim();
switch (dim) {
case ResourceDimension::buffer:
case ResourceDimension::texture1d:
case ResourceDimension::texture1darray:
case ResourceDimension::texture2d:
case ResourceDimension::texture2darray:
case ResourceDimension::texture3d:
break;
default:
return emitOpError("invalid dimension for typed UAV: ")
<< stringifyResourceDimension(dim);
}
if (failed(verifyNoOrderPreservingCounter(*this, getFlags())))
return failure();
return verifyUavRange(*this, getLbound(), getUbound());
}

LogicalResult DclUavRaw::verify() {
if (failed(verifyNoOrderPreservingCounter(*this, getFlags())))
return failure();
return verifyUavRange(*this, getLbound(), getUbound());
}

LogicalResult DclUavStructured::verify() {
auto stride = getStructByteStride();
if (stride % 4 != 0)
return emitOpError("struct byte stride must be a multiple of 4, got ")
<< stride;
return verifyUavRange(*this, getLbound(), getUbound());
}

//===----------------------------------------------------------------------===//
// TableGen'd attribute method definitions
//===----------------------------------------------------------------------===//
Expand Down
Loading