summaryrefslogtreecommitdiffstats
path: root/tools/render-test/shader-input-layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/render-test/shader-input-layout.cpp')
-rw-r--r--tools/render-test/shader-input-layout.cpp2396
1 files changed, 1245 insertions, 1151 deletions
diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp
index 013e86c37..e2cf25809 100644
--- a/tools/render-test/shader-input-layout.cpp
+++ b/tools/render-test/shader-input-layout.cpp
@@ -2,6 +2,7 @@
#define _CRT_SECURE_NO_WARNINGS 1
#include "shader-input-layout.h"
+
#include "core/slang-token-reader.h"
#include "core/slang-type-text-util.h"
@@ -9,7 +10,7 @@
namespace renderer_test
{
- using namespace Slang;
+using namespace Slang;
// clang-format off
#define SLANG_SCALAR_TYPES(x) \
@@ -19,1177 +20,1229 @@ namespace renderer_test
// clang-format on
- Format _getFormatFromName(const UnownedStringSlice& slice)
+Format _getFormatFromName(const UnownedStringSlice& slice)
+{
+ for (int i = 0; i < int(Format::_Count); ++i)
{
- for (int i = 0; i < int(Format::_Count); ++i)
+ const FormatInfo& info = getFormatInfo(Format(i));
+ if (slice == info.name)
{
- const FormatInfo& info = getFormatInfo(Format(i));
- if (slice == info.name)
- {
- return Format(i);
- }
+ return Format(i);
}
- return Format::Unknown;
}
+ return Format::Unknown;
+}
- struct TypeInfo
- {
- UnownedStringSlice name;
- SlangScalarType type;
- };
+struct TypeInfo
+{
+ UnownedStringSlice name;
+ SlangScalarType type;
+};
-#define SLANG_SCALAR_TYPE_INFO(name, value) { UnownedStringSlice::fromLiteral(name), SLANG_SCALAR_TYPE_##value },
- static const TypeInfo g_scalarTypeInfos[] =
- {
- SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO)
- };
+#define SLANG_SCALAR_TYPE_INFO(name, value) \
+ {UnownedStringSlice::fromLiteral(name), SLANG_SCALAR_TYPE_##value},
+static const TypeInfo g_scalarTypeInfos[] = {SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO)};
#undef SLANG_SCALAR_TYPES
#undef SLANG_SCALAR_TYPE_INFO
- static SlangScalarType _getScalarType(const UnownedStringSlice& slice)
+static SlangScalarType _getScalarType(const UnownedStringSlice& slice)
+{
+ for (const auto& info : g_scalarTypeInfos)
{
- for (const auto& info : g_scalarTypeInfos)
+ if (info.name == slice)
{
- if (info.name == slice)
- {
- return info.type;
- }
+ return info.type;
}
- return SLANG_SCALAR_TYPE_NONE;
}
+ return SLANG_SCALAR_TYPE_NONE;
+}
- void ShaderInputLayout::AggVal::addField(ShaderInputLayout::Field const& field)
- {
- fields.add(field);
- }
+void ShaderInputLayout::AggVal::addField(ShaderInputLayout::Field const& field)
+{
+ fields.add(field);
+}
- void ShaderInputLayout::ArrayVal::addField(ShaderInputLayout::Field const& field)
+void ShaderInputLayout::ArrayVal::addField(ShaderInputLayout::Field const& field)
+{
+ vals.add(field.val);
+}
+
+class ShaderInputLayoutFormatException : public Exception
+{
+public:
+ ShaderInputLayoutFormatException(String message)
+ : Exception(message)
{
- vals.add(field.val);
}
+};
- class ShaderInputLayoutFormatException : public Exception
- {
- public:
- ShaderInputLayoutFormatException(String message)
- : Exception(message)
- {}
- };
+struct ShaderInputLayoutParser
+{
+ ShaderInputLayout* layout;
+ RandomGenerator* rand;
- struct ShaderInputLayoutParser
+ ShaderInputLayoutParser(ShaderInputLayout* layout, RandomGenerator* rand)
+ : layout(layout), rand(rand)
{
- ShaderInputLayout* layout;
- RandomGenerator* rand;
-
- ShaderInputLayoutParser(ShaderInputLayout* layout, RandomGenerator* rand)
- : layout(layout)
- , rand(rand)
- {}
+ }
- RefPtr<ShaderInputLayout::ParentVal> parentVal;
- List<RefPtr<ShaderInputLayout::ParentVal>> parentValStack;
+ RefPtr<ShaderInputLayout::ParentVal> parentVal;
+ List<RefPtr<ShaderInputLayout::ParentVal>> parentValStack;
- SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::TextureVal* val)
+ SlangResult parseOption(
+ Misc::TokenReader& parser,
+ String const& word,
+ ShaderInputLayout::TextureVal* val)
+ {
+ if (word == "depth")
{
- if (word == "depth")
- {
- val->textureDesc.isDepthTexture = true;
- }
- else if (word == "arrayLength")
- {
- parser.Read("=");
- val->textureDesc.arrayLength = parser.ReadInt();
- }
- else if (word == "size")
- {
- parser.Read("=");
- auto size = parser.ReadInt();
- val->textureDesc.size = size;
- }
- else if (word == "content")
- {
- parser.Read("=");
- auto contentWord = parser.ReadWord();
- if (contentWord == "zero")
- val->textureDesc.content = InputTextureContent::Zero;
- else if (contentWord == "one")
- val->textureDesc.content = InputTextureContent::One;
- else if (contentWord == "chessboard")
- val->textureDesc.content = InputTextureContent::ChessBoard;
- else
- val->textureDesc.content = InputTextureContent::Gradient;
- }
- else if (word == "sampleCount")
- {
- parser.Read("=");
- auto contentWord = parser.ReadWord();
- if(contentWord == "one")
- val->textureDesc.sampleCount = InputTextureSampleCount::One;
- else if(contentWord == "two")
- val->textureDesc.sampleCount = InputTextureSampleCount::Two;
- else if(contentWord == "four")
- val->textureDesc.sampleCount = InputTextureSampleCount::Four;
- else if(contentWord == "eight")
- val->textureDesc.sampleCount = InputTextureSampleCount::Eight;
- else if(contentWord == "sixteen")
- val->textureDesc.sampleCount = InputTextureSampleCount::Sixteen;
- else if(contentWord == "thirtyTwo")
- val->textureDesc.sampleCount = InputTextureSampleCount::ThirtyTwo;
- else if(contentWord == "sixtyFour")
- val->textureDesc.sampleCount = InputTextureSampleCount::SixtyFour;
- }
- else if(word == "mipMaps")
- {
- parser.Read("=");
- val->textureDesc.mipMapCount = int(parser.ReadInt());
- }
- else if(word == "format")
- {
- val->textureDesc.format = parseFormatOption(parser);
-
- if (val->textureDesc.format == Format::Unknown)
- {
- return SLANG_FAIL;
- }
- }
- else
- {
- return SLANG_FAIL;
- }
- return SLANG_OK;
+ val->textureDesc.isDepthTexture = true;
}
-
- SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::SamplerVal* val)
+ else if (word == "arrayLength")
{
- if (word == "depthCompare")
- {
- val->samplerDesc.isCompareSampler = true;
- }
+ parser.Read("=");
+ val->textureDesc.arrayLength = parser.ReadInt();
+ }
+ else if (word == "size")
+ {
+ parser.Read("=");
+ auto size = parser.ReadInt();
+ val->textureDesc.size = size;
+ }
+ else if (word == "content")
+ {
+ parser.Read("=");
+ auto contentWord = parser.ReadWord();
+ if (contentWord == "zero")
+ val->textureDesc.content = InputTextureContent::Zero;
+ else if (contentWord == "one")
+ val->textureDesc.content = InputTextureContent::One;
+ else if (contentWord == "chessboard")
+ val->textureDesc.content = InputTextureContent::ChessBoard;
else
+ val->textureDesc.content = InputTextureContent::Gradient;
+ }
+ else if (word == "sampleCount")
+ {
+ parser.Read("=");
+ auto contentWord = parser.ReadWord();
+ if (contentWord == "one")
+ val->textureDesc.sampleCount = InputTextureSampleCount::One;
+ else if (contentWord == "two")
+ val->textureDesc.sampleCount = InputTextureSampleCount::Two;
+ else if (contentWord == "four")
+ val->textureDesc.sampleCount = InputTextureSampleCount::Four;
+ else if (contentWord == "eight")
+ val->textureDesc.sampleCount = InputTextureSampleCount::Eight;
+ else if (contentWord == "sixteen")
+ val->textureDesc.sampleCount = InputTextureSampleCount::Sixteen;
+ else if (contentWord == "thirtyTwo")
+ val->textureDesc.sampleCount = InputTextureSampleCount::ThirtyTwo;
+ else if (contentWord == "sixtyFour")
+ val->textureDesc.sampleCount = InputTextureSampleCount::SixtyFour;
+ }
+ else if (word == "mipMaps")
+ {
+ parser.Read("=");
+ val->textureDesc.mipMapCount = int(parser.ReadInt());
+ }
+ else if (word == "format")
+ {
+ val->textureDesc.format = parseFormatOption(parser);
+
+ if (val->textureDesc.format == Format::Unknown)
{
return SLANG_FAIL;
}
- return SLANG_OK;
}
+ else
+ {
+ return SLANG_FAIL;
+ }
+ return SLANG_OK;
+ }
-
- SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::CombinedTextureSamplerVal* val)
+ SlangResult parseOption(
+ Misc::TokenReader& parser,
+ String const& word,
+ ShaderInputLayout::SamplerVal* val)
+ {
+ if (word == "depthCompare")
+ {
+ val->samplerDesc.isCompareSampler = true;
+ }
+ else
{
- auto result = parseOption(parser, word, val->textureVal);
- if(SLANG_SUCCEEDED(result)) return result;
+ return SLANG_FAIL;
+ }
+ return SLANG_OK;
+ }
+
- result = parseOption(parser, word, val->samplerVal);
+ SlangResult parseOption(
+ Misc::TokenReader& parser,
+ String const& word,
+ ShaderInputLayout::CombinedTextureSamplerVal* val)
+ {
+ auto result = parseOption(parser, word, val->textureVal);
+ if (SLANG_SUCCEEDED(result))
return result;
- }
- SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::DataValBase* val)
+ result = parseOption(parser, word, val->samplerVal);
+ return result;
+ }
+
+ SlangResult parseOption(
+ Misc::TokenReader& parser,
+ String const& word,
+ ShaderInputLayout::DataValBase* val)
+ {
+ if (word == "data")
{
- if (word == "data")
- {
- parser.Read("=");
+ parser.Read("=");
- parser.Read("[");
- uint32_t offset = 0;
- while (!parser.IsEnd() && !parser.LookAhead("]"))
+ parser.Read("[");
+ uint32_t offset = 0;
+ while (!parser.IsEnd() && !parser.LookAhead("]"))
+ {
+ bool negate = false;
+ if (parser.NextToken().Type == Misc::TokenType::OpSub)
{
- bool negate = false;
- if(parser.NextToken().Type == Misc::TokenType::OpSub)
- {
- parser.ReadToken();
- negate = true;
- }
+ parser.ReadToken();
+ negate = true;
+ }
- if (parser.NextToken().Type == Misc::TokenType::IntLiteral)
- {
- uint32_t value = parser.ReadUInt();
- if(negate) value = uint32_t(-int32_t(value));
- val->bufferData.add(value);
- }
- else
- {
- auto floatNum = parser.ReadFloat();
- if(negate) floatNum = -floatNum;
- val->bufferData.add(*(unsigned int*)&floatNum);
- }
- offset += 4;
+ if (parser.NextToken().Type == Misc::TokenType::IntLiteral)
+ {
+ uint32_t value = parser.ReadUInt();
+ if (negate)
+ value = uint32_t(-int32_t(value));
+ val->bufferData.add(value);
}
- parser.Read("]");
- }
- else
- {
- return SLANG_FAIL;
+ else
+ {
+ auto floatNum = parser.ReadFloat();
+ if (negate)
+ floatNum = -floatNum;
+ val->bufferData.add(*(unsigned int*)&floatNum);
+ }
+ offset += 4;
}
- return SLANG_OK;
+ parser.Read("]");
}
+ else
+ {
+ return SLANG_FAIL;
+ }
+ return SLANG_OK;
+ }
- SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::BufferVal* val)
+ SlangResult parseOption(
+ Misc::TokenReader& parser,
+ String const& word,
+ ShaderInputLayout::BufferVal* val)
+ {
+ if (word == "stride")
{
- if (word == "stride")
- {
- parser.Read("=");
- val->bufferDesc.stride = parser.ReadInt();
- }
- else if (word == "count")
- {
- parser.Read("=");
- val->bufferDesc.elementCount = parser.ReadInt();
- }
- else if (word == "counter")
- {
- parser.Read("=");
- val->bufferDesc.counter = parser.ReadInt();
- }
- else if (word == "random")
- {
- parser.Read("(");
- // Read the type
- String type = parser.ReadWord();
- SlangScalarType scalarType = _getScalarType(type.getUnownedSlice());
- if (scalarType == SLANG_SCALAR_TYPE_NONE)
+ parser.Read("=");
+ val->bufferDesc.stride = parser.ReadInt();
+ }
+ else if (word == "count")
+ {
+ parser.Read("=");
+ val->bufferDesc.elementCount = parser.ReadInt();
+ }
+ else if (word == "counter")
+ {
+ parser.Read("=");
+ val->bufferDesc.counter = parser.ReadInt();
+ }
+ else if (word == "random")
+ {
+ parser.Read("(");
+ // Read the type
+ String type = parser.ReadWord();
+ SlangScalarType scalarType = _getScalarType(type.getUnownedSlice());
+ if (scalarType == SLANG_SCALAR_TYPE_NONE)
+ {
+ StringBuilder scalarTypeNames;
+ for (const auto& info : g_scalarTypeInfos)
{
- StringBuilder scalarTypeNames;
- for (const auto& info : g_scalarTypeInfos)
+ if (scalarTypeNames.getLength() != 0)
{
- if (scalarTypeNames.getLength() != 0)
- {
- scalarTypeNames << ", ";
- }
- scalarTypeNames << info.name;
+ scalarTypeNames << ", ";
}
-
- throw ShaderInputLayoutFormatException(StringBuilder() << "Expecting " << scalarTypeNames << " " << parser.NextToken().Position.Line);
+ scalarTypeNames << info.name;
}
- parser.Read(",");
- const int size = int(parser.ReadUInt());
+ throw ShaderInputLayoutFormatException(
+ StringBuilder()
+ << "Expecting " << scalarTypeNames << " " << parser.NextToken().Position.Line);
+ }
+
+ parser.Read(",");
+ const int size = int(parser.ReadUInt());
- switch (scalarType)
+ switch (scalarType)
+ {
+ case SLANG_SCALAR_TYPE_INT32:
{
- case SLANG_SCALAR_TYPE_INT32:
- {
- bool hasRange = false;
+ bool hasRange = false;
+
+ int32_t minValue = -0x7fffffff - 1;
+ int32_t maxValue = 0x7fffffff;
- int32_t minValue = -0x7fffffff - 1;
- int32_t maxValue = 0x7fffffff;
+ if (parser.LookAhead(","))
+ {
+ hasRange = true;
+ parser.ReadToken();
+ minValue = parser.ReadInt();
if (parser.LookAhead(","))
{
- hasRange = true;
parser.ReadToken();
- minValue = parser.ReadInt();
-
- if (parser.LookAhead(","))
- {
- parser.ReadToken();
- maxValue = parser.ReadInt();
- }
+ maxValue = parser.ReadInt();
}
- SLANG_ASSERT(minValue <= maxValue);
- maxValue = (maxValue >= minValue) ? maxValue : minValue;
+ }
+ SLANG_ASSERT(minValue <= maxValue);
+ maxValue = (maxValue >= minValue) ? maxValue : minValue;
- // Generate the data
- val->bufferData.setCount(size);
+ // Generate the data
+ val->bufferData.setCount(size);
- int32_t* dst = (int32_t*)val->bufferData.getBuffer();
- for (int i = 0; i < size; ++i)
- {
- dst[i] = hasRange ? rand->nextInt32InRange(minValue, maxValue) : rand->nextInt32();
- }
- break;
+ int32_t* dst = (int32_t*)val->bufferData.getBuffer();
+ for (int i = 0; i < size; ++i)
+ {
+ dst[i] = hasRange ? rand->nextInt32InRange(minValue, maxValue)
+ : rand->nextInt32();
}
- case SLANG_SCALAR_TYPE_UINT32:
+ break;
+ }
+ case SLANG_SCALAR_TYPE_UINT32:
+ {
+ bool hasRange = false;
+ uint32_t minValue = 0;
+ uint32_t maxValue = 0xffffffff;
+
+ if (parser.LookAhead(","))
{
- bool hasRange = false;
- uint32_t minValue = 0;
- uint32_t maxValue = 0xffffffff;
+ parser.ReadToken();
+ minValue = parser.ReadUInt();
+
+ hasRange = true;
if (parser.LookAhead(","))
{
parser.ReadToken();
- minValue = parser.ReadUInt();
-
- hasRange = true;
-
- if (parser.LookAhead(","))
- {
- parser.ReadToken();
- maxValue = parser.ReadUInt();
- }
+ maxValue = parser.ReadUInt();
}
+ }
- SLANG_ASSERT(minValue <= maxValue);
- maxValue = (maxValue >= minValue) ? maxValue : minValue;
+ SLANG_ASSERT(minValue <= maxValue);
+ maxValue = (maxValue >= minValue) ? maxValue : minValue;
- // Generate the data
- val->bufferData.setCount(size);
+ // Generate the data
+ val->bufferData.setCount(size);
- uint32_t* dst = (uint32_t*)val->bufferData.getBuffer();
- for (int i = 0; i < size; ++i)
- {
- dst[i] = hasRange ? rand->nextUInt32InRange(minValue, maxValue) : rand->nextUInt32();
- }
-
- break;
+ uint32_t* dst = (uint32_t*)val->bufferData.getBuffer();
+ for (int i = 0; i < size; ++i)
+ {
+ dst[i] = hasRange ? rand->nextUInt32InRange(minValue, maxValue)
+ : rand->nextUInt32();
}
- case SLANG_SCALAR_TYPE_FLOAT32:
+
+ break;
+ }
+ case SLANG_SCALAR_TYPE_FLOAT32:
+ {
+ float minValue = -1.0f;
+ float maxValue = 1.0f;
+
+ if (parser.LookAhead(","))
{
- float minValue = -1.0f;
- float maxValue = 1.0f;
-
+ parser.ReadToken();
+ minValue = parser.ReadFloat();
+
if (parser.LookAhead(","))
{
parser.ReadToken();
- minValue = parser.ReadFloat();
-
- if (parser.LookAhead(","))
- {
- parser.ReadToken();
- maxValue = parser.ReadFloat();
- }
+ maxValue = parser.ReadFloat();
}
+ }
- SLANG_ASSERT(minValue <= maxValue);
- maxValue = (maxValue >= minValue) ? maxValue : minValue;
+ SLANG_ASSERT(minValue <= maxValue);
+ maxValue = (maxValue >= minValue) ? maxValue : minValue;
- // Generate the data
- val->bufferData.setCount(size);
+ // Generate the data
+ val->bufferData.setCount(size);
- float* dst = (float*)val->bufferData.getBuffer();
- for (int i = 0; i < size; ++i)
- {
- dst[i] = (rand->nextUnitFloat32() * (maxValue - minValue)) + minValue;
- }
- break;
+ float* dst = (float*)val->bufferData.getBuffer();
+ for (int i = 0; i < size; ++i)
+ {
+ dst[i] = (rand->nextUnitFloat32() * (maxValue - minValue)) + minValue;
}
+ break;
}
+ }
- // Read the range
+ // Read the range
- parser.Read(")");
- }
- else if(word == "format")
- {
- val->bufferDesc.format = parseFormatOption(parser);
- }
- else
- {
- return parseOption(parser, word, static_cast<ShaderInputLayout::DataValBase*>(val));
- }
- return SLANG_OK;
+ parser.Read(")");
}
-
- SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::ObjectVal* val)
+ else if (word == "format")
{
- if( word == "type" )
- {
- parser.Read("=");
- val->typeName = parser.ReadWord();
- }
- else
- {
- return SLANG_FAIL;
- }
- return SLANG_OK;
+ val->bufferDesc.format = parseFormatOption(parser);
+ }
+ else
+ {
+ return parseOption(parser, word, static_cast<ShaderInputLayout::DataValBase*>(val));
}
+ return SLANG_OK;
+ }
- Format parseFormatOption(Misc::TokenReader& parser)
+ SlangResult parseOption(
+ Misc::TokenReader& parser,
+ String const& word,
+ ShaderInputLayout::ObjectVal* val)
+ {
+ if (word == "type")
{
parser.Read("=");
- auto formatWord = parser.ReadWord();
-
- return _getFormatFromName(formatWord.getUnownedSlice());
+ val->typeName = parser.ReadWord();
}
+ else
+ {
+ return SLANG_FAIL;
+ }
+ return SLANG_OK;
+ }
- template<typename T>
- void maybeParseOptions(Misc::TokenReader& parser, T* val)
+ Format parseFormatOption(Misc::TokenReader& parser)
+ {
+ parser.Read("=");
+ auto formatWord = parser.ReadWord();
+
+ return _getFormatFromName(formatWord.getUnownedSlice());
+ }
+
+ template<typename T>
+ void maybeParseOptions(Misc::TokenReader& parser, T* val)
+ {
+ // parse options
+ if (parser.LookAhead("("))
{
- // parse options
- if (parser.LookAhead("("))
+ parser.Read("(");
+ while (!parser.IsEnd() && !parser.LookAhead(")"))
{
- parser.Read("(");
- while (!parser.IsEnd() && !parser.LookAhead(")"))
+ auto word = parser.ReadWord();
+ if (SLANG_FAILED(parseOption(parser, word, val)))
{
- auto word = parser.ReadWord();
- if( SLANG_FAILED(parseOption(parser, word, val)) )
- {
- throw ShaderInputLayoutFormatException(String("Unsupported option '") + word + String("' at line ") + String(parser.NextToken().Position.Line));
- }
-
- if (parser.LookAhead(","))
- parser.Read(",");
- else
- break;
+ throw ShaderInputLayoutFormatException(
+ String("Unsupported option '") + word + String("' at line ") +
+ String(parser.NextToken().Position.Line));
}
- parser.Read(")");
+
+ if (parser.LookAhead(","))
+ parser.Read(",");
+ else
+ break;
}
+ parser.Read(")");
}
+ }
- RefPtr<ShaderInputLayout::Val> parseNumericValExpr(Misc::TokenReader& parser, bool negate = false)
+ RefPtr<ShaderInputLayout::Val> parseNumericValExpr(
+ Misc::TokenReader& parser,
+ bool negate = false)
+ {
+ switch (parser.NextToken().Type)
{
- switch(parser.NextToken().Type)
+ case Misc::TokenType::IntLiteral:
{
- case Misc::TokenType::IntLiteral:
- {
- RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal;
-
- uint32_t value = parser.ReadUInt();
- if(negate) value = uint32_t(-int32_t(value));
- val->bufferData.add(value);
+ RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal;
- return val;
- }
- break;
+ uint32_t value = parser.ReadUInt();
+ if (negate)
+ value = uint32_t(-int32_t(value));
+ val->bufferData.add(value);
- case Misc::TokenType::DoubleLiteral:
- {
- RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal;
+ return val;
+ }
+ break;
- float floatValue = parser.ReadFloat();
- if(negate) floatValue = -floatValue;
+ case Misc::TokenType::DoubleLiteral:
+ {
+ RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal;
- uint32_t value = 0;
- memcpy(&value, &floatValue, sizeof(floatValue));
- val->bufferData.add(value);
+ float floatValue = parser.ReadFloat();
+ if (negate)
+ floatValue = -floatValue;
- return val;
- }
- break;
+ uint32_t value = 0;
+ memcpy(&value, &floatValue, sizeof(floatValue));
+ val->bufferData.add(value);
- default:
- throw ShaderInputLayoutFormatException(String("Expected a numeric literal but found '") + parser.NextToken().Content + String("' at line") + String(parser.NextToken().Position.Line));
+ return val;
}
+ break;
+
+ default:
+ throw ShaderInputLayoutFormatException(
+ String("Expected a numeric literal but found '") + parser.NextToken().Content +
+ String("' at line") + String(parser.NextToken().Position.Line));
}
+ }
- String parseTypeName(Misc::TokenReader& parser)
+ String parseTypeName(Misc::TokenReader& parser)
+ {
+ String typeName = parser.ReadWord();
+ if (parser.AdvanceIf("<"))
{
- String typeName = parser.ReadWord();
- if (parser.AdvanceIf("<"))
+ StringBuilder sb;
+ sb << typeName << "<";
+ for (;;)
{
- StringBuilder sb;
- sb << typeName << "<";
- for (;;)
- {
- if (parser.LookAhead(Misc::TokenType::IntLiteral))
- sb << parser.ReadInt();
- else
- sb << parseTypeName(parser);
- if (!parser.AdvanceIf(","))
- break;
- sb << ",";
- }
- sb << ">";
- parser.Read(">");
- return sb.produceString();
+ if (parser.LookAhead(Misc::TokenType::IntLiteral))
+ sb << parser.ReadInt();
+ else
+ sb << parseTypeName(parser);
+ if (!parser.AdvanceIf(","))
+ break;
+ sb << ",";
}
- return typeName;
+ sb << ">";
+ parser.Read(">");
+ return sb.produceString();
}
+ return typeName;
+ }
- RefPtr<ShaderInputLayout::Val> parseValExpr(Misc::TokenReader& parser)
- {
- typedef Misc::TokenType TokenType;
+ RefPtr<ShaderInputLayout::Val> parseValExpr(Misc::TokenReader& parser)
+ {
+ typedef Misc::TokenType TokenType;
- switch(parser.NextToken().Type)
+ switch (parser.NextToken().Type)
+ {
+ case TokenType::OpSub:
{
- case TokenType::OpSub:
- {
- parser.ReadToken();
- return parseNumericValExpr(parser, true);
- }
- break;
-
- case TokenType::IntLiteral:
- case TokenType::DoubleLiteral:
- return parseNumericValExpr(parser);
-
- case TokenType::LBrace:
- {
- // aggregate
- parser.ReadToken();
- RefPtr<ShaderInputLayout::AggVal> val = new ShaderInputLayout::AggVal;
-
- while( !parser.IsEnd() && !parser.LookAhead(TokenType::RBrace) )
- {
- ShaderInputLayout::Field field;
-
- if( parser.LookAhead(TokenType::Identifier) && parser.NextToken(1).Type == TokenType::Colon )
- {
- field.name = parser.ReadWord();
- parser.Read(TokenType::Colon);
- }
-
- field.val = parseValExpr(parser);
-
- val->fields.add(field);
-
- if(parser.LookAhead(TokenType::RBrace))
- break;
-
- parser.Read(TokenType::Comma);
- }
- parser.Read(TokenType::RBrace);
+ parser.ReadToken();
+ return parseNumericValExpr(parser, true);
+ }
+ break;
+ case TokenType::IntLiteral:
+ case TokenType::DoubleLiteral: return parseNumericValExpr(parser);
- return val;
- }
- break;
+ case TokenType::LBrace:
+ {
+ // aggregate
+ parser.ReadToken();
+ RefPtr<ShaderInputLayout::AggVal> val = new ShaderInputLayout::AggVal;
- case TokenType::LBracket:
+ while (!parser.IsEnd() && !parser.LookAhead(TokenType::RBrace))
{
- // array
- parser.ReadToken();
- RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal;
+ ShaderInputLayout::Field field;
- while( !parser.IsEnd() && !parser.LookAhead(TokenType::RBracket) )
+ if (parser.LookAhead(TokenType::Identifier) &&
+ parser.NextToken(1).Type == TokenType::Colon)
{
- val->vals.add(parseValExpr(parser));
-
- if(parser.LookAhead(TokenType::RBracket))
- break;
-
- parser.Read(TokenType::Comma);
+ field.name = parser.ReadWord();
+ parser.Read(TokenType::Colon);
}
- parser.Read(TokenType::RBracket);
-
- return val;
- }
- break;
- case TokenType::Identifier:
- {
- if( parser.AdvanceIf("new") )
- {
- RefPtr<ShaderInputLayout::ObjectVal> val = new ShaderInputLayout::ObjectVal;
+ field.val = parseValExpr(parser);
- if( parser.NextToken().Type == TokenType::Identifier )
- {
- val->typeName = parseTypeName(parser);
- }
+ val->fields.add(field);
- val->contentVal = parseValExpr(parser);
- return val;
- }
- else if( parser.AdvanceIf("out") )
- {
- auto val = parseValExpr(parser);
- val->isOutput = true;
- return val;
- }
- else if (parser.AdvanceIf("specialize"))
- {
- RefPtr<ShaderInputLayout::SpecializeVal> val =
- new ShaderInputLayout::SpecializeVal();
+ if (parser.LookAhead(TokenType::RBrace))
+ break;
- parser.Read(Misc::TokenType::LParent);
- while (!parser.IsEnd() &&
- parser.NextToken().Type != Misc::TokenType::RParent)
- {
- val->typeArgs.add(parseTypeName(parser));
- if (!parser.AdvanceIf(","))
- break;
- }
- parser.Read(Misc::TokenType::RParent);
- val->contentVal = parseValExpr(parser);
- return val;
- }
- else if (parser.AdvanceIf("dynamic"))
- {
- RefPtr<ShaderInputLayout::SpecializeVal> val =
- new ShaderInputLayout::SpecializeVal();
- val->typeArgs.add("__Dynamic");
- val->contentVal = parseValExpr(parser);
- return val;
- }
- else
- {
- // We assume that any other word is introducing one of the other
- // cases for a parse-able value.
- return parseVal(parser);
- }
+ parser.Read(TokenType::Comma);
}
- break;
+ parser.Read(TokenType::RBrace);
- default:
- throw ShaderInputLayoutFormatException(String("Unexpected '") + parser.NextToken().Content + String("' at line") + String(parser.NextToken().Position.Line));
- }
- }
- RefPtr<ShaderInputLayout::Val> parseVal(Misc::TokenReader& parser)
- {
- auto word = parser.NextToken().Content;
- if (parser.AdvanceIf("begin_array"))
- {
- RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal;
- pushParentVal(val);
return val;
}
- else if (parser.AdvanceIf("begin_object"))
- {
- RefPtr<ShaderInputLayout::ObjectVal> val = new ShaderInputLayout::ObjectVal;
- maybeParseOptions(parser, val.Ptr());
-
- RefPtr<ShaderInputLayout::AggVal> contentVal = new ShaderInputLayout::AggVal;
- val->contentVal = contentVal;
- pushParentVal(contentVal);
+ break;
- return val;
- }
- else if (parser.AdvanceIf("uniform"))
+ case TokenType::LBracket:
{
- RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("cbuffer"))
- {
- // A `cbuffer` is basically just an object where the content of
- // the object is being provided by `uniform` data instead.
+ // array
+ parser.ReadToken();
+ RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal;
- RefPtr<ShaderInputLayout::ObjectVal> objVal = new ShaderInputLayout::ObjectVal;
+ while (!parser.IsEnd() && !parser.LookAhead(TokenType::RBracket))
+ {
+ val->vals.add(parseValExpr(parser));
- RefPtr<ShaderInputLayout::DataVal> dataVal = new ShaderInputLayout::DataVal;
- maybeParseOptions(parser, dataVal.Ptr());
+ if (parser.LookAhead(TokenType::RBracket))
+ break;
- objVal->contentVal = dataVal;
+ parser.Read(TokenType::Comma);
+ }
+ parser.Read(TokenType::RBracket);
- return objVal;
- }
- else if (parser.AdvanceIf("ubuffer"))
- {
- RefPtr<ShaderInputLayout::BufferVal> val = new ShaderInputLayout::BufferVal;
- val->bufferDesc.type = InputBufferType::StorageBuffer;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("Texture1D"))
- {
- RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
- val->textureDesc.dimension = 1;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("RWTextureBuffer"))
- {
- RefPtr<ShaderInputLayout::BufferVal> val = new ShaderInputLayout::BufferVal;
- val->bufferDesc.type = InputBufferType::StorageBuffer;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("Texture2D"))
- {
- RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
- val->textureDesc.dimension = 2;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("Texture3D"))
- {
- RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
- val->textureDesc.dimension = 3;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("TextureCube"))
- {
- RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
- val->textureDesc.dimension = 2;
- val->textureDesc.isCube = true;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("RWTexture1D"))
- {
- RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
- val->textureDesc.dimension = 1;
- val->textureDesc.isRWTexture = true;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("RWTexture2D"))
- {
- RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
- val->textureDesc.dimension = 2;
- val->textureDesc.isRWTexture = true;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("RWTexture3D"))
- {
- RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
- val->textureDesc.dimension = 3;
- val->textureDesc.isRWTexture = true;
- maybeParseOptions(parser, val.Ptr());
return val;
}
- else if (parser.AdvanceIf("RWTextureCube"))
- {
- RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
- val->textureDesc.dimension = 2;
- val->textureDesc.isCube = true;
- val->textureDesc.isRWTexture = true;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("Sampler"))
- {
- RefPtr<ShaderInputLayout::SamplerVal> val = new ShaderInputLayout::SamplerVal;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("TextureSampler1D"))
- {
- RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = new ShaderInputLayout::CombinedTextureSamplerVal;
- val->textureVal = new ShaderInputLayout::TextureVal;
- val->samplerVal = new ShaderInputLayout::SamplerVal;
- val->textureVal->textureDesc.dimension = 1;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("TextureSampler2D"))
- {
- RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = new ShaderInputLayout::CombinedTextureSamplerVal;
- val->textureVal = new ShaderInputLayout::TextureVal;
- val->samplerVal = new ShaderInputLayout::SamplerVal;
- val->textureVal->textureDesc.dimension = 2;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("TextureSampler3D"))
- {
- RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = new ShaderInputLayout::CombinedTextureSamplerVal;
- val->textureVal = new ShaderInputLayout::TextureVal;
- val->samplerVal = new ShaderInputLayout::SamplerVal;
- val->textureVal->textureDesc.dimension = 3;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("TextureSamplerCube"))
- {
- RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val = new ShaderInputLayout::CombinedTextureSamplerVal;
- val->textureVal = new ShaderInputLayout::TextureVal;
- val->samplerVal = new ShaderInputLayout::SamplerVal;
- val->textureVal->textureDesc.dimension = 2;
- val->textureVal->textureDesc.isCube = true;
- maybeParseOptions(parser, val.Ptr());
- return val;
- }
- else if (parser.AdvanceIf("AccelerationStructure"))
- {
- RefPtr<ShaderInputLayout::AccelerationStructureVal> val =
- new ShaderInputLayout::AccelerationStructureVal();
- return val;
- }
- else
- {
- throw ShaderInputLayoutFormatException(String("Unknown shader input type '") + word + String("' at line") + String(parser.NextToken().Position.Line));
- }
- parser.ReadToken();
- return nullptr;
- }
-
- String parseName(Misc::TokenReader& parser)
- {
- typedef Misc::Token Token;
- typedef Misc::TokenType TokenType;
-
- StringBuilder builder;
+ break;
- Token nameToken = parser.ReadToken();
- if (nameToken.Type != TokenType::Identifier)
+ case TokenType::Identifier:
{
- throw ShaderInputLayoutFormatException(StringBuilder() << "Invalid input syntax at line " << parser.NextToken().Position.Line);
- }
- builder << nameToken.Content;
+ if (parser.AdvanceIf("new"))
+ {
+ RefPtr<ShaderInputLayout::ObjectVal> val = new ShaderInputLayout::ObjectVal;
- for(;;)
- {
- Token token = parser.NextToken(0);
+ if (parser.NextToken().Type == TokenType::Identifier)
+ {
+ val->typeName = parseTypeName(parser);
+ }
- if (token.Type == TokenType::LBracket)
+ val->contentVal = parseValExpr(parser);
+ return val;
+ }
+ else if (parser.AdvanceIf("out"))
{
- parser.ReadToken();
- int index = parser.ReadInt();
- SLANG_ASSERT(index >= 0);
- parser.ReadMatchingToken(TokenType::RBracket);
-
- builder << "[" << index << "]";
+ auto val = parseValExpr(parser);
+ val->isOutput = true;
+ return val;
}
- else if (token.Type == TokenType::Dot)
+ else if (parser.AdvanceIf("specialize"))
{
- parser.ReadToken();
- Token identifierToken = parser.ReadMatchingToken(TokenType::Identifier);
+ RefPtr<ShaderInputLayout::SpecializeVal> val =
+ new ShaderInputLayout::SpecializeVal();
- builder << "." << identifierToken.Content;
+ parser.Read(Misc::TokenType::LParent);
+ while (!parser.IsEnd() && parser.NextToken().Type != Misc::TokenType::RParent)
+ {
+ val->typeArgs.add(parseTypeName(parser));
+ if (!parser.AdvanceIf(","))
+ break;
+ }
+ parser.Read(Misc::TokenType::RParent);
+ val->contentVal = parseValExpr(parser);
+ return val;
+ }
+ else if (parser.AdvanceIf("dynamic"))
+ {
+ RefPtr<ShaderInputLayout::SpecializeVal> val =
+ new ShaderInputLayout::SpecializeVal();
+ val->typeArgs.add("__Dynamic");
+ val->contentVal = parseValExpr(parser);
+ return val;
}
else
{
- return builder;
+ // We assume that any other word is introducing one of the other
+ // cases for a parse-able value.
+ return parseVal(parser);
}
}
+ break;
+
+ default:
+ throw ShaderInputLayoutFormatException(
+ String("Unexpected '") + parser.NextToken().Content + String("' at line") +
+ String(parser.NextToken().Position.Line));
}
+ }
- void parseFieldBindings(Misc::TokenReader& parser, ShaderInputLayout::Field& ioField)
+ RefPtr<ShaderInputLayout::Val> parseVal(Misc::TokenReader& parser)
+ {
+ auto word = parser.NextToken().Content;
+ if (parser.AdvanceIf("begin_array"))
{
- // parse bindings
- if (parser.LookAhead(":"))
- {
- parser.Read(":");
- while (!parser.IsEnd())
- {
- if (parser.AdvanceIf("out"))
- {
- ioField.val->isOutput = true;
- }
- else if (parser.AdvanceIf("name"))
- {
- // Optionally consume '='
- if (parser.NextToken().Type == Misc::TokenType::OpAssign)
- {
- parser.ReadToken();
- }
+ RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal;
+ pushParentVal(val);
+ return val;
+ }
+ else if (parser.AdvanceIf("begin_object"))
+ {
+ RefPtr<ShaderInputLayout::ObjectVal> val = new ShaderInputLayout::ObjectVal;
+ maybeParseOptions(parser, val.Ptr());
- ioField.name = parseName(parser);
- }
- else
- {
- fprintf(stderr, "Invalid TEST_INPUT syntax '%s'\n", parser.NextToken().Content.getBuffer());
- break;
- }
+ RefPtr<ShaderInputLayout::AggVal> contentVal = new ShaderInputLayout::AggVal;
+ val->contentVal = contentVal;
+ pushParentVal(contentVal);
- if (parser.LookAhead(","))
- parser.Read(",");
- }
- }
+ return val;
}
-
- void pushParentVal(ShaderInputLayout::ParentVal* val)
+ else if (parser.AdvanceIf("uniform"))
{
- parentValStack.add(parentVal);
- parentVal = val;
+ RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
}
-
- void parseValEntry(Misc::TokenReader& parser)
+ else if (parser.AdvanceIf("cbuffer"))
{
- auto parentForNewVal = parentVal;
+ // A `cbuffer` is basically just an object where the content of
+ // the object is being provided by `uniform` data instead.
- ShaderInputLayout::Field field;
- field.val = parseVal(parser);
- parseFieldBindings(parser, field);
+ RefPtr<ShaderInputLayout::ObjectVal> objVal = new ShaderInputLayout::ObjectVal;
- parentForNewVal->addField(field);
- }
+ RefPtr<ShaderInputLayout::DataVal> dataVal = new ShaderInputLayout::DataVal;
+ maybeParseOptions(parser, dataVal.Ptr());
+
+ objVal->contentVal = dataVal;
- void parseSetEntry(Misc::TokenReader& parser)
+ return objVal;
+ }
+ else if (parser.AdvanceIf("ubuffer"))
+ {
+ RefPtr<ShaderInputLayout::BufferVal> val = new ShaderInputLayout::BufferVal;
+ val->bufferDesc.type = InputBufferType::StorageBuffer;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("Texture1D"))
+ {
+ RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
+ val->textureDesc.dimension = 1;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("RWTextureBuffer"))
+ {
+ RefPtr<ShaderInputLayout::BufferVal> val = new ShaderInputLayout::BufferVal;
+ val->bufferDesc.type = InputBufferType::StorageBuffer;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("Texture2D"))
+ {
+ RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
+ val->textureDesc.dimension = 2;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("Texture3D"))
+ {
+ RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
+ val->textureDesc.dimension = 3;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("TextureCube"))
+ {
+ RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
+ val->textureDesc.dimension = 2;
+ val->textureDesc.isCube = true;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("RWTexture1D"))
+ {
+ RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
+ val->textureDesc.dimension = 1;
+ val->textureDesc.isRWTexture = true;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("RWTexture2D"))
+ {
+ RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
+ val->textureDesc.dimension = 2;
+ val->textureDesc.isRWTexture = true;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("RWTexture3D"))
+ {
+ RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
+ val->textureDesc.dimension = 3;
+ val->textureDesc.isRWTexture = true;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("RWTextureCube"))
+ {
+ RefPtr<ShaderInputLayout::TextureVal> val = new ShaderInputLayout::TextureVal;
+ val->textureDesc.dimension = 2;
+ val->textureDesc.isCube = true;
+ val->textureDesc.isRWTexture = true;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("Sampler"))
+ {
+ RefPtr<ShaderInputLayout::SamplerVal> val = new ShaderInputLayout::SamplerVal;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("TextureSampler1D"))
+ {
+ RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val =
+ new ShaderInputLayout::CombinedTextureSamplerVal;
+ val->textureVal = new ShaderInputLayout::TextureVal;
+ val->samplerVal = new ShaderInputLayout::SamplerVal;
+ val->textureVal->textureDesc.dimension = 1;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("TextureSampler2D"))
+ {
+ RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val =
+ new ShaderInputLayout::CombinedTextureSamplerVal;
+ val->textureVal = new ShaderInputLayout::TextureVal;
+ val->samplerVal = new ShaderInputLayout::SamplerVal;
+ val->textureVal->textureDesc.dimension = 2;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("TextureSampler3D"))
{
- auto parentForNewVal = parentVal;
+ RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val =
+ new ShaderInputLayout::CombinedTextureSamplerVal;
+ val->textureVal = new ShaderInputLayout::TextureVal;
+ val->samplerVal = new ShaderInputLayout::SamplerVal;
+ val->textureVal->textureDesc.dimension = 3;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("TextureSamplerCube"))
+ {
+ RefPtr<ShaderInputLayout::CombinedTextureSamplerVal> val =
+ new ShaderInputLayout::CombinedTextureSamplerVal;
+ val->textureVal = new ShaderInputLayout::TextureVal;
+ val->samplerVal = new ShaderInputLayout::SamplerVal;
+ val->textureVal->textureDesc.dimension = 2;
+ val->textureVal->textureDesc.isCube = true;
+ maybeParseOptions(parser, val.Ptr());
+ return val;
+ }
+ else if (parser.AdvanceIf("AccelerationStructure"))
+ {
+ RefPtr<ShaderInputLayout::AccelerationStructureVal> val =
+ new ShaderInputLayout::AccelerationStructureVal();
+ return val;
+ }
+ else
+ {
+ throw ShaderInputLayoutFormatException(
+ String("Unknown shader input type '") + word + String("' at line") +
+ String(parser.NextToken().Position.Line));
+ }
+ parser.ReadToken();
+ return nullptr;
+ }
- ShaderInputLayout::Field field;
- field.name = parseName(parser);
- parser.Read(Misc::TokenType::OpAssign);
- field.val = parseValExpr(parser);
+ String parseName(Misc::TokenReader& parser)
+ {
+ typedef Misc::Token Token;
+ typedef Misc::TokenType TokenType;
- parentForNewVal->addField(field);
- }
+ StringBuilder builder;
- void parseTypeConformance(Misc::TokenReader& parser)
+ Token nameToken = parser.ReadToken();
+ if (nameToken.Type != TokenType::Identifier)
{
- ShaderInputLayout::TypeConformanceVal conformance;
- conformance.derivedTypeName = parseTypeName(parser);
- parser.Read(":");
- conformance.baseTypeName = parseTypeName(parser);
- if (parser.AdvanceIf("="))
- conformance.idOverride = parser.ReadInt();
- layout->typeConformances.add(conformance);
+ throw ShaderInputLayoutFormatException(
+ StringBuilder() << "Invalid input syntax at line "
+ << parser.NextToken().Position.Line);
}
+ builder << nameToken.Content;
- void parseLine(Misc::TokenReader& parser)
+ for (;;)
{
- if (parser.LookAhead("entryPointSpecializationArg")
- || parser.LookAhead("type")
- || parser.LookAhead("entryPointExistentialType"))
+ Token token = parser.NextToken(0);
+
+ if (token.Type == TokenType::LBracket)
{
parser.ReadToken();
- StringBuilder typeExp;
- while (!parser.IsEnd())
- typeExp << parser.ReadToken().Content;
- layout->entryPointSpecializationArgs.add(typeExp);
+ int index = parser.ReadInt();
+ SLANG_ASSERT(index >= 0);
+ parser.ReadMatchingToken(TokenType::RBracket);
+
+ builder << "[" << index << "]";
}
- else if (parser.LookAhead("globalSpecializationArg")
- || parser.LookAhead("global_type")
- || parser.LookAhead("globalExistentialType"))
+ else if (token.Type == TokenType::Dot)
{
parser.ReadToken();
- StringBuilder typeExp;
- while (!parser.IsEnd())
- typeExp << parser.ReadToken().Content;
- layout->globalSpecializationArgs.add(typeExp);
- }
- else if (parser.AdvanceIf("render_targets"))
- {
- layout->numRenderTargets = parser.ReadInt();
- }
- else if( parser.AdvanceIf("end") )
- {
- parentVal = parentValStack.getLast();
- parentValStack.removeLast();
- }
- else if( parser.AdvanceIf("set") )
- {
- parseSetEntry(parser);
- }
- else if (parser.AdvanceIf("type_conformance"))
- {
- parseTypeConformance(parser);
+ Token identifierToken = parser.ReadMatchingToken(TokenType::Identifier);
+
+ builder << "." << identifierToken.Content;
}
else
{
- parseValEntry(parser);
+ return builder;
}
}
+ }
- RefPtr<ShaderInputLayout::AggVal> parse(const char * source)
+ void parseFieldBindings(Misc::TokenReader& parser, ShaderInputLayout::Field& ioField)
+ {
+ // parse bindings
+ if (parser.LookAhead(":"))
{
- RefPtr<ShaderInputLayout::AggVal> rootVal = new ShaderInputLayout::AggVal;
- parentVal = rootVal;
-
- auto lines = Misc::Split(source, '\n');
- for (auto & line : lines)
+ parser.Read(":");
+ while (!parser.IsEnd())
{
- if (line.startsWith("//TEST_INPUT:"))
+ if (parser.AdvanceIf("out"))
{
- auto lineContent = line.subString(13, line.getLength() - 13);
- Misc::TokenReader parser(lineContent);
- try
- {
- parseLine(parser);
- }
- catch (const Misc::TextFormatException&)
+ ioField.val->isOutput = true;
+ }
+ else if (parser.AdvanceIf("name"))
+ {
+ // Optionally consume '='
+ if (parser.NextToken().Type == Misc::TokenType::OpAssign)
{
- StringBuilder msg;
- msg << "Invalid input syntax at line " << parser.NextToken().Position.Line;
- throw ShaderInputLayoutFormatException(msg);
+ parser.ReadToken();
}
+
+ ioField.name = parseName(parser);
}
+ else
+ {
+ fprintf(
+ stderr,
+ "Invalid TEST_INPUT syntax '%s'\n",
+ parser.NextToken().Content.getBuffer());
+ break;
+ }
+
+ if (parser.LookAhead(","))
+ parser.Read(",");
}
+ }
+ }
- // TODO: check that stack has been maintained correctly...
+ void pushParentVal(ShaderInputLayout::ParentVal* val)
+ {
+ parentValStack.add(parentVal);
+ parentVal = val;
+ }
- return rootVal;
- }
- };
+ void parseValEntry(Misc::TokenReader& parser)
+ {
+ auto parentForNewVal = parentVal;
+
+ ShaderInputLayout::Field field;
+ field.val = parseVal(parser);
+ parseFieldBindings(parser, field);
+
+ parentForNewVal->addField(field);
+ }
- void ShaderInputLayout::parse(RandomGenerator* rand, const char * source)
+ void parseSetEntry(Misc::TokenReader& parser)
{
- rootVal = nullptr;
- globalSpecializationArgs.clear();
- entryPointSpecializationArgs.clear();
+ auto parentForNewVal = parentVal;
+
+ ShaderInputLayout::Field field;
+ field.name = parseName(parser);
+ parser.Read(Misc::TokenType::OpAssign);
+ field.val = parseValExpr(parser);
- ShaderInputLayoutParser parser(this, rand);
- rootVal = parser.parse(source);
+ parentForNewVal->addField(field);
}
- /* static */SlangResult ShaderInputLayout::writeBinding(slang::TypeLayoutReflection* typeLayout, const void* data, size_t sizeInBytes, WriterHelper writer)
+ void parseTypeConformance(Misc::TokenReader& parser)
{
- typedef slang::TypeReflection::ScalarType ScalarType;
+ ShaderInputLayout::TypeConformanceVal conformance;
+ conformance.derivedTypeName = parseTypeName(parser);
+ parser.Read(":");
+ conformance.baseTypeName = parseTypeName(parser);
+ if (parser.AdvanceIf("="))
+ conformance.idOverride = parser.ReadInt();
+ layout->typeConformances.add(conformance);
+ }
- slang::TypeReflection::ScalarType scalarType = slang::TypeReflection::ScalarType::None;
+ void parseLine(Misc::TokenReader& parser)
+ {
+ if (parser.LookAhead("entryPointSpecializationArg") || parser.LookAhead("type") ||
+ parser.LookAhead("entryPointExistentialType"))
+ {
+ parser.ReadToken();
+ StringBuilder typeExp;
+ while (!parser.IsEnd())
+ typeExp << parser.ReadToken().Content;
+ layout->entryPointSpecializationArgs.add(typeExp);
+ }
+ else if (
+ parser.LookAhead("globalSpecializationArg") || parser.LookAhead("global_type") ||
+ parser.LookAhead("globalExistentialType"))
+ {
+ parser.ReadToken();
+ StringBuilder typeExp;
+ while (!parser.IsEnd())
+ typeExp << parser.ReadToken().Content;
+ layout->globalSpecializationArgs.add(typeExp);
+ }
+ else if (parser.AdvanceIf("render_targets"))
+ {
+ layout->numRenderTargets = parser.ReadInt();
+ }
+ else if (parser.AdvanceIf("end"))
+ {
+ parentVal = parentValStack.getLast();
+ parentValStack.removeLast();
+ }
+ else if (parser.AdvanceIf("set"))
+ {
+ parseSetEntry(parser);
+ }
+ else if (parser.AdvanceIf("type_conformance"))
+ {
+ parseTypeConformance(parser);
+ }
+ else
+ {
+ parseValEntry(parser);
+ }
+ }
- slang::TypeLayoutReflection* elementTypeLayout = nullptr;
+ RefPtr<ShaderInputLayout::AggVal> parse(const char* source)
+ {
+ RefPtr<ShaderInputLayout::AggVal> rootVal = new ShaderInputLayout::AggVal;
+ parentVal = rootVal;
- if (typeLayout)
+ auto lines = Misc::Split(source, '\n');
+ for (auto& line : lines)
{
- switch (typeLayout->getKind())
+ if (line.startsWith("//TEST_INPUT:"))
{
-
- //case slang::TypeReflection::Kind::Struct:
- case slang::TypeReflection::Kind::Array:
- case slang::TypeReflection::Kind::Matrix:
- case slang::TypeReflection::Kind::Vector:
+ auto lineContent = line.subString(13, line.getLength() - 13);
+ Misc::TokenReader parser(lineContent);
+ try
{
- elementTypeLayout = typeLayout->getElementTypeLayout();
- break;
+ parseLine(parser);
}
- case slang::TypeReflection::Kind::Scalar:
+ catch (const Misc::TextFormatException&)
{
- elementTypeLayout = typeLayout;
- break;
- }
- case slang::TypeReflection::Kind::Resource:
- {
- elementTypeLayout = typeLayout->getElementTypeLayout();
- break;
- }
- case slang::TypeReflection::Kind::TextureBuffer:
- case slang::TypeReflection::Kind::ShaderStorageBuffer:
- {
- elementTypeLayout = typeLayout->getElementTypeLayout();
- break;
+ StringBuilder msg;
+ msg << "Invalid input syntax at line " << parser.NextToken().Position.Line;
+ throw ShaderInputLayoutFormatException(msg);
}
}
}
- if (elementTypeLayout)
- {
- scalarType = elementTypeLayout->getScalarType();
- }
+ // TODO: check that stack has been maintained correctly...
- if (scalarType != ScalarType::None && scalarType != ScalarType::Void)
- {
- UnownedStringSlice text = TypeTextUtil::getScalarTypeName(scalarType);
- // Write out the type
- writer.put("type: ");
- writer.put(text);
- writer.put("\n");
- }
+ return rootVal;
+ }
+};
+
+void ShaderInputLayout::parse(RandomGenerator* rand, const char* source)
+{
+ rootVal = nullptr;
+ globalSpecializationArgs.clear();
+ entryPointSpecializationArgs.clear();
+
+ ShaderInputLayoutParser parser(this, rand);
+ rootVal = parser.parse(source);
+}
+
+/* static */ SlangResult ShaderInputLayout::writeBinding(
+ slang::TypeLayoutReflection* typeLayout,
+ const void* data,
+ size_t sizeInBytes,
+ WriterHelper writer)
+{
+ typedef slang::TypeReflection::ScalarType ScalarType;
- switch (scalarType)
+ slang::TypeReflection::ScalarType scalarType = slang::TypeReflection::ScalarType::None;
+
+ slang::TypeLayoutReflection* elementTypeLayout = nullptr;
+
+ if (typeLayout)
+ {
+ switch (typeLayout->getKind())
{
- // TODO(JS):
- // Bool is here, because it's not clear across APIs how bool is laid out in memory
- default:
- case ScalarType::None:
- case ScalarType::Void:
- case ScalarType::Bool:
+
+ // case slang::TypeReflection::Kind::Struct:
+ case slang::TypeReflection::Kind::Array:
+ case slang::TypeReflection::Kind::Matrix:
+ case slang::TypeReflection::Kind::Vector:
{
- auto ptr = (const uint32_t*)data;
- const size_t size = sizeInBytes / sizeof(ptr[0]);
- for (size_t i = 0; i < size; ++i)
- {
- uint32_t v = ptr[i];
- writer.print("%X\n", v);
- }
+ elementTypeLayout = typeLayout->getElementTypeLayout();
break;
}
- case ScalarType::Float16:
+ case slang::TypeReflection::Kind::Scalar:
{
- auto ptr = (const uint16_t*)data;
- const size_t size = sizeInBytes / sizeof(ptr[0]);
- for (size_t i = 0; i < size; ++i)
- {
- const float v = HalfToFloat(ptr[i]);
- writer.print("%f\n", v);
- }
+ elementTypeLayout = typeLayout;
break;
}
- case ScalarType::UInt32:
+ case slang::TypeReflection::Kind::Resource:
{
- auto ptr = (const uint32_t*)data;
- const size_t size = sizeInBytes / sizeof(ptr[0]);
- for (size_t i = 0; i < size; ++i)
- {
- uint32_t v = ptr[i];
- writer.print("%u\n", v);
- }
+ elementTypeLayout = typeLayout->getElementTypeLayout();
break;
}
- case ScalarType::Int32:
+ case slang::TypeReflection::Kind::TextureBuffer:
+ case slang::TypeReflection::Kind::ShaderStorageBuffer:
{
- auto ptr = (const int32_t*)data;
- const size_t size = sizeInBytes / sizeof(ptr[0]);
- for (size_t i = 0; i < size; ++i)
- {
- int32_t v = ptr[i];
- writer.print("%i\n", v);
- }
+ elementTypeLayout = typeLayout->getElementTypeLayout();
break;
}
- case ScalarType::Int64:
+ }
+ }
+
+ if (elementTypeLayout)
+ {
+ scalarType = elementTypeLayout->getScalarType();
+ }
+
+ if (scalarType != ScalarType::None && scalarType != ScalarType::Void)
+ {
+ UnownedStringSlice text = TypeTextUtil::getScalarTypeName(scalarType);
+ // Write out the type
+ writer.put("type: ");
+ writer.put(text);
+ writer.put("\n");
+ }
+
+ switch (scalarType)
+ {
+ // TODO(JS):
+ // Bool is here, because it's not clear across APIs how bool is laid out in memory
+ default:
+ case ScalarType::None:
+ case ScalarType::Void:
+ case ScalarType::Bool:
+ {
+ auto ptr = (const uint32_t*)data;
+ const size_t size = sizeInBytes / sizeof(ptr[0]);
+ for (size_t i = 0; i < size; ++i)
+ {
+ uint32_t v = ptr[i];
+ writer.print("%X\n", v);
+ }
+ break;
+ }
+ case ScalarType::Float16:
+ {
+ auto ptr = (const uint16_t*)data;
+ const size_t size = sizeInBytes / sizeof(ptr[0]);
+ for (size_t i = 0; i < size; ++i)
{
- auto ptr = (const int64_t*)data;
- const size_t size = sizeInBytes / sizeof(ptr[0]);
- for (size_t i = 0; i < size; ++i)
- {
- int64_t v = ptr[i];
- writer.print("%" PRId64 "\n", v);
- }
- break;
+ const float v = HalfToFloat(ptr[i]);
+ writer.print("%f\n", v);
}
- case ScalarType::UInt64:
+ break;
+ }
+ case ScalarType::UInt32:
+ {
+ auto ptr = (const uint32_t*)data;
+ const size_t size = sizeInBytes / sizeof(ptr[0]);
+ for (size_t i = 0; i < size; ++i)
{
- auto ptr = (const uint64_t*)data;
- const size_t size = sizeInBytes / sizeof(ptr[0]);
- for (size_t i = 0; i < size; ++i)
- {
- uint64_t v = ptr[i];
- writer.print("%" PRIu64 "\n", v);
- }
- break;
+ uint32_t v = ptr[i];
+ writer.print("%u\n", v);
}
- case ScalarType::Float32:
+ break;
+ }
+ case ScalarType::Int32:
+ {
+ auto ptr = (const int32_t*)data;
+ const size_t size = sizeInBytes / sizeof(ptr[0]);
+ for (size_t i = 0; i < size; ++i)
{
- auto ptr = (const float*)data;
- const size_t size = sizeInBytes / sizeof(ptr[0]);
- for (size_t i = 0; i < size; ++i)
- {
- const float v = ptr[i];
- writer.print("%f\n", v);
- }
- break;
+ int32_t v = ptr[i];
+ writer.print("%i\n", v);
}
- case ScalarType::Float64:
+ break;
+ }
+ case ScalarType::Int64:
+ {
+ auto ptr = (const int64_t*)data;
+ const size_t size = sizeInBytes / sizeof(ptr[0]);
+ for (size_t i = 0; i < size; ++i)
{
- auto ptr = (const double*)data;
- const size_t size = sizeInBytes / sizeof(ptr[0]);
- for (size_t i = 0; i < size; ++i)
- {
- const double v = ptr[i];
- writer.print("%f\n", v);
- }
- break;
+ int64_t v = ptr[i];
+ writer.print("%" PRId64 "\n", v);
}
+ break;
+ }
+ case ScalarType::UInt64:
+ {
+ auto ptr = (const uint64_t*)data;
+ const size_t size = sizeInBytes / sizeof(ptr[0]);
+ for (size_t i = 0; i < size; ++i)
+ {
+ uint64_t v = ptr[i];
+ writer.print("%" PRIu64 "\n", v);
+ }
+ break;
+ }
+ case ScalarType::Float32:
+ {
+ auto ptr = (const float*)data;
+ const size_t size = sizeInBytes / sizeof(ptr[0]);
+ for (size_t i = 0; i < size; ++i)
+ {
+ const float v = ptr[i];
+ writer.print("%f\n", v);
+ }
+ break;
+ }
+ case ScalarType::Float64:
+ {
+ auto ptr = (const double*)data;
+ const size_t size = sizeInBytes / sizeof(ptr[0]);
+ for (size_t i = 0; i < size; ++i)
+ {
+ const double v = ptr[i];
+ writer.print("%f\n", v);
+ }
+ break;
}
-
- return SLANG_OK;
}
- void loadDataIntoHalf(uint16_t& out, const uint8_t& in)
- {
- out = FloatToHalf((float(in) / 255.0f));
- }
- void loadDataIntoFloat(float& out, const uint8_t& in)
- {
- out = (float(in)/255.0f);
- }
- template<typename T>
- void loadDataIntoUint(T& out, const uint8_t& in)
- {
- out = T(in);
- }
- template<typename T>
- void loadDataIntoInt(T& out, const uint8_t& in)
- {
- out = T(in);
- }
+ return SLANG_OK;
+}
- // T for type to return, F for function pointer to operate on uint8->T
- template<typename T, typename F>
- void generateTextureDataWithTargetTStorage(TextureData& output, const InputTextureDesc& desc, const rhi::FormatInfo& formatInfo, F loadUint8ToT)
- {
- // the following function assumes input of 0 or 1 since our testing framework only tests with 0 or 1
- TextureData work;
- generateTextureDataRGB8(work, desc);
+void loadDataIntoHalf(uint16_t& out, const uint8_t& in)
+{
+ out = FloatToHalf((float(in) / 255.0f));
+}
+void loadDataIntoFloat(float& out, const uint8_t& in)
+{
+ out = (float(in) / 255.0f);
+}
+template<typename T>
+void loadDataIntoUint(T& out, const uint8_t& in)
+{
+ out = T(in);
+}
+template<typename T>
+void loadDataIntoInt(T& out, const uint8_t& in)
+{
+ out = T(in);
+}
- output.init(desc.format);
+// T for type to return, F for function pointer to operate on uint8->T
+template<typename T, typename F>
+void generateTextureDataWithTargetTStorage(
+ TextureData& output,
+ const InputTextureDesc& desc,
+ const rhi::FormatInfo& formatInfo,
+ F loadUint8ToT)
+{
+ // the following function assumes input of 0 or 1 since our testing framework only tests with 0
+ // or 1
+ TextureData work;
+ generateTextureDataRGB8(work, desc);
- output.m_textureSize = work.m_textureSize;
- output.m_mipLevels = work.m_mipLevels;
- output.m_arraySize = work.m_arraySize;
+ output.init(desc.format);
- List<TextureData::Slice>& dstSlices = output.m_slices;
+ output.m_textureSize = work.m_textureSize;
+ output.m_mipLevels = work.m_mipLevels;
+ output.m_arraySize = work.m_arraySize;
- Index numSlices = work.m_slices.getCount();
- dstSlices.setCount(numSlices);
+ List<TextureData::Slice>& dstSlices = output.m_slices;
- for (int i = 0; i < numSlices; ++i)
- {
- const TextureData::Slice& srcSlice = work.m_slices[i];
+ Index numSlices = work.m_slices.getCount();
+ dstSlices.setCount(numSlices);
- const Index pixelCount = srcSlice.valuesCount;
- const uint8_t* srcPixels = (const uint8_t*)srcSlice.values;
+ for (int i = 0; i < numSlices; ++i)
+ {
+ const TextureData::Slice& srcSlice = work.m_slices[i];
- T* dstPixels = (T*)output.setSliceCount(i, pixelCount);
- switch (formatInfo.channelCount)
- {
- case 1:
+ const Index pixelCount = srcSlice.valuesCount;
+ const uint8_t* srcPixels = (const uint8_t*)srcSlice.values;
+
+ T* dstPixels = (T*)output.setSliceCount(i, pixelCount);
+ switch (formatInfo.channelCount)
+ {
+ case 1:
{
for (Index j = 0; j < pixelCount; ++j, srcPixels += 4, dstPixels += 1)
{
@@ -1198,7 +1251,7 @@ namespace renderer_test
}
break;
}
- case 2:
+ case 2:
{
for (Index j = 0; j < pixelCount; ++j, srcPixels += 4, dstPixels += 2)
{
@@ -1208,7 +1261,7 @@ namespace renderer_test
}
break;
}
- case 3:
+ case 3:
{
for (Index j = 0; j < pixelCount; ++j, srcPixels += 4, dstPixels += 3)
{
@@ -1219,7 +1272,7 @@ namespace renderer_test
}
break;
}
- case 4:
+ case 4:
{
for (Index j = 0; j < pixelCount; ++j, srcPixels += 4, dstPixels += 4)
{
@@ -1231,245 +1284,286 @@ namespace renderer_test
}
break;
}
- }
}
}
- void generateTextureData(TextureData& output, const InputTextureDesc& desc)
- {
- const FormatInfo& formatInfo = getFormatInfo(desc.format);
+}
+void generateTextureData(TextureData& output, const InputTextureDesc& desc)
+{
+ const FormatInfo& formatInfo = getFormatInfo(desc.format);
- switch (desc.format)
+ switch (desc.format)
+ {
+ case Format::R8G8B8A8_UNORM:
{
- case Format::R8G8B8A8_UNORM:
- {
- generateTextureDataRGB8(output, desc);
- break;
- }
- case Format::R16_FLOAT:
- case Format::R16G16_FLOAT:
- case Format::R16G16B16A16_FLOAT:
- {
- generateTextureDataWithTargetTStorage<uint16_t>(output, desc, formatInfo, loadDataIntoHalf);
- break;
- }
- case Format::R64_UINT:
- {
- generateTextureDataWithTargetTStorage<uint64_t>(output, desc, formatInfo, loadDataIntoUint<uint64_t>);
- break;
- }
- case Format::R32_FLOAT:
- case Format::R32G32_FLOAT:
- case Format::R32G32B32_FLOAT:
- case Format::R32G32B32A32_FLOAT:
- case Format::D32_FLOAT:
- {
- generateTextureDataWithTargetTStorage<float>(output, desc, formatInfo, loadDataIntoFloat);
- break;
- }
- case Format::R32_UINT:
- case Format::R32G32_UINT:
- case Format::R32G32B32_UINT:
- case Format::R32G32B32A32_UINT:
- {
- generateTextureDataWithTargetTStorage<uint32_t>(output, desc, formatInfo, loadDataIntoUint<uint32_t>);
- break;
- }
- case Format::R16_UINT:
- case Format::R16G16_UINT:
- case Format::R16G16B16A16_UINT:
- {
- generateTextureDataWithTargetTStorage<uint16_t>(output, desc, formatInfo, loadDataIntoUint<uint16_t>);
- break;
- }
- case Format::R8_UINT:
- case Format::R8G8_UINT:
- case Format::R8G8B8A8_UINT:
- {
- generateTextureDataWithTargetTStorage<uint8_t>(output, desc, formatInfo, loadDataIntoUint<uint8_t>);
- break;
- }
- case Format::R64_SINT:
- {
- generateTextureDataWithTargetTStorage<int64_t>(output, desc, formatInfo, loadDataIntoInt<int64_t>);
- break;
- }
- case Format::R32_SINT:
- case Format::R32G32_SINT:
- case Format::R32G32B32_SINT:
- case Format::R32G32B32A32_SINT:
- {
- generateTextureDataWithTargetTStorage<int32_t>(output, desc, formatInfo, loadDataIntoInt<int32_t>);
- break;
- }
- case Format::R16_SINT:
- case Format::R16G16_SINT:
- case Format::R16G16B16A16_SINT:
- {
- generateTextureDataWithTargetTStorage<int16_t>(output, desc, formatInfo, loadDataIntoInt<int16_t>);
- break;
- }
- case Format::R8_SINT:
- case Format::R8G8_SINT:
- case Format::R8G8B8A8_SINT:
- {
- generateTextureDataWithTargetTStorage<int8_t>(output, desc, formatInfo, loadDataIntoInt<int8_t>);
- break;
- }
- default:
- {
- SLANG_ASSERT(!"Unhandled format");
- break;
- }
+ generateTextureDataRGB8(output, desc);
+ break;
}
- }
-
- template <typename F>
- void _iteratePixels(int dimension, int size, unsigned int * buffer, F f)
- {
- if (dimension == 1)
- for (int i = 0; i < size; i++)
- buffer[i] = f(i, 0, 0);
- else if (dimension == 2)
- for (int i = 0; i < size; i++)
- for (int j = 0; j < size; j++)
- buffer[i*size + j] = f(j, i, 0);
- else if (dimension == 3)
- for (int i = 0; i < size; i++)
- for (int j = 0; j < size; j++)
- for (int k = 0; k < size; k++)
- buffer[i*size*size + j * size + k] = f(k, j, i);
- };
-
- void generateTextureDataRGB8(TextureData& output, const InputTextureDesc& inputDesc)
- {
- int arrLen = inputDesc.arrayLength;
- if (arrLen == 0)
- arrLen = 1;
-
- output.init(Format::R8G8B8A8_UNORM);
-
- enum class SimpleScalarType {
- kUint,
- kInt,
- kFloat,
- };
- SimpleScalarType type;
- const rhi::FormatInfo& formatInfo = getFormatInfo(inputDesc.format);
- switch (formatInfo.channelType)
- {
- case SLANG_SCALAR_TYPE_UINT64:
- case SLANG_SCALAR_TYPE_UINT32:
- case SLANG_SCALAR_TYPE_UINT16:
- case SLANG_SCALAR_TYPE_UINT8:
- type = SimpleScalarType::kUint;
+ case Format::R16_FLOAT:
+ case Format::R16G16_FLOAT:
+ case Format::R16G16B16A16_FLOAT:
+ {
+ generateTextureDataWithTargetTStorage<uint16_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoHalf);
break;
- case SLANG_SCALAR_TYPE_INT64:
- case SLANG_SCALAR_TYPE_INT32:
- case SLANG_SCALAR_TYPE_INT16:
- case SLANG_SCALAR_TYPE_INT8:
- type = SimpleScalarType::kInt;
+ }
+ case Format::R64_UINT:
+ {
+ generateTextureDataWithTargetTStorage<uint64_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoUint<uint64_t>);
break;
- case SLANG_SCALAR_TYPE_FLOAT64:
- case SLANG_SCALAR_TYPE_FLOAT32:
- case SLANG_SCALAR_TYPE_FLOAT16:
- type = SimpleScalarType::kFloat;
+ }
+ case Format::R32_FLOAT:
+ case Format::R32G32_FLOAT:
+ case Format::R32G32B32_FLOAT:
+ case Format::R32G32B32A32_FLOAT:
+ case Format::D32_FLOAT:
+ {
+ generateTextureDataWithTargetTStorage<float>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoFloat);
break;
- default:
- type = SimpleScalarType::kUint;
+ }
+ case Format::R32_UINT:
+ case Format::R32G32_UINT:
+ case Format::R32G32B32_UINT:
+ case Format::R32G32B32A32_UINT:
+ {
+ generateTextureDataWithTargetTStorage<uint32_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoUint<uint32_t>);
+ break;
+ }
+ case Format::R16_UINT:
+ case Format::R16G16_UINT:
+ case Format::R16G16B16A16_UINT:
+ {
+ generateTextureDataWithTargetTStorage<uint16_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoUint<uint16_t>);
+ break;
+ }
+ case Format::R8_UINT:
+ case Format::R8G8_UINT:
+ case Format::R8G8B8A8_UINT:
+ {
+ generateTextureDataWithTargetTStorage<uint8_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoUint<uint8_t>);
+ break;
+ }
+ case Format::R64_SINT:
+ {
+ generateTextureDataWithTargetTStorage<int64_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoInt<int64_t>);
break;
}
- //List<List<unsigned int>>& dataBuffer = output.dataBuffer;
- int arraySize = arrLen;
- if (inputDesc.isCube)
- arraySize *= 6;
- output.m_arraySize = arraySize;
- output.m_textureSize = inputDesc.size;
+ case Format::R32_SINT:
+ case Format::R32G32_SINT:
+ case Format::R32G32B32_SINT:
+ case Format::R32G32B32A32_SINT:
+ {
+ generateTextureDataWithTargetTStorage<int32_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoInt<int32_t>);
+ break;
+ }
+ case Format::R16_SINT:
+ case Format::R16G16_SINT:
+ case Format::R16G16B16A16_SINT:
+ {
+ generateTextureDataWithTargetTStorage<int16_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoInt<int16_t>);
+ break;
+ }
+ case Format::R8_SINT:
+ case Format::R8G8_SINT:
+ case Format::R8G8B8A8_SINT:
+ {
+ generateTextureDataWithTargetTStorage<int8_t>(
+ output,
+ desc,
+ formatInfo,
+ loadDataIntoInt<int8_t>);
+ break;
+ }
+ default:
+ {
+ SLANG_ASSERT(!"Unhandled format");
+ break;
+ }
+ }
+}
- const Index maxMipLevels = Math::Log2Floor(output.m_textureSize) + 1;
- Index mipLevels = (inputDesc.mipMapCount <= 0) ? maxMipLevels : inputDesc.mipMapCount;
- mipLevels = (mipLevels > maxMipLevels) ? maxMipLevels : mipLevels;
+template<typename F>
+void _iteratePixels(int dimension, int size, unsigned int* buffer, F f)
+{
+ if (dimension == 1)
+ for (int i = 0; i < size; i++)
+ buffer[i] = f(i, 0, 0);
+ else if (dimension == 2)
+ for (int i = 0; i < size; i++)
+ for (int j = 0; j < size; j++)
+ buffer[i * size + j] = f(j, i, 0);
+ else if (dimension == 3)
+ for (int i = 0; i < size; i++)
+ for (int j = 0; j < size; j++)
+ for (int k = 0; k < size; k++)
+ buffer[i * size * size + j * size + k] = f(k, j, i);
+};
+
+void generateTextureDataRGB8(TextureData& output, const InputTextureDesc& inputDesc)
+{
+ int arrLen = inputDesc.arrayLength;
+ if (arrLen == 0)
+ arrLen = 1;
- output.m_mipLevels = int(mipLevels);
- output.m_slices.setCount(output.m_mipLevels * output.m_arraySize);
+ output.init(Format::R8G8B8A8_UNORM);
- int slice = 0;
- for (int i = 0; i < arraySize; i++)
+ enum class SimpleScalarType
+ {
+ kUint,
+ kInt,
+ kFloat,
+ };
+ SimpleScalarType type;
+ const rhi::FormatInfo& formatInfo = getFormatInfo(inputDesc.format);
+ switch (formatInfo.channelType)
+ {
+ case SLANG_SCALAR_TYPE_UINT64:
+ case SLANG_SCALAR_TYPE_UINT32:
+ case SLANG_SCALAR_TYPE_UINT16:
+ case SLANG_SCALAR_TYPE_UINT8: type = SimpleScalarType::kUint; break;
+ case SLANG_SCALAR_TYPE_INT64:
+ case SLANG_SCALAR_TYPE_INT32:
+ case SLANG_SCALAR_TYPE_INT16:
+ case SLANG_SCALAR_TYPE_INT8: type = SimpleScalarType::kInt; break;
+ case SLANG_SCALAR_TYPE_FLOAT64:
+ case SLANG_SCALAR_TYPE_FLOAT32:
+ case SLANG_SCALAR_TYPE_FLOAT16: type = SimpleScalarType::kFloat; break;
+ default: type = SimpleScalarType::kUint; break;
+ }
+ // List<List<unsigned int>>& dataBuffer = output.dataBuffer;
+ int arraySize = arrLen;
+ if (inputDesc.isCube)
+ arraySize *= 6;
+ output.m_arraySize = arraySize;
+ output.m_textureSize = inputDesc.size;
+
+ const Index maxMipLevels = Math::Log2Floor(output.m_textureSize) + 1;
+ Index mipLevels = (inputDesc.mipMapCount <= 0) ? maxMipLevels : inputDesc.mipMapCount;
+ mipLevels = (mipLevels > maxMipLevels) ? maxMipLevels : mipLevels;
+
+ output.m_mipLevels = int(mipLevels);
+ output.m_slices.setCount(output.m_mipLevels * output.m_arraySize);
+
+ int slice = 0;
+ for (int i = 0; i < arraySize; i++)
+ {
+ for (int j = 0; j < output.m_mipLevels; j++)
{
- for (int j = 0; j < output.m_mipLevels; j++)
- {
- int size = output.m_textureSize >> j;
- int bufferLen = size;
- if (inputDesc.dimension == 2)
- bufferLen *= size;
- else if (inputDesc.dimension == 3)
- bufferLen *= size*size;
-
- uint32_t* dst = (uint32_t*)output.setSliceCount(slice, bufferLen);
-
- if (type == SimpleScalarType::kFloat)
- _iteratePixels(inputDesc.dimension, size, dst, [&](int x, int y, int z) -> unsigned int
+ int size = output.m_textureSize >> j;
+ int bufferLen = size;
+ if (inputDesc.dimension == 2)
+ bufferLen *= size;
+ else if (inputDesc.dimension == 3)
+ bufferLen *= size * size;
+
+ uint32_t* dst = (uint32_t*)output.setSliceCount(slice, bufferLen);
+
+ if (type == SimpleScalarType::kFloat)
+ _iteratePixels(
+ inputDesc.dimension,
+ size,
+ dst,
+ [&](int x, int y, int z) -> unsigned int
+ {
+ if (inputDesc.content == InputTextureContent::Zero)
{
- if (inputDesc.content == InputTextureContent::Zero)
- {
- return 0x0;
- }
- else if (inputDesc.content == InputTextureContent::One)
- {
+ return 0x0;
+ }
+ else if (inputDesc.content == InputTextureContent::One)
+ {
+ return 0xFFFFFFFF;
+ }
+ else if (inputDesc.content == InputTextureContent::Gradient)
+ {
+ unsigned char r = (unsigned char)(x / (float)(size - 1) * 255.0f);
+ unsigned char g = (unsigned char)(y / (float)(size - 1) * 255.0f);
+ unsigned char b = (unsigned char)(z / (float)(size - 1) * 255.0f);
+ return 0xFF000000 + r + (g << 8) + (b << 16);
+ }
+ else if (inputDesc.content == InputTextureContent::ChessBoard)
+ {
+ unsigned int xSig = x < (size >> 1) ? 1 : 0;
+ unsigned int ySig = y < (size >> 1) ? 1 : 0;
+ unsigned int zSig = z < (size >> 1) ? 1 : 0;
+ auto sig = xSig ^ ySig ^ zSig;
+ if (sig)
return 0xFFFFFFFF;
- }
- else if (inputDesc.content == InputTextureContent::Gradient)
- {
- unsigned char r = (unsigned char)(x / (float)(size - 1) * 255.0f);
- unsigned char g = (unsigned char)(y / (float)(size - 1) * 255.0f);
- unsigned char b = (unsigned char)(z / (float)(size - 1) * 255.0f);
- return 0xFF000000 + r + (g << 8) + (b << 16);
- }
- else if (inputDesc.content == InputTextureContent::ChessBoard)
- {
- unsigned int xSig = x < (size >> 1) ? 1 : 0;
- unsigned int ySig = y < (size >> 1) ? 1 : 0;
- unsigned int zSig = z < (size >> 1) ? 1 : 0;
- auto sig = xSig ^ ySig ^ zSig;
- if (sig)
- return 0xFFFFFFFF;
- else
- return 0xFF808080;
- }
+ else
+ return 0xFF808080;
+ }
+ return 0x0;
+ });
+ else if (type == SimpleScalarType::kUint || type == SimpleScalarType::kInt)
+ _iteratePixels(
+ inputDesc.dimension,
+ size,
+ dst,
+ [&](int x, int y, int z) -> unsigned int
+ {
+ if (inputDesc.content == InputTextureContent::Zero)
+ {
return 0x0;
- });
- else if (type == SimpleScalarType::kUint || type == SimpleScalarType::kInt)
- _iteratePixels(inputDesc.dimension, size, dst, [&](int x, int y, int z) -> unsigned int
+ }
+ else if (inputDesc.content == InputTextureContent::One)
{
- if (inputDesc.content == InputTextureContent::Zero)
- {
- return 0x0;
- }
- else if (inputDesc.content == InputTextureContent::One)
- {
+ return 0x01010101;
+ }
+ else if (inputDesc.content == InputTextureContent::Gradient)
+ {
+ unsigned char r = (unsigned char)(x / (float)(size - 1));
+ unsigned char g = (unsigned char)(y / (float)(size - 1));
+ unsigned char b = (unsigned char)(z / (float)(size - 1));
+ return 0x01000000 + r + (g << 8) + (b << 16);
+ }
+ else if (inputDesc.content == InputTextureContent::ChessBoard)
+ {
+ unsigned int xSig = x < (size >> 1) ? 1 : 0;
+ unsigned int ySig = y < (size >> 1) ? 1 : 0;
+ unsigned int zSig = z < (size >> 1) ? 1 : 0;
+ auto sig = xSig ^ ySig ^ zSig;
+ if (sig)
return 0x01010101;
- }
- else if (inputDesc.content == InputTextureContent::Gradient)
- {
- unsigned char r = (unsigned char)(x / (float)(size - 1));
- unsigned char g = (unsigned char)(y / (float)(size - 1));
- unsigned char b = (unsigned char)(z / (float)(size - 1));
- return 0x01000000 + r + (g << 8) + (b << 16);
- }
- else if (inputDesc.content == InputTextureContent::ChessBoard)
- {
- unsigned int xSig = x < (size >> 1) ? 1 : 0;
- unsigned int ySig = y < (size >> 1) ? 1 : 0;
- unsigned int zSig = z < (size >> 1) ? 1 : 0;
- auto sig = xSig ^ ySig ^ zSig;
- if (sig)
- return 0x01010101;
- else
- return 0x0;
- }
- return 0x0;
- });
- slice++;
- }
+ else
+ return 0x0;
+ }
+ return 0x0;
+ });
+ slice++;
}
}
}
+} // namespace renderer_test