Skip to content

Commit

Permalink
dumpspirv: Add support for FXB files
Browse files Browse the repository at this point in the history
  • Loading branch information
flibitijibibo committed Jan 26, 2025
1 parent 6ad6785 commit c146b67
Showing 1 changed file with 145 additions and 26 deletions.
171 changes: 145 additions & 26 deletions dumpspirv/dumpspirv.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,60 @@
*/

#include <SDL3/SDL.h>
#include <mojoshader.h>
#define __MOJOSHADER_INTERNAL__ 1
#include <mojoshader_internal.h>
#include <FNA3D.h>

static uint8_t compileFromFXB(const char *filename, const char *folder, SDL_IOStream *ops);
static uint8_t compileFromTrace(const char *filename, const char *folder, SDL_IOStream *ops);

int main(int argc, char** argv)
{
int arg;
char *folder;
unsigned char buf[4];
SDL_IOStream *ops;

for (arg = 1; arg < argc; arg += 1)
{
ops = SDL_IOFromFile(argv[arg], "rb");
if (ops == NULL)
{
SDL_Log("%s not found, ignoring", argv[arg]);
continue;
}
if (SDL_ReadIO(ops, buf, sizeof(buf)) < sizeof(buf))
{
SDL_Log("%s is too small, ignoring", argv[arg]);
SDL_CloseIO(ops);
continue;
}
SDL_SeekIO(ops, 0, SDL_IO_SEEK_SET);

SDL_asprintf(&folder, "%s.spirv", argv[arg]);
SDL_CreateDirectory(folder);

if ( ((buf[0] == 0x01) && (buf[1] == 0x09) && (buf[2] == 0xFF) && (buf[3] == 0xFE)) ||
((buf[0] == 0xCF) && (buf[1] == 0x0B) && (buf[2] == 0xF0) && (buf[3] == 0xBC)) )
{
compileFromFXB(argv[arg], folder, ops);
}
else
{
compileFromTrace(argv[arg], folder, ops);
}

SDL_free(folder);
SDL_CloseIO(ops);
}

return 0;
}

/*
* MojoShader Effects Implementation
*/

#define MAX_REG_FILE_F 8192
#define MAX_REG_FILE_I 2047
#define MAX_REG_FILE_B 2047
Expand Down Expand Up @@ -151,21 +202,106 @@ static const char* MOJOSHADERCALL getError(const void *ctx)
return "";
}

static uint8_t compileFromTrace(const char *filename);
/*
* FXB Compiler
*/

int main(int argc, char** argv)
static uint8_t compileFromFXB(const char *filename, const char *folder, SDL_IOStream *ops)
{
if (argc < 2)
MOJOSHADER_effect *effect;
TraceShader *shader;
SDL_PathInfo shaderPathInfo;
SDL_IOStream *shaderFile;
uint32_t shaderCrc;
char *shaderPath;
int64_t size;
void *fxb;
int i;

TraceContext traceCtx;
const MOJOSHADER_effectShaderContext ctx =
{
return 1;
compileShader,
addRef,
deleteShader,
getParseData,
bindShaders,
getBoundShaders,
mapUniformBufferMemory,
unmapUniformBufferMemory,
getError,
&traceCtx, /* shaderContext */
NULL, /* m */
NULL, /* f */
NULL /* malloc_data */
};

size = SDL_GetIOSize(ops);
fxb = SDL_malloc(size);
if (fxb == NULL)
{
return 0;
}
SDL_ReadIO(ops, fxb, size);

/* TODO: Add support for individual effects */
compileFromTrace(argv[1]);
effect = MOJOSHADER_compileEffect(
(const unsigned char*) fxb,
size,
NULL,
0,
NULL,
0,
&ctx
);
SDL_free(fxb);
if (effect == NULL)
{
SDL_Log("Compiling %s failed", filename);
return 0;
}

return 0;
for (i = 0; i < effect->object_count; i += 1)
{
if ( (effect->objects[i].type != MOJOSHADER_SYMTYPE_VERTEXSHADER) &&
(effect->objects[i].type != MOJOSHADER_SYMTYPE_PIXELSHADER) )
{
continue;
}
if (effect->objects[i].shader.is_preshader)
{
continue;
}

shader = (TraceShader*) effect->objects[i].shader.shader;

shaderCrc = SDL_crc32(
0,
shader->pd->output,
shader->pd->output_len - sizeof(SpirvPatchTable)
);
SDL_asprintf(&shaderPath, "%s/%x.spv", folder, shaderCrc);
SDL_GetPathInfo(shaderPath, &shaderPathInfo);
if (shaderPathInfo.type == SDL_PATHTYPE_NONE)
{
SDL_Log("New shader, crc %x\n", shaderCrc);
shaderFile = SDL_IOFromFile(shaderPath, "wb");
SDL_WriteIO(
shaderFile,
shader->pd->output,
shader->pd->output_len - sizeof(SpirvPatchTable)
);
SDL_CloseIO(shaderFile);
}
SDL_free(shaderPath);
}

MOJOSHADER_deleteEffect(effect);
}

/*
* FNA3D Trace Compiler
*/

/* This is ripped from FNA3D_Driver.h */
static inline MOJOSHADER_usage VertexAttribUsage(
FNA3D_VertexElementUsage usage
Expand Down Expand Up @@ -265,7 +401,7 @@ static inline MOJOSHADER_usage VertexAttribUsage(
#define MARK_QUERYPIXELCOUNT 55
#define MARK_SETSTRINGMARKER 56

static uint8_t compileFromTrace(const char *filename)
static uint8_t compileFromTrace(const char *filename, const char *folder, SDL_IOStream *ops)
{
#define READ(val) SDL_ReadIO(ops, &val, sizeof(val))

Expand All @@ -287,7 +423,6 @@ static uint8_t compileFromTrace(const char *filename)
NULL /* malloc_data */
};

SDL_IOStream *ops;
uint8_t mark, run;

/* CreateDevice, ResetBackbuffer */
Expand Down Expand Up @@ -434,7 +569,6 @@ static uint8_t compileFromTrace(const char *filename)
}

/* Compiler objects */
char *folder;
int numElements;
int curElement;
MOJOSHADER_vertexAttribute *vtxDecl;
Expand All @@ -449,20 +583,11 @@ static uint8_t compileFromTrace(const char *filename)
uint32_t numPasses;
MOJOSHADER_effectStateChanges stateChanges;

/* Check for the trace file */
ops = SDL_IOFromFile(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);
SDL_CloseIO(ops);
return 0;
}
READ(presentationParameters.backBufferWidth);
Expand All @@ -476,9 +601,6 @@ static uint8_t compileFromTrace(const char *filename)
READ(presentationParameters.renderTargetUsage);
READ(debugMode);

SDL_asprintf(&folder, "%s.spirv", filename);
SDL_CreateDirectory(folder);

/* Go through all the calls, let vsync do the timing if applicable */
run = 1;
READ(mark);
Expand Down Expand Up @@ -1229,10 +1351,7 @@ static uint8_t compileFromTrace(const char *filename)
READ(mark);
}

SDL_free(folder);

/* Clean up. We out. */
SDL_CloseIO(ops);
#define FREE_TRACES(type) \
if (trace##type##Count > 0) \
{ \
Expand Down

0 comments on commit c146b67

Please sign in to comment.