Skip to content

Commit 5130ff9

Browse files
committed
[mlir][dxsa] Add dcl_resource instruction
Example: 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> Signed-off-by: Vladimir Shiryaev <tagolog@users.noreply.github.com>
1 parent 534a8b0 commit 5130ff9

6 files changed

Lines changed: 276 additions & 0 deletions

File tree

mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,64 @@ def DXSA_SystemValueNameAttr :
255255
let assemblyFormat = "`<` $value `>`";
256256
}
257257

258+
def DXSA_ResourceDimension_Buffer : I32EnumAttrCase<"buffer", 1>;
259+
def DXSA_ResourceDimension_Texture1D : I32EnumAttrCase<"texture1d", 2>;
260+
def DXSA_ResourceDimension_Texture2D : I32EnumAttrCase<"texture2d", 3>;
261+
def DXSA_ResourceDimension_Texture2DMS : I32EnumAttrCase<"texture2dms", 4>;
262+
def DXSA_ResourceDimension_Texture3D : I32EnumAttrCase<"texture3d", 5>;
263+
def DXSA_ResourceDimension_TextureCube : I32EnumAttrCase<"texturecube", 6>;
264+
def DXSA_ResourceDimension_Texture1DArray : I32EnumAttrCase<"texture1darray", 7>;
265+
def DXSA_ResourceDimension_Texture2DArray : I32EnumAttrCase<"texture2darray", 8>;
266+
def DXSA_ResourceDimension_Texture2DMSArray : I32EnumAttrCase<"texture2dmsarray", 9>;
267+
def DXSA_ResourceDimension_TextureCubeArray : I32EnumAttrCase<"texturecubearray", 10>;
268+
269+
def DXSA_ResourceDimension : I32EnumAttr<
270+
"ResourceDimension", "input resource dimension", [
271+
DXSA_ResourceDimension_Buffer,
272+
DXSA_ResourceDimension_Texture1D,
273+
DXSA_ResourceDimension_Texture2D,
274+
DXSA_ResourceDimension_Texture2DMS,
275+
DXSA_ResourceDimension_Texture3D,
276+
DXSA_ResourceDimension_TextureCube,
277+
DXSA_ResourceDimension_Texture1DArray,
278+
DXSA_ResourceDimension_Texture2DArray,
279+
DXSA_ResourceDimension_Texture2DMSArray,
280+
DXSA_ResourceDimension_TextureCubeArray
281+
]> {
282+
let cppNamespace = "::mlir::dxsa";
283+
let genSpecializedAttr = 0;
284+
}
285+
286+
def DXSA_ResourceDimensionAttr :
287+
EnumAttr<DXSADialect, DXSA_ResourceDimension, "resource_dimension"> {
288+
let assemblyFormat = "$value";
289+
}
290+
291+
// `float` is a reserved C++ keyword, so the symbolic (C++ enum case) names use
292+
// PascalCase while the printable asm form stays lowercase.
293+
def DXSA_ResourceReturnType_Unorm : I32EnumAttrCase<"Unorm", 1, "unorm">;
294+
def DXSA_ResourceReturnType_Snorm : I32EnumAttrCase<"Snorm", 2, "snorm">;
295+
def DXSA_ResourceReturnType_Sint : I32EnumAttrCase<"Sint", 3, "sint">;
296+
def DXSA_ResourceReturnType_Uint : I32EnumAttrCase<"Uint", 4, "uint">;
297+
def DXSA_ResourceReturnType_Float : I32EnumAttrCase<"Float", 5, "float">;
298+
299+
def DXSA_ResourceReturnType : I32EnumAttr<
300+
"ResourceReturnType", "input resource per-component return type", [
301+
DXSA_ResourceReturnType_Unorm,
302+
DXSA_ResourceReturnType_Snorm,
303+
DXSA_ResourceReturnType_Sint,
304+
DXSA_ResourceReturnType_Uint,
305+
DXSA_ResourceReturnType_Float
306+
]> {
307+
let cppNamespace = "::mlir::dxsa";
308+
let genSpecializedAttr = 0;
309+
}
310+
311+
def DXSA_ResourceReturnTypeAttr :
312+
EnumAttr<DXSADialect, DXSA_ResourceReturnType, "resource_return_type"> {
313+
let assemblyFormat = "$value";
314+
}
315+
258316
//===----------------------------------------------------------------------===//
259317
// DXSA ComponentMask bit-enum (mask field of operand, normalized to bits 0..3)
260318
//===----------------------------------------------------------------------===//
@@ -1072,4 +1130,46 @@ def DXSA_DclStream : DXSA_Op<"dcl_stream"> {
10721130
let assemblyFormat = [{ $index attr-dict }];
10731131
}
10741132

1133+
def DXSA_DclResource : DXSA_Op<"dcl_resource"> {
1134+
let summary = "declares a shader input resource bound to a register";
1135+
let description = [{
1136+
The `dxsa.dcl_resource` operation declares a shader input resource
1137+
bound to a register.
1138+
1139+
Example:
1140+
1141+
```mlir
1142+
dxsa.dcl_resource <id = 0>, <dim = buffer>,
1143+
<x = unorm, y = snorm, z = sint, w = uint>
1144+
dxsa.dcl_resource <id = 5>, <dim = texture2dms, sample_count = 4>,
1145+
<x = float, y = float, z = float, w = float>
1146+
dxsa.dcl_resource <id = 0, lbound = 0, ubound = 3, space = 1>,
1147+
<dim = texture3d>, <x = float, y = float, z = float, w = float>
1148+
```
1149+
}];
1150+
1151+
let arguments = (ins
1152+
I32Attr:$id,
1153+
DXSA_ResourceDimensionAttr:$dim,
1154+
DXSA_ResourceReturnTypeAttr:$x,
1155+
DXSA_ResourceReturnTypeAttr:$y,
1156+
DXSA_ResourceReturnTypeAttr:$z,
1157+
DXSA_ResourceReturnTypeAttr:$w,
1158+
OptionalAttr<ConfinedAttr<I32Attr,
1159+
[IntPositive, IntMaxValue<127>]>>:$sample_count,
1160+
OptionalAttr<I32Attr>:$lbound,
1161+
OptionalAttr<I32Attr>:$ubound,
1162+
OptionalAttr<I32Attr>:$space);
1163+
let assemblyFormat = [{
1164+
` ` `<` `id` `=` $id
1165+
(`,` `lbound` `=` $lbound^ `,` `ubound` `=` $ubound
1166+
`,` `space` `=` $space)? `>` `,`
1167+
`<` `dim` `=` $dim
1168+
(`,` `sample_count` `=` $sample_count^)? `>` `,`
1169+
`<` `x` `=` $x `,` `y` `=` $y `,` `z` `=` $z `,` `w` `=` $w `>`
1170+
attr-dict
1171+
}];
1172+
let hasVerifier = 1;
1173+
}
1174+
10751175
#endif // DXSA_OPS

mlir/lib/Dialect/DXSA/IR/DXSA.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ LogicalResult DclSampler::verify() {
102102
return success();
103103
}
104104

105+
LogicalResult DclResource::verify() {
106+
auto dim = getDim();
107+
bool isMultisampled = dim == ResourceDimension::texture2dms ||
108+
dim == ResourceDimension::texture2dmsarray;
109+
if (isMultisampled && !getSampleCount())
110+
return emitOpError("missing sample_count for multisampled dimension ")
111+
<< stringifyResourceDimension(dim);
112+
if (!isMultisampled && getSampleCount())
113+
return emitOpError("sample_count is only valid for texture2dms and "
114+
"texture2dmsarray, got ")
115+
<< stringifyResourceDimension(dim);
116+
}
117+
105118
//===----------------------------------------------------------------------===//
106119
// TableGen'd attribute method definitions
107120
//===----------------------------------------------------------------------===//

mlir/lib/Target/DXSA/BinaryParser.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,20 @@ class DXBuilder {
733733
optionalToAttr(space));
734734
}
735735

736+
Instruction buildDclResource(
737+
uint32_t id, dxsa::ResourceDimension dim, dxsa::ResourceReturnType x,
738+
dxsa::ResourceReturnType y, dxsa::ResourceReturnType z,
739+
dxsa::ResourceReturnType w, std::optional<uint32_t> sampleCount,
740+
std::optional<uint32_t> lbound, std::optional<uint32_t> ubound,
741+
std::optional<uint32_t> space, Location loc) {
742+
auto toAttr = [&](std::optional<uint32_t> v) -> IntegerAttr {
743+
return v ? builder.getI32IntegerAttr(*v) : IntegerAttr();
744+
};
745+
return dxsa::DclResource::create(builder, loc, id, dim, x, y, z, w,
746+
toAttr(sampleCount), toAttr(lbound),
747+
toAttr(ubound), toAttr(space));
748+
}
749+
736750
private:
737751
MLIRContext *context;
738752
ModuleOp module;
@@ -1476,6 +1490,73 @@ class Parser {
14761490
return builder.buildDclSampler(id, lbound, ubound, space, *mode, loc);
14771491
}
14781492

1493+
FailureOr<dxsa::ResourceReturnType>
1494+
parseResourceReturnType(uint32_t returnTypeToken, uint32_t component,
1495+
Location loc) {
1496+
auto rawReturnType =
1497+
DECODE_D3D10_SB_RESOURCE_RETURN_TYPE(returnTypeToken, component);
1498+
auto returnType = dxsa::symbolizeResourceReturnType(rawReturnType);
1499+
if (!returnType)
1500+
return emitError(loc, "unknown resource return type: ") << rawReturnType;
1501+
return *returnType;
1502+
}
1503+
1504+
FailureOr<Instruction> parseDclResource(uint32_t opcodeToken, Location loc) {
1505+
auto rawDim = DECODE_D3D10_SB_RESOURCE_DIMENSION(opcodeToken);
1506+
auto dim = dxsa::symbolizeResourceDimension(rawDim);
1507+
if (!dim)
1508+
return emitError(loc, "unknown resource dimension: ") << rawDim;
1509+
1510+
std::optional<uint32_t> sampleCount;
1511+
if (*dim == dxsa::ResourceDimension::texture2dms ||
1512+
*dim == dxsa::ResourceDimension::texture2dmsarray) {
1513+
auto rawSampleCount = DECODE_D3D10_SB_RESOURCE_SAMPLE_COUNT(opcodeToken);
1514+
if (rawSampleCount == 0)
1515+
return emitError(loc, "sample count must be non-zero for multisampled "
1516+
"dimension ")
1517+
<< dxsa::stringifyResourceDimension(*dim);
1518+
sampleCount = rawSampleCount;
1519+
}
1520+
1521+
auto operand = parseInlineOperand();
1522+
FAILURE_IF_FAILED(operand);
1523+
if (operand->getType() != dxsa::InlineOperandType::resource)
1524+
return emitError(loc, "operand must be a resource register, got ")
1525+
<< dxsa::stringifyInlineOperandType(operand->getType());
1526+
auto indexArray = operand->getIndex();
1527+
auto indexDim = indexArray ? indexArray.size() : 0;
1528+
if (indexDim != 1 && indexDim != 3)
1529+
return emitError(loc, "operand must have a 1D or 3D index, got ")
1530+
<< indexDim;
1531+
auto id = indexArray[0];
1532+
std::optional<uint32_t> lbound, ubound;
1533+
if (indexDim == 3) {
1534+
lbound = indexArray[1];
1535+
ubound = indexArray[2];
1536+
}
1537+
1538+
auto returnTypeToken = parseToken();
1539+
FAILURE_IF_FAILED(returnTypeToken);
1540+
auto x = parseResourceReturnType(*returnTypeToken, 0, loc);
1541+
FAILURE_IF_FAILED(x);
1542+
auto y = parseResourceReturnType(*returnTypeToken, 1, loc);
1543+
FAILURE_IF_FAILED(y);
1544+
auto z = parseResourceReturnType(*returnTypeToken, 2, loc);
1545+
FAILURE_IF_FAILED(z);
1546+
auto w = parseResourceReturnType(*returnTypeToken, 3, loc);
1547+
FAILURE_IF_FAILED(w);
1548+
1549+
std::optional<uint32_t> space;
1550+
if (indexDim == 3) {
1551+
auto spaceToken = parseToken();
1552+
FAILURE_IF_FAILED(spaceToken);
1553+
space = *spaceToken;
1554+
}
1555+
1556+
return builder.buildDclResource(id, *dim, *x, *y, *z, *w, sampleCount,
1557+
lbound, ubound, space, loc);
1558+
}
1559+
14791560
OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc,
14801561
Instruction &out) {
14811562
FailureOr<Instruction> result;
@@ -1567,6 +1648,9 @@ class Parser {
15671648
case D3D10_SB_OPCODE_DCL_SAMPLER:
15681649
result = parseDclSampler(opcodeToken, loc);
15691650
break;
1651+
case D3D10_SB_OPCODE_DCL_RESOURCE:
1652+
result = parseDclResource(opcodeToken, loc);
1653+
break;
15701654
default:
15711655
return std::nullopt;
15721656
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_resource.bin | FileCheck %s
2+
3+
// CHECK: module {
4+
// CHECK-NEXT: dxsa.dcl_resource <id = 0>, <dim = buffer>, <x = unorm, y = snorm, z = sint, w = uint>
5+
// CHECK-NEXT: dxsa.dcl_resource <id = 1>, <dim = texture1d>, <x = float, y = float, z = float, w = float>
6+
// CHECK-NEXT: dxsa.dcl_resource <id = 2>, <dim = texture1darray>, <x = float, y = float, z = float, w = float>
7+
// CHECK-NEXT: dxsa.dcl_resource <id = 3>, <dim = texture2d>, <x = float, y = float, z = float, w = float>
8+
// CHECK-NEXT: dxsa.dcl_resource <id = 4>, <dim = texture2darray>, <x = float, y = float, z = float, w = float>
9+
// CHECK-NEXT: dxsa.dcl_resource <id = 5>, <dim = texture2dms, sample_count = 4>, <x = float, y = float, z = float, w = float>
10+
// CHECK-NEXT: dxsa.dcl_resource <id = 6>, <dim = texture2dmsarray, sample_count = 8>, <x = float, y = float, z = float, w = float>
11+
// CHECK-NEXT: dxsa.dcl_resource <id = 7>, <dim = texture3d>, <x = float, y = float, z = float, w = float>
12+
// CHECK-NEXT: dxsa.dcl_resource <id = 8>, <dim = texturecube>, <x = float, y = float, z = float, w = float>
13+
// CHECK-NEXT: dxsa.dcl_resource <id = 9>, <dim = texturecubearray>, <x = float, y = float, z = float, w = float>
14+
// CHECK-NEXT: dxsa.dcl_resource <id = 0, lbound = 0, ubound = 3, space = 1>, <dim = texture3d>, <x = float, y = float, z = float, w = float>
15+
// CHECK-NEXT: }
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: mlir-opt %s -split-input-file -verify-diagnostics
2+
3+
// expected-error@+1 {{'dxsa.dcl_resource' op missing sample_count for multisampled dimension texture2dms}}
4+
dxsa.dcl_resource <id = 0>, <dim = texture2dms>, <x = float, y = float, z = float, w = float>
5+
6+
// -----
7+
8+
// expected-error@+1 {{'dxsa.dcl_resource' op missing sample_count for multisampled dimension texture2dmsarray}}
9+
dxsa.dcl_resource <id = 0>, <dim = texture2dmsarray>, <x = float, y = float, z = float, w = float>
10+
11+
// -----
12+
13+
// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got buffer}}
14+
dxsa.dcl_resource <id = 0>, <dim = buffer, sample_count = 4>, <x = unorm, y = snorm, z = sint, w = uint>
15+
16+
// -----
17+
18+
// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture1d}}
19+
dxsa.dcl_resource <id = 0>, <dim = texture1d, sample_count = 4>, <x = float, y = float, z = float, w = float>
20+
21+
// -----
22+
23+
// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture1darray}}
24+
dxsa.dcl_resource <id = 0>, <dim = texture1darray, sample_count = 4>, <x = float, y = float, z = float, w = float>
25+
26+
// -----
27+
28+
// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture2d}}
29+
dxsa.dcl_resource <id = 0>, <dim = texture2d, sample_count = 4>, <x = float, y = float, z = float, w = float>
30+
31+
// -----
32+
33+
// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture2darray}}
34+
dxsa.dcl_resource <id = 0>, <dim = texture2darray, sample_count = 4>, <x = float, y = float, z = float, w = float>
35+
36+
// -----
37+
38+
// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texture3d}}
39+
dxsa.dcl_resource <id = 0>, <dim = texture3d, sample_count = 4>, <x = float, y = float, z = float, w = float>
40+
41+
// -----
42+
43+
// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texturecube}}
44+
dxsa.dcl_resource <id = 0>, <dim = texturecube, sample_count = 4>, <x = float, y = float, z = float, w = float>
45+
46+
// -----
47+
48+
// expected-error@+1 {{'dxsa.dcl_resource' op sample_count is only valid for texture2dms and texture2dmsarray, got texturecubearray}}
49+
dxsa.dcl_resource <id = 0>, <dim = texturecubearray, sample_count = 4>, <x = float, y = float, z = float, w = float>
50+
51+
// -----
52+
53+
// expected-error@+1 {{attribute 'sample_count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 127}}
54+
dxsa.dcl_resource <id = 0>, <dim = texture2dms, sample_count = 0>, <x = float, y = float, z = float, w = float>
55+
56+
// -----
57+
58+
// expected-error@+1 {{attribute 'sample_count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 127}}
59+
dxsa.dcl_resource <id = 0>, <dim = texture2dms, sample_count = 128>, <x = float, y = float, z = float, w = float>
60+
61+
// -----
62+
63+
// expected-error@+1 {{'dxsa.dcl_resource' op expected lbound <= ubound, got lbound=5, ubound=3}}
64+
dxsa.dcl_resource <id = 0, lbound = 5, ubound = 3, space = 1>, <dim = buffer>, <x = float, y = float, z = float, w = float>
188 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)