Map D3D calls and HLSL shaders back to GLES2 calls and GLSL ES shaders in PIX.
This makes debugging and profiling using PIX a lot more convenient. The top level of events are the GLES calls with their arguments. Those can be expanded to see the D3D calls that were issued for a particular GLES call.
When PIX is attached, the shaders are saved out to temporary files and referenced from the translated HLSL shaders via #line directives. This enabled source level debugging of the original GLSL from PIX for pixel and vertex shaders. The HLSL is also saved to a temporary file so that intrinsic functions like texture2D can be stepped into.
It also avoids creating a text file in the current working directory, which has continued to be an issue.
I made the dependency on d3d9.dll static again so it can be accessed by GetModuleHandle witihin DllMain.
I added an EVENT macro that issues D3DPERF_BeginEvent and D3DPERF_EndEvent around a C++ block. I replaced TRACE with EVENT for all the entry points.
I removed the tracing of shader source since the source is visible in PIX.
The means by which the filename of the temporary shader file is passed into the shader compiler is a little clunky. I did it that way to avoid changing the function signatures and breaking folks using the translator.
I plan to make the compiler respect #pragma optimize so that optimization can be disabled for debugging purposes. For now it just disables shader optimization in debug builds of ANGLE.
Review URL: http://codereview.appspot.com/3945043
git-svn-id: https://angleproject.googlecode.com/svn/trunk@541 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 649b457..3c41bc9 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -17,7 +17,7 @@
{
TIntermediate intermediate(infoSink);
TExtensionBehavior extBehavior;
- TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, infoSink);
+ TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, NULL, infoSink);
GlobalParseContext = &parseContext;
@@ -115,9 +115,19 @@
if (shaderSpec == SH_WEBGL_SPEC)
compileOptions |= SH_VALIDATE_LOOP_INDEXING;
+ // First string is path of source file if flag is set. The actual source follows.
+ const char* sourcePath = NULL;
+ int firstSource = 0;
+ if (compileOptions & SH_SOURCE_PATH)
+ {
+ sourcePath = shaderStrings[0];
+ ++firstSource;
+ }
+
TIntermediate intermediate(infoSink);
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
- shaderType, shaderSpec, infoSink);
+ shaderType, shaderSpec, compileOptions,
+ sourcePath, infoSink);
GlobalParseContext = &parseContext;
// We preserve symbols at the built-in level from compile-to-compile.
@@ -128,7 +138,7 @@
// Parse shader.
bool success =
- (PaParseStrings(numStrings, shaderStrings, NULL, &parseContext) == 0) &&
+ (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
(parseContext.treeRoot != NULL);
if (success) {
TIntermNode* root = parseContext.treeRoot;
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index d6e9232..02d845b 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -1003,6 +1003,7 @@
{
if (mInsideFunction)
{
+ outputLineDirective(node->getLine());
out << "{\n";
mScopeDepth++;
@@ -1019,6 +1020,8 @@
for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++)
{
+ outputLineDirective((*sit)->getLine());
+
if (isSingleStatement(*sit))
{
mUnfoldSelect->traverse(*sit);
@@ -1031,6 +1034,7 @@
if (mInsideFunction)
{
+ outputLineDirective(node->getEndLine());
out << "}\n";
mScopeDepth--;
@@ -1171,13 +1175,16 @@
sequence.erase(sequence.begin());
- out << ")\n"
- "{\n";
-
+ out << ")\n";
+
+ outputLineDirective(node->getLine());
+ out << "{\n";
+
mInsideFunction = true;
}
else if (visit == PostVisit)
{
+ outputLineDirective(node->getEndLine());
out << "}\n";
mInsideFunction = false;
@@ -1402,23 +1409,30 @@
node->getCondition()->traverse(this);
- out << ")\n"
- "{\n";
+ out << ")\n";
+
+ outputLineDirective(node->getLine());
+ out << "{\n";
if (node->getTrueBlock())
{
node->getTrueBlock()->traverse(this);
}
+ outputLineDirective(node->getLine());
out << ";}\n";
if (node->getFalseBlock())
{
- out << "else\n"
- "{\n";
+ out << "else\n";
+ outputLineDirective(node->getFalseBlock()->getLine());
+ out << "{\n";
+
+ outputLineDirective(node->getFalseBlock()->getLine());
node->getFalseBlock()->traverse(this);
+ outputLineDirective(node->getFalseBlock()->getLine());
out << ";}\n";
}
}
@@ -1442,8 +1456,10 @@
if (node->getType() == ELoopDoWhile)
{
- out << "do\n"
- "{\n";
+ out << "do\n";
+
+ outputLineDirective(node->getLine());
+ out << "{\n";
}
else
{
@@ -1483,8 +1499,10 @@
node->getExpression()->traverse(this);
}
- out << ")\n"
- "{\n";
+ out << ")\n";
+
+ outputLineDirective(node->getLine());
+ out << "{\n";
}
if (node->getBody())
@@ -1492,10 +1510,12 @@
node->getBody()->traverse(this);
}
+ outputLineDirective(node->getLine());
out << "}\n";
if (node->getType() == ELoopDoWhile)
{
+ outputLineDirective(node->getCondition()->getLine());
out << "while(\n";
node->getCondition()->traverse(this);
@@ -1531,7 +1551,10 @@
}
else if (visit == PostVisit)
{
- out << ";\n";
+ if (node->getExpression())
+ {
+ out << ";\n";
+ }
}
break;
default: UNREACHABLE();
@@ -1711,14 +1734,17 @@
index->traverse(this);
out << " += ";
out << increment;
- out << ")\n"
- "{\n";
+ out << ")\n";
+
+ outputLineDirective(node->getLine());
+ out << "{\n";
if (node->getBody())
{
node->getBody()->traverse(this);
}
+ outputLineDirective(node->getLine());
out << "}\n";
initial += 255 * increment;
@@ -1751,6 +1777,21 @@
}
}
+void OutputHLSL::outputLineDirective(int line)
+{
+ if ((mContext.compileOptions & SH_LINE_DIRECTIVES) && (line > 0))
+ {
+ mBody << "#line " << line;
+
+ if (mContext.sourcePath)
+ {
+ mBody << " \"" << mContext.sourcePath << "\"";
+ }
+
+ mBody << "\n";
+ }
+}
+
TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
{
TQualifier qualifier = symbol->getQualifier();
diff --git a/src/compiler/OutputHLSL.h b/src/compiler/OutputHLSL.h
index ddbd077..dbec5f6 100644
--- a/src/compiler/OutputHLSL.h
+++ b/src/compiler/OutputHLSL.h
@@ -49,6 +49,7 @@
bool isSingleStatement(TIntermNode *node);
bool handleExcessiveLoop(TIntermLoop *node);
void outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString);
+ void outputLineDirective(int line);
TString argumentString(const TIntermSymbol *symbol);
int vectorSize(const TType &type) const;
diff --git a/src/compiler/ParseHelper.h b/src/compiler/ParseHelper.h
index cb6e0d0..26b48c8 100644
--- a/src/compiler/ParseHelper.h
+++ b/src/compiler/ParseHelper.h
@@ -30,8 +30,8 @@
// they can be passed to the parser without needing a global.
//
struct TParseContext {
- TParseContext(TSymbolTable& symt, const TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, TInfoSink& is) :
- intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), treeRoot(0),
+ TParseContext(TSymbolTable& symt, const TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, const char* sourcePath, TInfoSink& is) :
+ intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), compileOptions(options), sourcePath(sourcePath), treeRoot(0),
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
inTypeParen(false), scanner(NULL), contextPragma(true, false) { }
TIntermediate& intermediate; // to hold and build a parse tree
@@ -40,6 +40,8 @@
TInfoSink& infoSink;
ShShaderType shaderType; // vertex or fragment language (future: pack or unpack)
ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
+ int compileOptions;
+ const char* sourcePath; // Path of source file or NULL.
TIntermNode* treeRoot; // root of parse tree being created
bool recoveredFromError; // true if a parse error has occurred, but we continue to parse
int numErrors;
diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y
index 5eae4b5..31d6317 100644
--- a/src/compiler/glslang.y
+++ b/src/compiler/glslang.y
@@ -1770,8 +1770,10 @@
compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
- if ($3 != 0)
+ if ($3 != 0) {
$3->setOp(EOpSequence);
+ $3->setEndLine($5.line);
+ }
$$ = $3;
}
;
@@ -1787,8 +1789,10 @@
$$ = 0;
}
| LEFT_BRACE statement_list RIGHT_BRACE {
- if ($2)
+ if ($2) {
$2->setOp(EOpSequence);
+ $2->setEndLine($3.line);
+ }
$$ = $2;
}
;
@@ -2061,6 +2065,9 @@
$$->getAsAggregate()->setOptimize(context->contextPragma.optimize);
$$->getAsAggregate()->setDebug(context->contextPragma.debug);
$$->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
+
+ if ($3 && $3->getAsAggregate())
+ $$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine());
}
;
diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp
index d00c7a3..3bf9df6 100644
--- a/src/compiler/glslang_tab.cpp
+++ b/src/compiler/glslang_tab.cpp
@@ -744,11 +744,11 @@
1553, 1558, 1563, 1568, 1573, 1578, 1583, 1588, 1593, 1598,
1604, 1610, 1616, 1621, 1626, 1631, 1644, 1657, 1665, 1668,
1683, 1714, 1718, 1724, 1732, 1748, 1752, 1756, 1757, 1763,
- 1764, 1765, 1766, 1767, 1771, 1772, 1772, 1772, 1780, 1781,
- 1786, 1789, 1797, 1800, 1806, 1807, 1811, 1819, 1823, 1833,
- 1838, 1855, 1855, 1860, 1860, 1867, 1867, 1875, 1878, 1884,
- 1887, 1893, 1897, 1904, 1911, 1918, 1925, 1936, 1945, 1949,
- 1956, 1959, 1965, 1965
+ 1764, 1765, 1766, 1767, 1771, 1772, 1772, 1772, 1782, 1783,
+ 1788, 1791, 1801, 1804, 1810, 1811, 1815, 1823, 1827, 1837,
+ 1842, 1859, 1859, 1864, 1864, 1871, 1871, 1879, 1882, 1888,
+ 1891, 1897, 1901, 1908, 1915, 1922, 1929, 1940, 1949, 1953,
+ 1960, 1963, 1969, 1969
};
#endif
@@ -4094,8 +4094,10 @@
case 157:
{
- if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0)
+ if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0) {
(yyvsp[(3) - (5)].interm.intermAggregate)->setOp(EOpSequence);
+ (yyvsp[(3) - (5)].interm.intermAggregate)->setEndLine((yyvsp[(5) - (5)].lex).line);
+ }
(yyval.interm.intermAggregate) = (yyvsp[(3) - (5)].interm.intermAggregate);
;}
break;
@@ -4120,8 +4122,10 @@
case 161:
{
- if ((yyvsp[(2) - (3)].interm.intermAggregate))
+ if ((yyvsp[(2) - (3)].interm.intermAggregate)) {
(yyvsp[(2) - (3)].interm.intermAggregate)->setOp(EOpSequence);
+ (yyvsp[(2) - (3)].interm.intermAggregate)->setEndLine((yyvsp[(3) - (3)].lex).line);
+ }
(yyval.interm.intermNode) = (yyvsp[(2) - (3)].interm.intermAggregate);
;}
break;
@@ -4481,6 +4485,9 @@
(yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->contextPragma.optimize);
(yyval.interm.intermNode)->getAsAggregate()->setDebug(context->contextPragma.debug);
(yyval.interm.intermNode)->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
+
+ if ((yyvsp[(3) - (3)].interm.intermNode) && (yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate())
+ (yyval.interm.intermNode)->getAsAggregate()->setEndLine((yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()->getEndLine());
;}
break;
diff --git a/src/compiler/intermediate.h b/src/compiler/intermediate.h
index f9fa1de..c3c073c 100644
--- a/src/compiler/intermediate.h
+++ b/src/compiler/intermediate.h
@@ -420,7 +420,7 @@
//
class TIntermAggregate : public TIntermOperator {
public:
- TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
+ TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0), endLine(0) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
~TIntermAggregate() { delete pragmaTable; }
@@ -441,6 +441,8 @@
bool getDebug() { return debug; }
void addToPragmaTable(const TPragmaTable& pTable);
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
+ void setEndLine(TSourceLoc line) { endLine = line; }
+ TSourceLoc getEndLine() const { return endLine; }
protected:
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
@@ -452,6 +454,7 @@
bool optimize;
bool debug;
TPragmaTable *pragmaTable;
+ TSourceLoc endLine;
};
//