|
|
/* FNA3D - 3D Graphics Library for FNA
|
|
|
*
|
|
|
* Copyright (c) 2020-2022 Ethan Lee
|
|
|
*
|
|
|
* This software is provided 'as-is', without any express or implied warranty.
|
|
|
* In no event will the authors be held liable for any damages arising from
|
|
|
* the use of this software.
|
|
|
*
|
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
|
* including commercial applications, and to alter it and redistribute it
|
|
|
* freely, subject to the following restrictions:
|
|
|
*
|
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
|
* claim that you wrote the original software. If you use this software in a
|
|
|
* product, an acknowledgment in the product documentation would be
|
|
|
* appreciated but is not required.
|
|
|
*
|
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
|
* misrepresented as being the original software.
|
|
|
*
|
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
|
*
|
|
|
* Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
#include <SDL.h>
|
|
|
#include <mojoshader.h>
|
|
|
#include <FNA3D.h>
|
|
|
|
|
|
#define MARK_CREATEDEVICE 0
|
|
|
#define MARK_DESTROYDEVICE 1
|
|
|
#define MARK_SWAPBUFFERS 2
|
|
|
#define MARK_CLEAR 3
|
|
|
#define MARK_DRAWINDEXEDPRIMITIVES 4
|
|
|
#define MARK_DRAWINSTANCEDPRIMITIVES 5
|
|
|
#define MARK_DRAWPRIMITIVES 6
|
|
|
#define MARK_SETVIEWPORT 7
|
|
|
#define MARK_SETSCISSORRECT 8
|
|
|
#define MARK_SETBLENDFACTOR 9
|
|
|
#define MARK_SETMULTISAMPLEMASK 10
|
|
|
#define MARK_SETREFERENCESTENCIL 11
|
|
|
#define MARK_SETBLENDSTATE 12
|
|
|
#define MARK_SETDEPTHSTENCILSTATE 13
|
|
|
#define MARK_APPLYRASTERIZERSTATE 14
|
|
|
#define MARK_VERIFYSAMPLER 15
|
|
|
#define MARK_VERIFYVERTEXSAMPLER 16
|
|
|
#define MARK_APPLYVERTEXBUFFERBINDINGS 17
|
|
|
#define MARK_SETRENDERTARGETS 18
|
|
|
#define MARK_RESOLVETARGET 19
|
|
|
#define MARK_RESETBACKBUFFER 20
|
|
|
#define MARK_READBACKBUFFER 21
|
|
|
#define MARK_CREATETEXTURE2D 22
|
|
|
#define MARK_CREATETEXTURE3D 23
|
|
|
#define MARK_CREATETEXTURECUBE 24
|
|
|
#define MARK_ADDDISPOSETEXTURE 25
|
|
|
#define MARK_SETTEXTUREDATA2D 26
|
|
|
#define MARK_SETTEXTUREDATA3D 27
|
|
|
#define MARK_SETTEXTUREDATACUBE 28
|
|
|
#define MARK_SETTEXTUREDATAYUV 29
|
|
|
#define MARK_GETTEXTUREDATA2D 30
|
|
|
#define MARK_GETTEXTUREDATA3D 31
|
|
|
#define MARK_GETTEXTUREDATACUBE 32
|
|
|
#define MARK_GENCOLORRENDERBUFFER 33
|
|
|
#define MARK_GENDEPTHSTENCILRENDERBUFFER 34
|
|
|
#define MARK_ADDDISPOSERENDERBUFFER 35
|
|
|
#define MARK_GENVERTEXBUFFER 36
|
|
|
#define MARK_ADDDISPOSEVERTEXBUFFER 37
|
|
|
#define MARK_SETVERTEXBUFFERDATA 38
|
|
|
#define MARK_GETVERTEXBUFFERDATA 39
|
|
|
#define MARK_GENINDEXBUFFER 40
|
|
|
#define MARK_ADDDISPOSEINDEXBUFFER 41
|
|
|
#define MARK_SETINDEXBUFFERDATA 42
|
|
|
#define MARK_GETINDEXBUFFERDATA 43
|
|
|
#define MARK_CREATEEFFECT 44
|
|
|
#define MARK_CLONEEFFECT 45
|
|
|
#define MARK_ADDDISPOSEEFFECT 46
|
|
|
#define MARK_SETEFFECTTECHNIQUE 47
|
|
|
#define MARK_APPLYEFFECT 48
|
|
|
#define MARK_BEGINPASSRESTORE 49
|
|
|
#define MARK_ENDPASSRESTORE 50
|
|
|
#define MARK_CREATEQUERY 51
|
|
|
#define MARK_ADDDISPOSEQUERY 52
|
|
|
#define MARK_QUERYBEGIN 53
|
|
|
#define MARK_QUERYEND 54
|
|
|
#define MARK_QUERYPIXELCOUNT 55
|
|
|
#define MARK_SETSTRINGMARKER 56
|
|
|
|
|
|
static uint8_t replay(const char *filename, uint8_t forceDebugMode)
|
|
|
{
|
|
|
#define READ(val) ops->read(ops, &val, sizeof(val), 1)
|
|
|
|
|
|
SDL_WindowFlags flags;
|
|
|
SDL_RWops *ops;
|
|
|
SDL_Event evt;
|
|
|
uint8_t mark, run;
|
|
|
|
|
|
/* CreateDevice, ResetBackbuffer */
|
|
|
FNA3D_Device *device;
|
|
|
FNA3D_PresentationParameters presentationParameters;
|
|
|
uint8_t debugMode;
|
|
|
|
|
|
/* SwapBuffers */
|
|
|
uint8_t hasSource, hasDestination;
|
|
|
FNA3D_Rect sourceRectangle;
|
|
|
FNA3D_Rect destinationRectangle;
|
|
|
|
|
|
/* Clear */
|
|
|
FNA3D_ClearOptions options;
|
|
|
FNA3D_Vec4 color;
|
|
|
float depth;
|
|
|
int32_t stencil;
|
|
|
|
|
|
/* Draw*Primitives */
|
|
|
FNA3D_PrimitiveType primitiveType;
|
|
|
int32_t baseVertex;
|
|
|
int32_t minVertexIndex;
|
|
|
int32_t numVertices;
|
|
|
int32_t startIndex;
|
|
|
int32_t primitiveCount;
|
|
|
int32_t instanceCount;
|
|
|
FNA3D_IndexElementSize indexElementSize;
|
|
|
int32_t vertexStart;
|
|
|
|
|
|
/* SetViewport */
|
|
|
FNA3D_Viewport viewport;
|
|
|
|
|
|
/* SetScissorRect */
|
|
|
FNA3D_Rect scissor;
|
|
|
|
|
|
/* SetBlendFactor */
|
|
|
FNA3D_Color blendFactor;
|
|
|
|
|
|
/* SetMultiSampleMask */
|
|
|
int32_t mask;
|
|
|
|
|
|
/* SetReferenceStencil */
|
|
|
int32_t ref;
|
|
|
|
|
|
/* SetBlendState */
|
|
|
FNA3D_BlendState blendState;
|
|
|
|
|
|
/* SetDepthStencilState */
|
|
|
FNA3D_DepthStencilState depthStencilState;
|
|
|
|
|
|
/* ApplyRasterizerState */
|
|
|
FNA3D_RasterizerState rasterizerState;
|
|
|
|
|
|
/* Verify*Sampler */
|
|
|
int32_t index;
|
|
|
FNA3D_SamplerState sampler;
|
|
|
|
|
|
/* ApplyVertexBufferBindings */
|
|
|
FNA3D_VertexBufferBinding *bindings;
|
|
|
FNA3D_VertexBufferBinding *binding;
|
|
|
FNA3D_VertexElement *elem;
|
|
|
int32_t numBindings;
|
|
|
uint8_t bindingsUpdated;
|
|
|
int32_t vi, vj;
|
|
|
|
|
|
/* SetRenderTargets */
|
|
|
FNA3D_RenderTargetBinding *renderTargets;
|
|
|
FNA3D_RenderTargetBinding *target;
|
|
|
int32_t numRenderTargets;
|
|
|
FNA3D_Renderbuffer *depthStencilBuffer;
|
|
|
FNA3D_DepthFormat depthFormat;
|
|
|
uint8_t preserveTargetContents;
|
|
|
int32_t ri;
|
|
|
|
|
|
/* ResolveTarget */
|
|
|
FNA3D_RenderTargetBinding resolveTarget;
|
|
|
|
|
|
/* Gen*Renderbuffer */
|
|
|
int32_t multiSampleCount;
|
|
|
|
|
|
/* *BufferData */
|
|
|
int32_t offsetInBytes;
|
|
|
int32_t elementCount;
|
|
|
int32_t elementSizeInBytes;
|
|
|
int32_t vertexStride;
|
|
|
FNA3D_SetDataOptions dataOptions;
|
|
|
|
|
|
/* SetEffectTechnique */
|
|
|
int32_t technique;
|
|
|
|
|
|
/* ApplyEffect */
|
|
|
uint32_t pass;
|
|
|
MOJOSHADER_effectStateChanges changes;
|
|
|
|
|
|
/* Miscellaneous allocations, dimensions, blah blah... */
|
|
|
int32_t x, y, z, w, h, d, level, levelCount, sizeInBytes, dataLength;
|
|
|
FNA3D_CubeMapFace cubeMapFace;
|
|
|
FNA3D_SurfaceFormat format;
|
|
|
FNA3D_BufferUsage usage;
|
|
|
uint8_t isRenderTarget, dynamic;
|
|
|
uint8_t nonNull;
|
|
|
void* miscBuffer;
|
|
|
|
|
|
/* Objects */
|
|
|
FNA3D_Texture *texture;
|
|
|
FNA3D_Renderbuffer *renderbuffer;
|
|
|
FNA3D_Buffer *buffer;
|
|
|
FNA3D_Effect *effect;
|
|
|
MOJOSHADER_effect *effectData;
|
|
|
FNA3D_Query *query;
|
|
|
|
|
|
/* Trace Objects */
|
|
|
FNA3D_Texture **traceTexture = NULL;
|
|
|
uint64_t traceTextureCount = 0;
|
|
|
FNA3D_Renderbuffer **traceRenderbuffer = NULL;
|
|
|
uint64_t traceRenderbufferCount = 0;
|
|
|
FNA3D_Buffer **traceVertexBuffer = NULL;
|
|
|
uint64_t traceVertexBufferCount = 0;
|
|
|
FNA3D_Buffer **traceIndexBuffer = NULL;
|
|
|
uint64_t traceIndexBufferCount = 0;
|
|
|
FNA3D_Effect **traceEffect = NULL;
|
|
|
MOJOSHADER_effect **traceEffectData = NULL;
|
|
|
uint64_t traceEffectCount = 0;
|
|
|
FNA3D_Query **traceQuery = NULL;
|
|
|
uint64_t traceQueryCount = 0;
|
|
|
uint64_t i, j, k;
|
|
|
#define REGISTER_OBJECT(array, type, object) \
|
|
|
for (i = 0; i < trace##array##Count; i += 1) \
|
|
|
{ \
|
|
|
if (trace##array[i] == NULL) \
|
|
|
{ \
|
|
|
trace##array[i] = object; \
|
|
|
break; \
|
|
|
} \
|
|
|
} \
|
|
|
if (i == trace##array##Count) \
|
|
|
{ \
|
|
|
trace##array##Count += 1; \
|
|
|
trace##array = SDL_realloc( \
|
|
|
trace##array, \
|
|
|
sizeof(FNA3D_##type*) * trace##array##Count \
|
|
|
); \
|
|
|
trace##array[i] = object; \
|
|
|
}
|
|
|
|
|
|
/* Check for the trace file */
|
|
|
ops = SDL_RWFromFile(filename, "rb");
|
|
|
if (ops == NULL)
|
|
|
{
|
|
|
SDL_Log("%s not found!", filename);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/* Beginning of the file should be a CreateDevice call */
|
|
|
READ(mark);
|
|
|
if (mark != MARK_CREATEDEVICE)
|
|
|
{
|
|
|
SDL_Log("%s is a bad trace!", filename);
|
|
|
ops->close(ops);
|
|
|
return 0;
|
|
|
}
|
|
|
READ(presentationParameters.backBufferWidth);
|
|
|
READ(presentationParameters.backBufferHeight);
|
|
|
READ(presentationParameters.backBufferFormat);
|
|
|
READ(presentationParameters.multiSampleCount);
|
|
|
READ(presentationParameters.isFullScreen);
|
|
|
READ(presentationParameters.depthStencilFormat);
|
|
|
READ(presentationParameters.presentationInterval);
|
|
|
READ(presentationParameters.displayOrientation);
|
|
|
READ(presentationParameters.renderTargetUsage);
|
|
|
READ(debugMode);
|
|
|
|
|
|
/* Create a window alongside the device */
|
|
|
flags = SDL_WINDOW_SHOWN | FNA3D_PrepareWindowAttributes();
|
|
|
if (presentationParameters.isFullScreen)
|
|
|
{
|
|
|
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
|
|
}
|
|
|
presentationParameters.deviceWindowHandle = SDL_CreateWindow(
|
|
|
"FNA3D Replay",
|
|
|
SDL_WINDOWPOS_CENTERED,
|
|
|
SDL_WINDOWPOS_CENTERED,
|
|
|
presentationParameters.backBufferWidth,
|
|
|
presentationParameters.backBufferHeight,
|
|
|
flags
|
|
|
);
|
|
|
device = FNA3D_CreateDevice(&presentationParameters, debugMode || forceDebugMode);
|
|
|
|
|
|
/* Go through all the calls, let vsync do the timing if applicable */
|
|
|
run = 1;
|
|
|
READ(mark);
|
|
|
while (run && mark != MARK_DESTROYDEVICE)
|
|
|
{
|
|
|
switch (mark)
|
|
|
{
|
|
|
case MARK_SWAPBUFFERS:
|
|
|
READ(hasSource);
|
|
|
if (hasSource)
|
|
|
{
|
|
|
READ(sourceRectangle.x);
|
|
|
READ(sourceRectangle.y);
|
|
|
READ(sourceRectangle.w);
|
|
|
READ(sourceRectangle.h);
|
|
|
}
|
|
|
READ(hasDestination);
|
|
|
if (hasDestination)
|
|
|
{
|
|
|
READ(destinationRectangle.x);
|
|
|
READ(destinationRectangle.y);
|
|
|
READ(destinationRectangle.w);
|
|
|
READ(destinationRectangle.h);
|
|
|
}
|
|
|
FNA3D_SwapBuffers(
|
|
|
device,
|
|
|
hasSource ? &sourceRectangle : NULL,
|
|
|
hasDestination ? &destinationRectangle : NULL,
|
|
|
presentationParameters.deviceWindowHandle
|
|
|
);
|
|
|
while (SDL_PollEvent(&evt) > 0)
|
|
|
{
|
|
|
if (evt.type == SDL_QUIT)
|
|
|
{
|
|
|
run = 0;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case MARK_CLEAR:
|
|
|
READ(options);
|
|
|
READ(color.x);
|
|
|
READ(color.y);
|
|
|
READ(color.z);
|
|
|
READ(color.w);
|
|
|
READ(depth);
|
|
|
READ(stencil);
|
|
|
FNA3D_Clear(device, options, &color, depth, stencil);
|
|
|
break;
|
|
|
case MARK_DRAWINDEXEDPRIMITIVES:
|
|
|
READ(primitiveType);
|
|
|
READ(baseVertex);
|
|
|
READ(minVertexIndex);
|
|
|
READ(numVertices);
|
|
|
READ(startIndex);
|
|
|
READ(primitiveCount);
|
|
|
READ(i);
|
|
|
READ(indexElementSize);
|
|
|
FNA3D_DrawIndexedPrimitives(
|
|
|
device,
|
|
|
primitiveType,
|
|
|
baseVertex,
|
|
|
minVertexIndex,
|
|
|
numVertices,
|
|
|
startIndex,
|
|
|
primitiveCount,
|
|
|
traceIndexBuffer[i],
|
|
|
indexElementSize
|
|
|
);
|
|
|
break;
|
|
|
case MARK_DRAWINSTANCEDPRIMITIVES:
|
|
|
READ(primitiveType);
|
|
|
READ(baseVertex);
|
|
|
READ(minVertexIndex);
|
|
|
READ(numVertices);
|
|
|
READ(startIndex);
|
|
|
READ(primitiveCount);
|
|
|
READ(instanceCount);
|
|
|
READ(i);
|
|
|
READ(indexElementSize);
|
|
|
FNA3D_DrawInstancedPrimitives(
|
|
|
device,
|
|
|
primitiveType,
|
|
|
baseVertex,
|
|
|
minVertexIndex,
|
|
|
numVertices,
|
|
|
startIndex,
|
|
|
primitiveCount,
|
|
|
instanceCount,
|
|
|
traceIndexBuffer[i],
|
|
|
indexElementSize
|
|
|
);
|
|
|
break;
|
|
|
case MARK_DRAWPRIMITIVES:
|
|
|
READ(primitiveType);
|
|
|
READ(vertexStart);
|
|
|
READ(primitiveCount);
|
|
|
FNA3D_DrawPrimitives(
|
|
|
device,
|
|
|
primitiveType,
|
|
|
vertexStart,
|
|
|
primitiveCount
|
|
|
);
|
|
|
break;
|
|
|
case MARK_SETVIEWPORT:
|
|
|
READ(viewport.x);
|
|
|
READ(viewport.y);
|
|
|
READ(viewport.w);
|
|
|
READ(viewport.h);
|
|
|
READ(viewport.minDepth);
|
|
|
READ(viewport.maxDepth);
|
|
|
FNA3D_SetViewport(device, &viewport);
|
|
|
break;
|
|
|
case MARK_SETSCISSORRECT:
|
|
|
READ(scissor.x);
|
|
|
READ(scissor.y);
|
|
|
READ(scissor.w);
|
|
|
READ(scissor.h);
|
|
|
FNA3D_SetScissorRect(device, &scissor);
|
|
|
break;
|
|
|
case MARK_SETBLENDFACTOR:
|
|
|
READ(blendFactor.r);
|
|
|
READ(blendFactor.g);
|
|
|
READ(blendFactor.b);
|
|
|
READ(blendFactor.a);
|
|
|
FNA3D_SetBlendFactor(device, &blendFactor);
|
|
|
break;
|
|
|
case MARK_SETMULTISAMPLEMASK:
|
|
|
READ(mask);
|
|
|
FNA3D_SetMultiSampleMask(device, mask);
|
|
|
break;
|
|
|
case MARK_SETREFERENCESTENCIL:
|
|
|
READ(ref);
|
|
|
FNA3D_SetReferenceStencil(device, ref);
|
|
|
break;
|
|
|
case MARK_SETBLENDSTATE:
|
|
|
READ(blendState.colorSourceBlend);
|
|
|
READ(blendState.colorDestinationBlend);
|
|
|
READ(blendState.colorBlendFunction);
|
|
|
READ(blendState.alphaSourceBlend);
|
|
|
READ(blendState.alphaDestinationBlend);
|
|
|
READ(blendState.alphaBlendFunction);
|
|
|
READ(blendState.colorWriteEnable);
|
|
|
READ(blendState.colorWriteEnable1);
|
|
|
READ(blendState.colorWriteEnable2);
|
|
|
READ(blendState.colorWriteEnable3);
|
|
|
READ(blendState.blendFactor.r);
|
|
|
READ(blendState.blendFactor.g);
|
|
|
READ(blendState.blendFactor.b);
|
|
|
READ(blendState.blendFactor.a);
|
|
|
READ(blendState.multiSampleMask);
|
|
|
FNA3D_SetBlendState(device, &blendState);
|
|
|
break;
|
|
|
case MARK_SETDEPTHSTENCILSTATE:
|
|
|
READ(depthStencilState.depthBufferEnable);
|
|
|
READ(depthStencilState.depthBufferWriteEnable);
|
|
|
READ(depthStencilState.depthBufferFunction);
|
|
|
READ(depthStencilState.stencilEnable);
|
|
|
READ(depthStencilState.stencilMask);
|
|
|
READ(depthStencilState.stencilWriteMask);
|
|
|
READ(depthStencilState.twoSidedStencilMode);
|
|
|
READ(depthStencilState.stencilFail);
|
|
|
READ(depthStencilState.stencilDepthBufferFail);
|
|
|
READ(depthStencilState.stencilPass);
|
|
|
READ(depthStencilState.stencilFunction);
|
|
|
READ(depthStencilState.ccwStencilFail);
|
|
|
READ(depthStencilState.ccwStencilDepthBufferFail);
|
|
|
READ(depthStencilState.ccwStencilPass);
|
|
|
READ(depthStencilState.ccwStencilFunction);
|
|
|
READ(depthStencilState.referenceStencil);
|
|
|
FNA3D_SetDepthStencilState(device, &depthStencilState);
|
|
|
break;
|
|
|
case MARK_APPLYRASTERIZERSTATE:
|
|
|
READ(rasterizerState.fillMode);
|
|
|
READ(rasterizerState.cullMode);
|
|
|
READ(rasterizerState.depthBias);
|
|
|
READ(rasterizerState.slopeScaleDepthBias);
|
|
|
READ(rasterizerState.scissorTestEnable);
|
|
|
READ(rasterizerState.multiSampleAntiAlias);
|
|
|
FNA3D_ApplyRasterizerState(device, &rasterizerState);
|
|
|
break;
|
|
|
case MARK_VERIFYSAMPLER:
|
|
|
READ(index);
|
|
|
READ(i);
|
|
|
READ(sampler.filter);
|
|
|
READ(sampler.addressU);
|
|
|
READ(sampler.addressV);
|
|
|
READ(sampler.addressW);
|
|
|
READ(sampler.mipMapLevelOfDetailBias);
|
|
|
READ(sampler.maxAnisotropy);
|
|
|
READ(sampler.maxMipLevel);
|
|
|
FNA3D_VerifySampler(
|
|
|
device,
|
|
|
index,
|
|
|
traceTexture[i],
|
|
|
&sampler
|
|
|
);
|
|
|
break;
|
|
|
case MARK_VERIFYVERTEXSAMPLER:
|
|
|
READ(index);
|
|
|
READ(i);
|
|
|
READ(sampler.filter);
|
|
|
READ(sampler.addressU);
|
|
|
READ(sampler.addressV);
|
|
|
READ(sampler.addressW);
|
|
|
READ(sampler.mipMapLevelOfDetailBias);
|
|
|
READ(sampler.maxAnisotropy);
|
|
|
READ(sampler.maxMipLevel);
|
|
|
FNA3D_VerifyVertexSampler(
|
|
|
device,
|
|
|
index,
|
|
|
traceTexture[i],
|
|
|
&sampler
|
|
|
);
|
|
|
break;
|
|
|
case MARK_APPLYVERTEXBUFFERBINDINGS:
|
|
|
READ(numBindings);
|
|
|
bindings = (FNA3D_VertexBufferBinding*) SDL_malloc(
|
|
|
sizeof(FNA3D_VertexBufferBinding) *
|
|
|
numBindings
|
|
|
);
|
|
|
for (vi = 0; vi < numBindings; vi += 1)
|
|
|
{
|
|
|
binding = &bindings[vi];
|
|
|
READ(i);
|
|
|
binding->vertexBuffer = traceVertexBuffer[i];
|
|
|
READ(binding->vertexDeclaration.vertexStride);
|
|
|
READ(binding->vertexDeclaration.elementCount);
|
|
|
binding->vertexDeclaration.elements = (FNA3D_VertexElement*) SDL_malloc(
|
|
|
sizeof(FNA3D_VertexElement) *
|
|
|
binding->vertexDeclaration.elementCount
|
|
|
);
|
|
|
for (vj = 0; vj < binding->vertexDeclaration.elementCount; vj += 1)
|
|
|
{
|
|
|
elem = &binding->vertexDeclaration.elements[vj];
|
|
|
READ(elem->offset);
|
|
|
READ(elem->vertexElementFormat);
|
|
|
READ(elem->vertexElementUsage);
|
|
|
READ(elem->usageIndex);
|
|
|
}
|
|
|
READ(binding->vertexOffset);
|
|
|
READ(binding->instanceFrequency);
|
|
|
}
|
|
|
READ(bindingsUpdated);
|
|
|
READ(baseVertex);
|
|
|
FNA3D_ApplyVertexBufferBindings(
|
|
|
device,
|
|
|
bindings,
|
|
|
numBindings,
|
|
|
bindingsUpdated,
|
|
|
baseVertex
|
|
|
);
|
|
|
for (vi = 0; vi < numBindings; vi += 1)
|
|
|
{
|
|
|
binding = &bindings[vi];
|
|
|
SDL_free(binding->vertexDeclaration.elements);
|
|
|
}
|
|
|
SDL_free(bindings);
|
|
|
break;
|
|
|
case MARK_SETRENDERTARGETS:
|
|
|
READ(numRenderTargets);
|
|
|
if (numRenderTargets == 0)
|
|
|
{
|
|
|
renderTargets = NULL;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
renderTargets = (FNA3D_RenderTargetBinding*) SDL_malloc(
|
|
|
sizeof(FNA3D_RenderTargetBinding) *
|
|
|
numRenderTargets
|
|
|
);
|
|
|
for (ri = 0; ri < numRenderTargets; ri += 1)
|
|
|
{
|
|
|
target = &renderTargets[ri];
|
|
|
READ(target->type);
|
|
|
if (target->type == FNA3D_RENDERTARGET_TYPE_2D)
|
|
|
{
|
|
|
READ(target->twod.width);
|
|
|
READ(target->twod.height);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
SDL_assert(target->type == FNA3D_RENDERTARGET_TYPE_CUBE);
|
|
|
READ(target->cube.size);
|
|
|
READ(target->cube.face);
|
|
|
}
|
|
|
|
|
|
READ(target->levelCount);
|
|
|
READ(target->multiSampleCount);
|
|
|
|
|
|
READ(nonNull);
|
|
|
if (nonNull)
|
|
|
{
|
|
|
READ(i);
|
|
|
target->texture = traceTexture[i];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
target->texture = NULL;
|
|
|
}
|
|
|
|
|
|
READ(nonNull);
|
|
|
if (nonNull)
|
|
|
{
|
|
|
READ(i);
|
|
|
target->colorBuffer = traceRenderbuffer[i];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
target->colorBuffer = NULL;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
READ(nonNull);
|
|
|
if (nonNull)
|
|
|
{
|
|
|
READ(i);
|
|
|
depthStencilBuffer = traceRenderbuffer[i];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
depthStencilBuffer = NULL;
|
|
|
}
|
|
|
|
|
|
READ(depthFormat);
|
|
|
READ(preserveTargetContents);
|
|
|
|
|
|
FNA3D_SetRenderTargets(
|
|
|
device,
|
|
|
renderTargets,
|
|
|
numRenderTargets,
|
|
|
depthStencilBuffer,
|
|
|
depthFormat,
|
|
|
preserveTargetContents
|
|
|
);
|
|
|
|
|
|
SDL_free(renderTargets);
|
|
|
break;
|
|
|
case MARK_RESOLVETARGET:
|
|
|
READ(resolveTarget.type);
|
|
|
if (resolveTarget.type == FNA3D_RENDERTARGET_TYPE_2D)
|
|
|
{
|
|
|
READ(resolveTarget.twod.width);
|
|
|
READ(resolveTarget.twod.height);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
SDL_assert(resolveTarget.type == FNA3D_RENDERTARGET_TYPE_CUBE);
|
|
|
READ(resolveTarget.cube.size);
|
|
|
READ(resolveTarget.cube.face);
|
|
|
}
|
|
|
|
|
|
READ(resolveTarget.levelCount);
|
|
|
READ(resolveTarget.multiSampleCount);
|
|
|
|
|
|
READ(nonNull);
|
|
|
if (nonNull)
|
|
|
{
|
|
|
READ(i);
|
|
|
resolveTarget.texture = traceTexture[i];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
resolveTarget.texture = NULL;
|
|
|
}
|
|
|
|
|
|
READ(nonNull);
|
|
|
if (nonNull)
|
|
|
{
|
|
|
READ(i);
|
|
|
resolveTarget.colorBuffer = traceRenderbuffer[i];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
resolveTarget.colorBuffer = NULL;
|
|
|
}
|
|
|
|
|
|
FNA3D_ResolveTarget(device, &resolveTarget);
|
|
|
break;
|
|
|
case MARK_RESETBACKBUFFER:
|
|
|
READ(presentationParameters.backBufferWidth);
|
|
|
READ(presentationParameters.backBufferHeight);
|
|
|
READ(presentationParameters.backBufferFormat);
|
|
|
READ(presentationParameters.multiSampleCount);
|
|
|
READ(presentationParameters.isFullScreen);
|
|
|
READ(presentationParameters.depthStencilFormat);
|
|
|
READ(presentationParameters.presentationInterval);
|
|
|
READ(presentationParameters.displayOrientation);
|
|
|
READ(presentationParameters.renderTargetUsage);
|
|
|
SDL_SetWindowFullscreen(
|
|
|
presentationParameters.deviceWindowHandle,
|
|
|
presentationParameters.isFullScreen ?
|
|
|
SDL_WINDOW_FULLSCREEN_DESKTOP :
|
|
|
0
|
|
|
);
|
|
|
SDL_SetWindowSize(
|
|
|
presentationParameters.deviceWindowHandle,
|
|
|
presentationParameters.backBufferWidth,
|
|
|
presentationParameters.backBufferHeight
|
|
|
);
|
|
|
FNA3D_ResetBackbuffer(device, &presentationParameters);
|
|
|
break;
|
|
|
case MARK_READBACKBUFFER:
|
|
|
READ(x);
|
|
|
READ(y);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
FNA3D_ReadBackbuffer(
|
|
|
device,
|
|
|
x,
|
|
|
y,
|
|
|
w,
|
|
|
h,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_CREATETEXTURE2D:
|
|
|
READ(format);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(levelCount);
|
|
|
READ(isRenderTarget);
|
|
|
texture = FNA3D_CreateTexture2D(
|
|
|
device,
|
|
|
format,
|
|
|
w,
|
|
|
h,
|
|
|
levelCount,
|
|
|
isRenderTarget
|
|
|
);
|
|
|
REGISTER_OBJECT(Texture, Texture, texture)
|
|
|
break;
|
|
|
case MARK_CREATETEXTURE3D:
|
|
|
READ(format);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(d);
|
|
|
READ(levelCount);
|
|
|
texture = FNA3D_CreateTexture3D(
|
|
|
device,
|
|
|
format,
|
|
|
w,
|
|
|
h,
|
|
|
d,
|
|
|
levelCount
|
|
|
);
|
|
|
REGISTER_OBJECT(Texture, Texture, texture)
|
|
|
break;
|
|
|
case MARK_CREATETEXTURECUBE:
|
|
|
READ(format);
|
|
|
READ(w);
|
|
|
READ(levelCount);
|
|
|
READ(isRenderTarget);
|
|
|
texture = FNA3D_CreateTextureCube(
|
|
|
device,
|
|
|
format,
|
|
|
w,
|
|
|
levelCount,
|
|
|
isRenderTarget
|
|
|
);
|
|
|
REGISTER_OBJECT(Texture, Texture, texture)
|
|
|
break;
|
|
|
case MARK_ADDDISPOSETEXTURE:
|
|
|
READ(i);
|
|
|
FNA3D_AddDisposeTexture(device, traceTexture[i]);
|
|
|
traceTexture[i] = NULL;
|
|
|
break;
|
|
|
case MARK_SETTEXTUREDATA2D:
|
|
|
READ(i);
|
|
|
READ(x);
|
|
|
READ(y);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(level);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
ops->read(ops, miscBuffer, dataLength, 1);
|
|
|
FNA3D_SetTextureData2D(
|
|
|
device,
|
|
|
traceTexture[i],
|
|
|
x,
|
|
|
y,
|
|
|
w,
|
|
|
h,
|
|
|
level,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_SETTEXTUREDATA3D:
|
|
|
READ(i);
|
|
|
READ(x);
|
|
|
READ(y);
|
|
|
READ(z);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(d);
|
|
|
READ(level);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
ops->read(ops, miscBuffer, dataLength, 1);
|
|
|
FNA3D_SetTextureData3D(
|
|
|
device,
|
|
|
traceTexture[i],
|
|
|
x,
|
|
|
y,
|
|
|
z,
|
|
|
w,
|
|
|
h,
|
|
|
d,
|
|
|
level,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_SETTEXTUREDATACUBE:
|
|
|
READ(i);
|
|
|
READ(x);
|
|
|
READ(y);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(cubeMapFace);
|
|
|
READ(level);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
ops->read(ops, miscBuffer, dataLength, 1);
|
|
|
FNA3D_SetTextureDataCube(
|
|
|
device,
|
|
|
traceTexture[i],
|
|
|
x,
|
|
|
y,
|
|
|
w,
|
|
|
h,
|
|
|
cubeMapFace,
|
|
|
level,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_SETTEXTUREDATAYUV:
|
|
|
READ(i);
|
|
|
READ(j);
|
|
|
READ(k);
|
|
|
READ(x);
|
|
|
READ(y);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
ops->read(ops, miscBuffer, dataLength, 1);
|
|
|
FNA3D_SetTextureDataYUV(
|
|
|
device,
|
|
|
traceTexture[i],
|
|
|
traceTexture[j],
|
|
|
traceTexture[k],
|
|
|
x,
|
|
|
y,
|
|
|
w,
|
|
|
h,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_GETTEXTUREDATA2D:
|
|
|
READ(i);
|
|
|
READ(x);
|
|
|
READ(y);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(level);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
FNA3D_GetTextureData2D(
|
|
|
device,
|
|
|
traceTexture[i],
|
|
|
x,
|
|
|
y,
|
|
|
w,
|
|
|
h,
|
|
|
level,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_GETTEXTUREDATA3D:
|
|
|
READ(i);
|
|
|
READ(x);
|
|
|
READ(y);
|
|
|
READ(z);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(d);
|
|
|
READ(level);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
FNA3D_GetTextureData3D(
|
|
|
device,
|
|
|
traceTexture[i],
|
|
|
x,
|
|
|
y,
|
|
|
z,
|
|
|
w,
|
|
|
h,
|
|
|
d,
|
|
|
level,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_GETTEXTUREDATACUBE:
|
|
|
READ(i);
|
|
|
READ(x);
|
|
|
READ(y);
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(cubeMapFace);
|
|
|
READ(level);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
FNA3D_GetTextureDataCube(
|
|
|
device,
|
|
|
traceTexture[i],
|
|
|
x,
|
|
|
y,
|
|
|
w,
|
|
|
h,
|
|
|
cubeMapFace,
|
|
|
level,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_GENCOLORRENDERBUFFER:
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(format);
|
|
|
READ(multiSampleCount);
|
|
|
READ(nonNull);
|
|
|
if (nonNull)
|
|
|
{
|
|
|
READ(i);
|
|
|
texture = traceTexture[i];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
texture = NULL;
|
|
|
}
|
|
|
renderbuffer = FNA3D_GenColorRenderbuffer(
|
|
|
device,
|
|
|
w,
|
|
|
h,
|
|
|
format,
|
|
|
multiSampleCount,
|
|
|
texture
|
|
|
);
|
|
|
REGISTER_OBJECT(Renderbuffer, Renderbuffer, renderbuffer)
|
|
|
break;
|
|
|
case MARK_GENDEPTHSTENCILRENDERBUFFER:
|
|
|
READ(w);
|
|
|
READ(h);
|
|
|
READ(depthFormat);
|
|
|
READ(multiSampleCount);
|
|
|
renderbuffer = FNA3D_GenDepthStencilRenderbuffer(
|
|
|
device,
|
|
|
w,
|
|
|
h,
|
|
|
depthFormat,
|
|
|
multiSampleCount
|
|
|
);
|
|
|
REGISTER_OBJECT(Renderbuffer, Renderbuffer, renderbuffer)
|
|
|
break;
|
|
|
case MARK_ADDDISPOSERENDERBUFFER:
|
|
|
READ(i);
|
|
|
FNA3D_AddDisposeRenderbuffer(
|
|
|
device,
|
|
|
traceRenderbuffer[i]
|
|
|
);
|
|
|
traceRenderbuffer[i] = NULL;
|
|
|
break;
|
|
|
case MARK_GENVERTEXBUFFER:
|
|
|
READ(dynamic);
|
|
|
READ(usage);
|
|
|
READ(sizeInBytes);
|
|
|
buffer = FNA3D_GenVertexBuffer(
|
|
|
device,
|
|
|
dynamic,
|
|
|
usage,
|
|
|
sizeInBytes
|
|
|
);
|
|
|
REGISTER_OBJECT(VertexBuffer, Buffer, buffer)
|
|
|
break;
|
|
|
case MARK_ADDDISPOSEVERTEXBUFFER:
|
|
|
READ(i);
|
|
|
FNA3D_AddDisposeVertexBuffer(
|
|
|
device,
|
|
|
traceVertexBuffer[i]
|
|
|
);
|
|
|
traceVertexBuffer[i] = NULL;
|
|
|
break;
|
|
|
case MARK_SETVERTEXBUFFERDATA:
|
|
|
READ(i);
|
|
|
READ(offsetInBytes);
|
|
|
READ(elementCount);
|
|
|
READ(elementSizeInBytes);
|
|
|
READ(vertexStride);
|
|
|
READ(dataOptions);
|
|
|
miscBuffer = SDL_malloc(vertexStride * elementCount);
|
|
|
ops->read(ops, miscBuffer, vertexStride * elementCount, 1);
|
|
|
FNA3D_SetVertexBufferData(
|
|
|
device,
|
|
|
traceVertexBuffer[i],
|
|
|
offsetInBytes,
|
|
|
miscBuffer,
|
|
|
elementCount,
|
|
|
elementSizeInBytes,
|
|
|
vertexStride,
|
|
|
dataOptions
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_GETVERTEXBUFFERDATA:
|
|
|
READ(i);
|
|
|
READ(offsetInBytes);
|
|
|
READ(elementCount);
|
|
|
READ(elementSizeInBytes);
|
|
|
READ(vertexStride);
|
|
|
miscBuffer = SDL_malloc(vertexStride * elementCount);
|
|
|
FNA3D_GetVertexBufferData(
|
|
|
device,
|
|
|
traceVertexBuffer[i],
|
|
|
offsetInBytes,
|
|
|
miscBuffer,
|
|
|
elementCount,
|
|
|
elementSizeInBytes,
|
|
|
vertexStride
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_GENINDEXBUFFER:
|
|
|
READ(dynamic);
|
|
|
READ(usage);
|
|
|
READ(sizeInBytes);
|
|
|
buffer = FNA3D_GenIndexBuffer(
|
|
|
device,
|
|
|
dynamic,
|
|
|
usage,
|
|
|
sizeInBytes
|
|
|
);
|
|
|
REGISTER_OBJECT(IndexBuffer, Buffer, buffer)
|
|
|
break;
|
|
|
case MARK_ADDDISPOSEINDEXBUFFER:
|
|
|
READ(i);
|
|
|
FNA3D_AddDisposeIndexBuffer(
|
|
|
device,
|
|
|
traceIndexBuffer[i]
|
|
|
);
|
|
|
traceIndexBuffer[i] = NULL;
|
|
|
break;
|
|
|
case MARK_SETINDEXBUFFERDATA:
|
|
|
READ(i);
|
|
|
READ(offsetInBytes);
|
|
|
READ(dataLength);
|
|
|
READ(dataOptions);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
ops->read(ops, miscBuffer, dataLength, 1);
|
|
|
FNA3D_SetIndexBufferData(
|
|
|
device,
|
|
|
traceIndexBuffer[i],
|
|
|
offsetInBytes,
|
|
|
miscBuffer,
|
|
|
dataLength,
|
|
|
dataOptions
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_GETINDEXBUFFERDATA:
|
|
|
READ(i);
|
|
|
READ(offsetInBytes);
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
FNA3D_GetIndexBufferData(
|
|
|
device,
|
|
|
traceIndexBuffer[i],
|
|
|
offsetInBytes,
|
|
|
miscBuffer,
|
|
|
dataLength
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_CREATEEFFECT:
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
ops->read(ops, miscBuffer, dataLength, 1);
|
|
|
FNA3D_CreateEffect(
|
|
|
device,
|
|
|
(uint8_t*) miscBuffer,
|
|
|
dataLength,
|
|
|
&effect,
|
|
|
&effectData
|
|
|
);
|
|
|
SDL_free(miscBuffer);
|
|
|
for (i = 0; i < traceEffectCount; i += 1)
|
|
|
{
|
|
|
if (traceEffect[i] == NULL)
|
|
|
{
|
|
|
traceEffect[i] = effect;
|
|
|
traceEffectData[i] = effectData;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (i == traceEffectCount)
|
|
|
{
|
|
|
traceEffectCount += 1;
|
|
|
traceEffect = SDL_realloc(
|
|
|
traceEffect,
|
|
|
sizeof(FNA3D_Effect*) * traceEffectCount
|
|
|
);
|
|
|
traceEffectData = SDL_realloc(
|
|
|
traceEffectData,
|
|
|
sizeof(MOJOSHADER_effect*) * traceEffectCount
|
|
|
);
|
|
|
traceEffect[i] = effect;
|
|
|
traceEffectData[i] = effectData;
|
|
|
}
|
|
|
break;
|
|
|
case MARK_CLONEEFFECT:
|
|
|
READ(i);
|
|
|
FNA3D_CloneEffect(
|
|
|
device,
|
|
|
traceEffect[i],
|
|
|
&effect,
|
|
|
&effectData
|
|
|
);
|
|
|
for (i = 0; i < traceEffectCount; i += 1)
|
|
|
{
|
|
|
if (traceEffect[i] == NULL)
|
|
|
{
|
|
|
traceEffect[i] = effect;
|
|
|
traceEffectData[i] = effectData;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (i == traceEffectCount)
|
|
|
{
|
|
|
traceEffectCount += 1;
|
|
|
traceEffect = SDL_realloc(
|
|
|
traceEffect,
|
|
|
sizeof(FNA3D_Effect*) * traceEffectCount
|
|
|
);
|
|
|
traceEffectData = SDL_realloc(
|
|
|
traceEffectData,
|
|
|
sizeof(MOJOSHADER_effect*) * traceEffectCount
|
|
|
);
|
|
|
traceEffect[i] = effect;
|
|
|
traceEffectData[i] = effectData;
|
|
|
}
|
|
|
break;
|
|
|
case MARK_ADDDISPOSEEFFECT:
|
|
|
READ(i);
|
|
|
FNA3D_AddDisposeEffect(device, traceEffect[i]);
|
|
|
traceEffect[i] = NULL;
|
|
|
traceEffectData[i] = NULL;
|
|
|
break;
|
|
|
case MARK_SETEFFECTTECHNIQUE:
|
|
|
READ(i);
|
|
|
READ(technique);
|
|
|
FNA3D_SetEffectTechnique(
|
|
|
device,
|
|
|
traceEffect[i],
|
|
|
&traceEffectData[i]->techniques[technique]
|
|
|
);
|
|
|
break;
|
|
|
case MARK_APPLYEFFECT:
|
|
|
READ(i);
|
|
|
READ(pass);
|
|
|
effectData = traceEffectData[i];
|
|
|
for (vi = 0; vi < effectData->param_count; vi += 1)
|
|
|
{
|
|
|
ops->read(
|
|
|
ops,
|
|
|
effectData->params[vi].value.values,
|
|
|
effectData->params[vi].value.value_count * 4,
|
|
|
1
|
|
|
);
|
|
|
}
|
|
|
FNA3D_ApplyEffect(
|
|
|
device,
|
|
|
traceEffect[i],
|
|
|
pass,
|
|
|
&changes
|
|
|
);
|
|
|
break;
|
|
|
case MARK_BEGINPASSRESTORE:
|
|
|
READ(i);
|
|
|
FNA3D_BeginPassRestore(
|
|
|
device,
|
|
|
traceEffect[i],
|
|
|
&changes
|
|
|
);
|
|
|
break;
|
|
|
case MARK_ENDPASSRESTORE:
|
|
|
READ(i);
|
|
|
FNA3D_EndPassRestore(device, traceEffect[i]);
|
|
|
break;
|
|
|
case MARK_CREATEQUERY:
|
|
|
query = FNA3D_CreateQuery(device);
|
|
|
REGISTER_OBJECT(Query, Query, query)
|
|
|
break;
|
|
|
case MARK_ADDDISPOSEQUERY:
|
|
|
READ(i);
|
|
|
FNA3D_AddDisposeQuery(device, traceQuery[i]);
|
|
|
traceQuery[i] = NULL;
|
|
|
break;
|
|
|
case MARK_QUERYBEGIN:
|
|
|
READ(i);
|
|
|
FNA3D_QueryBegin(device, traceQuery[i]);
|
|
|
break;
|
|
|
case MARK_QUERYEND:
|
|
|
READ(i);
|
|
|
FNA3D_QueryEnd(device, traceQuery[i]);
|
|
|
break;
|
|
|
case MARK_QUERYPIXELCOUNT:
|
|
|
READ(i);
|
|
|
while (!FNA3D_QueryComplete(device, traceQuery[i]))
|
|
|
{
|
|
|
SDL_Delay(0);
|
|
|
}
|
|
|
FNA3D_QueryBegin(device, traceQuery[i]);
|
|
|
break;
|
|
|
case MARK_SETSTRINGMARKER:
|
|
|
READ(dataLength);
|
|
|
miscBuffer = SDL_malloc(dataLength);
|
|
|
ops->read(ops, miscBuffer, dataLength, 1);
|
|
|
FNA3D_SetStringMarker(device, (char*) miscBuffer);
|
|
|
SDL_free(miscBuffer);
|
|
|
break;
|
|
|
case MARK_CREATEDEVICE:
|
|
|
case MARK_DESTROYDEVICE:
|
|
|
SDL_assert(0 && "Unexpected mark!");
|
|
|
break;
|
|
|
default:
|
|
|
SDL_assert(0 && "Unrecognized mark!");
|
|
|
break;
|
|
|
}
|
|
|
READ(mark);
|
|
|
}
|
|
|
|
|
|
/* Clean up. We out. */
|
|
|
ops->close(ops);
|
|
|
#define FREE_TRACES(type) \
|
|
|
if (trace##type##Count > 0) \
|
|
|
{ \
|
|
|
for (i = 0; i < trace##type##Count; i += 1) \
|
|
|
{ \
|
|
|
if (trace##type[i] != NULL) \
|
|
|
{ \
|
|
|
FNA3D_AddDispose##type( \
|
|
|
device, \
|
|
|
trace##type[i] \
|
|
|
); \
|
|
|
} \
|
|
|
} \
|
|
|
SDL_free(trace##type); \
|
|
|
trace##type = NULL; \
|
|
|
trace##type##Count = 0; \
|
|
|
}
|
|
|
FREE_TRACES(Texture)
|
|
|
FREE_TRACES(Renderbuffer)
|
|
|
FREE_TRACES(VertexBuffer)
|
|
|
FREE_TRACES(IndexBuffer)
|
|
|
FREE_TRACES(Effect)
|
|
|
FREE_TRACES(Query)
|
|
|
if (traceEffectData != NULL)
|
|
|
{
|
|
|
SDL_free(traceEffectData);
|
|
|
traceEffectData = NULL;
|
|
|
}
|
|
|
#undef FREE_TRACES
|
|
|
FNA3D_DestroyDevice(device);
|
|
|
SDL_DestroyWindow(presentationParameters.deviceWindowHandle);
|
|
|
return !run;
|
|
|
|
|
|
#undef REGISTER_OBJECT
|
|
|
#undef READ
|
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
{
|
|
|
int i;
|
|
|
int replayArgIndex = 1;
|
|
|
uint8_t forceDebugMode = 0;
|
|
|
|
|
|
SDL_Init(SDL_INIT_VIDEO);
|
|
|
|
|
|
/* Make sure we don't recursively trace... */
|
|
|
SDL_SetHint("FNA3D_DISABLE_TRACING", "1");
|
|
|
|
|
|
if (argc > 1)
|
|
|
{
|
|
|
if (SDL_strcmp(argv[1], "-debug") == 0)
|
|
|
{
|
|
|
forceDebugMode = 1;
|
|
|
replayArgIndex += 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (replayArgIndex == argc)
|
|
|
{
|
|
|
replay("FNA3D_Trace.bin", forceDebugMode);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
for (i = replayArgIndex; i < argc; i += 1)
|
|
|
{
|
|
|
if (replay(argv[i], forceDebugMode))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
SDL_Quit();
|
|
|
return 0;
|
|
|
}
|
|
|
|