diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-10-13 18:14:42 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-10-13 18:14:42 -0700 |
| commit | 64ddefb90cf440df7879d1f2f9cc61de71e0f181 (patch) | |
| tree | 03d113b2e58c9e232021df38350744226600f79c /source | |
| parent | 575230b93370fea86ecccb53fba73927280e917b (diff) | |
Move reflection JSON generation into separate text fixture (#211)
Move reflection JSON generation into separate test fixture
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/compiler.cpp | 40 | ||||
| -rw-r--r-- | source/slang/compiler.h | 5 | ||||
| -rw-r--r-- | source/slang/options.cpp | 4 | ||||
| -rw-r--r-- | source/slang/reflection.cpp | 734 | ||||
| -rw-r--r-- | source/slang/reflection.h | 3 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 12 |
6 files changed, 3 insertions, 795 deletions
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp index d7de5c42e..d57c9b6cf 100644 --- a/source/slang/compiler.cpp +++ b/source/slang/compiler.cpp @@ -815,50 +815,14 @@ namespace Slang translationUnit->result = translationUnitResult; } - - // Allow for an "extra" target to verride things before we finish. - String extraResult; - switch (compileRequest->extraTarget) - { - case CodeGenTarget::ReflectionJSON: - { - String reflectionJSON = emitReflectionJSON(compileRequest->layout.Ptr()); - - // Clobber existing output so we don't have to deal with it - for( auto translationUnit : compileRequest->translationUnits ) - { - translationUnit->result = CompileResult(); - } - for( auto entryPoint : compileRequest->entryPoints ) - { - entryPoint->result = CompileResult(); - } - - extraResult = reflectionJSON; - } - break; - - default: - break; - } - // If we are in command-line mode, we might be expected to actually // write output to one or more files here. if (compileRequest->isCommandLineCompile) { - switch (compileRequest->extraTarget) + for( auto entryPoint : compileRequest->entryPoints ) { - case CodeGenTarget::ReflectionJSON: - fprintf(stdout, "%s", extraResult.begin()); - break; - - default: - for( auto entryPoint : compileRequest->entryPoints ) - { - writeEntryPointResult(entryPoint); - } - break; + writeEntryPointResult(entryPoint); } } diff --git a/source/slang/compiler.h b/source/slang/compiler.h index 1919699a1..ca06e3a65 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -47,7 +47,6 @@ namespace Slang SPIRVAssembly = SLANG_SPIRV_ASM, DXBytecode = SLANG_DXBC, DXBytecodeAssembly = SLANG_DXBC_ASM, - ReflectionJSON = SLANG_REFLECTION_JSON, SlangIR = SLANG_IR, SlangIRAssembly = SLANG_IR_ASM, }; @@ -187,10 +186,6 @@ namespace Slang // What target language are we compiling to? CodeGenTarget Target = CodeGenTarget::Unknown; - // An "extra" target that might override the first one - // when it comes to deciding output format, etc. - CodeGenTarget extraTarget = CodeGenTarget::Unknown; - // Directories to search for `#include` files or `import`ed modules List<SearchDirectory> searchDirectories; diff --git a/source/slang/options.cpp b/source/slang/options.cpp index 6b21798f5..693081f2a 100644 --- a/source/slang/options.cpp +++ b/source/slang/options.cpp @@ -310,10 +310,6 @@ struct OptionsParser #undef CASE - else if (name == "reflection-json") - { - target = SLANG_REFLECTION_JSON; - } else { fprintf(stderr, "unknown code generation target '%S'\n", name.ToWString().begin()); diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp index 5e18e8cfd..3ef3effab 100644 --- a/source/slang/reflection.cpp +++ b/source/slang/reflection.cpp @@ -851,737 +851,3 @@ SLANG_API SlangReflectionEntryPoint* spReflection_getEntryPointByIndex(SlangRefl return convert(program->entryPoints[(int) index].Ptr()); } - - - - - - - - - - - - - - - - - - - - -namespace Slang { - -// Debug helper code: dump reflection data after generation - -struct PrettyWriter -{ - StringBuilder sb; - bool startOfLine = true; - int indent = 0; -}; - -static void adjust(PrettyWriter& writer) -{ - if (!writer.startOfLine) - return; - - int indent = writer.indent; - for (int ii = 0; ii < indent; ++ii) - writer.sb << " "; - - 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); - } - - writer.sb << c; - } -} - -static void write(PrettyWriter& writer, UInt val) -{ - adjust(writer); - writer.sb << ((unsigned int) 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, - UInt index, - UInt count, - UInt 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"); - SLANG_UNEXPECTED("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"); - SLANG_UNEXPECTED("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"); - SLANG_UNEXPECTED("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"); - SLANG_UNEXPECTED("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: - SLANG_UNEXPECTED("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"); -} - -#if 0 -ReflectionBlob* ReflectionBlob::Create( - CollectionOfTranslationUnits* program) -{ - ReflectionGenerationContext context; - ReflectionBlob* blob = GenerateReflectionBlob(&context, program); -#if 0 - String debugDump = blob->emitAsJSON(); - OutputDebugStringA("REFLECTION BLOB\n"); - OutputDebugStringA(debugDump.begin()); -#endif - return blob; -} -#endif - -// JSON emit logic - - - -String emitReflectionJSON( - ProgramLayout* programLayout) -{ - auto programReflection = (slang::ShaderReflection*) programLayout; - - PrettyWriter writer; - emitReflectionJSON(writer, programReflection); - return writer.sb.ProduceString(); -} - -} diff --git a/source/slang/reflection.h b/source/slang/reflection.h index 3eef47c6b..6c0b39564 100644 --- a/source/slang/reflection.h +++ b/source/slang/reflection.h @@ -19,9 +19,6 @@ typedef uint64_t UInt64; class ProgramLayout; class TypeLayout; -String emitReflectionJSON( - ProgramLayout* programLayout); - // SlangTypeKind getReflectionTypeKind(Type* type); diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 65abbb3f2..66ff9e429 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -708,17 +708,7 @@ SLANG_API void spSetCodeGenTarget( SlangCompileRequest* request, int target) { - if (target == SLANG_REFLECTION_JSON) - { - // HACK: We special case this because reflection JSON is actually - // an additional output step that layers on top of an existing - // target - REQ(request)->extraTarget = Slang::CodeGenTarget::ReflectionJSON; - } - else - { - REQ(request)->Target = (Slang::CodeGenTarget)target; - } + REQ(request)->Target = (Slang::CodeGenTarget)target; } SLANG_API void spSetPassThrough( |
