From 0ee4d4b54732239b946bae7fde32bb21aa5a3ec3 Mon Sep 17 00:00:00 2001 From: "YONGH\\yongh" Date: Fri, 20 Oct 2017 18:24:30 -0400 Subject: in-progress work: allow render-test to generate and bind various resource inputs for running test shaders with arbitrary parameter definitions. This commit contains the parser of the resource input definition. --- source/core/core.vcxproj | 2 + source/core/text-io.h | 22 - source/core/token-reader.cpp | 868 ++++++++++++++++++++++++++ source/core/token-reader.h | 258 ++++++++ source/slang/bytecode.h | 2 +- source/slang/check.cpp | 3 +- source/slang/emit.cpp | 1 + source/slang/glsl.meta.slang.h | 2 +- source/slang/ir.cpp | 6 +- source/slang/lower-to-ir.cpp | 1 + tools/render-test/main.cpp | 12 +- tools/render-test/render-d3d11.cpp | 10 + tools/render-test/render-gl.cpp | 10 + tools/render-test/render-test.vcxproj | 13 + tools/render-test/render-test.vcxproj.filters | 6 + tools/render-test/render.h | 7 +- tools/render-test/shader-input-layout.cpp | 180 ++++++ tools/render-test/shader-input-layout.h | 52 ++ tools/slang-test/main.cpp | 4 +- 19 files changed, 1423 insertions(+), 36 deletions(-) create mode 100644 source/core/token-reader.cpp create mode 100644 source/core/token-reader.h create mode 100644 tools/render-test/shader-input-layout.cpp create mode 100644 tools/render-test/shader-input-layout.h diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj index ba9fe3d98..350482686 100644 --- a/source/core/core.vcxproj +++ b/source/core/core.vcxproj @@ -36,6 +36,7 @@ + @@ -44,6 +45,7 @@ + diff --git a/source/core/text-io.h b/source/core/text-io.h index e4bdc6e2d..c914e340a 100644 --- a/source/core/text-io.h +++ b/source/core/text-io.h @@ -311,28 +311,6 @@ namespace Slang stream = 0; } }; - - inline List Split(String text, char c) - { - List result; - StringBuilder sb; - for (int i = 0; i < text.Length(); i++) - { - if (text[i] == c) - { - auto str = sb.ToString(); - if (str.Length() != 0) - result.Add(str); - sb.Clear(); - } - else - sb << text[i]; - } - auto lastStr = sb.ToString(); - if (lastStr.Length()) - result.Add(lastStr); - return result; - } } #endif diff --git a/source/core/token-reader.cpp b/source/core/token-reader.cpp new file mode 100644 index 000000000..5f7115112 --- /dev/null +++ b/source/core/token-reader.cpp @@ -0,0 +1,868 @@ +#include "token-reader.h" + +namespace Slang +{ + enum class TokenizeErrorType + { + InvalidCharacter, InvalidEscapeSequence + }; + + enum class State + { + Start, Identifier, Operator, Int, Hex, Fixed, Double, Char, String, MultiComment, SingleComment + }; + + enum class LexDerivative + { + None, Line, File + }; + + inline bool IsLetter(char ch) + { + return ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || ch == '_'); + } + + inline bool IsDigit(char ch) + { + return ch >= '0' && ch <= '9'; + } + + inline bool IsPunctuation(char ch) + { + return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%' || + ch == '!' || ch == '^' || ch == '&' || ch == '(' || ch == ')' || + ch == '=' || ch == '{' || ch == '}' || ch == '[' || ch == ']' || + ch == '|' || ch == ';' || ch == ',' || ch == '.' || ch == '<' || + ch == '>' || ch == '~' || ch == '@' || ch == ':' || ch == '?' || ch == '#'; + } + + inline bool IsWhiteSpace(char ch) + { + return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v'); + } + + void ParseOperators(const String & str, List & tokens, TokenFlags& tokenFlags, int line, int col, int startPos, String fileName) + { + int pos = 0; + while (pos < (int)str.Length()) + { + wchar_t curChar = str[pos]; + wchar_t nextChar = (pos < (int)str.Length() - 1) ? str[pos + 1] : '\0'; + wchar_t nextNextChar = (pos < (int)str.Length() - 2) ? str[pos + 2] : '\0'; + auto InsertToken = [&](TokenType type, const String & ct) + { + tokens.Add(Token(type, ct, line, col + pos, pos + startPos, fileName, tokenFlags)); + tokenFlags = 0; + }; + switch (curChar) + { + case '+': + if (nextChar == '+') + { + InsertToken(TokenType::OpInc, "++"); + pos += 2; + } + else if (nextChar == '=') + { + InsertToken(TokenType::OpAddAssign, "+="); + pos += 2; + } + else + { + InsertToken(TokenType::OpAdd, "+"); + pos++; + } + break; + case '-': + if (nextChar == '-') + { + InsertToken(TokenType::OpDec, "--"); + pos += 2; + } + else if (nextChar == '=') + { + InsertToken(TokenType::OpSubAssign, "-="); + pos += 2; + } + else if (nextChar == '>') + { + InsertToken(TokenType::RightArrow, "->"); + pos += 2; + } + else + { + InsertToken(TokenType::OpSub, "-"); + pos++; + } + break; + case '*': + if (nextChar == '=') + { + InsertToken(TokenType::OpMulAssign, "*="); + pos += 2; + } + else + { + InsertToken(TokenType::OpMul, "*"); + pos++; + } + break; + case '/': + if (nextChar == '=') + { + InsertToken(TokenType::OpDivAssign, "/="); + pos += 2; + } + else + { + InsertToken(TokenType::OpDiv, "/"); + pos++; + } + break; + case '%': + if (nextChar == '=') + { + InsertToken(TokenType::OpModAssign, "%="); + pos += 2; + } + else + { + InsertToken(TokenType::OpMod, "%"); + pos++; + } + break; + case '|': + if (nextChar == '|') + { + InsertToken(TokenType::OpOr, "||"); + pos += 2; + } + else if (nextChar == '=') + { + InsertToken(TokenType::OpOrAssign, "|="); + pos += 2; + } + else + { + InsertToken(TokenType::OpBitOr, "|"); + pos++; + } + break; + case '&': + if (nextChar == '&') + { + InsertToken(TokenType::OpAnd, "&&"); + pos += 2; + } + else if (nextChar == '=') + { + InsertToken(TokenType::OpAndAssign, "&="); + pos += 2; + } + else + { + InsertToken(TokenType::OpBitAnd, "&"); + pos++; + } + break; + case '^': + if (nextChar == '=') + { + InsertToken(TokenType::OpXorAssign, "^="); + pos += 2; + } + else + { + InsertToken(TokenType::OpBitXor, "^"); + pos++; + } + break; + case '>': + if (nextChar == '>') + { + if (nextNextChar == '=') + { + InsertToken(TokenType::OpShrAssign, ">>="); + pos += 3; + } + else + { + InsertToken(TokenType::OpRsh, ">>"); + pos += 2; + } + } + else if (nextChar == '=') + { + InsertToken(TokenType::OpGeq, ">="); + pos += 2; + } + else + { + InsertToken(TokenType::OpGreater, ">"); + pos++; + } + break; + case '<': + if (nextChar == '<') + { + if (nextNextChar == '=') + { + InsertToken(TokenType::OpShlAssign, "<<="); + pos += 3; + } + else + { + InsertToken(TokenType::OpLsh, "<<"); + pos += 2; + } + } + else if (nextChar == '=') + { + InsertToken(TokenType::OpLeq, "<="); + pos += 2; + } + else + { + InsertToken(TokenType::OpLess, "<"); + pos++; + } + break; + case '=': + if (nextChar == '=') + { + InsertToken(TokenType::OpEql, "=="); + pos += 2; + } + else + { + InsertToken(TokenType::OpAssign, "="); + pos++; + } + break; + case '!': + if (nextChar == '=') + { + InsertToken(TokenType::OpNeq, "!="); + pos += 2; + } + else + { + InsertToken(TokenType::OpNot, "!"); + pos++; + } + break; + case '?': + InsertToken(TokenType::QuestionMark, "?"); + pos++; + break; + case '@': + InsertToken(TokenType::At, "@"); + pos++; + break; + case '#': + if (nextChar == '#') + { + InsertToken(TokenType::PoundPound, "##"); + pos += 2; + } + else + { + InsertToken(TokenType::Pound, "#"); + pos++; + } + pos++; + break; + case ':': + InsertToken(TokenType::Colon, ":"); + pos++; + break; + case '~': + InsertToken(TokenType::OpBitNot, "~"); + pos++; + break; + case ';': + InsertToken(TokenType::Semicolon, ";"); + pos++; + break; + case ',': + InsertToken(TokenType::Comma, ","); + pos++; + break; + case '.': + InsertToken(TokenType::Dot, "."); + pos++; + break; + case '{': + InsertToken(TokenType::LBrace, "{"); + pos++; + break; + case '}': + InsertToken(TokenType::RBrace, "}"); + pos++; + break; + case '[': + InsertToken(TokenType::LBracket, "["); + pos++; + break; + case ']': + InsertToken(TokenType::RBracket, "]"); + pos++; + break; + case '(': + InsertToken(TokenType::LParent, "("); + pos++; + break; + case ')': + InsertToken(TokenType::RParent, ")"); + pos++; + break; + } + } + } + + List TokenizeText(const String & fileName, const String & text) + { + int lastPos = 0, pos = 0; + int line = 1, col = 0; + String file = fileName; + State state = State::Start; + StringBuilder tokenBuilder; + int tokenLine, tokenCol; + List tokenList; + LexDerivative derivative = LexDerivative::None; + TokenFlags tokenFlags = TokenFlag::AtStartOfLine; + auto InsertToken = [&](TokenType type) + { + derivative = LexDerivative::None; + tokenList.Add(Token(type, tokenBuilder.ToString(), tokenLine, tokenCol, pos, file, tokenFlags)); + tokenFlags = 0; + tokenBuilder.Clear(); + }; + auto ProcessTransferChar = [&](char nextChar) + { + switch (nextChar) + { + case '\\': + case '\"': + case '\'': + tokenBuilder.Append(nextChar); + break; + case 't': + tokenBuilder.Append('\t'); + break; + case 's': + tokenBuilder.Append(' '); + break; + case 'n': + tokenBuilder.Append('\n'); + break; + case 'r': + tokenBuilder.Append('\r'); + break; + case 'b': + tokenBuilder.Append('\b'); + break; + } + }; + while (pos <= (int)text.Length()) + { + char curChar = (pos < (int)text.Length() ? text[pos] : ' '); + char nextChar = (pos < (int)text.Length() - 1) ? text[pos + 1] : '\0'; + if (lastPos != pos) + { + if (curChar == '\n') + { + line++; + col = 0; + } + else + col++; + lastPos = pos; + } + + switch (state) + { + case State::Start: + if (IsLetter(curChar)) + { + state = State::Identifier; + tokenLine = line; + tokenCol = col; + } + else if (IsDigit(curChar)) + { + state = State::Int; + tokenLine = line; + tokenCol = col; + } + else if (curChar == '\'') + { + state = State::Char; + pos++; + tokenLine = line; + tokenCol = col; + } + else if (curChar == '"') + { + state = State::String; + pos++; + tokenLine = line; + tokenCol = col; + } + else if (curChar == '\r' || curChar == '\n') + { + tokenFlags |= TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace; + pos++; + } + else if (curChar == ' ' || curChar == '\t' || curChar == -62 || curChar == -96) // -62/-96:non-break space + { + tokenFlags |= TokenFlag::AfterWhitespace; + pos++; + } + else if (curChar == '/' && nextChar == '/') + { + state = State::SingleComment; + pos += 2; + } + else if (curChar == '/' && nextChar == '*') + { + pos += 2; + state = State::MultiComment; + } + else if (curChar == '.' && IsDigit(nextChar)) + { + tokenBuilder.Append("0."); + state = State::Fixed; + pos++; + } + else if (IsPunctuation(curChar)) + { + state = State::Operator; + tokenLine = line; + tokenCol = col; + } + else + { + pos++; + } + break; + case State::Identifier: + if (IsLetter(curChar) || IsDigit(curChar)) + { + tokenBuilder.Append(curChar); + pos++; + } + else + { + auto tokenStr = tokenBuilder.ToString(); +#if 0 + if (tokenStr == "#line_reset#") + { + line = 0; + col = 0; + tokenBuilder.Clear(); + } + else if (tokenStr == "#line") + { + derivative = LexDerivative::Line; + tokenBuilder.Clear(); + } + else if (tokenStr == "#file") + { + derivative = LexDerivative::File; + tokenBuilder.Clear(); + line = 0; + col = 0; + } + else +#endif + InsertToken(TokenType::Identifier); + state = State::Start; + } + break; + case State::Operator: + if (IsPunctuation(curChar) && !((curChar == '/' && nextChar == '/') || (curChar == '/' && nextChar == '*'))) + { + tokenBuilder.Append(curChar); + pos++; + } + else + { + //do token analyze + ParseOperators(tokenBuilder.ToString(), tokenList, tokenFlags, tokenLine, tokenCol, pos - tokenBuilder.Length(), file); + tokenBuilder.Clear(); + state = State::Start; + } + break; + case State::Int: + if (IsDigit(curChar)) + { + tokenBuilder.Append(curChar); + pos++; + } + else if (curChar == '.') + { + state = State::Fixed; + tokenBuilder.Append(curChar); + pos++; + } + else if (curChar == 'e' || curChar == 'E') + { + state = State::Double; + tokenBuilder.Append(curChar); + if (nextChar == '-' || nextChar == '+') + { + tokenBuilder.Append(nextChar); + pos++; + } + pos++; + } + else if (curChar == 'x') + { + state = State::Hex; + tokenBuilder.Append(curChar); + pos++; + } + else if (curChar == 'u') + { + pos++; + tokenBuilder.Append(curChar); + InsertToken(TokenType::IntLiteral); + state = State::Start; + } + else + { + if (derivative == LexDerivative::Line) + { + derivative = LexDerivative::None; + line = StringToInt(tokenBuilder.ToString()) - 1; + col = 0; + tokenBuilder.Clear(); + } + else + { + InsertToken(TokenType::IntLiteral); + } + state = State::Start; + } + break; + case State::Hex: + if (IsDigit(curChar) || (curChar >= 'a' && curChar <= 'f') || (curChar >= 'A' && curChar <= 'F')) + { + tokenBuilder.Append(curChar); + pos++; + } + else + { + InsertToken(TokenType::IntLiteral); + state = State::Start; + } + break; + case State::Fixed: + if (IsDigit(curChar)) + { + tokenBuilder.Append(curChar); + pos++; + } + else if (curChar == 'e' || curChar == 'E') + { + state = State::Double; + tokenBuilder.Append(curChar); + if (nextChar == '-' || nextChar == '+') + { + tokenBuilder.Append(nextChar); + pos++; + } + pos++; + } + else + { + if (curChar == 'f') + pos++; + InsertToken(TokenType::DoubleLiteral); + state = State::Start; + } + break; + case State::Double: + if (IsDigit(curChar)) + { + tokenBuilder.Append(curChar); + pos++; + } + else + { + if (curChar == 'f') + pos++; + InsertToken(TokenType::DoubleLiteral); + state = State::Start; + } + break; + case State::String: + if (curChar != '"') + { + if (curChar == '\\') + { + ProcessTransferChar(nextChar); + pos++; + } + else + tokenBuilder.Append(curChar); + } + else + { + if (derivative == LexDerivative::File) + { + derivative = LexDerivative::None; + file = tokenBuilder.ToString(); + tokenBuilder.Clear(); + } + else + { + InsertToken(TokenType::StringLiteral); + } + state = State::Start; + } + pos++; + break; + case State::Char: + if (curChar != '\'') + { + if (curChar == '\\') + { + ProcessTransferChar(nextChar); + pos++; + } + else + tokenBuilder.Append(curChar); + } + else + { + InsertToken(TokenType::CharLiteral); + state = State::Start; + } + pos++; + break; + case State::SingleComment: + if (curChar == '\n') + { + state = State::Start; + tokenFlags |= TokenFlag::AtStartOfLine | TokenFlag::AfterWhitespace; + } + pos++; + break; + case State::MultiComment: + if (curChar == '*' && nextChar == '/') + { + state = State::Start; + tokenFlags |= TokenFlag::AfterWhitespace; + pos += 2; + } + else + pos++; + break; + } + } + return tokenList; + } + List TokenizeText(const String & text) + { + return TokenizeText("", text); + } + + String EscapeStringLiteral(String str) + { + StringBuilder sb; + sb << "\""; + for (int i = 0; i < (int)str.Length(); i++) + { + switch (str[i]) + { + case ' ': + sb << "\\s"; + break; + case '\n': + sb << "\\n"; + break; + case '\r': + sb << "\\r"; + break; + case '\t': + sb << "\\t"; + break; + case '\v': + sb << "\\v"; + break; + case '\'': + sb << "\\\'"; + break; + case '\"': + sb << "\\\""; + break; + case '\\': + sb << "\\\\"; + break; + default: + sb << str[i]; + break; + } + } + sb << "\""; + return sb.ProduceString(); + } + + String UnescapeStringLiteral(String str) + { + StringBuilder sb; + for (int i = 0; i < (int)str.Length(); i++) + { + if (str[i] == '\\' && i < (int)str.Length() - 1) + { + switch (str[i + 1]) + { + case 's': + sb << " "; + break; + case 't': + sb << '\t'; + break; + case 'n': + sb << '\n'; + break; + case 'r': + sb << '\r'; + break; + case 'v': + sb << '\v'; + break; + case '\'': + sb << '\''; + break; + case '\"': + sb << "\""; + break; + case '\\': + sb << "\\"; + break; + default: + i = i - 1; + sb << str[i]; + } + i++; + } + else + sb << str[i]; + } + return sb.ProduceString(); + } + + + String TokenTypeToString(TokenType type) + { + switch (type) + { + case TokenType::EndOfFile: + return "end of file"; + case TokenType::Unknown: + return "UnknownToken"; + case TokenType::Identifier: + return "identifier"; + case TokenType::IntLiteral: + return "integer literal"; + case TokenType::DoubleLiteral: + return "floating-point literal"; + case TokenType::StringLiteral: + return "string literal"; + case TokenType::CharLiteral: + return "character literal"; + case TokenType::QuestionMark: + return "'?'"; + case TokenType::Colon: + return "':'"; + case TokenType::Semicolon: + return "';'"; + case TokenType::Comma: + return "','"; + case TokenType::LBrace: + return "'{'"; + case TokenType::RBrace: + return "'}'"; + case TokenType::LBracket: + return "'['"; + case TokenType::RBracket: + return "']'"; + case TokenType::LParent: + return "'('"; + case TokenType::RParent: + return "')'"; + case TokenType::At: + return "'@'"; + case TokenType::OpAssign: + return "'='"; + case TokenType::OpAdd: + return "'+'"; + case TokenType::OpSub: + return "'-'"; + case TokenType::OpMul: + return "'*'"; + case TokenType::OpDiv: + return "'/'"; + case TokenType::OpMod: + return "'%'"; + case TokenType::OpNot: + return "'!'"; + case TokenType::OpLsh: + return "'<<'"; + case TokenType::OpRsh: + return "'>>'"; + case TokenType::OpAddAssign: + return "'+='"; + case TokenType::OpSubAssign: + return "'-='"; + case TokenType::OpMulAssign: + return "'*='"; + case TokenType::OpDivAssign: + return "'/='"; + case TokenType::OpModAssign: + return "'%='"; + case TokenType::OpEql: + return "'=='"; + case TokenType::OpNeq: + return "'!='"; + case TokenType::OpGreater: + return "'>'"; + case TokenType::OpLess: + return "'<'"; + case TokenType::OpGeq: + return "'>='"; + case TokenType::OpLeq: + return "'<='"; + case TokenType::OpAnd: + return "'&&'"; + case TokenType::OpOr: + return "'||'"; + case TokenType::OpBitXor: + return "'^'"; + case TokenType::OpBitAnd: + return "'&'"; + case TokenType::OpBitOr: + return "'|'"; + case TokenType::OpInc: + return "'++'"; + case TokenType::OpDec: + return "'--'"; + case TokenType::Pound: + return "'#'"; + case TokenType::PoundPound: + return "'##'"; + default: + return ""; + } + } + + TokenReader::TokenReader(String text) + { + this->tokens = TokenizeText("", text); + tokenPtr = 0; + } +} diff --git a/source/core/token-reader.h b/source/core/token-reader.h new file mode 100644 index 000000000..aaebad756 --- /dev/null +++ b/source/core/token-reader.h @@ -0,0 +1,258 @@ +#ifndef CORE_TOKEN_READER_H +#define CORE_TOKEN_READER_H + +#include "basic.h" + +namespace Slang +{ + enum class TokenType + { + EndOfFile = -1, + // illegal + Unknown, + // identifier + Identifier, + // constant + IntLiteral, DoubleLiteral, StringLiteral, CharLiteral, + // operators + Semicolon, Comma, Dot, LBrace, RBrace, LBracket, RBracket, LParent, RParent, + OpAssign, OpAdd, OpSub, OpMul, OpDiv, OpMod, OpNot, OpBitNot, OpLsh, OpRsh, + OpEql, OpNeq, OpGreater, OpLess, OpGeq, OpLeq, + OpAnd, OpOr, OpBitXor, OpBitAnd, OpBitOr, + OpInc, OpDec, OpAddAssign, OpSubAssign, OpMulAssign, OpDivAssign, OpModAssign, + OpShlAssign, OpShrAssign, OpOrAssign, OpAndAssign, OpXorAssign, + + QuestionMark, Colon, RightArrow, At, Pound, PoundPound, + }; + + class CodePosition + { + public: + int Line = -1, Col = -1, Pos = -1; + String FileName; + String ToString() + { + StringBuilder sb(100); + sb << FileName; + if (Line != -1) + sb << "(" << Line << ")"; + return sb.ProduceString(); + } + CodePosition() = default; + CodePosition(int line, int col, int pos, String fileName) + { + Line = line; + Col = col; + Pos = pos; + this->FileName = fileName; + } + bool operator < (const CodePosition & pos) const + { + return FileName < pos.FileName || (FileName == pos.FileName && Line < pos.Line) || + (FileName == pos.FileName && Line == pos.Line && Col < pos.Col); + } + bool operator == (const CodePosition & pos) const + { + return FileName == pos.FileName && Line == pos.Line && Col == pos.Col; + } + }; + + enum TokenFlag : unsigned int + { + AtStartOfLine = 1 << 0, + AfterWhitespace = 1 << 1, + }; + typedef unsigned int TokenFlags; + + class Token + { + public: + TokenType Type = TokenType::Unknown; + String Content; + CodePosition Position; + TokenFlags flags; + Token() = default; + Token(TokenType type, const String & content, int line, int col, int pos, String fileName, TokenFlags flags = 0) + : flags(flags) + { + Type = type; + Content = content; + Position = CodePosition(line, col, pos, fileName); + } + }; + + class TextFormatException : public Exception + { + public: + TextFormatException(String message) + : Exception(message) + {} + }; + + class TokenReader + { + private: + bool legal; + List tokens; + int tokenPtr; + public: + TokenReader(String text); + int ReadInt() + { + auto token = ReadToken(); + bool neg = false; + if (token.Content == '-') + { + neg = true; + token = ReadToken(); + } + if (token.Type == TokenType::IntLiteral) + { + if (neg) + return -StringToInt(token.Content); + else + return StringToInt(token.Content); + } + throw TextFormatException("Text parsing error: int expected."); + } + unsigned int ReadUInt() + { + auto token = ReadToken(); + if (token.Type == TokenType::IntLiteral) + { + return StringToUInt(token.Content); + } + throw TextFormatException("Text parsing error: int expected."); + } + double ReadDouble() + { + auto token = ReadToken(); + bool neg = false; + if (token.Content == '-') + { + neg = true; + token = ReadToken(); + } + if (token.Type == TokenType::DoubleLiteral || token.Type == TokenType::IntLiteral) + { + if (neg) + return -StringToDouble(token.Content); + else + return StringToDouble(token.Content); + } + throw TextFormatException("Text parsing error: floating point value expected."); + } + float ReadFloat() + { + return (float)ReadDouble(); + } + String ReadWord() + { + auto token = ReadToken(); + if (token.Type == TokenType::Identifier) + { + return token.Content; + } + throw TextFormatException("Text parsing error: identifier expected."); + } + String Read(const char * expectedStr) + { + auto token = ReadToken(); + if (token.Content == expectedStr) + { + return token.Content; + } + throw TextFormatException("Text parsing error: \'" + String(expectedStr) + "\' expected."); + } + String Read(String expectedStr) + { + auto token = ReadToken(); + if (token.Content == expectedStr) + { + return token.Content; + } + throw TextFormatException("Text parsing error: \'" + expectedStr + "\' expected."); + } + + String ReadStringLiteral() + { + auto token = ReadToken(); + if (token.Type == TokenType::StringLiteral) + { + return token.Content; + } + throw TextFormatException("Text parsing error: string literal expected."); + } + void Back(int count) + { + tokenPtr -= count; + } + Token ReadToken() + { + if (tokenPtr < (int)tokens.Count()) + { + auto &rs = tokens[tokenPtr]; + tokenPtr++; + return rs; + } + throw TextFormatException("Unexpected ending."); + } + Token NextToken(int offset = 0) + { + if (tokenPtr + offset < (int)tokens.Count()) + return tokens[tokenPtr + offset]; + else + { + Token rs; + rs.Type = TokenType::Unknown; + return rs; + } + } + bool LookAhead(String token) + { + if (tokenPtr < (int)tokens.Count()) + { + auto next = NextToken(); + return next.Content == token; + } + else + { + return false; + } + } + bool IsEnd() + { + return tokenPtr == (int)tokens.Count(); + } + public: + bool IsLegalText() + { + return legal; + } + }; + + inline List Split(String text, char c) + { + List result; + StringBuilder sb; + for (int i = 0; i < (int)text.Length(); i++) + { + if (text[i] == c) + { + auto str = sb.ToString(); + if (str.Length() != 0) + result.Add(str); + sb.Clear(); + } + else + sb << text[i]; + } + auto lastStr = sb.ToString(); + if (lastStr.Length()) + result.Add(lastStr); + return result; + } +} + + +#endif \ No newline at end of file diff --git a/source/slang/bytecode.h b/source/slang/bytecode.h index f38007ba9..75b9f15cd 100644 --- a/source/slang/bytecode.h +++ b/source/slang/bytecode.h @@ -243,7 +243,7 @@ struct BCHeader // entry points for each target. }; -struct CompileRequest; +class CompileRequest; void generateBytecodeForCompileRequest( CompileRequest* compileReq); diff --git a/source/slang/check.cpp b/source/slang/check.cpp index f12e7e55d..5ebb22999 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -4,6 +4,7 @@ #include "compiler.h" #include "visitor.h" +#include "../core/secure-crt.h" #include namespace Slang @@ -4887,7 +4888,7 @@ namespace Slang if (auto decl = dynamic_cast(candidate.item.declRef.decl)) { char buffer[1024]; - sprintf(buffer, "[this:%p, primary:%p, next:%p]", + sprintf_s(buffer, sizeof(buffer), "[this:%p, primary:%p, next:%p]", decl, decl->primaryDecl, decl->nextDecl); diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 971f0345b..da9489a75 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -4517,6 +4517,7 @@ emitDeclImpl(decl, nullptr); switch(inst->op) { + case 0: // nothing yet default: emit(getIRName(inst)); break; diff --git a/source/slang/glsl.meta.slang.h b/source/slang/glsl.meta.slang.h index e43a51ea9..a4aade3c2 100644 --- a/source/slang/glsl.meta.slang.h +++ b/source/slang/glsl.meta.slang.h @@ -173,7 +173,7 @@ sb << "syntax patch : GLSLPatchModifier;\n"; // [GLSL 4.5] Interpolation Qualifiers sb << "syntax smooth : SimpleModifier;\n"; sb << "syntax flat : SimpleModifier;\n"; -sb << "syntax noperspectie : SimpleModifier;\n"; +sb << "syntax noperspective : SimpleModifier;\n"; // [GLSL 4.3.2] Constant Qualifier diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index 5ace50397..4bf9de5d3 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -1614,9 +1614,9 @@ namespace Slang // There are several ops we want to special-case here, // so that they will be more pleasant to look at. // +#if 0 switch (op) { -#if 0 case kIROp_Module: dumpIndent(context); dump(context, "module\n"); @@ -1688,11 +1688,11 @@ namespace Slang dumpChildrenRaw(context, block); } return; -#endif default: break; } +#endif #if 0 // We also want to special-case based on the *type* @@ -2918,7 +2918,7 @@ namespace Slang // TODO: are there any instruction types that need to be handled // specially here? That would be anything that has more state // than is visible in its operand list... - + case 0: // nothing yet default: { // The common case is that we just need to construct a cloned diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index a3d67b670..327902e4a 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -338,6 +338,7 @@ LoweredValInfo emitCallToVal( auto builder = context->irBuilder; switch (funcVal.flavor) { + case LoweredValInfo::Flavor::None: default: return LoweredValInfo::simple( builder->emitCallInst(type, getSimpleVal(context, funcVal), argCount, args)); diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp index 6907ba40f..02b1963ff 100644 --- a/tools/render-test/main.cpp +++ b/tools/render-test/main.cpp @@ -5,7 +5,7 @@ #include "render-d3d11.h" #include "render-gl.h" #include "slang-support.h" - +#include "shader-input-layout.h" #include #include @@ -55,7 +55,9 @@ Buffer* gConstantBuffer; InputLayout* gInputLayout; Buffer* gVertexBuffer; Buffer* gComputeResultBuffer; -ShaderProgram* gShaderProgram; +ShaderProgram* gShaderProgram; +BindingState* gBindingState; +ShaderInputLayout gShaderInputLayout; // Entry point name to use for vertex/fragment shader static char const* vertexEntryPointName = "vertexMain"; @@ -92,6 +94,8 @@ Error initializeShaders( fclose(sourceFile); sourceText[sourceSize] = 0; + gShaderInputLayout.Parse(sourceText); + ShaderCompileRequest::SourceInfo sourceInfo; sourceInfo.path = sourcePath; sourceInfo.text = sourceText; @@ -144,6 +148,7 @@ Error initializeInner( err = initializeShaders(shaderCompiler); if(err != Error::None) return err; + gBindingState = renderer->createBindingState(gShaderInputLayout); // Do other initialization that doesn't depend on the source language. @@ -222,7 +227,7 @@ void renderFrameInner( renderer->setShaderProgram(gShaderProgram); renderer->setConstantBuffer(0, gConstantBuffer); - + renderer->setBindingState(gBindingState); // renderer->draw(3); @@ -232,6 +237,7 @@ void runCompute(Renderer * renderer) { renderer->setShaderProgram(gShaderProgram); renderer->setStorageBuffer(0, gComputeResultBuffer); + renderer->setBindingState(gBindingState); renderer->dispatchCompute(1, 1, 1); } diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 6e9e04a78..8915952e0 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -751,6 +751,16 @@ public: auto dxContext = dxImmediateContext; dxContext->Dispatch(x, y, z); } + + virtual BindingState * createBindingState(const ShaderInputLayout & layout) + { + return nullptr; + } + + virtual void setBindingState(BindingState * state) + { + + } }; diff --git a/tools/render-test/render-gl.cpp b/tools/render-test/render-gl.cpp index 55647fb25..79dd09ad9 100644 --- a/tools/render-test/render-gl.cpp +++ b/tools/render-test/render-gl.cpp @@ -613,6 +613,16 @@ public: { glDispatchCompute(x, y, z); } + + virtual BindingState * createBindingState(const ShaderInputLayout & layout) + { + return nullptr; + } + + virtual void setBindingState(BindingState * state) + { + + } }; diff --git a/tools/render-test/render-test.vcxproj b/tools/render-test/render-test.vcxproj index 94af429e8..0b0f6b05e 100644 --- a/tools/render-test/render-test.vcxproj +++ b/tools/render-test/render-test.vcxproj @@ -96,6 +96,8 @@ Level3 Disabled WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + ../../source/ + MultiThreadedDebug Console @@ -109,6 +111,8 @@ Level3 Disabled _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + ../../source/ + MultiThreadedDebug Console @@ -124,6 +128,8 @@ true true WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + ../../source/ + MultiThreaded Console @@ -141,6 +147,8 @@ true true NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + ../../source/ + MultiThreaded Console @@ -154,6 +162,7 @@ + @@ -161,10 +170,14 @@ + + + {f9be7957-8399-899e-0c49-e714fddd4b65} + {db00da62-0533-4afd-b59f-a67d5b3a0808} diff --git a/tools/render-test/render-test.vcxproj.filters b/tools/render-test/render-test.vcxproj.filters index 6e0ff295a..985e24b8b 100644 --- a/tools/render-test/render-test.vcxproj.filters +++ b/tools/render-test/render-test.vcxproj.filters @@ -30,6 +30,9 @@ Source Files + + Source Files + @@ -50,5 +53,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/tools/render-test/render.h b/tools/render-test/render.h index 7f8f2fffa..426b0738a 100644 --- a/tools/render-test/render.h +++ b/tools/render-test/render.h @@ -3,13 +3,14 @@ #include "options.h" #include "window.h" +#include "shader-input-layout.h" namespace renderer_test { typedef struct Buffer Buffer; typedef struct InputLayout InputLayout; typedef struct ShaderProgram ShaderProgram; - +typedef struct BindingState BindingState; struct ShaderCompileRequest { struct SourceInfo @@ -93,7 +94,7 @@ public: virtual Buffer* createBuffer(BufferDesc const& desc) = 0; virtual InputLayout* createInputLayout(InputElementDesc const* inputElements, UInt inputElementCount) = 0; - + virtual BindingState* createBindingState(const ShaderInputLayout & shaderInput) = 0; virtual ShaderCompiler* getShaderCompiler() = 0; virtual void* map(Buffer* buffer, MapFlavor flavor) = 0; @@ -101,7 +102,7 @@ public: virtual void setInputLayout(InputLayout* inputLayout) = 0; virtual void setPrimitiveTopology(PrimitiveTopology topology) = 0; - + virtual void setBindingState(BindingState * state) = 0; virtual void setVertexBuffers(UInt startSlot, UInt slotCount, Buffer* const* buffers, UInt const* strides, UInt const* offsets) = 0; inline void setVertexBuffer(UInt slot, Buffer* buffer, UInt stride, UInt offset = 0) diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp new file mode 100644 index 000000000..c97028441 --- /dev/null +++ b/tools/render-test/shader-input-layout.cpp @@ -0,0 +1,180 @@ +#include "shader-input-layout.h" +#include "core/token-reader.h" + +namespace renderer_test +{ + using namespace Slang; + void ShaderInputLayout::Parse(const char * source) + { + entries.Clear(); + auto lines = Split(source, '\n'); + for (auto & line : lines) + { + if (line.StartsWith("//TEST_INPUT:")) + { + auto lineContent = line.SubString(13, line.Length() - 13); + TokenReader parser(lineContent); + try + { + ShaderInputLayoutEntry entry; + + if (parser.LookAhead("cbuffer")) + { + entry.type = ShaderInputType::Buffer; + entry.bufferDesc.type = InputBufferType::ConstantBuffer; + } + else if (parser.LookAhead("ubuffer")) + { + entry.type = ShaderInputType::Buffer; + entry.bufferDesc.type = InputBufferType::StorageBuffer; + } + else if (parser.LookAhead("Texture1D")) + { + entry.type = ShaderInputType::Texture; + entry.textureDesc.dimension = 1; + } + else if (parser.LookAhead("Texture2D")) + { + entry.type = ShaderInputType::Texture; + entry.textureDesc.dimension = 2; + } + else if (parser.LookAhead("Texture3D")) + { + entry.type = ShaderInputType::Texture; + entry.textureDesc.dimension = 3; + } + else if (parser.LookAhead("TextureCube")) + { + entry.type = ShaderInputType::Texture; + entry.textureDesc.dimension = 2; + entry.textureDesc.isCube = true; + } + else if (parser.LookAhead("Sampler")) + { + entry.type = ShaderInputType::Sampler; + } + else if (parser.LookAhead("Sampler1D")) + { + entry.type = ShaderInputType::CombinedTextureSampler; + entry.textureDesc.dimension = 1; + } + else if (parser.LookAhead("Sampler2D")) + { + entry.type = ShaderInputType::CombinedTextureSampler; + entry.textureDesc.dimension = 2; + } + else if (parser.LookAhead("Sampler3D")) + { + entry.type = ShaderInputType::CombinedTextureSampler; + entry.textureDesc.dimension = 3; + } + else if (parser.LookAhead("SamplerCube")) + { + entry.type = ShaderInputType::CombinedTextureSampler; + entry.textureDesc.dimension = 2; + entry.textureDesc.isCube = true; + } + parser.ReadToken(); + // parse options + if (parser.LookAhead("(")) + { + parser.Read("("); + while (!parser.IsEnd() && !parser.LookAhead(")")) + { + auto word = parser.ReadWord(); + if (word == "depth") + { + entry.textureDesc.isDepthTexture = true; + } + else if (word == "depthCompare") + { + entry.samplerDesc.isCompareSampler = true; + } + else if (word == "arrayLength") + { + parser.Read("="); + entry.textureDesc.arrayLength = parser.ReadInt(); + } + else if (word == "stride") + { + parser.Read("="); + entry.bufferDesc.stride = parser.ReadInt(); + } + else if (word == "data") + { + parser.Read("="); + parser.Read("["); + while (!parser.IsEnd() && !parser.LookAhead("]")) + { + if (parser.NextToken().Type == TokenType::IntLiteral) + { + entry.bufferData.Add(parser.ReadUInt()); + } + else + { + auto floatNum = parser.ReadFloat(); + entry.bufferData.Add(*(unsigned int*)&floatNum); + } + } + parser.Read("]"); + } + if (parser.LookAhead(",")) + parser.Read(","); + else + break; + } + parser.Read(")"); + // parse bindings + if (parser.LookAhead(":")) + { + parser.Read(":"); + while (!parser.IsEnd()) + { + if (parser.LookAhead("register")) + { + parser.ReadToken(); + parser.Read("("); + auto reg = parser.ReadWord(); + entry.hlslRegister = parser.ReadInt(); + parser.Read(")"); + } + else if (parser.LookAhead("layout")) + { + parser.ReadToken(); + parser.Read("("); + while (!parser.IsEnd() && !parser.LookAhead(")")) + { + auto word = parser.ReadWord(); + if (word == "binding") + { + parser.Read("="); + entry.glslBinding = parser.ReadInt(); + } + else if (word == "location") + { + parser.Read("="); + entry.glslLocation = parser.ReadInt(); + } + if (parser.LookAhead(",")) + parser.Read(","); + else + break; + } + parser.Read(")"); + } + if (parser.LookAhead(",")) + parser.Read(","); + } + } + } + } + catch (TextFormatException) + { + throw TextFormatException("Invalid input syntax at line " + parser.NextToken().Position.Line); + } + } + } + + + } +} \ No newline at end of file diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h new file mode 100644 index 000000000..788a72224 --- /dev/null +++ b/tools/render-test/shader-input-layout.h @@ -0,0 +1,52 @@ +#ifndef SLANG_TEST_SHADER_INPUT_LAYOUT_H +#define SLANG_TEST_SHADER_INPUT_LAYOUT_H + +#include "core/basic.h" + +namespace renderer_test +{ + enum class ShaderInputType + { + Buffer, Texture, Sampler, CombinedTextureSampler + }; + struct InputTextureDesc + { + int dimension = 2; + int arrayLength = 0; + bool isCube = false; + bool isDepthTexture = false; + }; + enum class InputBufferType + { + ConstantBuffer, StorageBuffer + }; + struct InputBufferDesc + { + InputBufferType type = InputBufferType::ConstantBuffer; + int stride = 0; // stride == 0 indicates an unstructured buffer. + }; + struct InputSamplerDesc + { + bool isCompareSampler = false; + }; + class ShaderInputLayoutEntry + { + public: + ShaderInputType type; + Slang::List bufferData; + InputTextureDesc textureDesc; + InputBufferDesc bufferDesc; + InputSamplerDesc samplerDesc; + int hlslRegister = -1; + int glslBinding = -1; + int glslLocation = -1; + }; + class ShaderInputLayout + { + public: + Slang::List entries; + void Parse(const char * source); + }; +} + +#endif \ No newline at end of file diff --git a/tools/slang-test/main.cpp b/tools/slang-test/main.cpp index fb10d46f6..181c34b00 100644 --- a/tools/slang-test/main.cpp +++ b/tools/slang-test/main.cpp @@ -1,6 +1,7 @@ // main.cpp #include "../../source/core/slang-io.h" +#include "../../source/core/token-reader.h" using namespace Slang; @@ -20,7 +21,6 @@ using namespace Slang; #include #include #include - enum OutputMode { // Default mode is to write test results to the console @@ -1145,7 +1145,7 @@ TestResult doComputeComparisonTestRunImpl(TestInput& input, const char * langOpt auto referenceProgramOutput = Split(File::ReadAllText(referenceOutput), '\n'); if (actualProgramOutput.Count() < referenceProgramOutput.Count()) return kTestResult_Fail; - for (int i = 0; i < referenceProgramOutput.Count(); i++) + for (int i = 0; i < (int)referenceProgramOutput.Count(); i++) { auto reference = StringToFloat(referenceProgramOutput[i]); auto actual = StringToFloat(actualProgramOutput[i]); -- cgit v1.2.3 From 0c8efd12667e66b3177c5d8557a0677c7d5d0e4e Mon Sep 17 00:00:00 2001 From: "YONGH\\yongh" Date: Fri, 20 Oct 2017 19:12:47 -0400 Subject: work in progress --- tools/render-test/render-d3d11.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 8915952e0..98b18e447 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -36,6 +36,7 @@ #endif #endif // +using namespace Slang; namespace renderer_test { @@ -752,6 +753,16 @@ public: dxContext->Dispatch(x, y, z); } + struct D3DBinding + { + ID3D11ShaderResourceView * resourceView; + + }; + struct D3DBindingState + { + List bindings; + }; + virtual BindingState * createBindingState(const ShaderInputLayout & layout) { return nullptr; -- cgit v1.2.3 From cc6184ebc4d0611be892eaff119de99f8b9e1ca6 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 10:35:44 -0400 Subject: Work in-progress: simple compute test passed. (d3d renderer) --- source/slang/type-defs.h | 1 - tests/compute/simple.slang | 2 +- tests/compute/simple.slang.expected.txt | 8 +- tools/render-test/main.cpp | 35 +-- tools/render-test/render-d3d11.cpp | 462 ++++++++++++++++++++++++++++-- tools/render-test/render-gl.cpp | 5 + tools/render-test/render.h | 2 +- tools/render-test/shader-input-layout.cpp | 115 +++++--- tools/render-test/shader-input-layout.h | 11 +- tools/slang-test/main.cpp | 6 +- 10 files changed, 541 insertions(+), 106 deletions(-) diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h index e928efb65..7ec801a14 100644 --- a/source/slang/type-defs.h +++ b/source/slang/type-defs.h @@ -318,7 +318,6 @@ SYNTAX_CLASS(GroupSharedType, Type) RAW( virtual ~GroupSharedType() { - int f = 0; } virtual Slang::String ToString() override; diff --git a/tests/compute/simple.slang b/tests/compute/simple.slang index 3f43c8cc7..8f53a79b2 100644 --- a/tests/compute/simple.slang +++ b/tests/compute/simple.slang @@ -1,5 +1,5 @@ //TEST(smoke,compute):COMPARE_COMPUTE: - +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out // This is a basic test for Slang compute shader. RWStructuredBuffer outputBuffer; diff --git a/tests/compute/simple.slang.expected.txt b/tests/compute/simple.slang.expected.txt index fdaa30664..98798bd61 100644 --- a/tests/compute/simple.slang.expected.txt +++ b/tests/compute/simple.slang.expected.txt @@ -1,4 +1,4 @@ -0.0 -1.0 -2.0 -3.0 \ No newline at end of file +0 +3F800000 +40000000 +40400000 \ No newline at end of file diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp index 02b1963ff..c19238f5d 100644 --- a/tools/render-test/main.cpp +++ b/tools/render-test/main.cpp @@ -54,7 +54,6 @@ uintptr_t gConstantBufferSize, gComputeResultBufferSize; Buffer* gConstantBuffer; InputLayout* gInputLayout; Buffer* gVertexBuffer; -Buffer* gComputeResultBuffer; ShaderProgram* gShaderProgram; BindingState* gBindingState; ShaderInputLayout gShaderInputLayout; @@ -125,16 +124,6 @@ Error initializeShaders( return Error::None; } - -void outputComputeResult(Renderer* renderer, const char * fileName) -{ - float* data = (float*)renderer->map(gComputeResultBuffer, MapFlavor::HostRead); - FILE* f = fopen(fileName, "wt"); - for (auto i = 0u; i < gComputeResultBufferSize / sizeof(UInt); i++) - fprintf(f, "%.9g\n", data[i]); - fclose(f); -} - // // At initialization time, we are going to load and compile our Slang shader // code, and then create the D3D11 API objects we need for rendering. @@ -162,20 +151,7 @@ Error initializeInner( gConstantBuffer = renderer->createBuffer(constantBufferDesc); if(!gConstantBuffer) return Error::Unexpected; - - gComputeResultBufferSize = 512 * sizeof(float); - BufferDesc computeResultBufferDesc; - computeResultBufferDesc.size = gComputeResultBufferSize; - computeResultBufferDesc.flavor = BufferFlavor::Storage; - gComputeResultBuffer = renderer->createBuffer(computeResultBufferDesc); - if (!gComputeResultBufferSize) - return Error::Unexpected; - // initialize buffer to 0 - char * ptr = (char*)renderer->map(gComputeResultBuffer, MapFlavor::HostWrite); - for (auto i = 0u; i < gComputeResultBufferSize; i++) - ptr[i] = 0; - renderer->unmap(gComputeResultBuffer); - + // Input Assembler (IA) InputElementDesc inputElements[] = { @@ -236,7 +212,6 @@ void renderFrameInner( void runCompute(Renderer * renderer) { renderer->setShaderProgram(gShaderProgram); - renderer->setStorageBuffer(0, gComputeResultBuffer); renderer->setBindingState(gBindingState); renderer->dispatchCompute(1, 1, 1); } @@ -434,10 +409,10 @@ int main( // If we are in a mode where output is requested, we need to snapshot the back buffer here if (gOptions.outputPath) { - if (gOptions.shaderType == ShaderProgramType::Compute) - outputComputeResult(renderer, gOptions.outputPath); - else - renderer->captureScreenShot(gOptions.outputPath); + if (gOptions.shaderType == ShaderProgramType::Compute) + renderer->serializeOutput(gBindingState, gOptions.outputPath); + else + renderer->captureScreenShot(gOptions.outputPath); return 0; } diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 98b18e447..2b8f12104 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -40,6 +40,22 @@ using namespace Slang; namespace renderer_test { +struct D3DBinding +{ + ShaderInputType type; + ID3D11ShaderResourceView * srv = nullptr; + ID3D11UnorderedAccessView * uav = nullptr; + ID3D11Buffer * buffer = nullptr; + ID3D11SamplerState * samplerState = nullptr; + int binding = 0; + bool isOutput = false; + int bufferLength = 0; +}; +struct D3DBindingState +{ + List bindings; +}; + // @@ -248,7 +264,9 @@ public: ID3D11DeviceContext* dxImmediateContext = NULL; ID3D11Texture2D* dxBackBufferTexture = NULL; ID3D11RenderTargetView* dxBackBufferRTV = NULL; - + List dxRenderTargetViews; + List dxRenderTargetTextures; + D3DBindingState * currentBindings = nullptr; virtual void initialize(void* inWindowHandle) override { auto windowHandle = (HWND) inWindowHandle; @@ -362,12 +380,32 @@ public: dxBackBufferTexture, NULL, &dxBackBufferRTV); - + dxRenderTargetViews.Add(dxBackBufferRTV); + for (int i = 0; i < 7; i++) + { + ID3D11Texture2D* texture; + D3D11_TEXTURE2D_DESC textureDesc; + dxBackBufferTexture->GetDesc(&textureDesc); + textureDesc.ArraySize = 1; + textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.MiscFlags = 0; + dxDevice->CreateTexture2D(&textureDesc, nullptr, &texture); + ID3D11RenderTargetView * rtv; + dxDevice->CreateRenderTargetView( + texture, + NULL, + &rtv); + dxRenderTargetViews.Add(rtv); + dxRenderTargetTextures.Add(texture); + } // We immediately bind the back-buffer render target view, and we aren't // going to switch. We don't bother with a depth buffer. dxImmediateContext->OMSetRenderTargets( - 1, - &dxBackBufferRTV, + dxRenderTargetViews.Count(), + dxRenderTargetViews.Buffer(), NULL); // Similarly, we are going to set up a viewport once, and then never @@ -390,9 +428,10 @@ public: virtual void clearFrame() override { - dxImmediateContext->ClearRenderTargetView( - dxBackBufferRTV, - clearColor); + for (auto i = 0u; i < dxRenderTargetViews.Count(); i++) + dxImmediateContext->ClearRenderTargetView( + dxRenderTargetViews[i], + clearColor); } virtual void presentFrame() override @@ -559,24 +598,24 @@ public: return (InputLayout*) dxInputLayout; } - virtual void* map(Buffer* buffer, MapFlavor flavor) override + void* map(ID3D11Buffer * buffer, MapFlavor flavor) { auto dxContext = dxImmediateContext; - auto dxBuffer = ((D3DBuffer*)buffer)->buffer; + auto dxBuffer = buffer; D3D11_MAP dxMapFlavor; - switch( flavor ) + switch (flavor) { case MapFlavor::WriteDiscard: dxMapFlavor = D3D11_MAP_WRITE_DISCARD; break; - case MapFlavor::HostWrite: - dxMapFlavor = D3D11_MAP_WRITE; - break; - case MapFlavor::HostRead: - dxMapFlavor = D3D11_MAP_READ; - break; + case MapFlavor::HostWrite: + dxMapFlavor = D3D11_MAP_WRITE; + break; + case MapFlavor::HostRead: + dxMapFlavor = D3D11_MAP_READ; + break; default: return nullptr; } @@ -586,19 +625,27 @@ public: // per-frame (we always use an identity projection). D3D11_MAPPED_SUBRESOURCE dxMapped; HRESULT hr = dxContext->Map(dxBuffer, 0, dxMapFlavor, 0, &dxMapped); - if(FAILED(hr)) + if (FAILED(hr)) return nullptr; return dxMapped.pData; } - virtual void unmap(Buffer* buffer) override + virtual void* map(Buffer* buffer, MapFlavor flavor) override + { + return map(((D3DBuffer*)buffer)->buffer, flavor); + } + + void unmap(ID3D11Buffer * buffer) { auto dxContext = dxImmediateContext; + dxContext->Unmap(buffer, 0); + } + virtual void unmap(Buffer* buffer) override + { auto dxBuffer = ((D3DBuffer*)buffer)->buffer; - - dxContext->Unmap(dxBuffer, 0); + unmap(dxBuffer); } virtual void setInputLayout(InputLayout* inputLayout) override @@ -687,7 +734,7 @@ public: virtual void draw(UInt vertexCount, UInt startVertex) override { auto dxContext = dxImmediateContext; - + applyBindingState(false); dxContext->Draw((UINT) vertexCount, (UINT) startVertex); } @@ -750,27 +797,386 @@ public: virtual void dispatchCompute(int x, int y, int z) override { auto dxContext = dxImmediateContext; + applyBindingState(true); dxContext->Dispatch(x, y, z); } - struct D3DBinding + void createInputBuffer( + InputBufferDesc & bufferDesc, + List & bufferData, + ID3D11Buffer * &bufferOut, + ID3D11UnorderedAccessView * &viewOut, + ID3D11ShaderResourceView * &srvOut) { - ID3D11ShaderResourceView * resourceView; + auto dxContext = dxImmediateContext; + D3D11_BUFFER_DESC desc = {0}; + desc.ByteWidth = bufferData.Count() * sizeof(unsigned int); + if (bufferDesc.type == InputBufferType::ConstantBuffer) + { + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER | D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + } + else + { + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + if (bufferDesc.stride != 0) + { + desc.StructureByteStride = bufferDesc.stride; + desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + } + else + { + desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; + } + } + D3D11_SUBRESOURCE_DATA data = {0}; + data.pSysMem = bufferData.Buffer(); + dxDevice->CreateBuffer(&desc, &data, &bufferOut); + int elemSize = bufferDesc.stride <= 0 ? 1 : bufferDesc.stride; + if (bufferDesc.type == InputBufferType::StorageBuffer) + { + D3D11_UNORDERED_ACCESS_VIEW_DESC viewDesc; + memset(&viewDesc, 0, sizeof(viewDesc)); + viewDesc.Buffer.FirstElement = 0; + viewDesc.Buffer.NumElements = (UINT)(bufferData.Count() * sizeof(unsigned int) / elemSize); + viewDesc.Buffer.Flags = 0; + viewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + viewDesc.Format = DXGI_FORMAT_UNKNOWN; + dxDevice->CreateUnorderedAccessView(bufferOut, &viewDesc, &viewOut); + } + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + memset(&srvDesc, 0, sizeof(srvDesc)); + srvDesc.Buffer.FirstElement = 0; + srvDesc.Buffer.ElementWidth = elemSize; + srvDesc.Buffer.NumElements = (UINT)(bufferData.Count() * sizeof(unsigned int) / elemSize); + srvDesc.Buffer.ElementOffset = 0; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + srvDesc.Format = DXGI_FORMAT_UNKNOWN; + dxDevice->CreateShaderResourceView(bufferOut, &srvDesc, &srvOut); + } - }; - struct D3DBindingState + void createInputTexture(const InputTextureDesc & inputDesc, ID3D11ShaderResourceView * &viewOut) { - List bindings; - }; + int arrLen = inputDesc.arrayLength; + if (arrLen == 0) + arrLen = 1; + List subRes; + List> dataBuffer; + int arraySize = arrLen; + if (inputDesc.isCube) + arraySize *= 6; + int textureSize = inputDesc.size; + int textureMipLevels = Math::Log2Floor(textureSize) + 1; + subRes.SetSize(textureMipLevels * arraySize); + dataBuffer.SetSize(subRes.Count()); + + auto iteratePixels = [&](int dimension, int size, unsigned int * buffer, auto 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); + }; + + int slice = 0; + for (int i = 0; i < arraySize; i++) + { + for (int j = 0; j < textureMipLevels; j++) + { + int size = textureSize >> j; + int bufferLen = size; + if (inputDesc.dimension == 2) + bufferLen *= size; + else if (inputDesc.dimension == 3) + bufferLen *= size*size; + dataBuffer[slice].SetSize(bufferLen); + subRes[slice].pSysMem = dataBuffer[slice].Buffer(); + subRes[slice].SysMemPitch = sizeof(unsigned int) * size; + subRes[slice].SysMemSlicePitch = sizeof(unsigned int) * size * size; + + iteratePixels(inputDesc.dimension, size, dataBuffer[slice].Buffer(), [&](int x, int y, int z) -> unsigned int + { + if (inputDesc.content == InputTextureContent::Zero) + { + 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 + return 0xFF808080; + } + return 0x0; + }); + slice++; + } + } + if (inputDesc.dimension == 1) + { + D3D11_TEXTURE1D_DESC desc = { 0 }; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET | D3D11_BIND_UNORDERED_ACCESS; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; + desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + desc.MipLevels = textureMipLevels; + desc.ArraySize = arraySize; + desc.Width = textureSize; + desc.Usage = D3D11_USAGE_DEFAULT; + + ID3D11Texture1D * texture; + dxDevice->CreateTexture1D(&desc, subRes.Buffer(), &texture); + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + if (inputDesc.arrayLength != 0) + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + viewDesc.Texture1D.MipLevels = textureMipLevels; + viewDesc.Texture1D.MostDetailedMip = 0; + viewDesc.Texture1DArray.ArraySize = arraySize; + viewDesc.Texture1DArray.FirstArraySlice = 0; + viewDesc.Texture1DArray.MipLevels = textureMipLevels; + viewDesc.Texture1DArray.MostDetailedMip = 0; + dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); + } + else if (inputDesc.dimension == 2) + { + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + D3D11_TEXTURE2D_DESC desc = { 0 }; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET | D3D11_BIND_UNORDERED_ACCESS; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; + desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + desc.MipLevels = textureMipLevels; + desc.ArraySize = arraySize; + if (inputDesc.isCube) + { + desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + viewDesc.TextureCube.MipLevels = textureMipLevels; + viewDesc.TextureCube.MostDetailedMip = 0; + viewDesc.TextureCubeArray.MipLevels = textureMipLevels; + viewDesc.TextureCubeArray.MostDetailedMip = 0; + viewDesc.TextureCubeArray.First2DArrayFace = 0; + viewDesc.TextureCubeArray.NumCubes = inputDesc.arrayLength; + } + else + { + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + viewDesc.Texture2D.MipLevels = textureMipLevels; + viewDesc.Texture2D.MostDetailedMip = 0; + viewDesc.Texture2DArray.ArraySize = arraySize; + viewDesc.Texture2DArray.FirstArraySlice = 0; + viewDesc.Texture2DArray.MipLevels = textureMipLevels; + viewDesc.Texture2DArray.MostDetailedMip = 0; + } + if (inputDesc.arrayLength != 0) + viewDesc.ViewDimension = (D3D11_SRV_DIMENSION)(int)(viewDesc.ViewDimension + 1); + desc.Width = textureSize; + desc.Height = textureSize; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + ID3D11Texture2D * texture; + dxDevice->CreateTexture2D(&desc, subRes.Buffer(), &texture); + dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); + } + else if (inputDesc.dimension == 3) + { + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + D3D11_TEXTURE3D_DESC desc = { 0 }; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET | D3D11_BIND_UNORDERED_ACCESS; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; + desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; + desc.MipLevels = textureMipLevels; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + desc.Width = textureSize; + desc.Height = textureSize; + desc.Depth = textureSize; + desc.Usage = D3D11_USAGE_DEFAULT; + ID3D11Texture3D * texture; + dxDevice->CreateTexture3D(&desc, subRes.Buffer(), &texture); + if (inputDesc.arrayLength != 0) + viewDesc.ViewDimension = (D3D11_SRV_DIMENSION)(int)(viewDesc.ViewDimension + 1); + viewDesc.Texture3D.MipLevels = textureMipLevels; + viewDesc.Texture3D.MostDetailedMip = 0; + dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); + } + } + void createInputSampler(const InputSamplerDesc & inputDesc, ID3D11SamplerState * & stateOut) + { + D3D11_SAMPLER_DESC desc; + memset(&desc, 0, sizeof(desc)); + desc.AddressU = desc.AddressV = desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + if (inputDesc.isCompareSampler) + { + desc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL; + desc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; + } + else + desc.Filter = D3D11_FILTER_ANISOTROPIC; + desc.MaxAnisotropy = 16; + desc.MinLOD = 0.0f; + desc.MaxLOD = 100.0f; + dxDevice->CreateSamplerState(&desc, &stateOut); + } virtual BindingState * createBindingState(const ShaderInputLayout & layout) { - return nullptr; + D3DBindingState * rs = new D3DBindingState(); + for (auto & entry : layout.entries) + { + D3DBinding rsEntry; + rsEntry.type = entry.type; + rsEntry.binding = entry.hlslBinding; + rsEntry.isOutput = entry.isOutput; + switch (entry.type) + { + case ShaderInputType::Buffer: + { + createInputBuffer(entry.bufferDesc, entry.bufferData, rsEntry.buffer, rsEntry.uav, rsEntry.srv); + rsEntry.bufferLength = entry.bufferData.Count() * sizeof(unsigned int); + } + break; + case ShaderInputType::Texture: + { + createInputTexture(entry.textureDesc, rsEntry.srv); + } + break; + case ShaderInputType::Sampler: + { + createInputSampler(entry.samplerDesc, rsEntry.samplerState); + } + break; + case ShaderInputType::CombinedTextureSampler: + { + throw "not implemented"; + } + break; + } + rs->bindings.Add(rsEntry); + } + return (BindingState*)rs; + } + + bool applyBindingState(bool isCompute) + { + auto dxContext = dxImmediateContext; + for (auto & binding : currentBindings->bindings) + { + if (binding.type == ShaderInputType::Buffer) + { + if (binding.uav) + { + if (isCompute) + dxContext->CSSetUnorderedAccessViews(binding.binding, 1, &binding.uav, nullptr); + else + dxContext->OMSetRenderTargetsAndUnorderedAccessViews(D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, + nullptr, nullptr, binding.binding, 1, &binding.uav, nullptr); + } + else + { + if (isCompute) + dxContext->CSSetShaderResources(binding.binding, 1, &binding.srv); + else + { + dxContext->PSSetShaderResources(binding.binding, 1, &binding.srv); + dxContext->VSSetShaderResources(binding.binding, 1, &binding.srv); + } + } + } + else if (binding.type == ShaderInputType::Texture) + { + if (binding.uav) + { + if (isCompute) + dxContext->CSSetUnorderedAccessViews(binding.binding, 1, &binding.uav, nullptr); + else + dxContext->OMSetRenderTargetsAndUnorderedAccessViews(D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, + nullptr, nullptr, binding.binding, 1, &binding.uav, nullptr); + } + else + { + if (isCompute) + dxContext->CSSetShaderResources(binding.binding, 1, &binding.srv); + else + { + dxContext->PSSetShaderResources(binding.binding, 1, &binding.srv); + dxContext->VSSetShaderResources(binding.binding, 1, &binding.srv); + } + } + } + else if (binding.type == ShaderInputType::Sampler) + { + if (isCompute) + dxContext->CSSetSamplers(binding.binding, 1, &binding.samplerState); + else + { + dxContext->PSSetSamplers(binding.binding, 1, &binding.samplerState); + dxContext->VSSetSamplers(binding.binding, 1, &binding.samplerState); + } + } + else + throw "not implemented"; + } } virtual void setBindingState(BindingState * state) { + auto dxBindingState = (D3DBindingState*) state; + currentBindings = dxBindingState; + } + virtual void serializeOutput(BindingState* state, const char * fileName) + { + auto dxContext = dxImmediateContext; + auto dxBindingState = (D3DBindingState*)state; + FILE * f = fopen(fileName, "wt"); + for (auto & binding : dxBindingState->bindings) + { + if (binding.isOutput) + { + if (binding.buffer) + { + auto ptr = (unsigned int *)map(binding.buffer, MapFlavor::HostRead); + for (auto i = 0u; i < binding.bufferLength / sizeof(unsigned int); i++) + fprintf(f, "%X\n", ptr[i]); + unmap(binding.buffer); + } + else + { + throw "not implemented"; + } + } + } + fclose(f); } }; diff --git a/tools/render-test/render-gl.cpp b/tools/render-test/render-gl.cpp index 79dd09ad9..ff9d54eb6 100644 --- a/tools/render-test/render-gl.cpp +++ b/tools/render-test/render-gl.cpp @@ -623,6 +623,11 @@ public: { } + + virtual void serializeOutput(BindingState* state, const char * fileName) + { + + } }; diff --git a/tools/render-test/render.h b/tools/render-test/render.h index 426b0738a..706868e9a 100644 --- a/tools/render-test/render.h +++ b/tools/render-test/render.h @@ -90,7 +90,7 @@ public: virtual void presentFrame() = 0; virtual void captureScreenShot(char const* outputPath) = 0; - + virtual void serializeOutput(BindingState * state, char const* outputPath) = 0; virtual Buffer* createBuffer(BufferDesc const& desc) = 0; virtual InputLayout* createInputLayout(InputElementDesc const* inputElements, UInt inputElementCount) = 0; diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp index c97028441..b606a1a13 100644 --- a/tools/render-test/shader-input-layout.cpp +++ b/tools/render-test/shader-input-layout.cpp @@ -49,6 +49,31 @@ namespace renderer_test entry.textureDesc.dimension = 2; entry.textureDesc.isCube = true; } + else if (parser.LookAhead("RWTexture1D")) + { + entry.type = ShaderInputType::Texture; + entry.textureDesc.dimension = 1; + entry.textureDesc.isRWTexture = true; + } + else if (parser.LookAhead("RWTexture2D")) + { + entry.type = ShaderInputType::Texture; + entry.textureDesc.dimension = 2; + entry.textureDesc.isRWTexture = true; + } + else if (parser.LookAhead("RWTexture3D")) + { + entry.type = ShaderInputType::Texture; + entry.textureDesc.dimension = 3; + entry.textureDesc.isRWTexture = true; + } + else if (parser.LookAhead("RWTextureCube")) + { + entry.type = ShaderInputType::Texture; + entry.textureDesc.dimension = 2; + entry.textureDesc.isCube = true; + entry.textureDesc.isRWTexture = true; + } else if (parser.LookAhead("Sampler")) { entry.type = ShaderInputType::Sampler; @@ -74,6 +99,11 @@ namespace renderer_test entry.textureDesc.dimension = 2; entry.textureDesc.isCube = true; } + else if (parser.LookAhead("render_targets")) + { + numRenderTargets = parser.ReadInt(); + continue; + } parser.ReadToken(); // parse options if (parser.LookAhead("(")) @@ -100,6 +130,11 @@ namespace renderer_test parser.Read("="); entry.bufferDesc.stride = parser.ReadInt(); } + else if (word == "size") + { + parser.Read("="); + entry.textureDesc.size = parser.ReadInt(); + } else if (word == "data") { parser.Read("="); @@ -118,55 +153,61 @@ namespace renderer_test } parser.Read("]"); } + else if (word == "content") + { + parser.Read("="); + auto contentWord = parser.ReadWord(); + if (contentWord == "zero") + entry.textureDesc.content = InputTextureContent::Zero; + else if (contentWord == "one") + entry.textureDesc.content = InputTextureContent::One; + else if (contentWord == "chessboard") + entry.textureDesc.content = InputTextureContent::ChessBoard; + else + entry.textureDesc.content = InputTextureContent::Gradient; + } if (parser.LookAhead(",")) parser.Read(","); else break; } - parser.Read(")"); - // parse bindings - if (parser.LookAhead(":")) + } + parser.Read(")"); + // parse bindings + if (parser.LookAhead(":")) + { + parser.Read(":"); + while (!parser.IsEnd()) { - parser.Read(":"); - while (!parser.IsEnd()) + if (parser.LookAhead("dxbinding")) { - if (parser.LookAhead("register")) - { - parser.ReadToken(); - parser.Read("("); - auto reg = parser.ReadWord(); - entry.hlslRegister = parser.ReadInt(); - parser.Read(")"); - } - else if (parser.LookAhead("layout")) - { - parser.ReadToken(); - parser.Read("("); - while (!parser.IsEnd() && !parser.LookAhead(")")) - { - auto word = parser.ReadWord(); - if (word == "binding") - { - parser.Read("="); - entry.glslBinding = parser.ReadInt(); - } - else if (word == "location") - { - parser.Read("="); - entry.glslLocation = parser.ReadInt(); - } - if (parser.LookAhead(",")) - parser.Read(","); - else - break; - } - parser.Read(")"); - } + parser.ReadToken(); + parser.Read("("); + entry.hlslBinding = parser.ReadInt(); + parser.Read(")"); + } + else if (parser.LookAhead("glbinding")) + { + parser.ReadToken(); + parser.Read("("); + entry.glslBinding = entry.glslLocation = parser.ReadInt(); if (parser.LookAhead(",")) + { parser.Read(","); + entry.glslLocation = parser.ReadInt(); + } + parser.Read(")"); + } + else if (parser.LookAhead("out")) + { + parser.ReadToken(); + entry.isOutput = true; } + if (parser.LookAhead(",")) + parser.Read(","); } } + entries.Add(entry); } catch (TextFormatException) { diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h index 788a72224..f2258b7b9 100644 --- a/tools/render-test/shader-input-layout.h +++ b/tools/render-test/shader-input-layout.h @@ -9,12 +9,19 @@ namespace renderer_test { Buffer, Texture, Sampler, CombinedTextureSampler }; + enum class InputTextureContent + { + Zero, One, ChessBoard, Gradient + }; struct InputTextureDesc { int dimension = 2; int arrayLength = 0; bool isCube = false; bool isDepthTexture = false; + bool isRWTexture = false; + int size = 4; + InputTextureContent content = InputTextureContent::One; }; enum class InputBufferType { @@ -37,7 +44,8 @@ namespace renderer_test InputTextureDesc textureDesc; InputBufferDesc bufferDesc; InputSamplerDesc samplerDesc; - int hlslRegister = -1; + bool isOutput = false; + int hlslBinding = -1; int glslBinding = -1; int glslLocation = -1; }; @@ -45,6 +53,7 @@ namespace renderer_test { public: Slang::List entries; + int numRenderTargets = 1; void Parse(const char * source); }; } diff --git a/tools/slang-test/main.cpp b/tools/slang-test/main.cpp index 181c34b00..272c1b618 100644 --- a/tools/slang-test/main.cpp +++ b/tools/slang-test/main.cpp @@ -1147,9 +1147,9 @@ TestResult doComputeComparisonTestRunImpl(TestInput& input, const char * langOpt return kTestResult_Fail; for (int i = 0; i < (int)referenceProgramOutput.Count(); i++) { - auto reference = StringToFloat(referenceProgramOutput[i]); - auto actual = StringToFloat(actualProgramOutput[i]); - if (abs(actual - reference) > 1e-7f) + auto reference = referenceProgramOutput[i]; + auto actual = actualProgramOutput[i]; + if (actual != reference) return kTestResult_Fail; } return kTestResult_Pass; -- cgit v1.2.3 From c8bda84077a73564e3ac05d8b886632b2b2561be Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 10:53:17 -0400 Subject: fix compute shader test result comparison --- tests/compute/generics-simple.slang.expected.txt | 8 ++++---- tools/slang-test/main.cpp | 12 ++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/compute/generics-simple.slang.expected.txt b/tests/compute/generics-simple.slang.expected.txt index fdaa30664..98798bd61 100644 --- a/tests/compute/generics-simple.slang.expected.txt +++ b/tests/compute/generics-simple.slang.expected.txt @@ -1,4 +1,4 @@ -0.0 -1.0 -2.0 -3.0 \ No newline at end of file +0 +3F800000 +40000000 +40400000 \ No newline at end of file diff --git a/tools/slang-test/main.cpp b/tools/slang-test/main.cpp index 676cb6875..cdea6b4dc 100644 --- a/tools/slang-test/main.cpp +++ b/tools/slang-test/main.cpp @@ -1168,8 +1168,16 @@ TestResult doComputeComparisonTestRunImpl(TestInput& input, const char * langOpt { auto reference = referenceProgramOutput[i]; auto actual = actualProgramOutput[i]; - if (actual != reference) - return kTestResult_Fail; + if (actual != reference) + { + // try to parse reference as float, and compare again + auto val = StringToFloat(reference); + auto uval = String((unsigned int)FloatAsInt(val), 16).ToUpper(); + if (actual != uval) + return kTestResult_Fail; + else + return kTestResult_Pass; + } } return kTestResult_Pass; } -- cgit v1.2.3 From 3c649614e5837bcf06f281f9aa5a63a350b5725b Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 11:10:40 -0400 Subject: fix test case --- tests/compute/generics-simple.slang | 2 +- tests/compute/simple.slang.actual.txt | 512 ---------------------------------- 2 files changed, 1 insertion(+), 513 deletions(-) delete mode 100644 tests/compute/simple.slang.actual.txt diff --git a/tests/compute/generics-simple.slang b/tests/compute/generics-simple.slang index 0002e444b..5a4a2e765 100644 --- a/tests/compute/generics-simple.slang +++ b/tests/compute/generics-simple.slang @@ -1,5 +1,5 @@ //TEST(smoke,compute):COMPARE_COMPUTE:-xslang -use-ir - +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out // Confirm that generics syntax can be used in user // code and generates valid output. diff --git a/tests/compute/simple.slang.actual.txt b/tests/compute/simple.slang.actual.txt deleted file mode 100644 index e8a8ee20b..000000000 --- a/tests/compute/simple.slang.actual.txt +++ /dev/null @@ -1,512 +0,0 @@ -0 -1 -2 -3 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -- cgit v1.2.3 From c68224e3e9158e54bdd7c0abe294e0bbf3f6e1a5 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 11:25:44 -0400 Subject: try fix linux build --- source/core/token-reader.cpp | 106 +------------------------------------------ 1 file changed, 1 insertion(+), 105 deletions(-) diff --git a/source/core/token-reader.cpp b/source/core/token-reader.cpp index 5f7115112..bf3294c8e 100644 --- a/source/core/token-reader.cpp +++ b/source/core/token-reader.cpp @@ -490,7 +490,7 @@ namespace Slang else { //do token analyze - ParseOperators(tokenBuilder.ToString(), tokenList, tokenFlags, tokenLine, tokenCol, pos - tokenBuilder.Length(), file); + ParseOperators(tokenBuilder.ToString(), tokenList, tokenFlags, tokenLine, tokenCol, (int)(pos - tokenBuilder.Length()), file); tokenBuilder.Clear(); state = State::Start; } @@ -756,110 +756,6 @@ namespace Slang return sb.ProduceString(); } - - String TokenTypeToString(TokenType type) - { - switch (type) - { - case TokenType::EndOfFile: - return "end of file"; - case TokenType::Unknown: - return "UnknownToken"; - case TokenType::Identifier: - return "identifier"; - case TokenType::IntLiteral: - return "integer literal"; - case TokenType::DoubleLiteral: - return "floating-point literal"; - case TokenType::StringLiteral: - return "string literal"; - case TokenType::CharLiteral: - return "character literal"; - case TokenType::QuestionMark: - return "'?'"; - case TokenType::Colon: - return "':'"; - case TokenType::Semicolon: - return "';'"; - case TokenType::Comma: - return "','"; - case TokenType::LBrace: - return "'{'"; - case TokenType::RBrace: - return "'}'"; - case TokenType::LBracket: - return "'['"; - case TokenType::RBracket: - return "']'"; - case TokenType::LParent: - return "'('"; - case TokenType::RParent: - return "')'"; - case TokenType::At: - return "'@'"; - case TokenType::OpAssign: - return "'='"; - case TokenType::OpAdd: - return "'+'"; - case TokenType::OpSub: - return "'-'"; - case TokenType::OpMul: - return "'*'"; - case TokenType::OpDiv: - return "'/'"; - case TokenType::OpMod: - return "'%'"; - case TokenType::OpNot: - return "'!'"; - case TokenType::OpLsh: - return "'<<'"; - case TokenType::OpRsh: - return "'>>'"; - case TokenType::OpAddAssign: - return "'+='"; - case TokenType::OpSubAssign: - return "'-='"; - case TokenType::OpMulAssign: - return "'*='"; - case TokenType::OpDivAssign: - return "'/='"; - case TokenType::OpModAssign: - return "'%='"; - case TokenType::OpEql: - return "'=='"; - case TokenType::OpNeq: - return "'!='"; - case TokenType::OpGreater: - return "'>'"; - case TokenType::OpLess: - return "'<'"; - case TokenType::OpGeq: - return "'>='"; - case TokenType::OpLeq: - return "'<='"; - case TokenType::OpAnd: - return "'&&'"; - case TokenType::OpOr: - return "'||'"; - case TokenType::OpBitXor: - return "'^'"; - case TokenType::OpBitAnd: - return "'&'"; - case TokenType::OpBitOr: - return "'|'"; - case TokenType::OpInc: - return "'++'"; - case TokenType::OpDec: - return "'--'"; - case TokenType::Pound: - return "'#'"; - case TokenType::PoundPound: - return "'##'"; - default: - return ""; - } - } - TokenReader::TokenReader(String text) { this->tokens = TokenizeText("", text); -- cgit v1.2.3 From 9882956fb76e8e1d8e7ca96c2c129da9cf784fec Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 21:40:14 -0400 Subject: test --- tools/render-test/render-d3d11.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 2b8f12104..9ffef42e1 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -1095,11 +1095,15 @@ public: { if (binding.uav) { + fprintf(stderr, "begin bind buffer\n"); + if (isCompute) dxContext->CSSetUnorderedAccessViews(binding.binding, 1, &binding.uav, nullptr); else dxContext->OMSetRenderTargetsAndUnorderedAccessViews(D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, binding.binding, 1, &binding.uav, nullptr); + fprintf(stderr, "end bind buffer\n"); + } else { @@ -1169,6 +1173,7 @@ public: for (auto i = 0u; i < binding.bufferLength / sizeof(unsigned int); i++) fprintf(f, "%X\n", ptr[i]); unmap(binding.buffer); + fprintf(stderr, "output[1] is %X\n", ptr[1]); } else { -- cgit v1.2.3 From 61624e3a88c21e05d96f1a42802141e3e7d4428d Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 21:48:20 -0400 Subject: attempt to fix --- tools/render-test/render-d3d11.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 9ffef42e1..5bfcf9563 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -270,7 +270,6 @@ public: virtual void initialize(void* inWindowHandle) override { auto windowHandle = (HWND) inWindowHandle; - // Rather than statically link against D3D, we load it dynamically. HMODULE d3d11 = LoadLibraryA("d3d11.dll"); @@ -832,6 +831,8 @@ public: desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; } } + fprintf(stderr, "buffer created\n"); + D3D11_SUBRESOURCE_DATA data = {0}; data.pSysMem = bufferData.Buffer(); dxDevice->CreateBuffer(&desc, &data, &bufferOut); @@ -846,6 +847,8 @@ public: viewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; viewDesc.Format = DXGI_FORMAT_UNKNOWN; dxDevice->CreateUnorderedAccessView(bufferOut, &viewDesc, &viewOut); + fprintf(stderr, "uav created\n"); + } D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; memset(&srvDesc, 0, sizeof(srvDesc)); @@ -856,6 +859,8 @@ public: srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; srvDesc.Format = DXGI_FORMAT_UNKNOWN; dxDevice->CreateShaderResourceView(bufferOut, &srvDesc, &srvOut); + fprintf(stderr, "srv created\n"); + } void createInputTexture(const InputTextureDesc & inputDesc, ID3D11ShaderResourceView * &viewOut) @@ -1050,6 +1055,8 @@ public: } virtual BindingState * createBindingState(const ShaderInputLayout & layout) { + fprintf(stderr, "pre-create binding state\n"); + D3DBindingState * rs = new D3DBindingState(); for (auto & entry : layout.entries) { @@ -1083,10 +1090,12 @@ public: } rs->bindings.Add(rsEntry); } + fprintf(stderr, "post-create binding state\n"); + return (BindingState*)rs; } - bool applyBindingState(bool isCompute) + void applyBindingState(bool isCompute) { auto dxContext = dxImmediateContext; for (auto & binding : currentBindings->bindings) -- cgit v1.2.3 From fd22e8a89dc4072294859ae3f988355e4c15d829 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 21:57:59 -0400 Subject: test --- tools/render-test/main.cpp | 2 +- tools/render-test/render-d3d11.cpp | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp index c19238f5d..69f97b779 100644 --- a/tools/render-test/main.cpp +++ b/tools/render-test/main.cpp @@ -384,7 +384,7 @@ int main( { if (message.message == WM_QUIT) { - return (int)message.wParam; + return (int)12345;// message.wParam; } TranslateMessage(&message); diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 5bfcf9563..a1cecd7c6 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -1090,7 +1090,6 @@ public: } rs->bindings.Add(rsEntry); } - fprintf(stderr, "post-create binding state\n"); return (BindingState*)rs; } @@ -1104,15 +1103,11 @@ public: { if (binding.uav) { - fprintf(stderr, "begin bind buffer\n"); - if (isCompute) dxContext->CSSetUnorderedAccessViews(binding.binding, 1, &binding.uav, nullptr); else dxContext->OMSetRenderTargetsAndUnorderedAccessViews(D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, binding.binding, 1, &binding.uav, nullptr); - fprintf(stderr, "end bind buffer\n"); - } else { @@ -1182,7 +1177,6 @@ public: for (auto i = 0u; i < binding.bufferLength / sizeof(unsigned int); i++) fprintf(f, "%X\n", ptr[i]); unmap(binding.buffer); - fprintf(stderr, "output[1] is %X\n", ptr[1]); } else { -- cgit v1.2.3 From 2f549e906b4e04fe57f776b5a187690cb9362e3c Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 22:20:56 -0400 Subject: try fix 2 --- tools/render-test/main.cpp | 2 +- tools/render-test/render-d3d11.cpp | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp index 69f97b779..d3247e55f 100644 --- a/tools/render-test/main.cpp +++ b/tools/render-test/main.cpp @@ -384,7 +384,7 @@ int main( { if (message.message == WM_QUIT) { - return (int)12345;// message.wParam; + return (int)message.wParam; } TranslateMessage(&message); diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index a1cecd7c6..e40c68405 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -403,7 +403,7 @@ public: // We immediately bind the back-buffer render target view, and we aren't // going to switch. We don't bother with a depth buffer. dxImmediateContext->OMSetRenderTargets( - dxRenderTargetViews.Count(), + 1, //dxRenderTargetViews.Count(), dxRenderTargetViews.Buffer(), NULL); @@ -427,7 +427,7 @@ public: virtual void clearFrame() override { - for (auto i = 0u; i < dxRenderTargetViews.Count(); i++) + for (auto i = 0u; i < 1; i++) dxImmediateContext->ClearRenderTargetView( dxRenderTargetViews[i], clearColor); @@ -1055,8 +1055,6 @@ public: } virtual BindingState * createBindingState(const ShaderInputLayout & layout) { - fprintf(stderr, "pre-create binding state\n"); - D3DBindingState * rs = new D3DBindingState(); for (auto & entry : layout.entries) { -- cgit v1.2.3 From 809f2bbe3b2f4544c246f7a226fddb9467c06cd4 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 22:24:23 -0400 Subject: try fix 3 --- tools/render-test/render-d3d11.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index e40c68405..7a43ca8c9 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -831,8 +831,6 @@ public: desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; } } - fprintf(stderr, "buffer created\n"); - D3D11_SUBRESOURCE_DATA data = {0}; data.pSysMem = bufferData.Buffer(); dxDevice->CreateBuffer(&desc, &data, &bufferOut); @@ -847,8 +845,6 @@ public: viewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; viewDesc.Format = DXGI_FORMAT_UNKNOWN; dxDevice->CreateUnorderedAccessView(bufferOut, &viewDesc, &viewOut); - fprintf(stderr, "uav created\n"); - } D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; memset(&srvDesc, 0, sizeof(srvDesc)); @@ -859,8 +855,6 @@ public: srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; srvDesc.Format = DXGI_FORMAT_UNKNOWN; dxDevice->CreateShaderResourceView(bufferOut, &srvDesc, &srvOut); - fprintf(stderr, "srv created\n"); - } void createInputTexture(const InputTextureDesc & inputDesc, ID3D11ShaderResourceView * &viewOut) -- cgit v1.2.3 From 84683a9bdab7a117a469caa3f442e399a2b60856 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 22:58:24 -0400 Subject: test 4 --- tools/render-test/render-d3d11.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 7a43ca8c9..e534be306 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -379,8 +379,8 @@ public: dxBackBufferTexture, NULL, &dxBackBufferRTV); - dxRenderTargetViews.Add(dxBackBufferRTV); - for (int i = 0; i < 7; i++) + //dxRenderTargetViews.Add(dxBackBufferRTV); + for (int i = 0; i < 8; i++) { ID3D11Texture2D* texture; D3D11_TEXTURE2D_DESC textureDesc; @@ -388,7 +388,7 @@ public: textureDesc.ArraySize = 1; textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.MiscFlags = 0; dxDevice->CreateTexture2D(&textureDesc, nullptr, &texture); @@ -400,10 +400,12 @@ public: dxRenderTargetViews.Add(rtv); dxRenderTargetTextures.Add(texture); } + dxBackBufferRTV = dxRenderTargetViews[0]; + dxBackBufferTexture = dxRenderTargetTextures[0]; // We immediately bind the back-buffer render target view, and we aren't // going to switch. We don't bother with a depth buffer. dxImmediateContext->OMSetRenderTargets( - 1, //dxRenderTargetViews.Count(), + dxRenderTargetViews.Count(), dxRenderTargetViews.Buffer(), NULL); @@ -427,7 +429,7 @@ public: virtual void clearFrame() override { - for (auto i = 0u; i < 1; i++) + for (auto i = 0u; i < dxRenderTargetViews.Count(); i++) dxImmediateContext->ClearRenderTargetView( dxRenderTargetViews[i], clearColor); @@ -942,7 +944,7 @@ public: D3D11_TEXTURE1D_DESC desc = { 0 }; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET | D3D11_BIND_UNORDERED_ACCESS; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; desc.MipLevels = textureMipLevels; desc.ArraySize = arraySize; @@ -970,7 +972,7 @@ public: D3D11_TEXTURE2D_DESC desc = { 0 }; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET | D3D11_BIND_UNORDERED_ACCESS; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; desc.MipLevels = textureMipLevels; desc.ArraySize = arraySize; @@ -1012,7 +1014,7 @@ public: D3D11_TEXTURE3D_DESC desc = { 0 }; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET | D3D11_BIND_UNORDERED_ACCESS; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; desc.MipLevels = textureMipLevels; viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; -- cgit v1.2.3 From deba0d8dd5a2580ecbffd6db00307a4ee022a58b Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 23:08:12 -0400 Subject: test 5 --- tools/render-test/render-d3d11.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index e534be306..8b930182d 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -386,8 +386,9 @@ public: D3D11_TEXTURE2D_DESC textureDesc; dxBackBufferTexture->GetDesc(&textureDesc); textureDesc.ArraySize = 1; + textureDesc.MipLevels = 1; textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; - textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.MiscFlags = 0; @@ -429,7 +430,7 @@ public: virtual void clearFrame() override { - for (auto i = 0u; i < dxRenderTargetViews.Count(); i++) + for (auto i = 0u; i < 1; i++) dxImmediateContext->ClearRenderTargetView( dxRenderTargetViews[i], clearColor); -- cgit v1.2.3 From ff4f9d9d129fccc56ac01d841295120ded789696 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 23:13:37 -0400 Subject: test 6 --- tools/render-test/render-d3d11.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 8b930182d..2f7f0aad4 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -384,9 +384,13 @@ public: { ID3D11Texture2D* texture; D3D11_TEXTURE2D_DESC textureDesc; - dxBackBufferTexture->GetDesc(&textureDesc); + //dxBackBufferTexture->GetDesc(&textureDesc); textureDesc.ArraySize = 1; textureDesc.MipLevels = 1; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Width = gWindowWidth; + textureDesc.Height = gWindowHeight; textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; -- cgit v1.2.3 From 19c4119fa00972825a9f81114dac6f796e6b35f7 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 23:31:17 -0400 Subject: test 7 --- tools/render-test/render-d3d11.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 2f7f0aad4..8643f229a 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -384,23 +384,16 @@ public: { ID3D11Texture2D* texture; D3D11_TEXTURE2D_DESC textureDesc; - //dxBackBufferTexture->GetDesc(&textureDesc); - textureDesc.ArraySize = 1; - textureDesc.MipLevels = 1; - textureDesc.SampleDesc.Count = 1; - textureDesc.SampleDesc.Quality = 0; - textureDesc.Width = gWindowWidth; - textureDesc.Height = gWindowHeight; - textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; - textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - textureDesc.Usage = D3D11_USAGE_DEFAULT; - textureDesc.MiscFlags = 0; + dxBackBufferTexture->GetDesc(&textureDesc); dxDevice->CreateTexture2D(&textureDesc, nullptr, &texture); ID3D11RenderTargetView * rtv; + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + rtvDesc.Texture2D.MipSlice = 0; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; dxDevice->CreateRenderTargetView( texture, - NULL, + &rtvDesc, &rtv); dxRenderTargetViews.Add(rtv); dxRenderTargetTextures.Add(texture); -- cgit v1.2.3 From 434d3428932ccaa0f6834d03c37adcab37d17a01 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 23 Oct 2017 23:42:23 -0400 Subject: bug fix --- tools/render-test/render-d3d11.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 8643f229a..8f73b4dd4 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -263,7 +263,6 @@ public: ID3D11Device* dxDevice = NULL; ID3D11DeviceContext* dxImmediateContext = NULL; ID3D11Texture2D* dxBackBufferTexture = NULL; - ID3D11RenderTargetView* dxBackBufferRTV = NULL; List dxRenderTargetViews; List dxRenderTargetTextures; D3DBindingState * currentBindings = nullptr; @@ -339,10 +338,8 @@ public: { hr = D3D11CreateDeviceAndSwapChain_( NULL, // adapter (use default) - D3D_DRIVER_TYPE_WARP, -// D3D_DRIVER_TYPE_HARDWARE, - +// D3D_DRIVER_TYPE_HARDWARE, NULL, // software deviceFlags, &featureLevels[ii], @@ -370,16 +367,12 @@ public: static const IID kIID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c }; + dxSwapChain->GetBuffer( 0, kIID_ID3D11Texture2D, (void**)&dxBackBufferTexture); - dxDevice->CreateRenderTargetView( - dxBackBufferTexture, - NULL, - &dxBackBufferRTV); - //dxRenderTargetViews.Add(dxBackBufferRTV); for (int i = 0; i < 8; i++) { ID3D11Texture2D* texture; @@ -398,8 +391,7 @@ public: dxRenderTargetViews.Add(rtv); dxRenderTargetTextures.Add(texture); } - dxBackBufferRTV = dxRenderTargetViews[0]; - dxBackBufferTexture = dxRenderTargetTextures[0]; + // We immediately bind the back-buffer render target view, and we aren't // going to switch. We don't bother with a depth buffer. dxImmediateContext->OMSetRenderTargets( @@ -427,7 +419,7 @@ public: virtual void clearFrame() override { - for (auto i = 0u; i < 1; i++) + for (auto i = 0u; i < dxRenderTargetViews.Count(); i++) dxImmediateContext->ClearRenderTargetView( dxRenderTargetViews[i], clearColor); @@ -435,6 +427,7 @@ public: virtual void presentFrame() override { + dxImmediateContext->CopyResource(dxBackBufferTexture, dxRenderTargetTextures[0]); dxSwapChain->Present(0, 0); } @@ -443,7 +436,7 @@ public: HRESULT hr = captureTextureToFile( dxDevice, dxImmediateContext, - dxBackBufferTexture, + dxRenderTargetTextures[0], outputPath); if( FAILED(hr) ) { -- cgit v1.2.3