summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/slang-reflection-test/main.cpp752
-rw-r--r--tools/slang-reflection-test/slang-reflection-test.vcxproj163
-rw-r--r--tools/slang-reflection-test/slang-reflection-test.vcxproj.filters22
-rw-r--r--tools/slang-test/main.cpp62
4 files changed, 999 insertions, 0 deletions
diff --git a/tools/slang-reflection-test/main.cpp b/tools/slang-reflection-test/main.cpp
new file mode 100644
index 000000000..9568dc3fe
--- /dev/null
+++ b/tools/slang-reflection-test/main.cpp
@@ -0,0 +1,752 @@
+// main.cpp
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <slang.h>
+
+struct PrettyWriter
+{
+ bool startOfLine = true;
+ int indent = 0;
+};
+
+static void writeRaw(PrettyWriter& writer, char const* begin, char const* end)
+{
+ fprintf(stdout, "%.*s", int(end - begin), begin);
+}
+
+static void writeRaw(PrettyWriter& writer, char const* begin)
+{
+ writeRaw(writer, begin, begin + strlen(begin));
+}
+
+static void writeRawChar(PrettyWriter& writer, int c)
+{
+ char buffer[] = { (char) c, 0 };
+ writeRaw(writer, buffer);
+}
+
+static void adjust(PrettyWriter& writer)
+{
+ if (!writer.startOfLine)
+ return;
+
+ int indent = writer.indent;
+ for (int ii = 0; ii < indent; ++ii)
+ writeRaw(writer, " ");
+
+ writer.startOfLine = false;
+}
+
+static void indent(PrettyWriter& writer)
+{
+ writer.indent++;
+}
+
+static void dedent(PrettyWriter& writer)
+{
+ writer.indent--;
+}
+
+static void write(PrettyWriter& writer, char const* text)
+{
+ // TODO: can do this more efficiently...
+ char const* cursor = text;
+ for(;;)
+ {
+ char c = *cursor++;
+ if (!c) break;
+
+ if (c == '\n')
+ {
+ writer.startOfLine = true;
+ }
+ else
+ {
+ adjust(writer);
+ }
+
+ writeRawChar(writer, c);
+ }
+}
+
+static void write(PrettyWriter& writer, SlangUInt val)
+{
+ adjust(writer);
+ fprintf(stdout, "%llu", (unsigned long long)val);
+}
+
+static void emitReflectionVarInfoJSON(PrettyWriter& writer, slang::VariableReflection* var);
+static void emitReflectionTypeLayoutJSON(PrettyWriter& writer, slang::TypeLayoutReflection* type);
+static void emitReflectionTypeJSON(PrettyWriter& writer, slang::TypeReflection* type);
+
+static void emitReflectionVarBindingInfoJSON(
+ PrettyWriter& writer,
+ SlangParameterCategory category,
+ SlangUInt index,
+ SlangUInt count,
+ SlangUInt space = 0)
+{
+ if( category == SLANG_PARAMETER_CATEGORY_UNIFORM )
+ {
+ write(writer,"\"kind\": \"uniform\"");
+ write(writer, ", ");
+ write(writer,"\"offset\": ");
+ write(writer, index);
+ write(writer, ", ");
+ write(writer, "\"size\": ");
+ write(writer, count);
+ }
+ else
+ {
+ write(writer, "\"kind\": \"");
+ switch( category )
+ {
+ #define CASE(NAME, KIND) case SLANG_PARAMETER_CATEGORY_##NAME: write(writer, #KIND); break
+ CASE(CONSTANT_BUFFER, constantBuffer);
+ CASE(SHADER_RESOURCE, shaderResource);
+ CASE(UNORDERED_ACCESS, unorderedAccess);
+ CASE(VERTEX_INPUT, vertexInput);
+ CASE(FRAGMENT_OUTPUT, fragmentOutput);
+ CASE(SAMPLER_STATE, samplerState);
+ CASE(UNIFORM, uniform);
+ CASE(DESCRIPTOR_TABLE_SLOT, descriptorTableSlot);
+ CASE(SPECIALIZATION_CONSTANT, specializationConstant);
+ CASE(MIXED, mixed);
+ #undef CASE
+
+ default:
+ write(writer, "unknown");
+ assert(!"unhandled case");
+ break;
+ }
+ write(writer, "\"");
+ if( space )
+ {
+ write(writer, ", ");
+ write(writer, "\"space\": ");
+ write(writer, space);
+ }
+ write(writer, ", ");
+ write(writer, "\"index\": ");
+ write(writer, index);
+ if( count != 1)
+ {
+ write(writer, ", ");
+ write(writer, "\"count\": ");
+ write(writer, count);
+ }
+ }
+}
+
+static void emitReflectionVarBindingInfoJSON(
+ PrettyWriter& writer,
+ slang::VariableLayoutReflection* var)
+{
+ auto typeLayout = var->getTypeLayout();
+ auto categoryCount = var->getCategoryCount();
+
+ if( categoryCount != 1 )
+ {
+ write(writer,"\"bindings\": [\n");
+ }
+ else
+ {
+ write(writer,"\"binding\": ");
+ }
+ indent(writer);
+
+ for(uint32_t cc = 0; cc < categoryCount; ++cc )
+ {
+ auto category = var->getCategoryByIndex(cc);
+ auto index = var->getOffset(category);
+ auto space = var->getBindingSpace(category);
+ auto count = typeLayout->getSize(category);
+
+ if (cc != 0) write(writer, ",\n");
+
+ write(writer,"{");
+ emitReflectionVarBindingInfoJSON(
+ writer,
+ category,
+ index,
+ count,
+ space);
+ write(writer,"}");
+ }
+
+ dedent(writer);
+ if( categoryCount != 1 )
+ {
+ write(writer,"\n]");
+ }
+}
+
+static void emitReflectionNameInfoJSON(
+ PrettyWriter& writer,
+ char const* name)
+{
+ // TODO: deal with escaping special characters if/when needed
+ write(writer, "\"name\": \"");
+ write(writer, name);
+ write(writer, "\"");
+}
+
+static void emitReflectionVarLayoutJSON(
+ PrettyWriter& writer,
+ slang::VariableLayoutReflection* var)
+{
+ write(writer, "{\n");
+ indent(writer);
+
+ emitReflectionNameInfoJSON(writer, var->getName());
+ write(writer, ",\n");
+
+ write(writer, "\"type\": ");
+ emitReflectionTypeLayoutJSON(writer, var->getTypeLayout());
+ write(writer, ",\n");
+
+ emitReflectionVarBindingInfoJSON(writer, var);
+
+ dedent(writer);
+ write(writer, "\n}");
+}
+
+static void emitReflectionScalarTypeInfoJSON(
+ PrettyWriter& writer,
+ SlangScalarType scalarType)
+{
+ write(writer, "\"scalarType\": \"");
+ switch (scalarType)
+ {
+ default:
+ write(writer, "unknown");
+ assert(!"unhandled case");
+ break;
+#define CASE(TAG, ID) case slang::TypeReflection::ScalarType::TAG: write(writer, #ID); break
+ CASE(Void, void);
+ CASE(Bool, bool);
+ CASE(Int32, int32);
+ CASE(UInt32, uint32);
+ CASE(Int64, int64);
+ CASE(UInt64, uint64);
+ CASE(Float16, float16);
+ CASE(Float32, float32);
+ CASE(Float64, float64);
+#undef CASE
+ }
+ write(writer, "\"");
+}
+
+static void emitReflectionTypeInfoJSON(
+ PrettyWriter& writer,
+ slang::TypeReflection* type)
+{
+ switch( type->getKind() )
+ {
+ case slang::TypeReflection::Kind::SamplerState:
+ write(writer, "\"kind\": \"samplerState\"");
+ break;
+
+ case slang::TypeReflection::Kind::Resource:
+ {
+ auto shape = type->getResourceShape();
+ auto access = type->getResourceAccess();
+ write(writer, "\"kind\": \"resource\"");
+ write(writer, ",\n");
+ write(writer, "\"baseShape\": \"");
+ switch (shape & SLANG_RESOURCE_BASE_SHAPE_MASK)
+ {
+ default:
+ write(writer, "unknown");
+ assert(!"unhandled case");
+ break;
+
+#define CASE(SHAPE, NAME) case SLANG_##SHAPE: write(writer, #NAME); break
+ CASE(TEXTURE_1D, texture1D);
+ CASE(TEXTURE_2D, texture2D);
+ CASE(TEXTURE_3D, texture3D);
+ CASE(TEXTURE_CUBE, textureCube);
+ CASE(TEXTURE_BUFFER, textureBuffer);
+ CASE(STRUCTURED_BUFFER, structuredBuffer);
+ CASE(BYTE_ADDRESS_BUFFER, byteAddressBuffer);
+#undef CASE
+ }
+ write(writer, "\"");
+ if (shape & SLANG_TEXTURE_ARRAY_FLAG)
+ {
+ write(writer, ",\n");
+ write(writer, "\"array\": true");
+ }
+ if (shape & SLANG_TEXTURE_MULTISAMPLE_FLAG)
+ {
+ write(writer, ",\n");
+ write(writer, "\"multisample\": true");
+ }
+
+ if( access != SLANG_RESOURCE_ACCESS_READ )
+ {
+ write(writer, ",\n\"access\": \"");
+ switch(access)
+ {
+ default:
+ write(writer, "unknown");
+ assert(!"unhandled case");
+ break;
+
+ case SLANG_RESOURCE_ACCESS_READ:
+ 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;
+ case SLANG_RESOURCE_ACCESS_CONSUME: write(writer, "consume"); break;
+ }
+ write(writer, "\"");
+ }
+ }
+ break;
+
+ case slang::TypeReflection::Kind::ConstantBuffer:
+ write(writer, "\"kind\": \"constantBuffer\"");
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeJSON(
+ writer,
+ type->getElementType());
+ break;
+
+ case slang::TypeReflection::Kind::TextureBuffer:
+ write(writer, "\"kind\": \"textureBuffer\"");
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeJSON(
+ writer,
+ type->getElementType());
+ break;
+
+ case slang::TypeReflection::Kind::ShaderStorageBuffer:
+ write(writer, "\"kind\": \"shaderStorageBuffer\"");
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeJSON(
+ writer,
+ type->getElementType());
+ break;
+
+ case slang::TypeReflection::Kind::Scalar:
+ write(writer, "\"kind\": \"scalar\"");
+ write(writer, ",\n");
+ emitReflectionScalarTypeInfoJSON(
+ writer,
+ type->getScalarType());
+ break;
+
+ case slang::TypeReflection::Kind::Vector:
+ write(writer, "\"kind\": \"vector\"");
+ write(writer, ",\n");
+ write(writer, "\"elementCount\": ");
+ write(writer, type->getElementCount());
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeJSON(
+ writer,
+ type->getElementType());
+ break;
+
+ case slang::TypeReflection::Kind::Matrix:
+ write(writer, "\"kind\": \"matrix\"");
+ write(writer, ",\n");
+ write(writer, "\"rowCount\": ");
+ write(writer, type->getRowCount());
+ write(writer, ",\n");
+ write(writer, "\"columnCount\": ");
+ write(writer, type->getColumnCount());
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeJSON(
+ writer,
+ type->getElementType());
+ break;
+
+ case slang::TypeReflection::Kind::Array:
+ {
+ auto arrayType = type;
+ write(writer, "\"kind\": \"array\"");
+ write(writer, ",\n");
+ write(writer, "\"elementCount\": ");
+ write(writer, arrayType->getElementCount());
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeJSON(writer, arrayType->getElementType());
+ }
+ break;
+
+ case slang::TypeReflection::Kind::Struct:
+ {
+ write(writer, "\"kind\": \"struct\",\n");
+ write(writer, "\"fields\": [\n");
+ indent(writer);
+
+ auto structType = type;
+ auto fieldCount = structType->getFieldCount();
+ for( uint32_t ff = 0; ff < fieldCount; ++ff )
+ {
+ if (ff != 0) write(writer, ",\n");
+ emitReflectionVarInfoJSON(
+ writer,
+ structType->getFieldByIndex(ff));
+ }
+ dedent(writer);
+ write(writer, "\n]");
+ }
+ break;
+
+ default:
+ assert(!"unhandled case");
+ break;
+ }
+}
+
+static void emitReflectionTypeLayoutInfoJSON(
+ PrettyWriter& writer,
+ slang::TypeLayoutReflection* typeLayout)
+{
+ switch( typeLayout->getKind() )
+ {
+ default:
+ emitReflectionTypeInfoJSON(writer, typeLayout->getType());
+ break;
+
+ case slang::TypeReflection::Kind::Array:
+ {
+ auto arrayTypeLayout = typeLayout;
+ auto elementTypeLayout = arrayTypeLayout->getElementTypeLayout();
+ write(writer, "\"kind\": \"array\"");
+ write(writer, ",\n");
+ write(writer, "\"elementCount\": ");
+ write(writer, arrayTypeLayout->getElementCount());
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeLayoutJSON(
+ writer,
+ elementTypeLayout);
+ if (arrayTypeLayout->getSize(SLANG_PARAMETER_CATEGORY_UNIFORM) != 0)
+ {
+ write(writer, ",\n");
+ write(writer, "\"uniformStride\": ");
+ write(writer, arrayTypeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM));
+ }
+ }
+ break;
+
+ case slang::TypeReflection::Kind::Struct:
+ {
+ write(writer, "\"kind\": \"struct\",\n");
+ write(writer, "\"fields\": [\n");
+ indent(writer);
+
+ auto structTypeLayout = typeLayout;
+ auto fieldCount = structTypeLayout->getFieldCount();
+ for( uint32_t ff = 0; ff < fieldCount; ++ff )
+ {
+ if (ff != 0) write(writer, ",\n");
+ emitReflectionVarLayoutJSON(
+ writer,
+ structTypeLayout->getFieldByIndex(ff));
+ }
+ dedent(writer);
+ write(writer, "\n]");
+ }
+ break;
+
+ case slang::TypeReflection::Kind::ConstantBuffer:
+ write(writer, "\"kind\": \"constantBuffer\"");
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeLayoutJSON(
+ writer,
+ typeLayout->getElementTypeLayout());
+ break;
+
+ case slang::TypeReflection::Kind::TextureBuffer:
+ write(writer, "\"kind\": \"textureBuffer\"");
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeLayoutJSON(
+ writer,
+ typeLayout->getElementTypeLayout());
+ break;
+
+ case slang::TypeReflection::Kind::ShaderStorageBuffer:
+ write(writer, "\"kind\": \"shaderStorageBuffer\"");
+ write(writer, ",\n");
+ write(writer, "\"elementType\": ");
+ emitReflectionTypeLayoutJSON(
+ writer,
+ typeLayout->getElementTypeLayout());
+ break;
+ }
+
+ // TODO: emit size info for types
+}
+
+static void emitReflectionTypeLayoutJSON(
+ PrettyWriter& writer,
+ slang::TypeLayoutReflection* typeLayout)
+{
+ write(writer, "{\n");
+ indent(writer);
+ emitReflectionTypeLayoutInfoJSON(writer, typeLayout);
+ dedent(writer);
+ write(writer, "\n}");
+}
+
+static void emitReflectionTypeJSON(
+ PrettyWriter& writer,
+ slang::TypeReflection* type)
+{
+ write(writer, "{\n");
+ indent(writer);
+ emitReflectionTypeInfoJSON(writer, type);
+ dedent(writer);
+ write(writer, "\n}");
+}
+
+static void emitReflectionVarInfoJSON(
+ PrettyWriter& writer,
+ slang::VariableReflection* var)
+{
+ emitReflectionNameInfoJSON(writer, var->getName());
+ write(writer, ",\n");
+
+ write(writer, "\"type\": ");
+ emitReflectionTypeJSON(writer, var->getType());
+}
+
+static void emitReflectionParamJSON(
+ PrettyWriter& writer,
+ slang::VariableLayoutReflection* param)
+{
+ write(writer, "{\n");
+ indent(writer);
+
+ emitReflectionNameInfoJSON(writer, param->getName());
+ write(writer, ",\n");
+
+ emitReflectionVarBindingInfoJSON(writer, param);
+ write(writer, ",\n");
+
+ write(writer, "\"type\": ");
+ emitReflectionTypeLayoutJSON(writer, param->getTypeLayout());
+
+ dedent(writer);
+ write(writer, "\n}");
+}
+
+template<typename T>
+struct Range
+{
+public:
+ Range(
+ T begin,
+ T end)
+ : mBegin(begin)
+ , mEnd(end)
+ {}
+
+ struct Iterator
+ {
+ public:
+ explicit Iterator(T value)
+ : mValue(value)
+ {}
+
+ T operator*() const { return mValue; }
+ void operator++() { mValue++; }
+
+ bool operator!=(Iterator const& other)
+ {
+ return mValue != other.mValue;
+ }
+
+ private:
+ T mValue;
+ };
+
+ Iterator begin() const { return Iterator(mBegin); }
+ Iterator end() const { return Iterator(mEnd); }
+
+private:
+ T mBegin;
+ T mEnd;
+};
+
+template<typename T>
+Range<T> range(T begin, T end)
+{
+ return Range<T>(begin, end);
+}
+
+template<typename T>
+Range<T> range(T end)
+{
+ return Range<T>(T(0), end);
+}
+
+static void emitReflectionEntryPointJSON(
+ PrettyWriter& writer,
+ slang::EntryPointReflection* entryPoint)
+{
+ write(writer, "{\n");
+ indent(writer);
+
+ emitReflectionNameInfoJSON(writer, entryPoint->getName());
+
+ switch (entryPoint->getStage())
+ {
+ case SLANG_STAGE_VERTEX: write(writer, ",\n\"stage:\": \"vertex\""); break;
+ case SLANG_STAGE_HULL: write(writer, ",\n\"stage:\": \"hull\""); break;
+ case SLANG_STAGE_DOMAIN: write(writer, ",\n\"stage:\": \"domain\""); break;
+ case SLANG_STAGE_GEOMETRY: write(writer, ",\n\"stage:\": \"geometry\""); break;
+ case SLANG_STAGE_FRAGMENT: write(writer, ",\n\"stage:\": \"fragment\""); break;
+ case SLANG_STAGE_COMPUTE: write(writer, ",\n\"stage:\": \"compute\""); break;
+ default:
+ break;
+ }
+
+ auto parameterCount = entryPoint->getParameterCount();
+ if (parameterCount)
+ {
+ write(writer, ",\n\"parameters\": [\n");
+ indent(writer);
+
+ for( auto pp : range(parameterCount) )
+ {
+ if(pp != 0) write(writer, ",\n");
+
+ auto parameter = entryPoint->getParameterByIndex(pp);
+ emitReflectionParamJSON(writer, parameter);
+ }
+
+ dedent(writer);
+ write(writer, "\n]");
+ }
+
+ if (entryPoint->usesAnySampleRateInput())
+ {
+ write(writer, ",\n\"usesAnySampleRateInput\": true");
+ }
+
+ if (entryPoint->getStage() == SLANG_STAGE_COMPUTE)
+ {
+ SlangUInt threadGroupSize[3];
+ entryPoint->getComputeThreadGroupSize(3, threadGroupSize);
+
+ write(writer, ",\n\"threadGroupSize\": [");
+ for (int ii = 0; ii < 3; ++ii)
+ {
+ if (ii != 0) write(writer, ", ");
+ write(writer, threadGroupSize[ii]);
+ }
+ write(writer, "]");
+ }
+
+ dedent(writer);
+ write(writer, "\n}");
+}
+
+static void emitReflectionJSON(
+ PrettyWriter& writer,
+ slang::ShaderReflection* programReflection)
+{
+ write(writer, "{\n");
+ indent(writer);
+ write(writer, "\"parameters\": [\n");
+ indent(writer);
+
+ auto parameterCount = programReflection->getParameterCount();
+ for( auto pp : range(parameterCount) )
+ {
+ if(pp != 0) write(writer, ",\n");
+
+ auto parameter = programReflection->getParameterByIndex(pp);
+ emitReflectionParamJSON(writer, parameter);
+ }
+
+ dedent(writer);
+ write(writer, "\n]");
+
+ auto entryPointCount = programReflection->getEntryPointCount();
+ if (entryPointCount)
+ {
+ write(writer, ",\n\"entryPoints\": [\n");
+ indent(writer);
+
+ for (auto ee : range(entryPointCount))
+ {
+ if (ee != 0) write(writer, ",\n");
+
+ auto entryPoint = programReflection->getEntryPointByIndex(ee);
+ emitReflectionEntryPointJSON(writer, entryPoint);
+ }
+
+ dedent(writer);
+ write(writer, "\n]");
+ }
+
+ dedent(writer);
+ write(writer, "\n}\n");
+}
+
+void emitReflectionJSON(
+ SlangReflection* reflection)
+{
+ auto programReflection = (slang::ShaderReflection*) reflection;
+
+ PrettyWriter writer;
+ emitReflectionJSON(writer, programReflection);
+}
+
+
+int main(
+ int argc,
+ char** argv)
+{
+ // Parse any command-line options
+
+ SlangSession* session = spCreateSession(nullptr);
+ SlangCompileRequest* request = spCreateCompileRequest(session);
+
+ char const* appName = "slang-reflection-test";
+ if(argc > 0) appName = argv[0];
+
+ int err = spProcessCommandLineArguments(request, &argv[1], argc - 1);
+ if( err )
+ {
+ char const* output = spGetDiagnosticOutput(request);
+ fputs(output, stderr);
+ exit(1);
+ }
+
+ if( spCompile(request) != 0 )
+ {
+ char const* output = spGetDiagnosticOutput(request);
+ fputs(output, stderr);
+ exit(1);
+ }
+
+ // Okay, let's go through and emit reflection info on whatever
+ // we have.
+
+ SlangReflection* reflection = spGetReflection(request);
+ emitReflectionJSON(reflection);
+
+ spDestroyCompileRequest(request);
+ spDestroySession(session);
+
+ return 0;
+}
diff --git a/tools/slang-reflection-test/slang-reflection-test.vcxproj b/tools/slang-reflection-test/slang-reflection-test.vcxproj
new file mode 100644
index 000000000..5ac386d57
--- /dev/null
+++ b/tools/slang-reflection-test/slang-reflection-test.vcxproj
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{22C45F4F-FB6B-4535-BED1-D3F5D0C71047}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>slangreflectiontest</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\build\slang-build.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\build\slang-build.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\build\slang-build.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\build\slang-build.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\source\slang\slang.vcxproj">
+ <Project>{db00da62-0533-4afd-b59f-a67d5b3a0808}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/tools/slang-reflection-test/slang-reflection-test.vcxproj.filters b/tools/slang-reflection-test/slang-reflection-test.vcxproj.filters
new file mode 100644
index 000000000..0d8d9e457
--- /dev/null
+++ b/tools/slang-reflection-test/slang-reflection-test.vcxproj.filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/tools/slang-test/main.cpp b/tools/slang-test/main.cpp
index 0bf2ff6af..83d512cc1 100644
--- a/tools/slang-test/main.cpp
+++ b/tools/slang-test/main.cpp
@@ -691,6 +691,67 @@ TestResult runSimpleTest(TestInput& input)
return result;
}
+TestResult runReflectionTest(TestInput& input)
+{
+ auto filePath = input.filePath;
+ auto outputStem = input.outputStem;
+
+ OSProcessSpawner spawner;
+
+ spawner.pushExecutablePath(String(options.binDir) + "slang-reflection-test" + osGetExecutableSuffix());
+ spawner.pushArgument(filePath);
+
+ for( auto arg : input.testOptions->args )
+ {
+ spawner.pushArgument(arg);
+ }
+
+ if (spawnAndWait(outputStem, spawner) != kOSError_None)
+ {
+ return kTestResult_Fail;
+ }
+
+ String actualOutput = getOutput(spawner);
+
+ String expectedOutputPath = outputStem + ".expected";
+ String expectedOutput;
+ try
+ {
+ expectedOutput = Slang::File::ReadAllText(expectedOutputPath);
+ }
+ catch (Slang::IOException)
+ {
+ }
+
+ // If no expected output file was found, then we
+ // expect everything to be empty
+ if (expectedOutput.Length() == 0)
+ {
+ expectedOutput = "result code = 0\nstandard error = {\n}\nstandard output = {\n}\n";
+ }
+
+ TestResult result = kTestResult_Pass;
+
+ // Otherwise we compare to the expected output
+ if (actualOutput != expectedOutput)
+ {
+ result = kTestResult_Fail;
+ }
+
+ // If the test failed, then we write the actual output to a file
+ // so that we can easily diff it from the command line and
+ // diagnose the problem.
+ if (result == kTestResult_Fail)
+ {
+ String actualOutputPath = outputStem + ".actual";
+ Slang::File::WriteAllText(actualOutputPath, actualOutput);
+
+ maybeDumpOutput(expectedOutput, actualOutput);
+ }
+
+ return result;
+}
+
TestResult runEvalTest(TestInput& input)
{
// We are going to load and evaluate the code
@@ -1235,6 +1296,7 @@ TestResult runTest(
TestCallback callback;
} kTestCommands[] = {
{ "SIMPLE", &runSimpleTest },
+ { "REFLECTION", &runReflectionTest },
#if SLANG_TEST_SUPPORT_HLSL
{ "COMPARE_HLSL", &runHLSLComparisonTest },
{ "COMPARE_HLSL_RENDER", &runHLSLRenderComparisonTest },