SDL_gpu_shadercross: Optional DXC usage (#56)

From 2ba79085e39371898ac871ba193cef412e4e09a5 Mon Sep 17 00:00:00 2001
From: Evan Hemsley <[EMAIL REDACTED]>
Date: Wed, 13 Nov 2024 10:58:03 -0800
Subject: [PATCH] Optional DXC usage (#56)

---
 CMakeLists.txt                                |   5 +
 .../SDL_gpu_shadercross.h                     |  34 +---
 src/SDL_gpu_shadercross.c                     | 191 ++++++++++--------
 src/cli.c                                     |  41 +---
 4 files changed, 117 insertions(+), 154 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7ae54ee..0b53c77 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,6 +33,7 @@ else()
 endif()
 
 # Options
+option(SDLGPUSHADERCROSS_DXC "Enable HLSL compilation via DXC" ON)
 option(SDLGPUSHADERCROSS_SHARED "Build shared SDL_gpu_shadercross library" ${SDLGPUSHADERCROSS_SHARED_DEFAULT})
 option(SDLGPUSHADERCROSS_STATIC "Build static SDL_gpu_shadercross library" ${SDLGPUSHADERCROSS_STATIC_DEFAULT})
 option(SDLGPUSHADERCROSS_SPIRVCROSS_SHARED "Link to shared library variants of dependencies" ON)
@@ -209,6 +210,10 @@ foreach(target IN LISTS SDL3_gpu_shadercross_targets)
 	sdl_add_warning_options(${target} WARNING_AS_ERROR ${SDLGPUSHADERCROSS_WERROR})
 	target_compile_features(${target} PRIVATE c_std_99)
 
+	if(SDLGPUSHADERCROSS_DXC)
+		add_compile_definitions(SDL_GPU_SHADERCROSS_DXC)
+	endif()
+
 	if(SDLGPUSHADERCROSS_SPIRVCROSS_SHARED)
 		target_link_libraries(${target} PRIVATE spirv-cross-c-shared)
 	else()
diff --git a/include/SDL3_gpu_shadercross/SDL_gpu_shadercross.h b/include/SDL3_gpu_shadercross/SDL_gpu_shadercross.h
index f19dfaf..3845275 100644
--- a/include/SDL3_gpu_shadercross/SDL_gpu_shadercross.h
+++ b/include/SDL3_gpu_shadercross/SDL_gpu_shadercross.h
@@ -38,14 +38,6 @@ extern "C" {
 #define SDL_GPU_SHADERCROSS_MINOR_VERSION 0
 #define SDL_GPU_SHADERCROSS_MICRO_VERSION 0
 
-#ifndef SDL_GPU_SHADERCROSS_SPIRVCROSS
-#define SDL_GPU_SHADERCROSS_SPIRVCROSS 1
-#endif /* SDL_GPU_SHADERCROSS_SPIRVCROSS */
-
-#ifndef SDL_GPU_SHADERCROSS_HLSL
-#define SDL_GPU_SHADERCROSS_HLSL 1
-#endif /* SDL_GPU_SHADERCROSS_HLSL */
-
 typedef enum SDL_ShaderCross_ShaderStage
 {
    SDL_SHADERCROSS_SHADERSTAGE_VERTEX,
@@ -53,13 +45,6 @@ typedef enum SDL_ShaderCross_ShaderStage
    SDL_SHADERCROSS_SHADERSTAGE_COMPUTE
 } SDL_ShaderCross_ShaderStage;
 
-typedef enum SDL_ShaderCross_ShaderModel
-{
-    SDL_SHADERCROSS_SHADERMODEL_INVALID,
-    SDL_SHADERCROSS_SHADERMODEL_5_0,
-    SDL_SHADERCROSS_SHADERMODEL_6_0
-} SDL_ShaderCross_ShaderModel;
-
 typedef struct SDL_ShaderCross_ShaderResourceInfo {
     Uint32 num_samplers;         /**< The number of samplers defined in the shader. */
     Uint32 num_storage_textures; /**< The number of storage textures defined in the shader. */
@@ -92,7 +77,6 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ShaderCross_Init(void);
  */
 extern SDL_DECLSPEC void SDLCALL SDL_ShaderCross_Quit(void);
 
-#if SDL_GPU_SHADERCROSS_SPIRVCROSS
 /**
  * Get the supported shader formats that SPIRV cross-compilation can output
  *
@@ -133,8 +117,7 @@ extern SDL_DECLSPEC void * SDLCALL SDL_ShaderCross_TranspileHLSLFromSPIRV(
     const Uint8 *bytecode,
     size_t bytecodeSize,
     const char *entrypoint,
-    SDL_ShaderCross_ShaderStage shaderStage,
-    SDL_ShaderCross_ShaderModel shaderModel);
+    SDL_ShaderCross_ShaderStage shaderStage);
 
 /**
  * Compile DXBC bytecode from SPIRV code.
@@ -212,9 +195,6 @@ extern SDL_DECLSPEC SDL_GPUComputePipeline * SDLCALL SDL_ShaderCross_CompileComp
     const char *entrypoint,
     const SDL_ShaderCross_ComputeResourceInfo *resourceInfo);
 
-#endif /* SDL_GPU_SHADERCROSS_SPIRVCROSS */
-
-#if SDL_GPU_SHADERCROSS_HLSL
 /**
  * Get the supported shader formats that HLSL cross-compilation can output
  *
@@ -223,7 +203,7 @@ extern SDL_DECLSPEC SDL_GPUComputePipeline * SDLCALL SDL_ShaderCross_CompileComp
 extern SDL_DECLSPEC SDL_GPUShaderFormat SDLCALL SDL_ShaderCross_GetHLSLShaderFormats(void);
 
 /**
- * Compile to DXBC bytecode from HLSL Shader Model 6.0 code via a SPIRV-Cross round trip.
+ * Compile to DXBC bytecode from HLSL code via a SPIRV-Cross round trip.
  *
  * You must SDL_free the returned buffer once you are done with it.
  *
@@ -244,7 +224,7 @@ extern SDL_DECLSPEC void * SDLCALL SDL_ShaderCross_CompileDXBCFromHLSL(
     size_t *size);
 
 /**
- * Compile to DXIL bytecode from HLSL Shader Model 6.0 code via a SPIRV-Cross round trip.
+ * Compile to DXIL bytecode from HLSL code via a SPIRV-Cross round trip.
  *
  * You must SDL_free the returned buffer once you are done with it.
  *
@@ -265,7 +245,7 @@ extern SDL_DECLSPEC void * SDLCALL SDL_ShaderCross_CompileDXILFromHLSL(
     size_t *size);
 
 /**
- * Compile to SPIRV bytecode from HLSL Shader Model 6.0 code.
+ * Compile to SPIRV bytecode from HLSL code.
  *
  * You must SDL_free the returned buffer once you are done with it.
  *
@@ -286,7 +266,7 @@ extern SDL_DECLSPEC void * SDLCALL SDL_ShaderCross_CompileSPIRVFromHLSL(
     size_t *size);
 
 /**
- * Compile an SDL GPU shader from HLSL Shader Model 6.0 code.
+ * Compile an SDL GPU shader from HLSL code.
  *
  * \param device the SDL GPU device.
  * \param hlslSource the HLSL source code for the shader.
@@ -307,7 +287,7 @@ extern SDL_DECLSPEC SDL_GPUShader * SDLCALL SDL_ShaderCross_CompileGraphicsShade
     const SDL_ShaderCross_ShaderResourceInfo *resourceInfo);
 
 /**
- * Compile an SDL GPU compute pipeline from HLSL Shader Model 6.0 code.
+ * Compile an SDL GPU compute pipeline from code.
  *
  * \param device the SDL GPU device.
  * \param hlslSource the HLSL source code for the shader.
@@ -325,8 +305,6 @@ extern SDL_DECLSPEC SDL_GPUComputePipeline * SDLCALL SDL_ShaderCross_CompileComp
     const char *includeDir,
     const SDL_ShaderCross_ComputeResourceInfo *resourceInfo);
 
-#endif /* SDL_GPU_SHADERCROSS_HLSL */
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/SDL_gpu_shadercross.c b/src/SDL_gpu_shadercross.c
index 43d6ec7..4ac52d9 100644
--- a/src/SDL_gpu_shadercross.c
+++ b/src/SDL_gpu_shadercross.c
@@ -23,8 +23,6 @@
 #include <SDL3/SDL_loadso.h>
 #include <SDL3/SDL_log.h>
 
-#if SDL_GPU_SHADERCROSS_HLSL
-
 /* Win32 Type Definitions */
 
 typedef int HRESULT;
@@ -37,6 +35,7 @@ typedef void *LPVOID;
 typedef void *REFIID;
 
 /* DXIL via DXC */
+#ifdef SDL_GPU_SHADERCROSS_DXC
 
 /* dxcompiler Type Definitions */
 typedef int BOOL;
@@ -327,6 +326,8 @@ typedef HRESULT(__stdcall *DxcCreateInstanceProc)(
 HRESULT DxcCreateInstance(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
 #endif
 
+#endif /* SDL_GPU_SHADERCROSS_DXC */
+
 static void *SDL_ShaderCross_INTERNAL_CompileUsingDXC(
     const char *hlslSource,
     const char *entrypoint,
@@ -335,6 +336,7 @@ static void *SDL_ShaderCross_INTERNAL_CompileUsingDXC(
     bool spirv,
     size_t *size) // filled in with number of bytes of returned buffer
 {
+#ifdef SDL_GPU_SHADERCROSS_DXC
     DxcBuffer source;
     IDxcResult *dxcResult;
     IDxcBlob *blob;
@@ -521,6 +523,10 @@ static void *SDL_ShaderCross_INTERNAL_CompileUsingDXC(
     utils->lpVtbl->Release(utils);
 
     return buffer;
+#else
+    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", "Shadercross was not built with DXC support, cannot compile using DXC!");
+    return NULL;
+#endif /* SDL_GPU_SHADERCROSS_DXC */
 }
 
 void *SDL_ShaderCross_CompileDXILFromHLSL(
@@ -547,8 +553,7 @@ void *SDL_ShaderCross_CompileDXILFromHLSL(
         spirv,
         spirvSize,
         entrypoint,
-        shaderStage,
-        SDL_SHADERCROSS_SHADERMODEL_6_0);
+        shaderStage);
 
     SDL_free(spirv);
     if (translatedSource == NULL) {
@@ -767,51 +772,53 @@ static ID3DBlob *SDL_ShaderCross_INTERNAL_CompileDXBC(
     return blob;
 }
 
-// Returns raw byte buffer
-void *SDL_ShaderCross_CompileDXBCFromHLSL(
+void *SDL_ShaderCross_INTERNAL_CompileDXBCFromHLSL(
     const char *hlslSource,
     const char *entrypoint,
     const char *includeDir,
     SDL_ShaderCross_ShaderStage shaderStage,
+    bool enableRoundtrip,
     size_t *size) // filled in with number of bytes of returned buffer
 {
-    // Need to roundtrip to SM 5.0
-    size_t spirv_size;
-    void *spirv = SDL_ShaderCross_CompileSPIRVFromHLSL(
-        hlslSource,
-        entrypoint,
-        includeDir,
-        shaderStage,
-        &spirv_size);
+    char *transpiledSource = NULL;
 
-    if (spirv == NULL) {
-        return NULL;
-    }
+    if (enableRoundtrip) {
+        // Need to roundtrip to SM 5.1
+        size_t spirv_size;
+        void *spirv = SDL_ShaderCross_CompileSPIRVFromHLSL(
+            hlslSource,
+            entrypoint,
+            includeDir,
+            shaderStage,
+            &spirv_size);
 
-    void *transpiledSource = SDL_ShaderCross_TranspileHLSLFromSPIRV(
-        spirv,
-        spirv_size,
-        entrypoint,
-        shaderStage,
-        SDL_SHADERCROSS_SHADERMODEL_5_0
-    );
-    SDL_free(spirv);
+        if (spirv == NULL) {
+            return NULL;
+        }
 
-    if (transpiledSource == NULL) {
-        return NULL;
+        transpiledSource = SDL_ShaderCross_TranspileHLSLFromSPIRV(
+            spirv,
+            spirv_size,
+            entrypoint,
+            shaderStage);
+        SDL_free(spirv);
+
+        if (transpiledSource == NULL) {
+            return NULL;
+        }
     }
 
     const char *shaderProfile;
     if (shaderStage == SDL_SHADERCROSS_SHADERSTAGE_VERTEX) {
-        shaderProfile = "vs_5_0";
+        shaderProfile = "vs_5_1";
     } else if (shaderStage == SDL_SHADERCROSS_SHADERSTAGE_FRAGMENT) {
-        shaderProfile = "ps_5_0";
+        shaderProfile = "ps_5_1";
     } else { // compute
-        shaderProfile = "cs_5_0";
+        shaderProfile = "cs_5_1";
     }
 
     ID3DBlob *blob = SDL_ShaderCross_INTERNAL_CompileDXBC(
-        transpiledSource,
+        transpiledSource != NULL ? transpiledSource : hlslSource,
         entrypoint,
         shaderProfile);
 
@@ -825,11 +832,30 @@ void *SDL_ShaderCross_CompileDXBCFromHLSL(
     SDL_memcpy(buffer, blob->lpVtbl->GetBufferPointer(blob), *size);
     blob->lpVtbl->Release(blob);
 
-    SDL_free(transpiledSource);
+    if (transpiledSource != NULL) {
+        SDL_free(transpiledSource);
+    }
 
     return buffer;
 }
 
+// Returns raw byte buffer
+void *SDL_ShaderCross_CompileDXBCFromHLSL(
+    const char *hlslSource,
+    const char *entrypoint,
+    const char *includeDir,
+    SDL_ShaderCross_ShaderStage shaderStage,
+    size_t *size) // filled in with number of bytes of returned buffer
+{
+    return SDL_ShaderCross_INTERNAL_CompileDXBCFromHLSL(
+        hlslSource,
+        entrypoint,
+        includeDir,
+        shaderStage,
+        true,
+        size);
+}
+
 static void *SDL_ShaderCross_INTERNAL_CreateShaderFromDXBC(
     SDL_GPUDevice *device,
     const char *hlslSource,
@@ -841,11 +867,12 @@ static void *SDL_ShaderCross_INTERNAL_CreateShaderFromDXBC(
     void *result;
     size_t bytecodeSize;
 
-    void *bytecode = SDL_ShaderCross_CompileDXBCFromHLSL(
+    void *bytecode = SDL_ShaderCross_INTERNAL_CompileDXBCFromHLSL(
         hlslSource,
         entrypoint,
         includeDir,
         shaderStage,
+        true,
         &bytecodeSize);
 
     if (bytecode == NULL) {
@@ -901,25 +928,28 @@ static void *SDL_ShaderCross_INTERNAL_CreateShaderFromHLSL(
     const void *resourceInfo)
 {
     SDL_GPUShaderFormat format = SDL_GetGPUShaderFormats(device);
-    if (format & SDL_GPU_SHADERFORMAT_DXBC) {
-        return SDL_ShaderCross_INTERNAL_CreateShaderFromDXBC(
+
+    if (format & SDL_GPU_SHADERFORMAT_DXIL) {
+        return SDL_ShaderCross_INTERNAL_CreateShaderFromDXC(
             device,
             hlslSource,
             entrypoint,
             includeDir,
             shaderStage,
-            resourceInfo);
+            resourceInfo,
+            false);
     }
-    if (format & SDL_GPU_SHADERFORMAT_DXIL) {
-        return SDL_ShaderCross_INTERNAL_CreateShaderFromDXC(
+
+    if (format & SDL_GPU_SHADERFORMAT_DXBC) {
+        return SDL_ShaderCross_INTERNAL_CreateShaderFromDXBC(
             device,
             hlslSource,
             entrypoint,
             includeDir,
             shaderStage,
-            resourceInfo,
-            false);
+            resourceInfo);
     }
+
     if (format & SDL_GPU_SHADERFORMAT_SPIRV) {
         return SDL_ShaderCross_INTERNAL_CreateShaderFromDXC(
             device,
@@ -930,6 +960,7 @@ static void *SDL_ShaderCross_INTERNAL_CreateShaderFromHLSL(
             resourceInfo,
             true);
     }
+
     if (format & SDL_GPU_SHADERFORMAT_MSL) {
         size_t bytecodeSize;
         void *spirv = SDL_ShaderCross_CompileSPIRVFromHLSL(
@@ -1000,14 +1031,6 @@ SDL_GPUComputePipeline *SDL_ShaderCross_CompileComputePipelineFromHLSL(
         (const void *)resourceInfo);
 }
 
-#endif /* SDL_GPU_SHADERCROSS_HLSL */
-
-#if SDL_GPU_SHADERCROSS_SPIRVCROSS
-
-#if !SDL_GPU_SHADERCROSS_HLSL
-#error SDL_GPU_SHADERCROSS_HLSL must be enabled for SDL_GPU_SHADERCROSS_SPIRVCROSS!
-#endif /* !SDL_GPU_SHADERCROSS_HLSL */
-
 #include <spirv_cross_c.h>
 
 #define SPVC_ERROR(func) \
@@ -1552,7 +1575,7 @@ static void *SDL_ShaderCross_INTERNAL_CompileFromSPIRV(
 
     if (targetFormat == SDL_GPU_SHADERFORMAT_DXBC) {
         backend = SPVC_BACKEND_HLSL;
-        shadermodel = 50;
+        shadermodel = 51;
     } else if (targetFormat == SDL_GPU_SHADERFORMAT_DXIL) {
         backend = SPVC_BACKEND_HLSL;
         shadermodel = 60;
@@ -1590,11 +1613,12 @@ static void *SDL_ShaderCross_INTERNAL_CompileFromSPIRV(
         createInfo.props = 0;
 
         if (targetFormat == SDL_GPU_SHADERFORMAT_DXBC) {
-            createInfo.code = SDL_ShaderCross_CompileDXBCFromHLSL(
+            createInfo.code = SDL_ShaderCross_INTERNAL_CompileDXBCFromHLSL(
                 transpileContext->translated_source,
                 transpileContext->cleansed_entrypoint,
                 NULL,
                 shaderStage,
+                false,
                 &createInfo.code_size);
         } else if (targetFormat == SDL_GPU_SHADERFORMAT_DXIL) {
             createInfo.code = SDL_ShaderCross_CompileDXILFromHLSL(
@@ -1622,11 +1646,12 @@ static void *SDL_ShaderCross_INTERNAL_CompileFromSPIRV(
         createInfo.props = 0;
 
         if (targetFormat == SDL_GPU_SHADERFORMAT_DXBC) {
-            createInfo.code = SDL_ShaderCross_CompileDXBCFromHLSL(
+            createInfo.code = SDL_ShaderCross_INTERNAL_CompileDXBCFromHLSL(
                 transpileContext->translated_source,
                 transpileContext->cleansed_entrypoint,
                 NULL,
                 shaderStage,
+                false,
                 &createInfo.code_size);
         } else if (targetFormat == SDL_GPU_SHADERFORMAT_DXIL) {
             createInfo.code = SDL_ShaderCross_CompileDXILFromHLSL(
@@ -1674,23 +1699,11 @@ void *SDL_ShaderCross_TranspileHLSLFromSPIRV(
     const Uint8 *bytecode,
     size_t bytecodeSize,
     const char *entrypoint,
-    SDL_ShaderCross_ShaderStage shaderStage,
-    SDL_ShaderCross_ShaderModel shaderModel)
+    SDL_ShaderCross_ShaderStage shaderStage)
 {
-    unsigned int spirv_cross_shader_model = 0;
-
-    if (shaderModel == SDL_SHADERCROSS_SHADERMODEL_5_0) {
-        spirv_cross_shader_model = 50;
-    } else if (shaderModel == SDL_SHADERCROSS_SHADERMODEL_6_0) {
-        spirv_cross_shader_model = 60;
-    } else {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", "Invalid shader profile!");
-        return NULL;
-    }
-
     SPIRVTranspileContext *context = SDL_ShaderCross_INTERNAL_TranspileFromSPIRV(
         SPVC_BACKEND_HLSL,
-        spirv_cross_shader_model,
+        60,
         shaderStage,
         bytecode,
         bytecodeSize,
@@ -1714,17 +1727,18 @@ void *SDL_ShaderCross_CompileDXBCFromSPIRV(
 {
     SPIRVTranspileContext *context = SDL_ShaderCross_INTERNAL_TranspileFromSPIRV(
         SPVC_BACKEND_HLSL,
-        50,
+        51,
         shaderStage,
         bytecode,
         bytecodeSize,
         entrypoint);
 
-    void *result = SDL_ShaderCross_CompileDXBCFromHLSL(
+    void *result = SDL_ShaderCross_INTERNAL_CompileDXBCFromHLSL(
         context->translated_source,
         context->cleansed_entrypoint,
         NULL,
         shaderStage,
+        false,
         size);
 
     SDL_ShaderCross_INTERNAL_DestroyTranspileContext(context);
@@ -1738,6 +1752,11 @@ void *SDL_ShaderCross_CompileDXILFromSPIRV(
     SDL_ShaderCross_ShaderStage shaderStage,
     size_t *size)
 {
+#ifndef SDL_GPU_SHADERCROSS_DXC
+    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", "Shadercross was not compiled with DXC support, cannot compile to SPIR-V!");
+    return NULL;
+#endif
+
     SPIRVTranspileContext *context = SDL_ShaderCross_INTERNAL_TranspileFromSPIRV(
         SPVC_BACKEND_HLSL,
         60,
@@ -1803,15 +1822,21 @@ static void *SDL_ShaderCross_INTERNAL_CreateShaderFromSPIRV(
             createInfo.props = 0;
             return SDL_CreateGPUShader(device, &createInfo);
         }
-    } else if (shader_formats & SDL_GPU_SHADERFORMAT_DXBC) {
-        format = SDL_GPU_SHADERFORMAT_DXBC;
-    } else if (shader_formats & SDL_GPU_SHADERFORMAT_DXIL) {
-        format = SDL_GPU_SHADERFORMAT_DXIL;
     } else if (shader_formats & SDL_GPU_SHADERFORMAT_MSL) {
         format = SDL_GPU_SHADERFORMAT_MSL;
     } else {
-        SDL_SetError("SDL_ShaderCross_INTERNAL_CreateShaderFromSPIRV: Unexpected SDL_GPUBackend");
-        return NULL;
+        if ((shader_formats & SDL_GPU_SHADERFORMAT_DXBC) && SDL_D3DCompile != NULL) {
+            format = SDL_GPU_SHADERFORMAT_DXBC;
+        }
+#ifdef SDL_GPU_SHADERCROSS_DXC
+        else if (shader_formats & SDL_GPU_SHADERFORMAT_DXIL) {
+            format = SDL_GPU_SHADERFORMAT_DXIL;
+        }
+#endif
+        else {
+            SDL_SetError("SDL_ShaderCross_INTERNAL_CreateShaderFromSPIRV: Unexpected SDL_GPUBackend");
+            return NULL;
+        }
     }
 
     return SDL_ShaderCross_INTERNAL_CompileFromSPIRV(
@@ -1857,8 +1882,6 @@ SDL_GPUComputePipeline *SDL_ShaderCross_CompileComputePipelineFromSPIRV(
         (const void *)resourceInfo);
 }
 
-#endif /* SDL_GPU_SHADERCROSS_SPIRVCROSS */
-
 bool SDL_ShaderCross_Init(void)
 {
     #if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
@@ -1889,7 +1912,6 @@ bool SDL_ShaderCross_Init(void)
 
 void SDL_ShaderCross_Quit(void)
 {
-#if SDL_GPU_SHADERCROSS_HLSL
     if (d3dcompiler_dll != NULL) {
         SDL_UnloadObject(d3dcompiler_dll);
         d3dcompiler_dll = NULL;
@@ -1905,17 +1927,13 @@ void SDL_ShaderCross_Quit(void)
         SDL_DxcCreateInstance = NULL;
     }
     #endif
-#endif /* SDL_GPU_SHADERCROSS_HLSL */
 }
 
-#ifdef SDL_GPU_SHADERCROSS_SPIRVCROSS
-
 SDL_GPUShaderFormat SDL_ShaderCross_GetSPIRVShaderFormats(void)
 {
     /* SPIRV and MSL can always be output as-is with no preprocessing since we require SPIRV-Cross */
     SDL_GPUShaderFormat supportedFormats = SDL_GPU_SHADERFORMAT_SPIRV | SDL_GPU_SHADERFORMAT_MSL;
 
-#if SDL_GPU_SHADERCROSS_HLSL
     /* SPIRV-Cross + DXC allows us to cross-compile to HLSL, then compile to DXIL */
     supportedFormats |= SDL_GPU_SHADERFORMAT_DXIL;
 
@@ -1923,19 +1941,18 @@ SDL_GPUShaderFormat SDL_ShaderCross_GetSPIRVShaderFormats(void)
     if (d3dcompiler_dll != NULL) {
         supportedFormats |= SDL_GPU_SHADERFORMAT_DXBC;
     }
-#endif /* SDL_GPU_SHADERCROSS_HLSL */
 
     return supportedFormats;
 }
 
-#endif /* SDL_GPU_SHADERCROSS_SPIRVCROSS */
-
-#if SDL_GPU_SHADERCROSS_HLSL
-
 SDL_GPUShaderFormat SDL_ShaderCross_GetHLSLShaderFormats(void)
 {
+    SDL_GPUShaderFormat supportedFormats = 0;
+
     /* DXC allows compilation from HLSL to DXIL and SPIRV */
-    SDL_GPUShaderFormat supportedFormats = SDL_GPU_SHADERFORMAT_DXIL | SDL_GPU_SHADERFORMAT_SPIRV;
+#ifdef SDL_GPU_SHADERCROSS_DXC
+    supportedFormats |= SDL_GPU_SHADERFORMAT_DXIL | SDL_GPU_SHADERFORMAT_DXBC;
+#endif
 
     /* FXC allows compilation of HLSL to DXBC */
     if (d3dcompiler_dll != NULL) {
@@ -1944,5 +1961,3 @@ SDL_GPUShaderFormat SDL_ShaderCross_GetHLSLShaderFormats(void)
 
     return supportedFormats;
 }
-
-#endif /* SDL_GPU_SHADERCROSS_HLSL */
diff --git a/src/cli.c b/src/cli.c
index 91d7a13..e658b73 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -42,7 +42,6 @@ void print_help(void)
     SDL_Log("  %-*s %s", column_width, "-d | --dest <value>", "Destination format. May be inferred from the filename. Values: [DXBC, DXIL, MSL, SPIRV, HLSL]");
     SDL_Log("  %-*s %s", column_width, "-t | --stage <value>", "Shader stage. May be inferred from the filename. Values: [vertex, fragment, compute]");
     SDL_Log("  %-*s %s", column_width, "-e | --entrypoint <value>", "Entrypoint function name. Default: \"main\".");
-    SDL_Log("  %-*s %s", column_width, "-m | --shadermodel <value>", "HLSL Shader Model. Only used with HLSL destination. Values: [5.0, 6.0]");
     SDL_Log("  %-*s %s", column_width, "-I | --include <value>", "HLSL include directory. Only used with HLSL source. Optional.");
     SDL_Log("  %-*s %s", column_width, "-o | --output <value>", "Output file.");
 }
@@ -53,12 +52,10 @@ int main(int argc, char *argv[])
     bool sourceValid = false;
     bool destinationValid = false;
     bool stageValid = false;
-    bool shaderModelValid = false; // only required for HLSL destination
 
     bool spirvSource = false;
     ShaderCross_ShaderFormat destinationFormat = SHADERFORMAT_INVALID;
     SDL_ShaderCross_ShaderStage shaderStage = SDL_SHADERCROSS_SHADERSTAGE_VERTEX;
-    SDL_ShaderCross_ShaderModel shaderModel = SDL_SHADERCROSS_SHADERMODEL_INVALID;
     char *outputFilename = NULL;
     char *entrypointName = "main";
     char *includeDir = NULL;
@@ -149,24 +146,6 @@ int main(int argc, char *argv[])
                 }
                 i += 1;
                 entrypointName = argv[i];
-            } else if (SDL_strcmp(arg, "-m") == 0 || SDL_strcmp(arg, "--model") == 0) {
-                if (i + 1 >= argc) {
-                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s requires an argument", arg);
-                    print_help();
-                    return 1;
-                }
-                i += 1;
-                if (SDL_strcmp(argv[i], "5.0") == 0) {
-                    shaderModel = SDL_SHADERCROSS_SHADERMODEL_5_0;
-                    shaderModelValid = true;
-                } else if (SDL_strcmp(argv[i], "6.0") == 0) {
-                    shaderModel = SDL_SHADERCROSS_SHADERMODEL_6_0;
-                    shaderModelValid = true;
-                } else {
-                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s is not a recognized HLSL Shader Model!", argv[i]);
-                    print_help();
-                    return 1;
-                }
             } else if (SDL_strcmp(arg, "-I") == 0 || SDL_strcmp(arg, "--include") == 0) {
                 if (includeDir) {
                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "'%s' can only be used once", arg);
@@ -316,18 +295,11 @@ int main(int argc, char *argv[])
             }
 
             case SHADERFORMAT_HLSL: {
-                if (!shaderModelValid) {
-                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", "HLSL destination requires a shader model specification!");
-                    print_help();
-                    return 1;
-                }
-
                 char *buffer = SDL_ShaderCross_TranspileHLSLFromSPIRV(
                     fileData,
                     fileSize,
                     entrypointName,
-                    shaderStage,
-                    shaderModel);
+                    shaderStage);
 
                 if (buffer == NULL) {
                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", "Failed to transpile HLSL from SPIRV!");
@@ -405,16 +377,10 @@ int main(int argc, char *argv[])
                     &bytecodeSize);
                 SDL_WriteIO(outputIO, buffer, bytecodeSize);
                 SDL_free(buffer);
-                return 0;
+                break;
             }
 
             case SHADERFORMAT_HLSL: {
-                if (!shaderModelValid) {
-                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", "HLSL destination requires a shader model specification!");
-                    print_help();
-                    return 1;
-                }
-
                 void *spirv = SDL_ShaderCross_CompileSPIRVFromHLSL(
                     fileData,
                     entrypointName,
@@ -431,8 +397,7 @@ int main(int argc, char *argv[])
                     spirv,
                     bytecodeSize,
                     entrypointName,
-                    shaderStage,
-                    shaderModel);
+                    shaderStage);
 
                 if (buffer == NULL) {
                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", "Failed to transpile HLSL from SPIRV!");