Skip to content

Commit

Permalink
Update mojoshader_sdlgpu for the new SDL_shader API
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSpydog committed Apr 18, 2024
1 parent a7138eb commit 5b33109
Showing 1 changed file with 60 additions and 74 deletions.
134 changes: 60 additions & 74 deletions src/mojoshader_sdlgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,11 @@ DECLSPEC void MOJOSHADER_sdlGetShaderModules(MOJOSHADER_sdlContext *ctx,
#endif
#endif /* SDL3_SHADER_LIBRARY */

typedef const void* (*SDLCALL SHD_TranslateFromSPIRV_func)(SDL_GpuBackend backend,
SDL_GpuShaderType shaderType,
const char* spirv,
size_t spirv_size,
size_t* output_size);
typedef int (*SDLCALL SHD_Init_func)(SDL_GpuDevice* device);
typedef void (*SDLCALL SHD_Quit_func)(void);
typedef SDL_GpuShaderModule* (*SDLCALL SHD_CreateShaderModuleFromSPIRV_func)(SDL_GpuShaderStage shader_stage,
const char* spirv,
size_t spirv_size);

/* Max entries for each register file type */
#define MAX_REG_FILE_F 8192
Expand All @@ -271,15 +271,14 @@ typedef const void* (*SDLCALL SHD_TranslateFromSPIRV_func)(SDL_GpuBackend backen
struct MOJOSHADER_sdlContext
{
SDL_GpuDevice *device;
SDL_GpuBackend backend;
const char *profile;

MOJOSHADER_malloc malloc_fn;
MOJOSHADER_free free_fn;
void *malloc_data;

void *sdl_shader_dll;
SHD_TranslateFromSPIRV_func SHD_TranslateFromSPIRV;
SHD_CreateShaderModuleFromSPIRV_func SHD_CreateShaderModuleFromSPIRV;

/* The constant register files...
* !!! FIXME: Man, it kills me how much memory this takes...
Expand Down Expand Up @@ -485,7 +484,8 @@ MOJOSHADER_sdlContext *MOJOSHADER_sdlCreateContext(
) {
MOJOSHADER_sdlContext* resultCtx;
void *sdl_shader;
SHD_TranslateFromSPIRV_func SHD_TranslateFromSPIRV;
SHD_Init_func SHD_Init;
SHD_CreateShaderModuleFromSPIRV_func SHD_CreateShaderModuleFromSPIRV;
SDL_GpuBackend backend = SDL_GpuGetBackend(device);

if (m == NULL) m = MOJOSHADER_internal_malloc;
Expand All @@ -494,7 +494,7 @@ MOJOSHADER_sdlContext *MOJOSHADER_sdlCreateContext(
if (backend == SDL_GPU_BACKEND_VULKAN)
{
sdl_shader = NULL;
SHD_TranslateFromSPIRV = NULL;
SHD_CreateShaderModuleFromSPIRV = NULL;
} // if
else
{
Expand All @@ -504,14 +504,25 @@ MOJOSHADER_sdlContext *MOJOSHADER_sdlCreateContext(
set_error("Backend requires SDL_shader, which is unavailable");
return NULL;
} // if
SHD_TranslateFromSPIRV = (SHD_TranslateFromSPIRV_func) SDL_LoadFunction(sdl_shader,
"SHD_TranslateFromSPIRV");
if (SHD_TranslateFromSPIRV == NULL)

SHD_Init = (SHD_Init_func) SDL_LoadFunction(sdl_shader, "SHD_Init");
if (SHD_Init == NULL)
{
set_error("Backend requires SHD_Init, which is unavailable");
SDL_UnloadObject(sdl_shader);
return NULL;
} // if

SHD_CreateShaderModuleFromSPIRV = (SHD_CreateShaderModuleFromSPIRV_func) SDL_LoadFunction(sdl_shader,
"SHD_CreateShaderModuleFromSPIRV");
if (SHD_CreateShaderModuleFromSPIRV == NULL)
{
set_error("Backend requires SHD_TranslateFromSPIRV, which is unavailable");
set_error("Backend requires SHD_CreateShaderModuleFromSPIRV, which is unavailable");
SDL_UnloadObject(sdl_shader);
return NULL;
} // if

SHD_Init(device); /* initialize SDL_shader with our GpuDevice */
} // else

resultCtx = (MOJOSHADER_sdlContext*) m(sizeof(MOJOSHADER_sdlContext), malloc_d);
Expand All @@ -523,11 +534,10 @@ MOJOSHADER_sdlContext *MOJOSHADER_sdlCreateContext(

SDL_memset(resultCtx, '\0', sizeof(MOJOSHADER_sdlContext));
resultCtx->device = device;
resultCtx->backend = backend;
resultCtx->profile = "spirv"; /* always use spirv and interop with SDL3_shader */

resultCtx->sdl_shader_dll = sdl_shader;
resultCtx->SHD_TranslateFromSPIRV = SHD_TranslateFromSPIRV;
resultCtx->SHD_CreateShaderModuleFromSPIRV = SHD_CreateShaderModuleFromSPIRV;

resultCtx->malloc_fn = m;
resultCtx->free_fn = f;
Expand All @@ -550,11 +560,18 @@ const char *MOJOSHADER_sdlGetError(
void MOJOSHADER_sdlDestroyContext(
MOJOSHADER_sdlContext *ctx
) {
SHD_Quit_func SHD_Quit;

if (ctx->linker_cache)
hash_destroy(ctx->linker_cache, ctx);

if (ctx->sdl_shader_dll)
if (ctx->sdl_shader_dll) {
SHD_Quit = (SHD_Quit_func) SDL_LoadFunction(ctx->sdl_shader_dll, "SHD_Quit");
if (SHD_Quit != NULL) {
SHD_Quit();
}
SDL_UnloadObject(ctx->sdl_shader_dll);
}

ctx->free_fn(ctx, ctx->malloc_data);
} // MOJOSHADER_sdlDestroyContext
Expand Down Expand Up @@ -618,10 +635,6 @@ MOJOSHADER_sdlProgram *MOJOSHADER_sdlLinkProgram(
const char *p_shader_source;
uint32_t v_shader_len;
uint32_t p_shader_len;
const void *v_transpiled_source;
const void *p_transpiled_source;
size_t v_transpiled_len;
size_t p_transpiled_len;
SDL_GpuShaderModuleCreateInfo createInfo;

if ((vshader == NULL) || (pshader == NULL)) /* Both shaders MUST exist! */
Expand All @@ -641,85 +654,58 @@ MOJOSHADER_sdlProgram *MOJOSHADER_sdlLinkProgram(
v_shader_len = vshader->parseData->output_len - sizeof(SpirvPatchTable);
p_shader_len = pshader->parseData->output_len - sizeof(SpirvPatchTable);

if (ctx->SHD_TranslateFromSPIRV == NULL)
if (ctx->SHD_CreateShaderModuleFromSPIRV == NULL)
{
// No translation needed, just reassign
v_transpiled_source = v_shader_source;
v_transpiled_len = v_shader_len;
createInfo.code = v_shader_source;
createInfo.codeSize = v_shader_len;
createInfo.format = SDL_GPU_SHADERFORMAT_SPIRV;
createInfo.stage = SDL_GPU_SHADERSTAGE_VERTEX;
result->vertexModule = SDL_GpuCreateShaderModule(
ctx->device,
&createInfo
);
} // if
else
{
v_transpiled_source = ctx->SHD_TranslateFromSPIRV(
ctx->backend,
SDL_GPU_SHADERTYPE_VERTEX,
result->vertexModule = ctx->SHD_CreateShaderModuleFromSPIRV(
SDL_GPU_SHADERSTAGE_VERTEX,
v_shader_source,
v_shader_len,
&v_transpiled_len
v_shader_len
);
} // else

if (v_transpiled_source == NULL)
if (result->vertexModule == NULL)
{
set_error(SDL_GetError()); // Technically should be SHD_GetError, but eh
ctx->free_fn(result, ctx->malloc_data);
return NULL;
} // if

if (ctx->SHD_TranslateFromSPIRV == NULL)
if (ctx->SHD_CreateShaderModuleFromSPIRV == NULL)
{
// No translation needed, just reassign
p_transpiled_source = p_shader_source;
p_transpiled_len = p_shader_len;
createInfo.code = p_shader_source;
createInfo.codeSize = p_shader_len;
createInfo.format = SDL_GPU_SHADERFORMAT_SPIRV;
createInfo.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
result->pixelModule = SDL_GpuCreateShaderModule(
ctx->device,
&createInfo
);
} // if
else
{
p_transpiled_source = ctx->SHD_TranslateFromSPIRV(
ctx->backend,
SDL_GPU_SHADERTYPE_FRAGMENT,
result->pixelModule = ctx->SHD_CreateShaderModuleFromSPIRV(
SDL_GPU_SHADERSTAGE_FRAGMENT,
p_shader_source,
p_shader_len,
&p_transpiled_len
p_shader_len
);
} // else

if (p_transpiled_source == NULL)
{
set_error(SDL_GetError()); // Technically should be SHD_GetError, but eh
ctx->free_fn((char*) v_transpiled_source, ctx->malloc_data);
return NULL;
} // if

createInfo.code = (uint8_t*) v_transpiled_source;
createInfo.codeSize = v_transpiled_len;
createInfo.type = SDL_GPU_SHADERTYPE_VERTEX;

result->vertexModule = SDL_GpuCreateShaderModule(
ctx->device,
&createInfo
);

if (v_transpiled_source != v_shader_source)
ctx->free_fn((char*) v_transpiled_source, ctx->malloc_data);

if (result->vertexModule == NULL)
{
ctx->free_fn(result, ctx->malloc_data);
return NULL;
} // if

createInfo.code = (uint8_t*) p_transpiled_source;
createInfo.codeSize = p_transpiled_len;
createInfo.type = SDL_GPU_SHADERTYPE_FRAGMENT;

result->pixelModule = SDL_GpuCreateShaderModule(
ctx->device,
&createInfo
);

if (p_transpiled_source != p_shader_source)
ctx->free_fn((char*) p_transpiled_source, ctx->malloc_data);

if (result->pixelModule == NULL)
{
set_error(SDL_GetError()); // Technically should be SHD_GetError, but eh
SDL_GpuQueueDestroyShaderModule(ctx->device, result->vertexModule);
ctx->free_fn(result, ctx->malloc_data);
return NULL;
Expand Down

0 comments on commit 5b33109

Please sign in to comment.