Show More
Commit Description:
Add missing component and message.
Commit Description:
Add missing component and message.
References:
File last commit:
Show/Diff file:
Action:
FNA/lib/FNA3D/replay/replay.c
1318 lines | 29.2 KiB | text/x-c | CLexer
1318 lines | 29.2 KiB | text/x-c | CLexer
r690 | /* 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; | ||||
} | ||||