From 2e2d5d565300f09f025dfda711ff523a1e49a0f7 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 7 Oct 2024 15:47:14 -0400 Subject: [PATCH] sdlgpu: Fill in blob compiler, still needs hash calculator --- mojoshader_sdlgpu.c | 120 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 3 deletions(-) diff --git a/mojoshader_sdlgpu.c b/mojoshader_sdlgpu.c index 4189347..d976ca3 100644 --- a/mojoshader_sdlgpu.c +++ b/mojoshader_sdlgpu.c @@ -65,6 +65,7 @@ struct MOJOSHADER_sdlContext struct { + SDL_GPUShaderFormat format; uint32_t numShaders; ShaderEntry *hashes; ShaderBlob *shaders; @@ -344,6 +345,7 @@ MOJOSHADER_sdlContext *MOJOSHADER_sdlCreateContext( { /* Just validate the bytecode, calculate a hash to find in blobCache */ resultCtx->profile = "bytecode"; + resultCtx->blob.format = SDL_GetGPUShaderFormats(device); } else { @@ -462,6 +464,119 @@ MOJOSHADER_sdlShaderData *MOJOSHADER_sdlCompileShader( return NULL; } // MOJOSHADER_sdlCompileShader +static inline uint64_t hash_vertex_shader( + MOJOSHADER_sdlContext *ctx, + MOJOSHADER_sdlShaderData *vshader, + MOJOSHADER_sdlVertexAttribute *vertexAttributes, + int vertexAttributeCount) +{ + // TODO: Combine d3dbc hash with vertex attribute hash +} + +static inline uint64_t hash_pixel_shader( + MOJOSHADER_sdlContext *ctx, + MOJOSHADER_sdlShaderData *pshader) +{ + // TODO: Calculate hash of pshader d3dbc +} + +static inline ShaderBlob *fetch_blob_shader( + MOJOSHADER_sdlContext *ctx, + uint64_t hash, + uint32_t *size) +{ + int32_t probes, searchIndex; + for (probes = 0; probes < ctx->blob.numShaders; probes += 1) + { + searchIndex = (hash + probes) % ctx->blob.numShaders; + if (ctx->blob.hashes[searchIndex].hash == hash) + { + *size = ctx->blob.hashes[searchIndex].size; + return &ctx->blob.shaders[searchIndex]; + } + } + set_error("MojoShaderPrecompiled.bin is incomplete!!!"); + return NULL; +} // fetch_blob_shader + +static MOJOSHADER_sdlProgram *compile_blob_program( + MOJOSHADER_sdlContext *ctx, + MOJOSHADER_sdlShaderData *vshader, + MOJOSHADER_sdlShaderData *pshader, + MOJOSHADER_sdlVertexAttribute *vertexAttributes, + int vertexAttributeCount) +{ + uint64_t hash; + ShaderBlob *vblob, *pblob; + uint32_t vlen, plen; + SDL_GPUShaderCreateInfo createInfo; + MOJOSHADER_sdlProgram *program = (MOJOSHADER_sdlProgram*) ctx->malloc_fn(sizeof(MOJOSHADER_sdlProgram), + ctx->malloc_data); + if (program == NULL) + { + out_of_memory(); + return NULL; + } // if + + // TODO: Maybe add the format to the blob header? + SDL_assert(ctx->blob.format & SDL_GPU_SHADERFORMAT_PRIVATE); + + hash = hash_vertex_shader(ctx, vshader, vertexAttributes, vertexAttributeCount); + vblob = fetch_blob_shader(ctx, hash, &vlen); + + hash = hash_pixel_shader(ctx, pshader); + pblob = fetch_blob_shader(ctx, hash, &plen); + + if ((vblob == NULL) || (pblob == NULL)) + { + ctx->free_fn(program, ctx->malloc_data); + return NULL; + } // if + + SDL_zero(createInfo); + createInfo.code = (const Uint8*) vblob->binary; + createInfo.code_size = vlen; + createInfo.entrypoint = vshader->parseData->mainfn; + createInfo.format = SDL_GPU_SHADERFORMAT_PRIVATE; + createInfo.stage = SDL_GPU_SHADERSTAGE_VERTEX; + createInfo.num_samplers = vshader->samplerSlots; + createInfo.num_uniform_buffers = 1; + + program->vertexShader = SDL_CreateGPUShader( + ctx->device, + &createInfo + ); + + if (program->vertexShader == NULL) + { + set_error(SDL_GetError()); + ctx->free_fn(program, ctx->malloc_data); + return NULL; + } // if + + createInfo.code = (const Uint8*) pblob->binary; + createInfo.code_size = plen; + createInfo.entrypoint = pshader->parseData->mainfn; + createInfo.format = ctx->blob.format; + createInfo.stage = SDL_GPU_SHADERSTAGE_FRAGMENT; + createInfo.num_samplers = pshader->samplerSlots; + + program->pixelShader = SDL_CreateGPUShader( + ctx->device, + &createInfo + ); + + if (program->pixelShader == NULL) + { + set_error(SDL_GetError()); + SDL_ReleaseGPUShader(ctx->device, program->vertexShader); + ctx->free_fn(program, ctx->malloc_data); + return NULL; + } // if + + return program; +} // compile_blob_program + static MOJOSHADER_sdlProgram *compile_spirv_program( MOJOSHADER_sdlContext *ctx, MOJOSHADER_sdlShaderData *vshader, @@ -608,9 +723,8 @@ MOJOSHADER_sdlProgram *MOJOSHADER_sdlLinkProgram( if (ctx->blob.numShaders > 0) { - // TODO: Combine bytecode hash with vertex attribute hash, search the - // result in ctx->blob. If found, send to CompileShader directly, - // otherwise do a really loud error saying the blob cache is incomplete + program = compile_blob_program(ctx, vshader, pshader, + vertexAttributes, vertexAttributeCount); } // if else {