summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-08-03 15:46:16 -0400
committerGitHub <noreply@github.com>2020-08-03 15:46:16 -0400
commit79ba9279becf480c9d92bb2faaede0e241f0b029 (patch)
tree5e904295c6b0731fdfba0d17ab03ba54d5f92565
parent9ac5c51ae1f0664a9dcb31392894e4f76bdbcf98 (diff)
First pass support for Sampler Feedback (#1470)
* Add the Feedback texture types. Depreciate SLANG_RESOURCE_EXT_SHAPE_MASK. * Starting point to test sampler feedback. * WIP on FeedbackSampler. * Use __target_intrinsic to override the output of sampler feedback types. * Use newer generic syntax for FeedbackTexture. * Reflects Feedback type. * SLANG_TYPE_KIND_TEXTURE_FEEDBACK -> SLANG_TYPE_KIND_FEEDBACK * Added reflection test. * Reneable issue with generics in sampler-feedback-basic.slang * Add methods to FeedbackTexture2D/Array. Make test cover test cases. * Sampler feedback produces DXC code. * Disabled Sampler feedback test - as requires newer version of DXC. * Fix bug in reflection tool output. * Fix problem with direct-spirv-emit.slang.expected due to update to glslang. * Fix direct-spirv-emit.slang * Use SLANG_RESOURCE_EXT_SHAPE_MASK again * Make Feedback be emitted as a textue type prefix. Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
-rw-r--r--slang.h5
-rw-r--r--source/slang/hlsl.meta.slang96
-rw-r--r--source/slang/slang-ast-dump.cpp15
-rw-r--r--source/slang/slang-ast-serialize.cpp5
-rw-r--r--source/slang/slang-ast-type.h16
-rw-r--r--source/slang/slang-emit-cpp.cpp6
-rw-r--r--source/slang/slang-emit-hlsl.cpp7
-rw-r--r--source/slang/slang-ir.h1
-rw-r--r--source/slang/slang-reflection.cpp4
-rw-r--r--source/slang/slang-syntax.cpp8
-rw-r--r--source/slang/slang-type-system-shared.cpp10
-rw-r--r--source/slang/slang-type-system-shared.h7
-rw-r--r--tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang46
-rw-r--r--tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang.expected110
-rw-r--r--tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang.hlsl43
-rw-r--r--tools/slang-reflection-test/slang-reflection-test-main.cpp32
16 files changed, 405 insertions, 6 deletions
diff --git a/slang.h b/slang.h
index fd6655fea..e00b813a8 100644
--- a/slang.h
+++ b/slang.h
@@ -1801,6 +1801,7 @@ extern "C"
SLANG_TYPE_KIND_INTERFACE,
SLANG_TYPE_KIND_OUTPUT_STREAM,
SLANG_TYPE_KIND_SPECIALIZED,
+ SLANG_TYPE_KIND_FEEDBACK,
SLANG_TYPE_KIND_COUNT,
};
@@ -1842,6 +1843,8 @@ extern "C"
SLANG_ACCELERATION_STRUCTURE = 0x09,
SLANG_RESOURCE_EXT_SHAPE_MASK = 0xF0,
+
+ SLANG_TEXTURE_FEEDBACK_FLAG = 0x10,
SLANG_TEXTURE_ARRAY_FLAG = 0x40,
SLANG_TEXTURE_MULTISAMPLE_FLAG = 0x80,
@@ -1862,6 +1865,7 @@ extern "C"
SLANG_RESOURCE_ACCESS_RASTER_ORDERED,
SLANG_RESOURCE_ACCESS_APPEND,
SLANG_RESOURCE_ACCESS_CONSUME,
+ SLANG_RESOURCE_ACCESS_WRITE,
};
typedef unsigned int SlangParameterCategory;
@@ -2205,6 +2209,7 @@ namespace slang
Interface = SLANG_TYPE_KIND_INTERFACE,
OutputStream = SLANG_TYPE_KIND_OUTPUT_STREAM,
Specialized = SLANG_TYPE_KIND_SPECIALIZED,
+ Feedback = SLANG_TYPE_KIND_FEEDBACK,
};
enum ScalarType : SlangScalarType
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 69fc6bea0..b2748c50d 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -3616,6 +3616,8 @@ matrix<T,N,M> WaveMultiPrefixSum(matrix<T,N,M> value, uint4 mask);
// `typedef`s to help with the fact that HLSL has been sorta-kinda case insensitive at various points
typedef Texture2D texture2D;
+
+
${{{{
// Buffer types
@@ -3989,9 +3991,101 @@ void SetMeshOutputCounts(uint vertexCount, uint primitiveCount);
void DispatchMesh<P>(uint threadGroupCountX, uint threadGroupCountY, uint threadGroupCountZ, P meshPayload);
//
-// TODO: "Sampler feedback" types `FeedbackTexture2D` and `FeedbackTexture2DArray`.
+// "Sampler feedback" types `FeedbackTexture2D` and `FeedbackTexture2DArray`.
//
+// https://microsoft.github.io/DirectX-Specs/d3d/SamplerFeedback.html
+
+// The docs describe these as 'types' but their syntax makes them seem enum like, and enum is a simpler way to implement them
+// But slang enums are always 'enum class like', so I use an empty struct type here
+
+[sealed]
+interface __BuiltinSamplerFeedbackType {};
+
+[sealed]
+__magic_type(FeedbackType, $(int(FeedbackType::Kind::MinMip)))
+__target_intrinsic(hlsl, SAMPLER_FEEDBACK_MIN_MIP)
+struct SAMPLER_FEEDBACK_MIN_MIP : __BuiltinSamplerFeedbackType {};
+
+[sealed]
+__magic_type(FeedbackType, $(int(FeedbackType::Kind::MipRegionUsed)))
+__target_intrinsic(hlsl, SAMPLER_FEEDBACK_MIP_REGION_USED)
+struct SAMPLER_FEEDBACK_MIP_REGION_USED : __BuiltinSamplerFeedbackType {};
+
+// All of these objects are write-only resources that point to a special kind of unordered access view meant for sampler feedback.
+
+// Calculate the flavor constants
+${{{{
+static const int feedbackTexture2DFlavor = int(TextureFlavor::create(TextureFlavor::Shape::Shape2D, SLANG_RESOURCE_ACCESS_WRITE, SLANG_TEXTURE_FEEDBACK_FLAG).flavor);
+static const int feedbackTexture2DArrayFlavor = int(TextureFlavor::create(TextureFlavor::Shape::Shape2D, SLANG_RESOURCE_ACCESS_WRITE, SLANG_TEXTURE_FEEDBACK_FLAG | SLANG_TEXTURE_ARRAY_FLAG).flavor);
+}}}}
+
+__magic_type(Texture, $(feedbackTexture2DFlavor))
+__intrinsic_type($(kIROp_TextureType + (feedbackTexture2DFlavor << kIROpMeta_OtherShift)))
+struct FeedbackTexture2D<T : __BuiltinSamplerFeedbackType>
+{
+ // With Clamp
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedback($1, $2, $3, $4)")
+ void WriteSamplerFeedback<S>(Texture2D<S> tex, SamplerState samp, float2 location, float clamp);
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackBias($1, $2, $3, $4, $5)")
+ void WriteSamplerFeedbackBias<S>(Texture2D<S> tex, SamplerState samp, float2 location, float bias, float clamp);
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackGrad($1, $2, $3, $4, $5, $6)")
+ void WriteSamplerFeedbackGrad<S>(Texture2D<S> tex, SamplerState samp, float2 location, float2 ddx, float2 ddy, float clamp);
+
+ // Level
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackLevel($1, $2, $3, $4)")
+ void WriteSamplerFeedbackLevel<S>(Texture2D<S> tex, SamplerState samp, float2 location, float lod);
+
+ // Without Clamp
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedback($1, $2, $3)")
+ void WriteSamplerFeedback<S>(Texture2D<S> tex, SamplerState samp, float2 location);
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackBias($1, $2, $3, $4)")
+ void WriteSamplerFeedbackBias<S>(Texture2D<S> tex, SamplerState samp, float2 location, float bias);
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackGrad($1, $2, $3, $4, $5)")
+ void WriteSamplerFeedbackGrad<S>(Texture2D<S> tex, SamplerState samp, float2 location, float2 ddx, float2 ddy);
+};
+
+
+
+__magic_type(Texture, $(feedbackTexture2DArrayFlavor))
+__intrinsic_type($(kIROp_TextureType + (feedbackTexture2DArrayFlavor << kIROpMeta_OtherShift)))
+struct FeedbackTexture2DArray<T : __BuiltinSamplerFeedbackType>
+{
+ // With Clamp
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedback($1, $2, $3, $4)")
+ void WriteSamplerFeedback<S>(Texture2DArray<S> texArray, SamplerState samp, float3 location, float clamp);
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackBias($1, $2, $3, $4, $5)")
+ void WriteSamplerFeedbackBias<S>(Texture2DArray<S> texArray, SamplerState samp, float3 location, float bias, float clamp);
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackGrad($1, $2, $3, $4, $5, $6)")
+ void WriteSamplerFeedbackGrad<S>(Texture2DArray<S> texArray, SamplerState samp, float3 location, float3 ddx, float3 ddy, float clamp);
+
+ // Level
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackLevel($1, $2, $3, $4)")
+ void WriteSamplerFeedbackLevel<S>(Texture2DArray<S> texArray, SamplerState samp, float3 location, float lod);
+
+ // Without Clamp
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedback($1, $2, $3)")
+ void WriteSamplerFeedback<S>(Texture2DArray<S> texArray, SamplerState samp, float3 location);
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackBias($1, $2, $3, $4)")
+ void WriteSamplerFeedbackBias<S>(Texture2DArray<S> texArray, SamplerState samp, float3 location, float bias);
+
+ __target_intrinsic(hlsl, "($0).WriteSamplerFeedbackGrad($1, $2, $3, $4, $5)")
+ void WriteSamplerFeedbackGrad<S>(Texture2DArray<S> texArray, SamplerState samp, float3 location, float3 ddx, float3 ddy);
+};
+
//
// DXR 1.1 and `TraceRayInline` support
//
diff --git a/source/slang/slang-ast-dump.cpp b/source/slang/slang-ast-dump.cpp
index 16b264f9b..806a9146b 100644
--- a/source/slang/slang-ast-dump.cpp
+++ b/source/slang/slang-ast-dump.cpp
@@ -414,6 +414,21 @@ struct ASTDumpContext
m_writer->emit(m_buf);
}
+ void dump(FeedbackType::Kind kind)
+ {
+ m_buf.Clear();
+ const char* name = nullptr;
+ switch (kind)
+ {
+ case FeedbackType::Kind::MinMip: name = "MinMip"; break;
+ case FeedbackType::Kind::MipRegionUsed: name = "MipRegionUsed"; break;
+ }
+
+ m_buf << "FeedbackType::Kind{" << name << "}";
+ m_writer->emit(m_buf);
+ }
+
+
void dump(SamplerStateFlavor flavor)
{
switch (flavor)
diff --git a/source/slang/slang-ast-serialize.cpp b/source/slang/slang-ast-serialize.cpp
index b1d7ba7e7..141bed368 100644
--- a/source/slang/slang-ast-serialize.cpp
+++ b/source/slang/slang-ast-serialize.cpp
@@ -100,6 +100,11 @@ struct ASTSerialIdentityTypeInfo
template <>
struct ASTSerialTypeInfo<ASTSerialIndex> : public ASTSerialIdentityTypeInfo<ASTSerialIndex> {};
+
+// Because is sized, we don't need to convert
+template <>
+struct ASTSerialTypeInfo<FeedbackType::Kind> : public ASTSerialIdentityTypeInfo<FeedbackType::Kind> {};
+
// Implement for Basic Types
template <>
diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h
index 10fd1ea34..6673fa426 100644
--- a/source/slang/slang-ast-type.h
+++ b/source/slang/slang-ast-type.h
@@ -107,6 +107,19 @@ class BuiltinType : public DeclRefType
SLANG_ABSTRACT_CLASS(BuiltinType)
};
+class FeedbackType : public BuiltinType
+{
+ SLANG_CLASS(FeedbackType)
+
+ enum class Kind : uint8_t
+ {
+ MinMip, /// SAMPLER_FEEDBACK_MIN_MIP
+ MipRegionUsed, /// SAMPLER_FEEDBACK_MIP_REGION_USED
+ };
+
+ Kind kind;
+};
+
// Resources that contain "elements" that can be fetched
class ResourceType : public BuiltinType
{
@@ -140,6 +153,8 @@ protected:
}
};
+
+
class TextureType : public TextureTypeBase
{
SLANG_CLASS(TextureType)
@@ -150,6 +165,7 @@ protected:
{}
};
+
// This is a base type for texture/sampler pairs,
// as they exist in, e.g., GLSL
class TextureSamplerType : public TextureTypeBase
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 14033866b..bac71f1d8 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -340,6 +340,12 @@ SlangResult CPPSourceEmitter::_calcCPPTextureTypeName(IRTextureTypeBase* texType
case SLANG_RESOURCE_ACCESS_CONSUME:
outName << "Consume";
break;
+ case SLANG_RESOURCE_ACCESS_WRITE:
+ if (texType->isFeedback())
+ {
+ outName << "Feedback";
+ }
+ break;
default:
SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled resource access mode");
return SLANG_FAIL;
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index 440b9bc68..036c4701a 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -243,6 +243,13 @@ void HLSLSourceEmitter::_emitHLSLTextureType(IRTextureTypeBase* texType)
m_writer->emit("Consume");
break;
+ case SLANG_RESOURCE_ACCESS_WRITE:
+ if (texType->isFeedback())
+ {
+ m_writer->emit("Feedback");
+ }
+ break;
+
default:
SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled resource access mode");
break;
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index b9668aaa8..d59b0c3ea 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -936,6 +936,7 @@ struct IRResourceTypeBase : IRType
{
return getFlavor().getBaseShape();
}
+ bool isFeedback() const { return getFlavor().isFeedback(); }
bool isMultisample() const { return getFlavor().isMultisample(); }
bool isArray() const { return getFlavor().isArray(); }
SlangResourceShape getShape() const { return getFlavor().getShape(); }
diff --git a/source/slang/slang-reflection.cpp b/source/slang/slang-reflection.cpp
index 4ed1c3e5d..6d53e1a89 100644
--- a/source/slang/slang-reflection.cpp
+++ b/source/slang/slang-reflection.cpp
@@ -241,6 +241,10 @@ SLANG_API SlangTypeKind spReflectionType_GetKind(SlangReflectionType* inType)
{
return SLANG_TYPE_KIND_RESOURCE;
}
+ else if (auto feedbackType = as<FeedbackType>(type))
+ {
+ return SLANG_TYPE_KIND_FEEDBACK;
+ }
// TODO: need a better way to handle this stuff...
#define CASE(TYPE) \
else if(as<TYPE>(type)) do { \
diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp
index d207b45bf..aa11b1b0f 100644
--- a/source/slang/slang-syntax.cpp
+++ b/source/slang/slang-syntax.cpp
@@ -491,6 +491,14 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
textureType->declRef = declRef;
return textureType;
}
+ else if (magicMod->name == "FeedbackType")
+ {
+ SLANG_ASSERT(subst == nullptr);
+ auto type = astBuilder->create<FeedbackType>();
+ type->declRef = declRef;
+ type->kind = FeedbackType::Kind(magicMod->tag);
+ return type;
+ }
// TODO: eventually everything should follow this pattern,
// and we can drive the dispatch with a table instead
diff --git a/source/slang/slang-type-system-shared.cpp b/source/slang/slang-type-system-shared.cpp
index 7ccde5bcd..a8265de20 100644
--- a/source/slang/slang-type-system-shared.cpp
+++ b/source/slang/slang-type-system-shared.cpp
@@ -1,5 +1,7 @@
#include "slang-type-system-shared.h"
+#include "../core/slang-common.h"
+
namespace Slang
{
TextureFlavor TextureFlavor::create(SlangResourceShape shape, SlangResourceAccess access)
@@ -8,4 +10,12 @@ namespace Slang
rs.flavor = uint16_t(shape | (access << 8));
return rs;
}
+
+ TextureFlavor TextureFlavor::create(SlangResourceShape shape, SlangResourceAccess access, int flags)
+ {
+ SLANG_ASSERT((flags & ~int(SLANG_RESOURCE_EXT_SHAPE_MASK)) == 0);
+ TextureFlavor rs;
+ rs.flavor = uint16_t(shape | (access << 8) | flags);
+ return rs;
+ }
}
diff --git a/source/slang/slang-type-system-shared.h b/source/slang/slang-type-system-shared.h
index 01289fcbf..3b3dc6a91 100644
--- a/source/slang/slang-type-system-shared.h
+++ b/source/slang/slang-type-system-shared.h
@@ -48,6 +48,9 @@ FOREACH_BASE_TYPE(DEFINE_BASE_TYPE)
//
// TODO(tfoley): is this even meaningful/used?
// ShadowFlag = 0x80,
+
+ // For feedback texture
+ FeedbackFlag = SLANG_TEXTURE_FEEDBACK_FLAG,
};
enum Shape : uint8_t
@@ -57,7 +60,7 @@ FOREACH_BASE_TYPE(DEFINE_BASE_TYPE)
Shape3D = SLANG_TEXTURE_3D,
ShapeCube = SLANG_TEXTURE_CUBE,
ShapeBuffer = SLANG_TEXTURE_BUFFER,
-
+
Shape1DArray = Shape1D | ArrayFlag,
Shape2DArray = Shape2D | ArrayFlag,
// No Shape3DArray
@@ -77,6 +80,7 @@ FOREACH_BASE_TYPE(DEFINE_BASE_TYPE)
Shape getBaseShape() const { return Shape(flavor & BaseShapeMask); }
bool isArray() const { return (flavor & ArrayFlag) != 0; }
bool isMultisample() const { return (flavor & MultisampleFlag) != 0; }
+ bool isFeedback() const { return (flavor & FeedbackFlag) != 0; }
// bool isShadow() const { return (flavor & ShadowFlag) != 0; }
SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const { return flavor == rhs.flavor; }
@@ -89,6 +93,7 @@ FOREACH_BASE_TYPE(DEFINE_BASE_TYPE)
TextureFlavor(uint32_t tag) { flavor = (uint16_t)tag; }
static TextureFlavor create(SlangResourceShape shape, SlangResourceAccess access);
+ static TextureFlavor create(SlangResourceShape shape, SlangResourceAccess access, int flags);
};
enum class SamplerStateFlavor : uint8_t
diff --git a/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang b/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang
new file mode 100644
index 000000000..9e707b229
--- /dev/null
+++ b/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang
@@ -0,0 +1,46 @@
+//TEST:REFLECTION: -entry main -stage fragment -profile sm_6_5 -target hlsl
+//DISABLE_TEST:CROSS_COMPILE: -entry main -stage fragment -profile sm_6_5 -target dxil-assembly
+
+FeedbackTexture2D<SAMPLER_FEEDBACK_MIN_MIP> feedbackMinMip;
+FeedbackTexture2D<SAMPLER_FEEDBACK_MIP_REGION_USED> feedbackMipRegionUsed;
+FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIN_MIP> feedbackMinMipArray;
+FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIP_REGION_USED> feebackMipRegionUsedArray;
+
+Texture2D<float> tex2D;
+Texture2DArray<float> tex2DArray;
+SamplerState samp;
+
+float4 main() : SV_Target
+{
+ float2 coords2D = float2(1, 2);
+ float3 coords2DArray = float3(1, 2, 3);
+
+ float clamp = 4;
+ float bias = 0.5F;
+ float lod = 6;
+ float2 ddx = float2(1.0F / 32, 2.0F / 32);
+ float2 ddy = float2(3.0F / 32, 4.0F / 32);
+
+ // Clamped
+ feedbackMinMip.WriteSamplerFeedback(tex2D, samp, coords2D, clamp);
+
+ feedbackMinMip.WriteSamplerFeedbackBias(tex2D, samp, coords2D, bias, clamp);
+ feedbackMinMip.WriteSamplerFeedbackGrad(tex2D, samp, coords2D, ddx, ddy, clamp);
+
+ // Level
+ feedbackMinMip.WriteSamplerFeedbackLevel(tex2D, samp, coords2D, lod);
+
+ // No Clamp
+ feedbackMinMip.WriteSamplerFeedback(tex2D, samp, coords2D );
+ feedbackMinMip.WriteSamplerFeedbackBias(tex2D, samp, coords2D, bias);
+ feedbackMinMip.WriteSamplerFeedbackGrad(tex2D, samp, coords2D, ddx, ddy);
+
+ // Array
+ feedbackMinMipArray.WriteSamplerFeedback(tex2DArray, samp, coords2DArray);
+ feebackMipRegionUsedArray.WriteSamplerFeedback(tex2DArray, samp, coords2DArray);
+
+ // Using feedbackMipRegionUsed
+ feedbackMipRegionUsed.WriteSamplerFeedback(tex2D, samp, coords2D);
+
+ return float4(1, 2, 3, 4);
+}
diff --git a/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang.expected b/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang.expected
new file mode 100644
index 000000000..1d4dda6b0
--- /dev/null
+++ b/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang.expected
@@ -0,0 +1,110 @@
+result code = 0
+standard error = {
+}
+standard output = {
+{
+ "parameters": [
+ {
+ "name": "feedbackMinMip",
+ "binding": {"kind": "unorderedAccess", "index": 0},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D",
+ "feedback": true,
+ "access": "write",
+ "resultType": {
+ "kind": "Feedback",
+ "name": "SAMPLER_FEEDBACK_MIN_MIP"
+ }
+ }
+ },
+ {
+ "name": "feedbackMipRegionUsed",
+ "binding": {"kind": "unorderedAccess", "index": 1},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D",
+ "feedback": true,
+ "access": "write",
+ "resultType": {
+ "kind": "Feedback",
+ "name": "SAMPLER_FEEDBACK_MIP_REGION_USED"
+ }
+ }
+ },
+ {
+ "name": "feedbackMinMipArray",
+ "binding": {"kind": "unorderedAccess", "index": 2},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D",
+ "array": true,
+ "feedback": true,
+ "access": "write",
+ "resultType": {
+ "kind": "Feedback",
+ "name": "SAMPLER_FEEDBACK_MIN_MIP"
+ }
+ }
+ },
+ {
+ "name": "feebackMipRegionUsedArray",
+ "binding": {"kind": "unorderedAccess", "index": 3},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D",
+ "array": true,
+ "feedback": true,
+ "access": "write",
+ "resultType": {
+ "kind": "Feedback",
+ "name": "SAMPLER_FEEDBACK_MIP_REGION_USED"
+ }
+ }
+ },
+ {
+ "name": "tex2D",
+ "binding": {"kind": "shaderResource", "index": 0},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D"
+ }
+ },
+ {
+ "name": "tex2DArray",
+ "binding": {"kind": "shaderResource", "index": 1},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D",
+ "array": true
+ }
+ },
+ {
+ "name": "samp",
+ "binding": {"kind": "samplerState", "index": 0},
+ "type": {
+ "kind": "samplerState"
+ }
+ }
+ ],
+ "entryPoints": [
+ {
+ "name": "main",
+ "stage:": "fragment",
+ "result:": {
+ "stage": "fragment",
+ "binding": {"kind": "varyingOutput", "index": 0},
+ "semanticName": "SV_TARGET",
+ "type": {
+ "kind": "vector",
+ "elementCount": 4,
+ "elementType": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ }
+ }
+ }
+ }
+ ]
+}
+}
diff --git a/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang.hlsl b/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang.hlsl
new file mode 100644
index 000000000..b72991503
--- /dev/null
+++ b/tests/hlsl-intrinsic/sampler-feedback/sampler-feedback-basic.slang.hlsl
@@ -0,0 +1,43 @@
+FeedbackTexture2D<SAMPLER_FEEDBACK_MIN_MIP> feedbackMinMip_0;
+FeedbackTexture2D<SAMPLER_FEEDBACK_MIP_REGION_USED> feedbackMipRegionUsed_0;
+FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIN_MIP> feedbackMinMipArray_0;
+FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIP_REGION_USED> feebackMipRegionUsedArray_0;
+
+Texture2D<float> tex2D_0;
+Texture2DArray<float> tex2DArray_0;
+SamplerState samp_0;
+
+float4 main() : SV_Target
+{
+ float2 coords2D = float2(1, 2);
+ float3 coords2DArray = float3(1, 2, 3);
+
+ float clamp = 4;
+ float bias = 0.5F;
+ float lod = 6;
+ float2 ddx = float2(1.0F / 32, 2.0F / 32);
+ float2 ddy = float2(3.0F / 32, 4.0F / 32);
+
+ // Clamped
+ feedbackMinMip_0.WriteSamplerFeedback(tex2D_0, samp_0, coords2D, clamp);
+
+ feedbackMinMip_0.WriteSamplerFeedbackBias(tex2D_0, samp_0, coords2D, bias, clamp);
+ feedbackMinMip_0.WriteSamplerFeedbackGrad(tex2D_0, samp_0, coords2D, ddx, ddy, clamp);
+
+ // Level
+ feedbackMinMip_0.WriteSamplerFeedbackLevel(tex2D_0, samp_0, coords2D, lod);
+
+ // No Clamp
+ feedbackMinMip_0.WriteSamplerFeedback(tex2D_0, samp_0, coords2D );
+ feedbackMinMip_0.WriteSamplerFeedbackBias(tex2D_0, samp_0, coords2D, bias);
+ feedbackMinMip_0.WriteSamplerFeedbackGrad(tex2D_0, samp_0, coords2D, ddx, ddy);
+
+ // Array
+ feedbackMinMipArray_0.WriteSamplerFeedback(tex2DArray_0, samp_0, coords2DArray);
+ feebackMipRegionUsedArray_0.WriteSamplerFeedback(tex2DArray_0, samp_0, coords2DArray);
+
+ // Using feedbackMipRegionUsed
+ feedbackMipRegionUsed_0.WriteSamplerFeedback(tex2D_0, samp_0, coords2D);
+
+ return float4(1, 2, 3, 4);
+} \ No newline at end of file
diff --git a/tools/slang-reflection-test/slang-reflection-test-main.cpp b/tools/slang-reflection-test/slang-reflection-test-main.cpp
index ba6096f20..655b4e41d 100644
--- a/tools/slang-reflection-test/slang-reflection-test-main.cpp
+++ b/tools/slang-reflection-test/slang-reflection-test-main.cpp
@@ -539,6 +539,11 @@ static void emitReflectionResourceTypeBaseInfoJSON(
comma(writer);
write(writer, "\"multisample\": true");
}
+ if (shape & SLANG_TEXTURE_FEEDBACK_FLAG)
+ {
+ comma(writer);
+ write(writer, "\"feedback\": true");
+ }
if( access != SLANG_RESOURCE_ACCESS_READ )
{
@@ -553,7 +558,7 @@ static void emitReflectionResourceTypeBaseInfoJSON(
case SLANG_RESOURCE_ACCESS_READ:
break;
-
+ case SLANG_RESOURCE_ACCESS_WRITE: write(writer, "write"); break;
case SLANG_RESOURCE_ACCESS_READ_WRITE: write(writer, "readWrite"); break;
case SLANG_RESOURCE_ACCESS_RASTER_ORDERED: write(writer, "rasterOrdered"); break;
case SLANG_RESOURCE_ACCESS_APPEND: write(writer, "append"); break;
@@ -730,6 +735,12 @@ static void emitReflectionTypeInfoJSON(
comma(writer);
emitReflectionNameInfoJSON(writer, type->getName());
break;
+ case slang::TypeReflection::Kind::Feedback:
+ comma(writer);
+ write(writer, "\"kind\": \"Feedback\"");
+ comma(writer);
+ emitReflectionNameInfoJSON(writer, type->getName());
+ break;
default:
assert(!"unhandled case");
break;
@@ -909,9 +920,11 @@ static void emitReflectionTypeLayoutInfoJSON(
// the relevant cases here.
//
auto type = typeLayout->getType();
- auto shape = type->getResourceShape();
+ auto shape = type->getResourceShape();
- if( (shape & SLANG_RESOURCE_BASE_SHAPE_MASK) == SLANG_STRUCTURED_BUFFER )
+ const auto baseType = shape & SLANG_RESOURCE_BASE_SHAPE_MASK;
+
+ if (baseType == SLANG_STRUCTURED_BUFFER)
{
emitReflectionResourceTypeBaseInfoJSON(writer, type);
@@ -924,9 +937,20 @@ static void emitReflectionTypeLayoutInfoJSON(
resultTypeLayout);
}
}
+ else if (shape & SLANG_TEXTURE_FEEDBACK_FLAG)
+ {
+ emitReflectionResourceTypeBaseInfoJSON(writer, type);
+
+ if (auto resultType = typeLayout->getResourceResultType())
+ {
+ comma(writer);
+ write(writer, "\"resultType\": ");
+ emitReflectionTypeJSON(writer, resultType);
+ }
+ }
else
{
- emitReflectionTypeInfoJSON(writer, typeLayout->getType());
+ emitReflectionTypeInfoJSON(writer, type);
}
}
break;