Skip to content

Commit

Permalink
Update to SDL_gpu_shadercross.h
Browse files Browse the repository at this point in the history
  • Loading branch information
flibitijibibo committed Aug 8, 2024
1 parent dd66d07 commit 3a7b7cd
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 18 deletions.
4 changes: 2 additions & 2 deletions mojoshader_sdlgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

#include <SDL3/SDL.h>

#define SDL_GPU_SPIRVCROSS_IMPLEMENTATION
#include "spirv/SDL_gpu_spirvcross.h"
#define SDL_GPU_SHADERCROSS_IMPLEMENTATION
#include "spirv/SDL_gpu_shadercross.h"

/* Max entries for each register file type */
#define MAX_REG_FILE_F 8192
Expand Down
229 changes: 213 additions & 16 deletions spirv/SDL_gpu_spirvcross.h → spirv/SDL_gpu_shadercross.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,193 @@
#ifndef SDL_GPU_SPIRVCROSS_H
#define SDL_GPU_SPIRVCROSS_H
#ifndef SDL_GPU_SHADERCROSS_H
#define SDL_GPU_SHADERCROSS_H

#include <SDL3/SDL.h>

#ifndef SDL_GPU_SHADERCROSS_SPIRVCROSS
#define SDL_GPU_SHADERCROSS_SPIRVCROSS 1
#endif

#ifndef SDL_GPU_SHADERCROSS_HLSL
#define SDL_GPU_SHADERCROSS_HLSL 1
#endif

#if SDL_GPU_SHADERCROSS_SPIRVCROSS
extern void *SDL_CompileFromSPIRV(SDL_GpuDevice *device,
void *createInfo,
SDL_bool isCompute);
#endif

#if SDL_GPU_SHADERCROSS_HLSL
extern void *SDL_CompileFromHLSL(SDL_GpuDevice *device,
void *createInfo,
const char *hlslSource,
const char *shaderProfile);
#endif

#endif /* SDL_GPU_SHADERCROSS_H */

#ifdef SDL_GPU_SHADERCROSS_IMPLEMENTATION

#if SDL_GPU_SHADERCROSS_HLSL

/* Win32 Type Definitions */
typedef int HRESULT;
typedef const void *LPCVOID;
typedef size_t SIZE_T;
typedef const char *LPCSTR;
typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef void *LPVOID;
typedef void *REFIID; /* hack, unused */
typedef void D3D_SHADER_MACRO; /* hack, unused */
typedef void ID3DInclude; /* hack, unused */

/* Dynamic Library / Linking */
#ifdef D3DCOMPILER_DLL
#undef D3DCOMPILER_DLL
#endif
#if defined(_WIN32)
#define D3DCOMPILER_DLL "d3dcompiler_47.dll"
#elif defined(__APPLE__)
#define D3DCOMPILER_DLL "libvkd3d-utils.1.dylib"
#else
#define D3DCOMPILER_DLL "libvkd3d-utils.so.1"
#endif

/* __stdcall declaration, largely taken from vkd3d_windows.h */
#ifndef _WIN32
#ifdef __stdcall
#undef __stdcall
#endif
#ifdef __x86_64__
#define __stdcall __attribute__((ms_abi))
#else
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || defined(__APPLE__)
#define __stdcall __attribute__((__stdcall__)) __attribute__((__force_align_arg_pointer__))
#else
#define __stdcall __attribute__((__stdcall__))
#endif
#endif
#endif

/* ID3DBlob definition, used by both D3DCompiler and DXCompiler */
typedef struct ID3DBlob ID3DBlob;
typedef struct ID3DBlobVtbl
{
HRESULT(__stdcall *QueryInterface)
(ID3DBlob *This, REFIID riid, void **ppvObject);
ULONG(__stdcall *AddRef)
(ID3DBlob *This);
ULONG(__stdcall *Release)
(ID3DBlob *This);
LPVOID(__stdcall *GetBufferPointer)
(ID3DBlob *This);
SIZE_T(__stdcall *GetBufferSize)
(ID3DBlob *This);
} ID3DBlobVtbl;
struct ID3DBlob
{
const ID3DBlobVtbl *lpVtbl;
};
#define ID3D10Blob ID3DBlob

/* D3DCompiler */
static void *d3dcompiler_dll = NULL;

typedef HRESULT(__stdcall *pfn_D3DCompile)(
LPCVOID pSrcData,
SIZE_T SrcDataSize,
LPCSTR pSourceName,
const D3D_SHADER_MACRO *pDefines,
ID3DInclude *pInclude,
LPCSTR pEntrypoint,
LPCSTR pTarget,
UINT Flags1,
UINT Flags2,
ID3DBlob **ppCode,
ID3DBlob **ppErrorMsgs);

static pfn_D3DCompile SDL_D3DCompile = NULL;

void *SDL_CompileFromHLSL(
SDL_GpuDevice *device,
void *createInfo,
const char *hlslSource,
const char *shaderProfile)
{
ID3DBlob *blob;
ID3DBlob *errorBlob;
HRESULT ret;
void *result;

#endif /* SDL_GPU_SPIRVCROSS_H */
/* FIXME: d3dcompiler could probably be loaded in a better spot */
if (d3dcompiler_dll == NULL) {
d3dcompiler_dll = SDL_LoadObject(D3DCOMPILER_DLL);
if (d3dcompiler_dll == NULL) {
return NULL;
}
}

#ifdef SDL_GPU_SPIRVCROSS_IMPLEMENTATION
if (SDL_D3DCompile == NULL) {
SDL_D3DCompile = (pfn_D3DCompile)SDL_LoadFunction(d3dcompiler_dll, "D3DCompile");
if (SDL_D3DCompile == NULL) {
return NULL;
}
}

ret = SDL_D3DCompile(
hlslSource,
SDL_strlen(hlslSource),
NULL,
NULL,
NULL,
((SDL_GpuShaderCreateInfo *)createInfo)->entryPointName,
shaderProfile,
0,
0,
&blob,
&errorBlob);

#include "spirv_cross_c.h"
if (ret < 0) {
SDL_LogError(
SDL_LOG_CATEGORY_GPU,
"HLSL compilation failed: %s",
errorBlob->lpVtbl->GetBufferPointer(errorBlob));
return NULL;
}

if (shaderProfile[0] == 'c' && shaderProfile[1] == 's') {
SDL_GpuComputePipelineCreateInfo newCreateInfo;
newCreateInfo = *(SDL_GpuComputePipelineCreateInfo *)createInfo;
newCreateInfo.code = blob->lpVtbl->GetBufferPointer(blob);
newCreateInfo.codeSize = blob->lpVtbl->GetBufferSize(blob);
newCreateInfo.format = SDL_GPU_SHADERFORMAT_DXBC;

result = SDL_GpuCreateComputePipeline(device, &newCreateInfo);
} else {
SDL_GpuShaderCreateInfo newCreateInfo;
newCreateInfo = *(SDL_GpuShaderCreateInfo *)createInfo;
newCreateInfo.code = blob->lpVtbl->GetBufferPointer(blob);
newCreateInfo.codeSize = blob->lpVtbl->GetBufferSize(blob);
newCreateInfo.format = SDL_GPU_SHADERFORMAT_DXBC;

result = SDL_GpuCreateShader(device, &newCreateInfo);
}

blob->lpVtbl->Release(blob);

return result;
}

#endif

#if SDL_GPU_SHADERCROSS_SPIRVCROSS

#if !SDL_GPU_SHADERCROSS_HLSL
#error SDL_GPU_SHADERCROSS_HLSL must be enabled for SDL_GPU_SHADERCROSS_SPIRVCROSS!
#endif

#include <spirv_cross_c.h>

#if defined(_WIN32)
#define SPIRV_CROSS_DLL "spirv-cross-c-shared.dll"
Expand Down Expand Up @@ -78,7 +254,7 @@ void *SDL_CompileFromSPIRV(
case SDL_GPU_BACKEND_D3D11:
case SDL_GPU_BACKEND_D3D12:
backend = SPVC_BACKEND_HLSL;
format = SDL_GPU_SHADERFORMAT_HLSL;
format = SDL_GPU_SHADERFORMAT_DXBC;
break;
case SDL_GPU_BACKEND_METAL:
backend = SPVC_BACKEND_MSL;
Expand Down Expand Up @@ -184,23 +360,42 @@ void *SDL_CompileFromSPIRV(
SDL_GpuComputePipelineCreateInfo newCreateInfo;
newCreateInfo = *(SDL_GpuComputePipelineCreateInfo *)createInfo;
newCreateInfo.format = format;
newCreateInfo.code = (const Uint8 *)translated_source;
newCreateInfo.codeSize = SDL_strlen(translated_source) + 1;
newCreateInfo.entryPointName = cleansed_entrypoint;

/* Create the pipeline! */
compiledResult = SDL_GpuCreateComputePipeline(device, &newCreateInfo);
if (backend == SPVC_BACKEND_HLSL) {
compiledResult = SDL_CompileFromHLSL(
device,
&newCreateInfo,
translated_source,
(shadermodel == 50) ? "cs_5_0" : "cs_5_1");
} else {
newCreateInfo.code = (const Uint8 *)translated_source;
newCreateInfo.codeSize = SDL_strlen(translated_source) + 1;
compiledResult = SDL_GpuCreateComputePipeline(device, &newCreateInfo);
}
} else {

SDL_GpuShaderCreateInfo newCreateInfo;
newCreateInfo = *createInfo;
newCreateInfo.format = format;
newCreateInfo.code = (const Uint8 *)translated_source;
newCreateInfo.codeSize = SDL_strlen(translated_source) + 1;
newCreateInfo.entryPointName = cleansed_entrypoint;

/* Create the shader! */
compiledResult = SDL_GpuCreateShader(device, &newCreateInfo);
if (backend == SPVC_BACKEND_HLSL) {
const char *profile;
if (newCreateInfo.stage == SDL_GPU_SHADERSTAGE_VERTEX) {
profile = (shadermodel == 50) ? "vs_5_0" : "vs_5_1";
} else {
profile = (shadermodel == 50) ? "ps_5_0" : "ps_5_1";
}
compiledResult = SDL_CompileFromHLSL(
device,
&newCreateInfo,
translated_source,
profile);
} else {
newCreateInfo.code = (const Uint8 *)translated_source;
newCreateInfo.codeSize = SDL_strlen(translated_source) + 1;
compiledResult = SDL_GpuCreateShader(device, &newCreateInfo);
}
}

/* Clean up */
Expand All @@ -209,4 +404,6 @@ void *SDL_CompileFromSPIRV(
return compiledResult;
}

#endif /* SDL_GPU_SPIRVCROSS_IMPLEMENTATION */
#endif

#endif /* SDL_GPU_SHADERCROSS_IMPLEMENTATION */

0 comments on commit 3a7b7cd

Please sign in to comment.