Skip to content

Commit c146b67

Browse files
committed
dumpspirv: Add support for FXB files
1 parent 6ad6785 commit c146b67

File tree

1 file changed

+145
-26
lines changed

1 file changed

+145
-26
lines changed

dumpspirv/dumpspirv.c

+145-26
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,60 @@
2525
*/
2626

2727
#include <SDL3/SDL.h>
28-
#include <mojoshader.h>
28+
#define __MOJOSHADER_INTERNAL__ 1
29+
#include <mojoshader_internal.h>
2930
#include <FNA3D.h>
3031

32+
static uint8_t compileFromFXB(const char *filename, const char *folder, SDL_IOStream *ops);
33+
static uint8_t compileFromTrace(const char *filename, const char *folder, SDL_IOStream *ops);
34+
35+
int main(int argc, char** argv)
36+
{
37+
int arg;
38+
char *folder;
39+
unsigned char buf[4];
40+
SDL_IOStream *ops;
41+
42+
for (arg = 1; arg < argc; arg += 1)
43+
{
44+
ops = SDL_IOFromFile(argv[arg], "rb");
45+
if (ops == NULL)
46+
{
47+
SDL_Log("%s not found, ignoring", argv[arg]);
48+
continue;
49+
}
50+
if (SDL_ReadIO(ops, buf, sizeof(buf)) < sizeof(buf))
51+
{
52+
SDL_Log("%s is too small, ignoring", argv[arg]);
53+
SDL_CloseIO(ops);
54+
continue;
55+
}
56+
SDL_SeekIO(ops, 0, SDL_IO_SEEK_SET);
57+
58+
SDL_asprintf(&folder, "%s.spirv", argv[arg]);
59+
SDL_CreateDirectory(folder);
60+
61+
if ( ((buf[0] == 0x01) && (buf[1] == 0x09) && (buf[2] == 0xFF) && (buf[3] == 0xFE)) ||
62+
((buf[0] == 0xCF) && (buf[1] == 0x0B) && (buf[2] == 0xF0) && (buf[3] == 0xBC)) )
63+
{
64+
compileFromFXB(argv[arg], folder, ops);
65+
}
66+
else
67+
{
68+
compileFromTrace(argv[arg], folder, ops);
69+
}
70+
71+
SDL_free(folder);
72+
SDL_CloseIO(ops);
73+
}
74+
75+
return 0;
76+
}
77+
78+
/*
79+
* MojoShader Effects Implementation
80+
*/
81+
3182
#define MAX_REG_FILE_F 8192
3283
#define MAX_REG_FILE_I 2047
3384
#define MAX_REG_FILE_B 2047
@@ -151,21 +202,106 @@ static const char* MOJOSHADERCALL getError(const void *ctx)
151202
return "";
152203
}
153204

154-
static uint8_t compileFromTrace(const char *filename);
205+
/*
206+
* FXB Compiler
207+
*/
155208

156-
int main(int argc, char** argv)
209+
static uint8_t compileFromFXB(const char *filename, const char *folder, SDL_IOStream *ops)
157210
{
158-
if (argc < 2)
211+
MOJOSHADER_effect *effect;
212+
TraceShader *shader;
213+
SDL_PathInfo shaderPathInfo;
214+
SDL_IOStream *shaderFile;
215+
uint32_t shaderCrc;
216+
char *shaderPath;
217+
int64_t size;
218+
void *fxb;
219+
int i;
220+
221+
TraceContext traceCtx;
222+
const MOJOSHADER_effectShaderContext ctx =
159223
{
160-
return 1;
224+
compileShader,
225+
addRef,
226+
deleteShader,
227+
getParseData,
228+
bindShaders,
229+
getBoundShaders,
230+
mapUniformBufferMemory,
231+
unmapUniformBufferMemory,
232+
getError,
233+
&traceCtx, /* shaderContext */
234+
NULL, /* m */
235+
NULL, /* f */
236+
NULL /* malloc_data */
237+
};
238+
239+
size = SDL_GetIOSize(ops);
240+
fxb = SDL_malloc(size);
241+
if (fxb == NULL)
242+
{
243+
return 0;
161244
}
245+
SDL_ReadIO(ops, fxb, size);
162246

163-
/* TODO: Add support for individual effects */
164-
compileFromTrace(argv[1]);
247+
effect = MOJOSHADER_compileEffect(
248+
(const unsigned char*) fxb,
249+
size,
250+
NULL,
251+
0,
252+
NULL,
253+
0,
254+
&ctx
255+
);
256+
SDL_free(fxb);
257+
if (effect == NULL)
258+
{
259+
SDL_Log("Compiling %s failed", filename);
260+
return 0;
261+
}
165262

166-
return 0;
263+
for (i = 0; i < effect->object_count; i += 1)
264+
{
265+
if ( (effect->objects[i].type != MOJOSHADER_SYMTYPE_VERTEXSHADER) &&
266+
(effect->objects[i].type != MOJOSHADER_SYMTYPE_PIXELSHADER) )
267+
{
268+
continue;
269+
}
270+
if (effect->objects[i].shader.is_preshader)
271+
{
272+
continue;
273+
}
274+
275+
shader = (TraceShader*) effect->objects[i].shader.shader;
276+
277+
shaderCrc = SDL_crc32(
278+
0,
279+
shader->pd->output,
280+
shader->pd->output_len - sizeof(SpirvPatchTable)
281+
);
282+
SDL_asprintf(&shaderPath, "%s/%x.spv", folder, shaderCrc);
283+
SDL_GetPathInfo(shaderPath, &shaderPathInfo);
284+
if (shaderPathInfo.type == SDL_PATHTYPE_NONE)
285+
{
286+
SDL_Log("New shader, crc %x\n", shaderCrc);
287+
shaderFile = SDL_IOFromFile(shaderPath, "wb");
288+
SDL_WriteIO(
289+
shaderFile,
290+
shader->pd->output,
291+
shader->pd->output_len - sizeof(SpirvPatchTable)
292+
);
293+
SDL_CloseIO(shaderFile);
294+
}
295+
SDL_free(shaderPath);
296+
}
297+
298+
MOJOSHADER_deleteEffect(effect);
167299
}
168300

301+
/*
302+
* FNA3D Trace Compiler
303+
*/
304+
169305
/* This is ripped from FNA3D_Driver.h */
170306
static inline MOJOSHADER_usage VertexAttribUsage(
171307
FNA3D_VertexElementUsage usage
@@ -265,7 +401,7 @@ static inline MOJOSHADER_usage VertexAttribUsage(
265401
#define MARK_QUERYPIXELCOUNT 55
266402
#define MARK_SETSTRINGMARKER 56
267403

268-
static uint8_t compileFromTrace(const char *filename)
404+
static uint8_t compileFromTrace(const char *filename, const char *folder, SDL_IOStream *ops)
269405
{
270406
#define READ(val) SDL_ReadIO(ops, &val, sizeof(val))
271407

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

290-
SDL_IOStream *ops;
291426
uint8_t mark, run;
292427

293428
/* CreateDevice, ResetBackbuffer */
@@ -434,7 +569,6 @@ static uint8_t compileFromTrace(const char *filename)
434569
}
435570

436571
/* Compiler objects */
437-
char *folder;
438572
int numElements;
439573
int curElement;
440574
MOJOSHADER_vertexAttribute *vtxDecl;
@@ -449,20 +583,11 @@ static uint8_t compileFromTrace(const char *filename)
449583
uint32_t numPasses;
450584
MOJOSHADER_effectStateChanges stateChanges;
451585

452-
/* Check for the trace file */
453-
ops = SDL_IOFromFile(filename, "rb");
454-
if (ops == NULL)
455-
{
456-
SDL_Log("%s not found!", filename);
457-
return 0;
458-
}
459-
460586
/* Beginning of the file should be a CreateDevice call */
461587
READ(mark);
462588
if (mark != MARK_CREATEDEVICE)
463589
{
464590
SDL_Log("%s is a bad trace!", filename);
465-
SDL_CloseIO(ops);
466591
return 0;
467592
}
468593
READ(presentationParameters.backBufferWidth);
@@ -476,9 +601,6 @@ static uint8_t compileFromTrace(const char *filename)
476601
READ(presentationParameters.renderTargetUsage);
477602
READ(debugMode);
478603

479-
SDL_asprintf(&folder, "%s.spirv", filename);
480-
SDL_CreateDirectory(folder);
481-
482604
/* Go through all the calls, let vsync do the timing if applicable */
483605
run = 1;
484606
READ(mark);
@@ -1229,10 +1351,7 @@ static uint8_t compileFromTrace(const char *filename)
12291351
READ(mark);
12301352
}
12311353

1232-
SDL_free(folder);
1233-
12341354
/* Clean up. We out. */
1235-
SDL_CloseIO(ops);
12361355
#define FREE_TRACES(type) \
12371356
if (trace##type##Count > 0) \
12381357
{ \

0 commit comments

Comments
 (0)