summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-03-28 08:17:48 -0700
committerGitHub <noreply@github.com>2018-03-28 08:17:48 -0700
commit184dc5cd6998b6277881fae4a68d91de86e2d63f (patch)
tree364b6496a428a9595f9d4e86b56e1d4d888384b4
parent17b66ef006cd15f822284b7f8fe4a45d77e75944 (diff)
Merge from v0.9.15 (#460)
* Fix bug when subscripting a type that must be split (#396) The logic was creating a `PairPseudoExpr` as part of a subscript (`operator[]`) operation, but neglecting to fill in its `pairInfo` field, which led to a null-pointer crash further along. * Allow writes to UAV textures (#416) Work on #415 This issue is already fixed in the `v0.10.*` line, but I'm back-porting the fix to `v0.9.*`. The issue here was that the stdlib declarations for texture types were only including the `get` accessor for subscript operations, even if the texture was write-able. I've also included the fixes for other subscript accessors in the stdlib (notably that `OutputPatch<T>` is readable, but not writable, despite what the name seems to imply). * Fix infinite loop in semantic parsing (#424) The code for parsing semantics was looking for a fixed set of tokens to terminate a semantic list, rather than assuming that whenever you don't see a `:` ahead, you probably are done with semantics. This meant that you could get into an infinite loop just with simple mistakes like leaving out a `;`. This change fixes the parser to note infinite loop in this case, and adds a test case to verify the fix. * Expose HLSL `shared` modifier through reflection. (#436) This is a request from Falcor, because the `shared` modifier can be used as a hint to optimize the grouping of parameters for binding. The intention is that `shared` marks shader parameters (including parameter blocks) that will us the same values across many draw calls (e.g., per-frame data, as opposed to per-model or per-instance). The mechanism I'm using here is to provide a general reflection API for exposing the `Modifier`s already attached to declarations. While the only modifier exposed is `shared`, and the only modifier information being exposed is presence/absence, this interface could be extended down the line.
-rw-r--r--slang.h27
-rw-r--r--source/slang/reflection.cpp20
-rw-r--r--tests/reflection/shared-modifier.hlsl12
-rw-r--r--tests/reflection/shared-modifier.hlsl.expected47
-rw-r--r--tools/slang-reflection-test/main.cpp18
5 files changed, 123 insertions, 1 deletions
diff --git a/slang.h b/slang.h
index c3c87e9a8..42f0c5610 100644
--- a/slang.h
+++ b/slang.h
@@ -497,6 +497,7 @@ extern "C"
typedef struct SlangReflection SlangReflection;
typedef struct SlangReflectionEntryPoint SlangReflectionEntryPoint;
+ typedef struct SlangReflectionModifier SlangReflectionModifier;
typedef struct SlangReflectionType SlangReflectionType;
typedef struct SlangReflectionTypeLayout SlangReflectionTypeLayout;
typedef struct SlangReflectionVariable SlangReflectionVariable;
@@ -643,6 +644,12 @@ extern "C"
SLANG_LAYOUT_RULES_DEFAULT,
};
+ typedef SlangUInt32 SlangModifierID;
+ enum
+ {
+ SLANG_MODIFIER_SHARED,
+ };
+
// Type Reflection
SLANG_API SlangTypeKind spReflectionType_GetKind(SlangReflectionType* type);
@@ -683,6 +690,8 @@ extern "C"
SLANG_API char const* spReflectionVariable_GetName(SlangReflectionVariable* var);
SLANG_API SlangReflectionType* spReflectionVariable_GetType(SlangReflectionVariable* var);
+ SLANG_API SlangReflectionModifier* spReflectionVariable_FindModifier(SlangReflectionVariable* var, SlangModifierID modifierID);
+
// Variable Layout Reflection
SLANG_API SlangReflectionVariable* spReflectionVariableLayout_GetVariable(SlangReflectionVariableLayout* var);
@@ -1034,6 +1043,14 @@ namespace slang
}
};
+ struct Modifier
+ {
+ enum ID : SlangModifierID
+ {
+ Shared = SLANG_MODIFIER_SHARED,
+ };
+ };
+
struct VariableReflection
{
char const* getName()
@@ -1045,6 +1062,11 @@ namespace slang
{
return (TypeReflection*) spReflectionVariable_GetType((SlangReflectionVariable*) this);
}
+
+ Modifier* findModifier(Modifier::ID id)
+ {
+ return (Modifier*) spReflectionVariable_FindModifier((SlangReflectionVariable*) this, (SlangModifierID) id);
+ }
};
struct VariableLayoutReflection
@@ -1059,6 +1081,11 @@ namespace slang
return getVariable()->getName();
}
+ Modifier* findModifier(Modifier::ID id)
+ {
+ return getVariable()->findModifier(id);
+ }
+
TypeLayoutReflection* getTypeLayout()
{
return (TypeLayoutReflection*) spReflectionVariableLayout_GetTypeLayout((SlangReflectionVariableLayout*) this);
diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp
index 65901d6af..20cd188de 100644
--- a/source/slang/reflection.cpp
+++ b/source/slang/reflection.cpp
@@ -681,6 +681,26 @@ SLANG_API SlangReflectionType* spReflectionVariable_GetType(SlangReflectionVaria
return convert(var->getType());
}
+SLANG_API SlangReflectionModifier* spReflectionVariable_FindModifier(SlangReflectionVariable* inVar, SlangModifierID modifierID)
+{
+ auto var = convert(inVar);
+ if(!var) return nullptr;
+
+ Modifier* modifier = nullptr;
+ switch( modifierID )
+ {
+ case SLANG_MODIFIER_SHARED:
+ modifier = var->FindModifier<HLSLEffectSharedModifier>();
+ break;
+
+ default:
+ return nullptr;
+ }
+
+ return (SlangReflectionModifier*) modifier;
+}
+
+
// Variable Layout Reflection
SLANG_API SlangReflectionVariable* spReflectionVariableLayout_GetVariable(SlangReflectionVariableLayout* inVarLayout)
diff --git a/tests/reflection/shared-modifier.hlsl b/tests/reflection/shared-modifier.hlsl
new file mode 100644
index 000000000..45a1dfac8
--- /dev/null
+++ b/tests/reflection/shared-modifier.hlsl
@@ -0,0 +1,12 @@
+// shared-modifier.hlsl
+//TEST:REFLECTION:-profile ps_5_0 -target hlsl
+
+// Confirm that we expose the `shared` modifier in reflection data.
+
+Texture2D t;
+shared SamplerState s;
+
+float4 main(float2 uv : UV) : SV_Target
+{
+ return t.Sample(s, uv);
+} \ No newline at end of file
diff --git a/tests/reflection/shared-modifier.hlsl.expected b/tests/reflection/shared-modifier.hlsl.expected
new file mode 100644
index 000000000..ddb982177
--- /dev/null
+++ b/tests/reflection/shared-modifier.hlsl.expected
@@ -0,0 +1,47 @@
+result code = 0
+standard error = {
+}
+standard output = {
+{
+ "parameters": [
+ {
+ "name": "t",
+ "binding": {"kind": "shaderResource", "index": 0},
+ "type": {
+ "kind": "resource",
+ "baseShape": "texture2D"
+ }
+ },
+ {
+ "name": "s",
+ "shared": true,
+ "binding": {"kind": "samplerState", "index": 0},
+ "type": {
+ "kind": "samplerState"
+ }
+ }
+ ],
+ "entryPoints": [
+ {
+ "name": "main",
+ "stage:": "fragment",
+ "parameters": [
+ {
+ "name": "uv",
+ "stage": "fragment",
+ "binding": {"kind": "varyingInput", "index": 0},
+ "semanticName": "UV",
+ "type": {
+ "kind": "vector",
+ "elementCount": 2,
+ "elementType": {
+ "kind": "scalar",
+ "scalarType": "float32"
+ }
+ }
+ }
+ ]
+ }
+ ]
+}
+}
diff --git a/tools/slang-reflection-test/main.cpp b/tools/slang-reflection-test/main.cpp
index 90be8f5c7..b900f3f62 100644
--- a/tools/slang-reflection-test/main.cpp
+++ b/tools/slang-reflection-test/main.cpp
@@ -239,6 +239,16 @@ static void emitReflectionNameInfoJSON(
write(writer, "\"");
}
+static void emitReflectionModifierInfoJSON(
+ PrettyWriter& writer,
+ slang::VariableReflection* var)
+{
+ if( var->findModifier(slang::Modifier::Shared) )
+ {
+ write(writer, ",\n\"shared\": true");
+ }
+}
+
static void emitReflectionVarLayoutJSON(
PrettyWriter& writer,
slang::VariableLayoutReflection* var)
@@ -252,6 +262,8 @@ static void emitReflectionVarLayoutJSON(
write(writer, "\"type\": ");
emitReflectionTypeLayoutJSON(writer, var->getTypeLayout());
+ emitReflectionModifierInfoJSON(writer, var->getVariable());
+
emitReflectionVarBindingInfoJSON(writer, var);
dedent(writer);
@@ -607,8 +619,10 @@ static void emitReflectionVarInfoJSON(
slang::VariableReflection* var)
{
emitReflectionNameInfoJSON(writer, var->getName());
- write(writer, ",\n");
+ emitReflectionModifierInfoJSON(writer, var);
+
+ write(writer, ",\n");
write(writer, "\"type\": ");
emitReflectionTypeJSON(writer, var->getType());
}
@@ -622,6 +636,8 @@ static void emitReflectionParamJSON(
emitReflectionNameInfoJSON(writer, param->getName());
+ emitReflectionModifierInfoJSON(writer, param->getVariable());
+
emitReflectionVarBindingInfoJSON(writer, param);
write(writer, ",\n");