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
This commit is contained in:
apatrick@chromium.org 2011-01-26 19:30:57 +00:00
Родитель e9874058c9
Коммит 0f4cefe946
23 изменённых файлов: 535 добавлений и 305 удалений

Просмотреть файл

@ -71,7 +71,9 @@ typedef enum {
SH_VALIDATE_LOOP_INDEXING = 0x0001,
SH_INTERMEDIATE_TREE = 0x0002,
SH_OBJECT_CODE = 0x0004,
SH_ATTRIBUTES_UNIFORMS = 0x0008
SH_ATTRIBUTES_UNIFORMS = 0x0008,
SH_LINE_DIRECTIVES = 0x0010,
SH_SOURCE_PATH = 0x0200,
} ShCompileOptions;
//

Просмотреть файл

@ -5,7 +5,7 @@
{
'target_defaults': {
'defines': [
'TRACE_OUTPUT_FILE="angle-debug.txt"',
'ANGLE_DISABLE_TRACE',
],
},
'targets': [
@ -183,7 +183,10 @@
'msvs_settings': {
'VCLinkerTool': {
'AdditionalLibraryDirectories': ['$(DXSDK_DIR)/lib/x86'],
'AdditionalDependencies': ['d3dx9.lib'],
'AdditionalDependencies': [
'd3d9.lib',
'd3dx9.lib',
],
}
},
},
@ -215,6 +218,7 @@
'VCLinkerTool': {
'AdditionalLibraryDirectories': ['$(DXSDK_DIR)/lib/x86'],
'AdditionalDependencies': [
'd3d9.lib',
'dxguid.lib',
],
}

Просмотреть файл

@ -1,44 +1,96 @@
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// debug.cpp: Debugging utilities.
#include "common/debug.h"
#include <stdio.h>
#include <stdarg.h>
#ifndef TRACE_OUTPUT_FILE
#define TRACE_OUTPUT_FILE "debug.txt"
#endif
static bool trace_on = true;
namespace gl
{
void trace(const char *format, ...)
{
#if !defined(ANGLE_DISABLE_TRACE)
if (trace_on)
{
if (format)
{
FILE *file = fopen(TRACE_OUTPUT_FILE, "a");
if (file)
{
va_list vararg;
va_start(vararg, format);
vfprintf(file, format, vararg);
va_end(vararg);
fclose(file);
}
}
}
#endif // !defined(ANGLE_DISABLE_TRACE)
}
}
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// debug.cpp: Debugging utilities.
#include "common/debug.h"
#include <stdio.h>
#include <stdarg.h>
#include <d3d9.h>
#include <windows.h>
namespace gl
{
typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
{
#if !defined(ANGLE_DISABLE_PERF)
if (perfActive())
{
char message[4096];
int len = vsprintf_s(message, format, vararg);
if (len < 0)
{
return;
}
// There are no ASCII variants of these D3DPERF functions.
wchar_t wideMessage[4096];
for (int i = 0; i < len; ++i)
{
wideMessage[i] = message[i];
}
wideMessage[len] = 0;
perfFunc(0, wideMessage);
}
#endif
#if !defined(ANGLE_DISABLE_TRACE)
#if defined(NDEBUG)
if (traceFileDebugOnly)
{
return;
}
#endif
FILE* file = fopen(TRACE_OUTPUT_FILE, "a");
if (file)
{
vfprintf(file, format, vararg);
fclose(file);
}
#endif
}
void trace(bool traceFileDebugOnly, const char *format, ...)
{
va_list vararg;
va_start(vararg, format);
output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
va_end(vararg);
}
bool perfActive()
{
#if defined(ANGLE_DISABLE_PERF)
return false;
#else
return D3DPERF_GetStatus() != 0;
#endif
}
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
{
va_list vararg;
va_start(vararg, format);
output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
va_end(vararg);
}
ScopedPerfEventHelper::~ScopedPerfEventHelper()
{
#if !defined(ANGLE_DISABLE_PERF)
if (perfActive())
{
D3DPERF_EndEvent();
}
#endif
}
}

Просмотреть файл

@ -12,49 +12,87 @@
#include <stdio.h>
#include <assert.h>
#include "common/angleutils.h"
#if !defined(TRACE_OUTPUT_FILE)
#define TRACE_OUTPUT_FILE "debug.txt"
#endif
namespace gl
{
// Outputs text to the debugging log
void trace(const char *format, ...);
void trace(bool traceFileDebugOnly, const char *format, ...);
// Returns whether D3DPERF is active.
bool perfActive();
// Pairs a D3D begin event with an end event.
class ScopedPerfEventHelper
{
public:
ScopedPerfEventHelper(const char* format, ...);
~ScopedPerfEventHelper();
private:
DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
};
}
// A macro to output a trace of a function call and its arguments to the debugging log
#if !defined(NDEBUG) && !defined(ANGLE_DISABLE_TRACE)
#define TRACE(message, ...) gl::trace("trace: %s"message"\n", __FUNCTION__, __VA_ARGS__)
#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
#define TRACE(message, ...) (void(0))
#else
#define TRACE(...) ((void)0)
#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): "message"\n", __FUNCTION__, __LINE__, __VA_ARGS__)
#endif
// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing. Will occur even in release mode.
#define FIXME(message, ...) gl::trace("fixme: %s"message"\n", __FUNCTION__, __VA_ARGS__)
// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
#define FIXME(message, ...) (void(0))
#else
#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): "message"\n", __FUNCTION__, __LINE__, __VA_ARGS__)
#endif
// A macro to output a function call and its arguments to the debugging log, in case of error. Will occur even in release mode.
#define ERR(message, ...) gl::trace("err: %s"message"\n", __FUNCTION__, __VA_ARGS__)
// A macro to output a function call and its arguments to the debugging log, in case of error.
#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
#define ERR(message, ...) (void(0))
#else
#define ERR(message, ...) gl::trace(false, "err: %s(%d): "message"\n", __FUNCTION__, __LINE__, __VA_ARGS__)
#endif
// A macro to log a performance event around a scope.
#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF)
#define EVENT(message, ...) (void(0))
#else
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s\n" message, __FUNCTION__, __VA_ARGS__);
#endif
// A macro asserting a condition and outputting failures to the debug log
#if !defined(NDEBUG)
#define ASSERT(expression) do { \
if(!(expression)) \
ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \
assert(expression); \
assert(expression); \
} while(0)
#else
#define ASSERT(expression) (void(0))
#endif
// A macro to indicate unimplemented functionality
#ifndef NDEBUG
#define UNIMPLEMENTED() do { \
FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
assert(false); \
} while(0)
#if !defined(NDEBUG)
#define UNIMPLEMENTED() do { \
FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
assert(false); \
} while(0)
#else
#define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__)
#endif
// A macro for code which is not expected to be reached under valid assumptions
#ifndef NDEBUG
#define UNREACHABLE() do { \
ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \
assert(false); \
} while(0)
#if !defined(NDEBUG)
#define UNREACHABLE() do { \
ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \
assert(false); \
} while(0)
#else
#define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__)
#endif

Просмотреть файл

@ -1,7 +1,7 @@
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 540
#define BUILD_REVISION 541
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)

Просмотреть файл

@ -17,7 +17,7 @@ bool InitializeSymbolTable(
{
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 @@ bool TCompiler::compile(const char* const shaderStrings[],
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 @@ bool TCompiler::compile(const char* const shaderStrings[],
// 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;

Просмотреть файл

@ -1003,6 +1003,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
if (mInsideFunction)
{
outputLineDirective(node->getLine());
out << "{\n";
mScopeDepth++;
@ -1019,6 +1020,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
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 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (mInsideFunction)
{
outputLineDirective(node->getEndLine());
out << "}\n";
mScopeDepth--;
@ -1171,13 +1175,16 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
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 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
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 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
if (node->getType() == ELoopDoWhile)
{
out << "do\n"
"{\n";
out << "do\n";
outputLineDirective(node->getLine());
out << "{\n";
}
else
{
@ -1483,8 +1499,10 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
node->getExpression()->traverse(this);
}
out << ")\n"
"{\n";
out << ")\n";
outputLineDirective(node->getLine());
out << "{\n";
}
if (node->getBody())
@ -1492,10 +1510,12 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
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 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
}
else if (visit == PostVisit)
{
out << ";\n";
if (node->getExpression())
{
out << ";\n";
}
}
break;
default: UNREACHABLE();
@ -1711,14 +1734,17 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
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::outputTriplet(Visit visit, const TString &preString, const TStr
}
}
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();

Просмотреть файл

@ -49,6 +49,7 @@ class OutputHLSL : public TIntermTraverser
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;

Просмотреть файл

@ -30,8 +30,8 @@ struct TPragma {
// 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 @@ struct TParseContext {
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;

Просмотреть файл

@ -1770,8 +1770,10 @@ simple_statement
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 @@ compound_statement_no_new_scope
$$ = 0;
}
| LEFT_BRACE statement_list RIGHT_BRACE {
if ($2)
if ($2) {
$2->setOp(EOpSequence);
$2->setEndLine($3.line);
}
$$ = $2;
}
;
@ -2061,6 +2065,9 @@ function_definition
$$->getAsAggregate()->setOptimize(context->contextPragma.optimize);
$$->getAsAggregate()->setDebug(context->contextPragma.debug);
$$->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
if ($3 && $3->getAsAggregate())
$$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine());
}
;

Просмотреть файл

@ -744,11 +744,11 @@ static const yytype_uint16 yyrline[] =
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 @@ yyreduce:
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 @@ yyreduce:
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 @@ yyreduce:
(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;

Просмотреть файл

@ -420,7 +420,7 @@ typedef TMap<TString, TString> TPragmaTable;
//
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 @@ public:
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 @@ protected:
bool optimize;
bool debug;
TPragmaTable *pragmaTable;
TSourceLoc endLine;
};
//

Просмотреть файл

@ -55,22 +55,13 @@ bool Display::initialize()
return true;
}
mD3d9Module = LoadLibrary(TEXT("d3d9.dll"));
mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
if (mD3d9Module == NULL)
{
terminate();
return false;
}
typedef IDirect3D9* (WINAPI *Direct3DCreate9Func)(UINT);
Direct3DCreate9Func Direct3DCreate9Ptr = reinterpret_cast<Direct3DCreate9Func>(GetProcAddress(mD3d9Module, "Direct3DCreate9"));
if (Direct3DCreate9Ptr == NULL)
{
terminate();
return false;
}
typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
@ -85,7 +76,7 @@ bool Display::initialize()
}
else
{
mD3d9 = Direct3DCreate9Ptr(D3D_SDK_VERSION);
mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
}
if (mD3d9)
@ -267,7 +258,6 @@ void Display::terminate()
if (mD3d9Module)
{
FreeLibrary(mD3d9Module);
mD3d9Module = NULL;
}
}

Просмотреть файл

@ -80,7 +80,7 @@ extern "C"
{
EGLint __stdcall eglGetError(void)
{
TRACE("()");
EVENT("()");
EGLint error = egl::getCurrentError();
@ -94,7 +94,7 @@ EGLint __stdcall eglGetError(void)
EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
{
TRACE("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
try
{
@ -121,7 +121,7 @@ EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
dpy, major, minor);
try
@ -153,7 +153,7 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
{
TRACE("(EGLDisplay dpy = 0x%0.8p)", dpy);
EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
try
{
@ -178,7 +178,7 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
try
{
@ -213,7 +213,7 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
"EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
dpy, configs, config_size, num_config);
@ -250,7 +250,7 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co
EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
"EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
dpy, attrib_list, configs, config_size, num_config);
@ -289,7 +289,7 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
dpy, config, attribute, value);
try
@ -318,7 +318,7 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint
EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
"const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
try
@ -385,7 +385,7 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
dpy, config, attrib_list);
try
@ -411,7 +411,7 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
"const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
try
@ -437,7 +437,7 @@ EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EG
EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
try
{
@ -467,7 +467,7 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
dpy, surface, attribute, value);
try
@ -552,7 +552,7 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
EGLBoolean __stdcall eglBindAPI(EGLenum api)
{
TRACE("(EGLenum api = 0x%X)", api);
EVENT("(EGLenum api = 0x%X)", api);
try
{
@ -581,7 +581,7 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api)
EGLenum __stdcall eglQueryAPI(void)
{
TRACE("()");
EVENT("()");
try
{
@ -599,7 +599,7 @@ EGLenum __stdcall eglQueryAPI(void)
EGLBoolean __stdcall eglWaitClient(void)
{
TRACE("()");
EVENT("()");
try
{
@ -617,7 +617,7 @@ EGLBoolean __stdcall eglWaitClient(void)
EGLBoolean __stdcall eglReleaseThread(void)
{
TRACE("()");
EVENT("()");
try
{
@ -635,7 +635,7 @@ EGLBoolean __stdcall eglReleaseThread(void)
EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
"EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
dpy, buftype, buffer, config, attrib_list);
@ -662,7 +662,7 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu
EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
dpy, surface, attribute, value);
try
@ -688,7 +688,7 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
try
{
@ -713,7 +713,7 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
try
{
@ -738,7 +738,7 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
try
{
@ -770,7 +770,7 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
"const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
try
@ -818,7 +818,7 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
try
{
@ -848,7 +848,7 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
dpy, draw, read, ctx);
try
@ -896,7 +896,7 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
EGLContext __stdcall eglGetCurrentContext(void)
{
TRACE("()");
EVENT("()");
try
{
@ -914,7 +914,7 @@ EGLContext __stdcall eglGetCurrentContext(void)
EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
{
TRACE("(EGLint readdraw = %d)", readdraw);
EVENT("(EGLint readdraw = %d)", readdraw);
try
{
@ -943,7 +943,7 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
EGLDisplay __stdcall eglGetCurrentDisplay(void)
{
TRACE("()");
EVENT("()");
try
{
@ -961,7 +961,7 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void)
EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
dpy, ctx, attribute, value);
try
@ -987,7 +987,7 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr
EGLBoolean __stdcall eglWaitGL(void)
{
TRACE("()");
EVENT("()");
try
{
@ -1005,7 +1005,7 @@ EGLBoolean __stdcall eglWaitGL(void)
EGLBoolean __stdcall eglWaitNative(EGLint engine)
{
TRACE("(EGLint engine = %d)", engine);
EVENT("(EGLint engine = %d)", engine);
try
{
@ -1023,7 +1023,7 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine)
EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
try
{
@ -1056,7 +1056,7 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{
TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
try
{
@ -1081,7 +1081,7 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
__eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
{
TRACE("(const char *procname = \"%s\")", procname);
EVENT("(const char *procname = \"%s\")", procname);
try
{

Просмотреть файл

@ -62,7 +62,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib"
AdditionalDependencies="d3d9.lib dxguid.lib"
LinkIncremental="2"
ModuleDefinitionFile="libEGL.def"
GenerateDebugInformation="true"
@ -140,7 +140,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="dxguid.lib"
AdditionalDependencies="d3d9.lib dxguid.lib"
LinkIncremental="1"
ModuleDefinitionFile="libEGL.def"
GenerateDebugInformation="true"

Просмотреть файл

@ -18,16 +18,16 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
case DLL_PROCESS_ATTACH:
{
#ifndef NDEBUG
FILE *debug = fopen("debug.txt", "rt");
#if !defined(ANGLE_DISABLE_TRACE)
FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
if (debug)
{
fclose(debug);
debug = fopen("debug.txt", "wt"); // Erase
fclose(debug);
}
#endif
if (debug)
{
fclose(debug);
debug = fopen(TRACE_OUTPUT_FILE, "wt"); // Erase
fclose(debug);
}
#endif
currentTLS = TlsAlloc();

Просмотреть файл

@ -971,7 +971,24 @@ ID3DXBuffer *Program::compileToBinary(const char *hlsl, const char *profile, ID3
ID3DXBuffer *binary = NULL;
ID3DXBuffer *errorMessage = NULL;
HRESULT result = D3DXCompileShader(hlsl, (UINT)strlen(hlsl), NULL, NULL, "main", profile, 0, &binary, &errorMessage, constantTable);
DWORD result;
if (perfActive())
{
DWORD flags = D3DXSHADER_DEBUG;
#ifndef NDEBUG
flags |= D3DXSHADER_SKIPOPTIMIZATION;
#endif
std::string sourcePath = getTempPath();
std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
result = D3DXCompileShader(sourceText.c_str(), sourceText.size(), NULL, NULL, "main", profile, flags, &binary, &errorMessage, constantTable);
}
else
{
result = D3DXCompileShader(hlsl, (UINT)strlen(hlsl), NULL, NULL, "main", profile, 0, &binary, &errorMessage, constantTable);
}
if (SUCCEEDED(result))
{
@ -1461,9 +1478,6 @@ bool Program::linkVaryings()
" return output;\n"
"}\n";
TRACE("\n%s", mPixelHLSL.c_str());
TRACE("\n%s", mVertexHLSL.c_str());
return true;
}

Просмотреть файл

@ -278,12 +278,33 @@ void Shader::compileToHLSL(void *compiler)
return;
}
TRACE("\n%s", mSource);
delete[] mInfoLog;
mInfoLog = NULL;
int result = ShCompile(compiler, &mSource, 1, SH_OBJECT_CODE);
int compileOptions = SH_OBJECT_CODE;
std::string sourcePath;
if (perfActive())
{
sourcePath = getTempPath();
writeFile(sourcePath.c_str(), mSource, strlen(mSource));
compileOptions |= SH_LINE_DIRECTIVES;
}
int result;
if (sourcePath.empty())
{
result = ShCompile(compiler, &mSource, 1, compileOptions);
}
else
{
const char* sourceStrings[2] =
{
sourcePath.c_str(),
mSource
};
result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
}
if (result)
{
@ -291,8 +312,6 @@ void Shader::compileToHLSL(void *compiler)
ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
mHlsl = new char[objCodeLen];
ShGetObjectCode(compiler, mHlsl);
TRACE("\n%s", mHlsl);
}
else
{

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -62,7 +62,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="D3dx9.lib"
AdditionalDependencies="d3d9.lib D3dx9.lib"
LinkIncremental="2"
ModuleDefinitionFile="libGLESv2.def"
GenerateDebugInformation="true"
@ -140,7 +140,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="D3dx9.lib"
AdditionalDependencies="d3d9.lib D3dx9.lib"
LinkIncremental="1"
IgnoreAllDefaultLibraries="false"
ModuleDefinitionFile="libGLESv2.def"

Просмотреть файл

@ -119,23 +119,23 @@ void error(GLenum errorCode)
{
case GL_INVALID_ENUM:
context->recordInvalidEnum();
gl::trace("\t! Error generated: invalid enum\n");
TRACE("\t! Error generated: invalid enum\n");
break;
case GL_INVALID_VALUE:
context->recordInvalidValue();
gl::trace("\t! Error generated: invalid value\n");
TRACE("\t! Error generated: invalid value\n");
break;
case GL_INVALID_OPERATION:
context->recordInvalidOperation();
gl::trace("\t! Error generated: invalid operation\n");
TRACE("\t! Error generated: invalid operation\n");
break;
case GL_OUT_OF_MEMORY:
context->recordOutOfMemory();
gl::trace("\t! Error generated: out of memory\n");
TRACE("\t! Error generated: out of memory\n");
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
context->recordInvalidFramebufferOperation();
gl::trace("\t! Error generated: invalid framebuffer operation\n");
TRACE("\t! Error generated: invalid framebuffer operation\n");
break;
default: UNREACHABLE();
}

Просмотреть файл

@ -9,6 +9,8 @@
#include "libGLESv2/utilities.h"
#include <limits>
#include <stdio.h>
#include <windows.h>
#include "common/debug.h"
@ -847,3 +849,36 @@ GLenum ConvertDepthStencilFormat(D3DFORMAT format)
}
}
std::string getTempPath()
{
char path[MAX_PATH];
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
if (pathLen == 0)
{
UNREACHABLE();
return std::string();
}
UINT unique = GetTempFileNameA(path, "sh", 0, path);
if (unique == 0)
{
UNREACHABLE();
return std::string();
}
return path;
}
void writeFile(const char* path, const void* content, size_t size)
{
FILE* file = fopen(path, "w");
if (!file)
{
UNREACHABLE();
return;
}
fwrite(content, sizeof(char), size, file);
fclose(file);
}

Просмотреть файл

@ -14,6 +14,8 @@
#include <GLES2/gl2ext.h>
#include <d3d9.h>
#include <string>
namespace gl
{
@ -78,4 +80,7 @@ GLenum ConvertDepthStencilFormat(D3DFORMAT format);
}
std::string getTempPath();
void writeFile(const char* path, const void* data, size_t size);
#endif // LIBGLESV2_UTILITIES_H