diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/slang-reflection-test/main.cpp | 752 | ||||
| -rw-r--r-- | tools/slang-reflection-test/slang-reflection-test.vcxproj | 163 | ||||
| -rw-r--r-- | tools/slang-reflection-test/slang-reflection-test.vcxproj.filters | 22 | ||||
| -rw-r--r-- | tools/slang-test/main.cpp | 62 |
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 }, |
