summaryrefslogtreecommitdiffstats
path: root/source/slang
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 /source/slang
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>
Diffstat (limited to 'source/slang')
-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
11 files changed, 173 insertions, 2 deletions
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