diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAResourceOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAResourceOps.td index f1a401e107e8..e73ef4c04357 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAResourceOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAResourceOps.td @@ -76,4 +76,432 @@ def DXSA_EvalSnapped : DXSA_BinaryOp<"eval_snapped"> { }]; } +//===----------------------------------------------------------------------===// +// dxsa.sample +//===----------------------------------------------------------------------===// + +def DXSA_SampleOffsetAttr : AttrDef { + let mnemonic = "sample_offset"; + let summary = "immediate offset for the texture coordinates for the sample"; + let description = [{ + The dxsa.sample_offset attribute indicates that the texture coordinates for + the sample are to be offset by a set of provided immediate texel space + integer constant values. The literal values are a set of 4 bit 2's + complement numbers, having integer range [-8,7]. + }]; + let parameters = (ins "int32_t":$u, "int32_t":$v, "int32_t":$w); + let assemblyFormat = "`<` struct(params) `>`"; + let genVerifyDecl = 1; +} + +def DXSA_SampleClampFeedbackAttr : AttrDef { + let mnemonic = "sample_clamp_feedback"; + let summary = "optional LOD clamp and Tiled Resources shader feedback status output value"; + let description = [{ + The dxsa.sample_clamp_feed attribute is an optional pair of operands for + dxsa.sample instruction. + + `lod_clamp` is an additional 32 bit scalar LOD clamp operand. + + `feedback` is a shader feedback status output value. The contents + of the return value are opaque - direct reading by the shader + program is disallowed. + }]; + + let parameters = (ins + AttrParameter<"SrcOperandAttr", "lod_clamp">:$lod_clamp, + AttrParameter<"DstOperandAttr", "feedback">:$feedback); + + let assemblyFormat = "`<` $lod_clamp `,` $feedback `>`"; +} + +def DXSA_Sample : DXSA_Op<"sample"> { + let summary = "sample data from the specified texture using the filtering mode identified by the given sampler"; + let description = [{ + The dxsa.sample operation uses provided address, sample data from the + specified Element/texture using the filtering mode identified by the given + sampler. The source data may come from any Resource Type (5), other than + Buffers. + + `src_address` provides the set of texture coordinates needed to perform the + sample, as floating point values referencing normalized space in the texture. + + `src_resource` is a texture register (t). This is simply a + placeholder for a texture, including the return data type of the + resource being sampled. + + `src_sampler` is a sampler register (s). This is simply a + placeholder for a collection of filtering controls (such as point + vs. linear, mipmapping and address wrapping controls). + + The optional `offset` operand suffix (address offset by immediate + integer) indicates that the texture coordinates for the sample are + to be offset by a set of provided immediate texel space integer + constant values. The literal values are a set of 4 bit 2's + complement numbers, having integer range [-8,7]. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler + (`,` $offset^)? + attr-dict + }]; +} + +def DXSA_SampleClampFeedback : DXSA_Op<"sample_cl_s"> { + let summary = "same as `dxsa.sample`, but with an additional LOD clamp and status output"; + let description = [{ + `src_address`, `src_resource`, `src_sampler`, `offset` operands + are the same as in `dxsa.sample` instruction. + + The `clamp_feedback` operand appends an additional 32 bit scalar + LOD clamp operand and an additional 32 bit scalar Tiled Resources + shader feedback status output value. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SampleClampFeedbackAttr:$clamp_feedback, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $clamp_feedback + (`,` $offset^)? + attr-dict + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.sample_b +//===----------------------------------------------------------------------===// + +def DXSA_SampleB : DXSA_Op<"sample_b"> { + let summary = "sample data from the specified texture with an additional bias applied to the LOD"; + let description = [{ + The `dxsa.sample_b` operation uses provided address, sample data from the + specified Element/texture using the filtering mode identified by the given + sampler. The source data may come from any Resource Type(5), other than + Buffers. An additional bias is applied to the level of detail computed as + part of the instruction execution. + + `src_address`, `src_resource`, `src_sampler` and `offset` operands + are the same as in `dxsa.sample` instruction. + + The `src_lod_bias` value is added to the computed LOD on a per-pixel basis, + along with the sampler MipLODBias value, prior to the clamp to MinLOD and + MaxLOD. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_lod_bias, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $src_lod_bias + (`,` $offset^)? + attr-dict + }]; +} + +def DXSA_SampleBClampFeedback : DXSA_Op<"sample_b_cl_s"> { + let summary = "same as `dxsa.sample_b`, but with an additional LOD clamp and status output"; + let description = [{ + `src_address`, `src_resource`, `src_sampler`, `src_lod_bias` and + `offset` operands are the same as in `dxsa.sample_b` instruction. + + The `clamp_feedback` operand appends an additional 32 bit scalar + LOD clamp operand and an additional 32 bit scalar Tiled Resources + shader feedback status output value. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_lod_bias, + DXSA_SampleClampFeedbackAttr:$clamp_feedback, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $src_lod_bias `,` $clamp_feedback + (`,` $offset^)? + attr-dict + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.sample_d +//===----------------------------------------------------------------------===// + +def DXSA_SampleD : DXSA_Op<"sample_d"> { + let summary = "sample data from the specified texture with derivatives for X and Y"; + let description = [{ + The `dxsa.sample_d` operation uses provided address, sample data from the + specified Element/texture using the filtering mode identified by the given + sampler. The source data may come from any Resource Type(5), other than + Buffers. + + `src_address`, `src_resource`, `src_sampler` and `offset` operands + are the same as in `dxsa.sample` instruction. + + Derivatives for the source address in the x direction and the y direction are + provided by extra parameters, `src_x_derivatives` and `src_y_derivatives`, + respectively. These derivatives are in normalized texture coordinate space. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_x_derivatives, + DXSA_SrcOperandAttr:$src_y_derivatives, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler + `,` $src_x_derivatives `,` $src_y_derivatives + (`,` $offset^)? + attr-dict + }]; +} + +def DXSA_SampleDClampFeedback : DXSA_Op<"sample_d_cl_s"> { + let summary = "same as `dxsa.sample_d`, but with an additional LOD clamp and status output"; + let description = [{ + `dst`, `src`_address, `src`_resource, `src`_sampler, + `src`_x_derivatives, `src`_y_derivatives and `offset` operands are + the same as in `dxsa.sample_d` instruction. + + The `clamp_feedback` operand appends an additional 32 bit scalar + LOD clamp operand and an additional 32 bit scalar Tiled Resources + shader feedback status output value. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_x_derivatives, + DXSA_SrcOperandAttr:$src_y_derivatives, + DXSA_SampleClampFeedbackAttr:$clamp_feedback, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler + `,` $src_x_derivatives `,` $src_y_derivatives `,` $clamp_feedback + (`,` $offset^)? + attr-dict + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.sample_l +//===----------------------------------------------------------------------===// + +def DXSA_SampleL : DXSA_Op<"sample_l"> { + let summary = "sample data from the specified texture with specific LOD"; + let description = [{ + `dxsa.sample_l` is identical to `dxsa.sample`, except that LOD is provided + directly by the application as a scalar value, representing no anisotropy. + + `src_address`, `src_resource`, `src_sampler` and `offset` operands + are the same as in `dxsa.sample` instruction. + + `src_lod` is the LOD value. If the LOD value is <= 0, the zero'th (biggest + map) is chosen, with the magnify filter applied (if applicable based on the + filter mode). Since `src_lod` is a floating point value, the fractional + value is used to interpolate (if the minify filter is LINEAR or with + anisotropic filtering) between two mip levels. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_lod, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $src_lod + (`,` $offset^)? + attr-dict + }]; +} + +def DXSA_SampleLFeedback : DXSA_Op<"sample_l_cl_s"> { + let summary = "same as `dxsa.sample_l`, but with an additional LOD clamp and status output"; + let description = [{ + `dst`, `src_address`, `src_resource`,`src_sampler`, `src_lod` and + `offset` operands are the same as in `dxsa.sample_l` instruction. + + The `clamp_feedback` operand appends an additional 32 bit scalar + LOD clamp operand and an additional 32 bit scalar Tiled Resources + shader feedback status output value. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_lod, + DXSA_DstOperandAttr:$feedback, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $src_lod `,` $feedback + (`,` $offset^)? + attr-dict + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.sample_c +//===----------------------------------------------------------------------===// + +def DXSA_SampleC : DXSA_Op<"sample_c"> { + let summary = "perform a comparison filter"; + let description = [{ + `dxsa.sample_c` is to provide a building-block for Percentage-Closer Depth + filtering. The 'c' in sample_c stands for Comparison. + + The operands to `dxsa.sample_c` are identical to `dxsa.sample`, except that + there is an additional float32 source operand, `src_reference_value`, which + must be a register with single-component selected, or a scalar literal. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_reference_value, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $src_reference_value + (`,` $offset^)? + attr-dict + }]; +} + +def DXSA_SampleCClampFeedback : DXSA_Op<"sample_c_cl_s"> { + let summary = "same as `dxsa.sample_c`, but with an additional LOD clamp and status output"; + let description = [{ + `dst`,`src_address`,`src_resource`,`src_sampler`,`src_reference_value` + and `offset operands are the same as in `dxsa.sample_c` + instruction. + + The `clamp_feedback` operand appends an additional 32 bit scalar + LOD clamp operand and an additional 32 bit scalar Tiled Resources + shader feedback status output value. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_reference_value, + DXSA_SampleClampFeedbackAttr:$clamp_feedback, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $src_reference_value `,` $clamp_feedback + (`,` $offset^)? + attr-dict + }]; +} + +//===----------------------------------------------------------------------===// +// dxsa.sample_c_lz +//===----------------------------------------------------------------------===// + +def DXSA_SampleCLZ : DXSA_Op<"sample_c_lz"> { + let summary = "perform a comparison filter with zero LOD"; + let description = [{ + Same as `dxsa.sample_c`, except LOD is 0, and derivatives are ignored (as if + they are 0). The 'lz' stands for level-zero. Because derivatives are + ignored, this instruction is available in shaders other than the Pixel + Shader. + + `dxsa.sample_c` is to provide a building-block for Percentage-Closer Depth + filtering. The 'c' in sample_c stands for Comparison. + + The operands to `dxsa.sample_c_lz` are identical to `dxsa.sample_c`. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_reference_value, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $src_reference_value + (`,` $offset^)? + attr-dict + }]; +} + +def DXSA_SampleCLZFeedback : DXSA_Op<"sample_c_lz_s"> { + let summary = "same as `dxsa.sample_c_lz`, but with an additional LOD clamp and status output"; + let description = [{ + `dst`, `src_address`, `src_resource`, `src_sampler`, + `src_reference_value`, `offset` operands are the same as in + `dxsa.sample` instruction. + + The `clamp_feedback` operand appends an additional 32 bit scalar + LOD clamp operand and an additional 32 bit scalar Tiled Resources + shader feedback status output value. + }]; + + let arguments = (ins + DXSA_DstOperandAttr:$dst, + DXSA_SrcOperandAttr:$src_address, + DXSA_SrcOperandAttr:$src_resource, + DXSA_SrcOperandAttr:$src_sampler, + DXSA_SrcOperandAttr:$src_reference_value, + DXSA_SampleClampFeedbackAttr:$feedback, + OptionalAttr:$offset); + let results = (outs); + + let assemblyFormat = [{ + $dst `,` $src_address `,` $src_resource `,` $src_sampler `,` $src_reference_value `,` $feedback + (`,` $offset^)? + attr-dict + }]; +} + #endif // MLIR_DIALECT_DXSA_IR_DXSARESOURCEOPS diff --git a/mlir/lib/Dialect/DXSA/IR/DXSAOperand.cpp b/mlir/lib/Dialect/DXSA/IR/DXSAOperand.cpp index 9208efaa6cf4..8027465af4c7 100644 --- a/mlir/lib/Dialect/DXSA/IR/DXSAOperand.cpp +++ b/mlir/lib/Dialect/DXSA/IR/DXSAOperand.cpp @@ -991,3 +991,18 @@ void SrcOperandAttr::print(AsmPrinter &printer) const { printNegAndAbsModifier(printer, getModifier(), [&] { printSrcOperandBody(printer, *this); }); } + +LogicalResult +SampleOffsetAttr::verify(function_ref emitError, + int32_t u, int32_t v, int32_t w) { + int32_t values[] = {u, v, w}; + for (int32_t value : values) { + if (value < -8 || value > 7) { + return emitError() + << "sample offsets must be 4 bit 2's complement numbers, " + "having integer range [-8,7], got " + << value; + } + } + return success(); +} diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index 7910d7acc105..b641df41ccab 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -390,6 +390,30 @@ struct InstructionModifier { // Whether an op carries a precise modifier attribute. enum class HasPreciseAttr { No, Yes }; +struct ExtendedInstructionSampleOffset { + int32_t u; + int32_t v; + int32_t w; +}; + +struct ExtendedInstructionResourceDim { + uint32_t dim; + std::optional stride; +}; + +struct ExtendedInstructionResourceReturnType { + uint32_t x; + uint32_t y; + uint32_t z; + uint32_t w; +}; + +struct ExtendedInstruction { + std::optional sampleOffset; + std::optional resourceDim; + std::optional resourceReturnType; +}; + struct OperandModifier { uint32_t modifier{0}; uint32_t minPrecision{0}; @@ -1006,6 +1030,144 @@ class DXBuilder { builder.getI32IntegerAttr(y), builder.getI32IntegerAttr(z)); } + dxsa::SampleOffsetAttr + buildSampleOffsetAttr(const ExtendedInstructionSampleOffset &sampleOffset) { + return dxsa::SampleOffsetAttr::get(context, sampleOffset.u, sampleOffset.v, + sampleOffset.w); + } + + dxsa::SampleClampFeedbackAttr + buildSampleClampFeedbackAttr(dxsa::SrcOperandAttr clamp, + dxsa::DstOperandAttr feedback) { + return dxsa::SampleClampFeedbackAttr::get(context, clamp, feedback); + } + + Instruction buildSample(dxsa::DstOperandAttr dst, + dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, + dxsa::SrcOperandAttr srcSampler, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::Sample::create(builder, loc, dst, srcAddress, srcResource, + srcSampler, offset); + } + + Instruction buildSampleClampFeedback( + dxsa::DstOperandAttr dst, dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, dxsa::SrcOperandAttr srcSampler, + dxsa::SampleClampFeedbackAttr clampFeedback, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleClampFeedback::create(builder, loc, dst, srcAddress, + srcResource, srcSampler, + clampFeedback, offset); + } + + Instruction buildSampleB(dxsa::DstOperandAttr dst, + dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, + dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcLodBias, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleB::create(builder, loc, dst, srcAddress, srcResource, + srcSampler, srcLodBias, offset); + } + + Instruction buildSampleBClampFeedback( + dxsa::DstOperandAttr dst, dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcLodBias, + dxsa::SampleClampFeedbackAttr clampFeedback, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleBClampFeedback::create( + builder, loc, dst, srcAddress, srcResource, srcSampler, srcLodBias, + clampFeedback, offset); + } + + Instruction buildSampleD(dxsa::DstOperandAttr dst, + dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, + dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcXDerivatives, + dxsa::SrcOperandAttr srcYDerivatives, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleD::create(builder, loc, dst, srcAddress, srcResource, + srcSampler, srcXDerivatives, srcYDerivatives, + offset); + } + + Instruction buildSampleDClampFeedback( + dxsa::DstOperandAttr dst, dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcXDerivatives, + dxsa::SrcOperandAttr srcYDerivatives, + dxsa::SampleClampFeedbackAttr clampFeedback, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleDClampFeedback::create( + builder, loc, dst, srcAddress, srcResource, srcSampler, srcXDerivatives, + srcYDerivatives, clampFeedback, offset); + } + + Instruction buildSampleL(dxsa::DstOperandAttr dst, + dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, + dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcLod, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleL::create(builder, loc, dst, srcAddress, srcResource, + srcSampler, srcLod, offset); + } + + Instruction buildSampleLFeedback( + dxsa::DstOperandAttr dst, dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcLod, dxsa::DstOperandAttr feedback, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleLFeedback::create(builder, loc, dst, srcAddress, + srcResource, srcSampler, srcLod, + feedback, offset); + } + + Instruction buildSampleC(dxsa::DstOperandAttr dst, + dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, + dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcReferenceValue, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleC::create(builder, loc, dst, srcAddress, srcResource, + srcSampler, srcReferenceValue, offset); + } + + Instruction buildSampleCClampFeedback( + dxsa::DstOperandAttr dst, dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcReferenceValue, + dxsa::SampleClampFeedbackAttr clampFeedback, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleCClampFeedback::create( + builder, loc, dst, srcAddress, srcResource, srcSampler, + srcReferenceValue, clampFeedback, offset); + } + + Instruction buildSampleCLZ(dxsa::DstOperandAttr dst, + dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, + dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcReferenceValue, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleCLZ::create(builder, loc, dst, srcAddress, srcResource, + srcSampler, srcReferenceValue, offset); + } + + Instruction buildSampleCLZFeedback( + dxsa::DstOperandAttr dst, dxsa::SrcOperandAttr srcAddress, + dxsa::SrcOperandAttr srcResource, dxsa::SrcOperandAttr srcSampler, + dxsa::SrcOperandAttr srcReferenceValue, + dxsa::SampleClampFeedbackAttr clampFeedback, + dxsa::SampleOffsetAttr offset, Location loc) { + return dxsa::SampleCLZFeedback::create( + builder, loc, dst, srcAddress, srcResource, srcSampler, + srcReferenceValue, clampFeedback, offset); + } + private: MLIRContext *context; OpBuilder builder; @@ -1745,6 +1907,215 @@ class Parser { return builder.buildGsStreamIndexOp(*index, loc); } + void parseExtendedInstruction(uint32_t extendedToken, + ExtendedInstruction &ext) { + switch (DECODE_D3D10_SB_EXTENDED_OPCODE_TYPE(extendedToken)) { + case D3D10_SB_EXTENDED_OPCODE_EMPTY: + return; + case D3D10_SB_EXTENDED_OPCODE_SAMPLE_CONTROLS: { + auto token = static_cast(extendedToken); + int32_t offsets[3] = { + DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET( + D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_U, token), + DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET( + D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_V, token), + DECODE_IMMEDIATE_D3D10_SB_ADDRESS_OFFSET( + D3D10_SB_IMMEDIATE_ADDRESS_OFFSET_W, token), + }; + for (int32_t &offset : offsets) { + // Sign extend from 4 bits to 32. + if (offset & 0x8) { + offset |= 0xfffffff0; + } + } + ext.sampleOffset = {offsets[0], offsets[1], offsets[2]}; + return; + } + case D3D11_SB_EXTENDED_OPCODE_RESOURCE_DIM: { + auto dim = DECODE_D3D11_SB_EXTENDED_RESOURCE_DIMENSION(extendedToken); + auto stride = + (dim == D3D11_SB_RESOURCE_DIMENSION_STRUCTURED_BUFFER) + ? std::optional( + DECODE_D3D11_SB_EXTENDED_RESOURCE_DIMENSION_STRUCTURE_STRIDE( + extendedToken)) + : std::nullopt; + ext.resourceDim = {dim, stride}; + return; + } + case D3D11_SB_EXTENDED_OPCODE_RESOURCE_RETURN_TYPE: { + ext.resourceReturnType = { + DECODE_D3D11_SB_EXTENDED_RESOURCE_RETURN_TYPE(extendedToken, 0), + DECODE_D3D11_SB_EXTENDED_RESOURCE_RETURN_TYPE(extendedToken, 1), + DECODE_D3D11_SB_EXTENDED_RESOURCE_RETURN_TYPE(extendedToken, 2), + DECODE_D3D11_SB_EXTENDED_RESOURCE_RETURN_TYPE(extendedToken, 3), + }; + return; + } + } + } + + FailureOr parseSampleInstruction(uint32_t opcode, + ExtendedInstruction &ext, + size_t beginOffset, + uint32_t length, Location loc) { + dxsa::SampleOffsetAttr offset; + if (ext.sampleOffset) { + offset = builder.buildSampleOffsetAttr(*ext.sampleOffset); + } + + auto dst = parseDstOperand(); + FAILURE_IF_FAILED(dst); + + dxsa::DstOperandAttr feedback; + switch (opcode) { + case D3DWDDM1_3_SB_OPCODE_SAMPLE_CLAMP_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_D_CLAMP_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_B_CLAMP_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_L_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_CLAMP_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_LZ_FEEDBACK: + auto op = parseDstOperand(); + FAILURE_IF_FAILED(op); + feedback = *op; + break; + } + + auto srcAddress = parseSrcOperand(); + FAILURE_IF_FAILED(srcAddress); + + auto srcResource = parseSrcOperand(); + FAILURE_IF_FAILED(srcResource); + + auto srcSampler = parseSrcOperand(); + FAILURE_IF_FAILED(srcSampler); + + FailureOr instr; + switch (opcode) { + case D3D10_SB_OPCODE_SAMPLE: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_CLAMP_FEEDBACK: { + if (feedback) { + auto clamp = parseSrcOperand(); + FAILURE_IF_FAILED(clamp); + + auto clampFeedback = + builder.buildSampleClampFeedbackAttr(*clamp, feedback); + instr = builder.buildSampleClampFeedback(*dst, *srcAddress, + *srcResource, *srcSampler, + clampFeedback, offset, loc); + } else { + instr = builder.buildSample(*dst, *srcAddress, *srcResource, + *srcSampler, offset, loc); + } + break; + } + case D3D10_SB_OPCODE_SAMPLE_D: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_D_CLAMP_FEEDBACK: { + auto srcXDerivatives = parseSrcOperand(); + FAILURE_IF_FAILED(srcXDerivatives); + + auto srcYDerivatives = parseSrcOperand(); + FAILURE_IF_FAILED(srcYDerivatives); + + if (feedback) { + auto clamp = parseSrcOperand(); + FAILURE_IF_FAILED(clamp); + + auto clampFeedback = + builder.buildSampleClampFeedbackAttr(*clamp, feedback); + instr = builder.buildSampleDClampFeedback( + *dst, *srcAddress, *srcResource, *srcSampler, *srcXDerivatives, + *srcYDerivatives, clampFeedback, offset, loc); + } else { + instr = builder.buildSampleD(*dst, *srcAddress, *srcResource, + *srcSampler, *srcXDerivatives, + *srcYDerivatives, offset, loc); + } + break; + } + case D3D10_SB_OPCODE_SAMPLE_B: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_B_CLAMP_FEEDBACK: { + auto srcLodBias = parseSrcOperand(); + FAILURE_IF_FAILED(srcLodBias); + + if (feedback) { + auto clamp = parseSrcOperand(); + FAILURE_IF_FAILED(clamp); + auto clampFeedback = + builder.buildSampleClampFeedbackAttr(*clamp, feedback); + instr = builder.buildSampleBClampFeedback( + *dst, *srcAddress, *srcResource, *srcSampler, *srcLodBias, + clampFeedback, offset, loc); + } else { + instr = builder.buildSampleB(*dst, *srcAddress, *srcResource, + *srcSampler, *srcLodBias, offset, loc); + } + break; + } + case D3D10_SB_OPCODE_SAMPLE_L: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_L_FEEDBACK: { + auto srcLod = parseSrcOperand(); + FAILURE_IF_FAILED(srcLod); + + if (feedback) { + instr = builder.buildSampleLFeedback(*dst, *srcAddress, *srcResource, + *srcSampler, *srcLod, feedback, + offset, loc); + } else { + instr = builder.buildSampleL(*dst, *srcAddress, *srcResource, + *srcSampler, *srcLod, offset, loc); + } + break; + } + case D3D10_SB_OPCODE_SAMPLE_C: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_CLAMP_FEEDBACK: { + auto srcReferenceValue = parseSrcOperand(); + FAILURE_IF_FAILED(srcReferenceValue); + + if (feedback) { + auto clamp = parseSrcOperand(); + FAILURE_IF_FAILED(clamp); + auto clampFeedback = + builder.buildSampleClampFeedbackAttr(*clamp, feedback); + instr = builder.buildSampleCClampFeedback( + *dst, *srcAddress, *srcResource, *srcSampler, *srcReferenceValue, + clampFeedback, offset, loc); + } else { + instr = + builder.buildSampleC(*dst, *srcAddress, *srcResource, *srcSampler, + *srcReferenceValue, offset, loc); + } + break; + } + case D3D10_SB_OPCODE_SAMPLE_C_LZ: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_LZ_FEEDBACK: { + auto srcReferenceValue = parseSrcOperand(); + FAILURE_IF_FAILED(srcReferenceValue); + + if (feedback) { + auto clamp = parseSrcOperand(); + FAILURE_IF_FAILED(clamp); + auto clampFeedback = + builder.buildSampleClampFeedbackAttr(*clamp, feedback); + + instr = builder.buildSampleCLZFeedback(*dst, *srcAddress, *srcResource, + *srcSampler, *srcReferenceValue, + clampFeedback, offset, loc); + } else { + instr = + builder.buildSampleCLZ(*dst, *srcAddress, *srcResource, *srcSampler, + *srcReferenceValue, offset, loc); + } + break; + } + default: + llvm_unreachable("unhandled instruction"); + } + + FAILURE_IF_FAILED(instr); + FAILURE_IF_FAILED(verifyInstructionLength(beginOffset, length)); + return instr; + } + FailureOr parseDclInput(Location loc) { auto operand = parseDstOperand(); FAILURE_IF_FAILED(operand); @@ -2350,6 +2721,18 @@ class Parser { modifier.saturate = DECODE_IS_D3D10_SB_INSTRUCTION_SATURATE_ENABLED(*opcodeToken0); + ExtendedInstruction extendedInst; + if (DECODE_IS_D3D10_SB_OPCODE_EXTENDED(*opcodeToken0)) { + // opcodeToken0 is followed by zero or more opcodeToken1 that describe + // sampler or resource parameters. + Token opcodeToken1; + do { + opcodeToken1 = parseToken(); + FAILURE_IF_FAILED(opcodeToken1); + parseExtendedInstruction(*opcodeToken1, extendedInst); + } while (DECODE_IS_D3D10_SB_OPCODE_EXTENDED(*opcodeToken1)); + } + // TODO: extended instructions: // BOOL b51PlusShader = // BOOL bExtended = DECODE_IS_D3D10_SB_OPCODE_EXTENDED(Token) @@ -2693,6 +3076,20 @@ class Parser { case D3D11_SB_OPCODE_SYNC: return parseSync(*opcodeToken0, beginOffset, instructionLengthInTokens, getLocation()); + case D3D10_SB_OPCODE_SAMPLE: + case D3D10_SB_OPCODE_SAMPLE_B: + case D3D10_SB_OPCODE_SAMPLE_C: + case D3D10_SB_OPCODE_SAMPLE_C_LZ: + case D3D10_SB_OPCODE_SAMPLE_D: + case D3D10_SB_OPCODE_SAMPLE_L: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_CLAMP_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_B_CLAMP_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_CLAMP_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_C_LZ_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_D_CLAMP_FEEDBACK: + case D3DWDDM1_3_SB_OPCODE_SAMPLE_L_FEEDBACK: + return parseSampleInstruction(opcode, extendedInst, beginOffset, + instructionLengthInTokens, getLocation()); } #undef SATURABLE_OP #undef PLAIN_OP diff --git a/mlir/test/Target/DXSA/sample.test b/mlir/test/Target/DXSA/sample.test new file mode 100644 index 000000000000..a2fcf748a480 --- /dev/null +++ b/mlir/test/Target/DXSA/sample.test @@ -0,0 +1,21 @@ +// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip + +// CHECK: dxsa.sample r<0>, v<0, >, t<3, vector>, s<5> + +0x8b000045, 0x800000c2, 0x00155543, 0x001000f2, +0x00000000, 0x00101046, 0x00000000, 0x00107e46, +0x00000003, 0x00106000, 0x00000005 + +// CHECK: dxsa.sample r<1>, v<0, >, t<3, vector>, s<5>, + +0x8c000045, 0x8000f601, 0x800000c2, 0x00155543, +0x001000f2, 0x00000001, 0x00101046, 0x00000000, +0x00107e46, 0x00000003, 0x00106000, 0x00000005 + +// CHECK: dxsa.sample_cl_s r<1>, v<0, >, t<3, vector>, s<5>, , + +0x8f0000e6, 0x80003801, 0x800000c2, 0x00155543, +0x001000f2, 0x00000001, 0x0000d000, 0x00101046, +0x00000000, 0x00107e46, 0x00000003, 0x00106000, +0x00000005, 0x00004001, 0x3f000000 diff --git a/mlir/test/Target/DXSA/sample_b.test b/mlir/test/Target/DXSA/sample_b.test new file mode 100644 index 000000000000..e7841a1f3335 --- /dev/null +++ b/mlir/test/Target/DXSA/sample_b.test @@ -0,0 +1,17 @@ +// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip + +// CHECK: dxsa.sample_b r<0>, v<0, >, t<3, vector>, s<5>, v<0, > + +0x8d00004a, 0x800000c2, 0x00155543, 0x001000f2, +0x00000000, 0x00101046, 0x00000000, 0x00107e46, +0x00000003, 0x00106000, 0x00000005, 0x0010101a, +0x00000000 + +// CHECK: dxsa.sample_b_cl_s r<1>, v<0, >, t<3, vector>, s<5>, v<0, >, , + +0x910000e7, 0x80003801, 0x800000c2, 0x00155543, +0x001000f2, 0x00000001, 0x0000d000, 0x00101046, +0x00000000, 0x00107e46, 0x00000003, 0x00106000, +0x00000005, 0x0010101a, 0x00000000, 0x00004001, +0x3f000000 diff --git a/mlir/test/Target/DXSA/sample_c.test b/mlir/test/Target/DXSA/sample_c.test new file mode 100644 index 000000000000..245852033a93 --- /dev/null +++ b/mlir/test/Target/DXSA/sample_c.test @@ -0,0 +1,17 @@ +// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip + +// CHECK: dxsa.sample_c r<0, >, v<0, >, t<3, vector, >, s<5>, r<0, > + +0x8d000046, 0x800000c2, 0x00155543, 0x00100022, +0x00000000, 0x00101046, 0x00000000, 0x00107006, +0x00000003, 0x00106000, 0x00000005, 0x0010000a, +0x00000000 + +// CHECK: dxsa.sample_c_cl_s r<1, >, v<0, >, t<3, vector, >, s<5>, r<0, >, , + +0x910000e9, 0x80003801, 0x800000c2, 0x00155543, +0x00100012, 0x00000001, 0x0000d000, 0x00101046, +0x00000000, 0x00107006, 0x00000003, 0x00106000, +0x00000005, 0x0010000a, 0x00000000, 0x00004001, +0x3f000000 diff --git a/mlir/test/Target/DXSA/sample_c_lz.test b/mlir/test/Target/DXSA/sample_c_lz.test new file mode 100644 index 000000000000..0219c6b7962c --- /dev/null +++ b/mlir/test/Target/DXSA/sample_c_lz.test @@ -0,0 +1,17 @@ +// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip + +// CHECK: dxsa.sample_c_lz r<0, >, v<0, >, t<3, vector, >, s<5>, r<0, > + +0x8d000047, 0x800000c2, 0x00155543, 0x00100022, +0x00000000, 0x00101046, 0x00000000, 0x00107006, +0x00000003, 0x00106000, 0x00000005, 0x0010000a, +0x00000000 + +// CHECK: dxsa.sample_c_lz_s r<1, >, v<0, >, t<3, vector, >, s<5>, r<0, >, , + +0x910000e5, 0x80003801, 0x800000c2, 0x00155543, +0x00100012, 0x00000001, 0x0000d000, 0x00101046, +0x00000000, 0x00107006, 0x00000003, 0x00106000, +0x00000005, 0x0010000a, 0x00000000, 0x00004001, +0x3f000000 diff --git a/mlir/test/Target/DXSA/sample_d.test b/mlir/test/Target/DXSA/sample_d.test new file mode 100644 index 000000000000..2f2337c27a4a --- /dev/null +++ b/mlir/test/Target/DXSA/sample_d.test @@ -0,0 +1,17 @@ +// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip + +// CHECK: dxsa.sample_d r<0>, v<0, >, t<3, vector>, s<5>, v<0, >, v<0, > + +0x8f000049, 0x800000c2, 0x00155543, 0x001000f2, +0x00000000, 0x00101046, 0x00000000, 0x00107e46, +0x00000003, 0x00106000, 0x00000005, 0x00101556, +0x00000000, 0x00101516, 0x00000000 + +// CHECK: dxsa.sample_d_cl_s r<1>, v<0, >, t<3, vector>, s<5>, v<0, >, v<0, >, , + +0x930000e8, 0x80003801, 0x800000c2, 0x00155543, +0x001000f2, 0x00000001, 0x0000d000, 0x00101046, +0x00000000, 0x00107e46, 0x00000003, 0x00106000, +0x00000005, 0x00101556, 0x00000000, 0x00101516, +0x00000000, 0x00004001, 0x3f000000 \ No newline at end of file diff --git a/mlir/test/Target/DXSA/sample_l.test b/mlir/test/Target/DXSA/sample_l.test new file mode 100644 index 000000000000..58c677a80d6f --- /dev/null +++ b/mlir/test/Target/DXSA/sample_l.test @@ -0,0 +1,30 @@ +// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip + +// CHECK: dxsa.sample_l r<0>, v<0, >, t<3, vector>, s<5>, v<0, > + +0x8d000048, 0x800000c2, 0x00155543, 0x001000f2, +0x00000000, 0x00101046, 0x00000000, 0x00107e46, +0x00000003, 0x00106000, 0x00000005, 0x0010101a, +0x00000000 + +// CHECK: dxsa.sample_l r<1>, v<0, >, t<3, vector>, s<5>, v<0, >, + +0x8e000048, 0x8000f601, 0x800000c2, 0x00155543, +0x001000f2, 0x00000001, 0x00101046, 0x00000000, +0x00107e46, 0x00000003, 0x00106000, 0x00000005, +0x0010101a, 0x00000000 + +// CHECK: dxsa.sample_l_cl_s r<1>, v<0>, t<5, vector>, s<5>, v<0, >, r<2, > + +0x8f0000e4, 0x80000282, 0x00155543, 0x001000f2, +0x00000001, 0x00100012, 0x00000002, 0x00101e46, +0x00000000, 0x00107e46, 0x00000005, 0x00106000, +0x00000005, 0x0010101a, 0x00000000 + +// CHECK: dxsa.sample_l_cl_s r<1>, v<0, >, t<3, vector>, s<5>, v<0, >, r<2, >, + +0x900000e4, 0x80005a01, 0x800000c2, 0x00155543, +0x001000f2, 0x00000001, 0x00100012, 0x00000002, +0x00101046, 0x00000000, 0x00107e46, 0x00000003, +0x00106000, 0x00000005, 0x0010101a, 0x00000000 diff --git a/mlir/test/Target/DXSA/sample_offset_invalid.mlir b/mlir/test/Target/DXSA/sample_offset_invalid.mlir new file mode 100644 index 000000000000..e9a1cba1fb00 --- /dev/null +++ b/mlir/test/Target/DXSA/sample_offset_invalid.mlir @@ -0,0 +1,29 @@ +// RUN: mlir-opt %s -split-input-file -verify-diagnostics + +// expected-error@+1 {{sample offsets must be 4 bit 2's complement numbers, having integer range [-8,7]}} +dxsa.sample r<1>, v<0, >, t<3, vector>, s<5>, + +// ----- + +// expected-error@+1 {{sample offsets must be 4 bit 2's complement numbers, having integer range [-8,7]}} +dxsa.sample r<1>, v<0, >, t<3, vector>, s<5>, + +// ----- + +// expected-error@+1 {{sample offsets must be 4 bit 2's complement numbers, having integer range [-8,7]}} +dxsa.sample r<1>, v<0, >, t<3, vector>, s<5>, + +// ----- + +// expected-error@+1 {{sample offsets must be 4 bit 2's complement numbers, having integer range [-8,7]}} +dxsa.sample r<1>, v<0, >, t<3, vector>, s<5>, + +// ----- + +// expected-error@+1 {{sample offsets must be 4 bit 2's complement numbers, having integer range [-8,7]}} +dxsa.sample r<1>, v<0, >, t<3, vector>, s<5>, + +// ----- + +// expected-error@+1 {{sample offsets must be 4 bit 2's complement numbers, having integer range [-8,7]}} +dxsa.sample r<1>, v<0, >, t<3, vector>, s<5>,