From 33751db0458943e0c6a7110c7ef0d7fb46b47c74 Mon Sep 17 00:00:00 2001 From: Caleb Cornett Date: Sun, 20 Mar 2022 18:24:08 -0400 Subject: [PATCH] Remove spirv-cross, take HLSL files as shader module input, update vertex format ABI --- .gitmodules | 3 - CMakeLists.txt | 18 -- SPIRV-Cross | 1 - src/Refresh_Driver_D3D11.c | 341 ++++++++------------------------ visualc/Refresh.vcxproj | 18 +- visualc/Refresh.vcxproj.filters | 27 --- 6 files changed, 91 insertions(+), 317 deletions(-) delete mode 160000 SPIRV-Cross diff --git a/.gitmodules b/.gitmodules index 1da3b2f..bf4fac3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "Vulkan-Headers"] path = Vulkan-Headers url = https://github.com/KhronosGroup/Vulkan-Headers.git -[submodule "SPIRV-Cross"] - path = SPIRV-Cross - url = https://github.com/KhronosGroup/SPIRV-Cross diff --git a/CMakeLists.txt b/CMakeLists.txt index eb46dee..a22ec80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,7 +79,6 @@ target_include_directories(Refresh PUBLIC $ $ $ - $ ) # MinGW builds should statically link libgcc @@ -93,23 +92,6 @@ set_target_properties(Refresh PROPERTIES OUTPUT_NAME "Refresh" SOVERSION ${LIB_MAJOR_VERSION} ) -# Internal Dependencies -if (BUILD_D3D11) - set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_CLI OFF CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_SHARED ON CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_STATIC OFF CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_ENABLE_C_API ON CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_ENABLE_HLSL ON CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_ENABLE_GLSL ON CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_ENABLE_REFLECT ON CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_ENABLE_MSL OFF CACHE "" INTERNAL FORCE) - set(SPIRV_CROSS_ENABLE_CPP OFF CACHE "" INTERNAL FORCE) - - add_subdirectory(SPIRV-Cross EXCLUDE_FROM_ALL) - target_link_libraries(Refresh PUBLIC spirv-cross-c-shared) -endif() - # SDL2 Dependency if (DEFINED SDL2_INCLUDE_DIRS AND DEFINED SDL2_LIBRARIES) message(STATUS "using pre-defined SDL2 variables SDL2_INCLUDE_DIRS and SDL2_LIBRARIES") diff --git a/SPIRV-Cross b/SPIRV-Cross deleted file mode 160000 index d5c3bd8..0000000 --- a/SPIRV-Cross +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d5c3bd8b5e7db9e2d7fe809944b47b8f88e1c732 diff --git a/src/Refresh_Driver_D3D11.c b/src/Refresh_Driver_D3D11.c index 17d47ae..c3c8ec8 100644 --- a/src/Refresh_Driver_D3D11.c +++ b/src/Refresh_Driver_D3D11.c @@ -39,8 +39,6 @@ #include #include -#include - /* Defines */ #define D3D11_DLL "d3d11.dll" @@ -129,7 +127,8 @@ static DXGI_FORMAT RefreshToD3D11_SurfaceFormat[] = static DXGI_FORMAT RefreshToD3D11_VertexFormat[] = { - DXGI_FORMAT_R32_FLOAT, /* SINGLE */ + DXGI_FORMAT_R32_UINT, /* UINT */ + DXGI_FORMAT_R32_FLOAT, /* FLOAT */ DXGI_FORMAT_R32G32_FLOAT, /* VECTOR2 */ DXGI_FORMAT_R32G32B32_FLOAT, /* VECTOR3 */ DXGI_FORMAT_R32G32B32A32_FLOAT, /* VECTOR4 */ @@ -328,11 +327,10 @@ typedef struct D3D11CommandBufferPool typedef struct D3D11ShaderModule { - spvc_context context; - size_t numEntryPoints; - const spvc_entry_point *entryPoints; - ID3D11DeviceChild **shaders; /* ID3D11VertexShader, ID3D11PixelShader, ID3D11ComputeShader */ - ID3D10Blob **blobs; + ID3D11DeviceChild *shader; /* ID3D11VertexShader, ID3D11PixelShader, ID3D11ComputeShader */ + ID3D10Blob *blob; + char *shaderSource; + size_t shaderSourceLength; } D3D11ShaderModule; typedef struct D3D11GraphicsPipeline @@ -899,7 +897,8 @@ static uint32_t D3D11_INTERNAL_FindIndexOfVertexBinding( static ID3D11InputLayout* D3D11_INTERNAL_FetchInputLayout( D3D11Renderer *renderer, Refresh_VertexInputState inputState, - ID3D10Blob *shaderBlob + void *shaderBytes, + size_t shaderByteLength ) { ID3D11InputLayout *result = NULL; D3D11_INPUT_ELEMENT_DESC *elementDescs; @@ -942,8 +941,8 @@ static ID3D11InputLayout* D3D11_INTERNAL_FetchInputLayout( renderer->device, elementDescs, inputState.vertexAttributeCount, - (void*) ID3D10Blob_GetBufferPointer(shaderBlob), - ID3D10Blob_GetBufferSize(shaderBlob), + shaderBytes, + shaderByteLength, &result ); if (FAILED(res)) @@ -975,10 +974,11 @@ static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline( ) { D3D11Renderer *renderer = (D3D11Renderer*) driverData; D3D11GraphicsPipeline *pipeline = (D3D11GraphicsPipeline*) SDL_malloc(sizeof(D3D11GraphicsPipeline)); - D3D11ShaderModule* vertShaderModule = (D3D11ShaderModule*) pipelineCreateInfo->vertexShaderInfo.shaderModule; - D3D11ShaderModule* fragShaderModule = (D3D11ShaderModule*) pipelineCreateInfo->fragmentShaderInfo.shaderModule; - int32_t vertexShaderIndex, fragmentShaderIndex; + D3D11ShaderModule *vertShaderModule = (D3D11ShaderModule*) pipelineCreateInfo->vertexShaderInfo.shaderModule; + D3D11ShaderModule *fragShaderModule = (D3D11ShaderModule*) pipelineCreateInfo->fragmentShaderInfo.shaderModule; + ID3D10Blob *errorBlob; int32_t i; + HRESULT res; /* Color attachments */ pipeline->numColorAttachments = pipelineCreateInfo->attachmentInfo.colorAttachmentCount; @@ -1024,54 +1024,79 @@ static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline( pipelineCreateInfo->rasterizerState ); - /* Vertex Shader + Input Layout */ - vertexShaderIndex = -1; - for (i = 0; i < vertShaderModule->numEntryPoints; i += 1) + /* Vertex Shader */ + if (vertShaderModule->shader == NULL) { - if ( vertShaderModule->entryPoints[i].execution_model == SpvExecutionModelVertex && - SDL_strcmp(vertShaderModule->entryPoints[i].name, pipelineCreateInfo->vertexShaderInfo.entryPointName) == 0 ) - { - vertexShaderIndex = i; - break; - } - } - if (vertexShaderIndex == -1) - { - Refresh_LogError( - "Graphics pipeline creation failed! No entry point '%s' exists for the vertex shader!", - pipelineCreateInfo->vertexShaderInfo.entryPointName + res = renderer->D3DCompileFunc( + vertShaderModule->shaderSource, + vertShaderModule->shaderSourceLength, + NULL, + NULL, + NULL, + "main", + "vs_5_0", + 0, + 0, + &vertShaderModule->blob, + &errorBlob ); - return NULL; - } + if (FAILED(res)) + { + Refresh_LogError("Vertex Shader Compile Error: %s", ID3D10Blob_GetBufferPointer(errorBlob)); + return NULL; + } + res = ID3D11Device_CreateVertexShader( + renderer->device, + ID3D10Blob_GetBufferPointer(vertShaderModule->blob), + ID3D10Blob_GetBufferSize(vertShaderModule->blob), + NULL, + (ID3D11VertexShader**) &vertShaderModule->shader + ); + ERROR_CHECK_RETURN("Could not create vertex shader", NULL); + } + pipeline->vertexShader = (ID3D11VertexShader*)vertShaderModule->shader; + + /* Input Layout */ pipeline->inputLayout = D3D11_INTERNAL_FetchInputLayout( renderer, pipelineCreateInfo->vertexInputState, - vertShaderModule->blobs[vertexShaderIndex] + ID3D10Blob_GetBufferPointer(vertShaderModule->blob), + ID3D10Blob_GetBufferSize(vertShaderModule->blob) ); - pipeline->vertexShader = (ID3D11VertexShader*) vertShaderModule->shaders[vertexShaderIndex]; /* Fragment Shader */ - fragmentShaderIndex = -1; - for (i = 0; i < fragShaderModule->numEntryPoints; i += 1) + if (fragShaderModule->shader == NULL) { - if ( fragShaderModule->entryPoints[i].execution_model == SpvExecutionModelFragment && - SDL_strcmp(fragShaderModule->entryPoints[i].name, pipelineCreateInfo->fragmentShaderInfo.entryPointName) == 0 ) - { - fragmentShaderIndex = i; - break; - } - } - if (fragmentShaderIndex == -1) - { - Refresh_LogError( - "Graphics pipeline creation failed! No entry point '%s' exists for the fragment shader!", - pipelineCreateInfo->vertexShaderInfo.entryPointName + res = renderer->D3DCompileFunc( + fragShaderModule->shaderSource, + fragShaderModule->shaderSourceLength, + NULL, + NULL, + NULL, + "main", + "ps_5_0", + 0, + 0, + &fragShaderModule->blob, + &errorBlob ); - return NULL; - } + if (FAILED(res)) + { + Refresh_LogError("Fragment Shader Compile Error: %s", ID3D10Blob_GetBufferPointer(errorBlob)); + return NULL; + } - pipeline->fragmentShader = (ID3D11PixelShader*) fragShaderModule->shaders[fragmentShaderIndex]; + res = ID3D11Device_CreatePixelShader( + renderer->device, + ID3D10Blob_GetBufferPointer(fragShaderModule->blob), + ID3D10Blob_GetBufferSize(fragShaderModule->blob), + NULL, + (ID3D11PixelShader**) &fragShaderModule->shader + ); + ERROR_CHECK_RETURN("Could not create pixel shader", NULL); + } + pipeline->fragmentShader = (ID3D11PixelShader*) fragShaderModule->shader; /* FIXME: Need to create uniform buffers for the shaders */ @@ -1090,199 +1115,14 @@ static Refresh_ShaderModule* D3D11_CreateShaderModule( Refresh_ShaderModuleCreateInfo *shaderModuleCreateInfo ) { D3D11Renderer *renderer = (D3D11Renderer*) driverData; - spvc_context context; - spvc_result result; - spvc_parsed_ir parsedIR; - spvc_compiler compiler; - const spvc_entry_point *entryPoints; - size_t numEntryPoints; - spvc_compiler_options compilerOptions; - char *hlslSource; - const char *shaderModel; - ID3DBlob **blobs; - ID3DBlob *errorBlob = NULL; - ID3D11DeviceChild **shaders; - D3D11ShaderModule *shaderModule; - uint32_t i; - HRESULT res; - /* Create the context */ - result = spvc_context_create(&context); - if (result != SPVC_SUCCESS) - { - Refresh_LogError("Could not create SPIRV Cross context! Error: %X", result); - return NULL; - } + D3D11ShaderModule *shaderModule = (D3D11ShaderModule*) SDL_malloc(sizeof(D3D11ShaderModule)); + shaderModule->shader = NULL; /* created when binding to a pipeline */ + shaderModule->blob = NULL; /* created when binding to a pipeline */ + shaderModule->shaderSourceLength = shaderModuleCreateInfo->codeSize; + shaderModule->shaderSource = (char*) SDL_malloc(shaderModule->shaderSourceLength); + SDL_memcpy(shaderModule->shaderSource, shaderModuleCreateInfo->byteCode, shaderModuleCreateInfo->codeSize); - /* Parse the SPIRV input */ - result = spvc_context_parse_spirv( - context, - shaderModuleCreateInfo->byteCode, - shaderModuleCreateInfo->codeSize / sizeof(uint32_t), /* word count, not byte length */ - &parsedIR - ); - if (result != SPVC_SUCCESS) - { - Refresh_LogError("Could not parse SPIRV! Error: %X", result); - spvc_context_destroy(context); /* free all context-related memory */ - return NULL; - } - - /* Create the cross compiler */ - result = spvc_context_create_compiler( - context, - SPVC_BACKEND_HLSL, - parsedIR, - SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, - &compiler - ); - if (result != SPVC_SUCCESS) - { - Refresh_LogError("Could not create SPIRV to HLSL cross compiler! Error: %X", result); - spvc_context_destroy(context); /* free all context-related memory */ - return NULL; - } - - /* Get entry points from the source bytecode */ - result = spvc_compiler_get_entry_points(compiler, &entryPoints, &numEntryPoints); - if (result != SPVC_SUCCESS) - { - Refresh_LogError("Could not get SPIRV entry points! Error: %X", result); - spvc_context_destroy(context); /* free all context-related memory */ - return NULL; - } - - /* Set HLSL cross-compile options (target SM5.0) */ - spvc_compiler_create_compiler_options(compiler, &compilerOptions); - spvc_compiler_options_set_uint( - compilerOptions, - SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL, - 50 /* shader model 5.0 */ - ); - spvc_compiler_options_set_bool( - compilerOptions, - SPVC_COMPILER_OPTION_FLIP_VERTEX_Y, - SPVC_TRUE - ); - spvc_compiler_install_compiler_options(compiler, compilerOptions); - - /* Cross compile to HLSL */ - result = spvc_compiler_compile(compiler, &hlslSource); - if (result != SPVC_SUCCESS) - { - Refresh_LogError("Could not cross-compile SPIRV to HLSL! Error: %X", result); - spvc_context_destroy(context); /* free all context-related memory */ - return NULL; - } - - /* Allocate memory for the D3D11 shader list */ - shaders = (ID3D11DeviceChild**) SDL_malloc(numEntryPoints * sizeof(ID3D11DeviceChild*)); - blobs = (ID3D10Blob**) SDL_malloc(numEntryPoints * sizeof(ID3D10Blob*)); - - /* Compile each HLSL entry point into a D3D shader */ - for (i = 0; i < numEntryPoints; i += 1) - { - /* Determine the exact shader model to use */ - switch (entryPoints[i].execution_model) - { - case SpvExecutionModelVertex: - shaderModel = "vs_5_0"; - break; - - case SpvExecutionModelFragment: - shaderModel = "ps_5_0"; - break; - - case SpvExecutionModelGLCompute: - shaderModel = "cs_5_0"; - break; - - default: - Refresh_LogError( - "Attempting to compile a shader with an unknown execution model: %X", - entryPoints[i].execution_model - ); - spvc_context_destroy(context); /* free all context-related memory */ - SDL_free(shaders); - return NULL; - } - - /* Compile the shader blob */ - res = renderer->D3DCompileFunc( - hlslSource, - SDL_strlen(hlslSource), - NULL, - NULL, - NULL, - entryPoints[i].name, - shaderModel, - 0, - 0, - &blobs[i], - &errorBlob - ); - if (FAILED(res)) - { - Refresh_LogError( - "D3DCompile failed on HLSL shader with entry point '%s'! Error: %X\nCompiler error message: %s", - entryPoints[i].name, - res, - errorBlob ? (const char*) ID3D10Blob_GetBufferPointer(errorBlob) : "" - ); - spvc_context_destroy(context); /* free all context-related memory */ - SDL_free(shaders); - return NULL; - } - - /* Create the shader from the blob */ - switch (entryPoints[i].execution_model) - { - case SpvExecutionModelVertex: - res = ID3D11Device_CreateVertexShader( - renderer->device, - ID3D10Blob_GetBufferPointer(blobs[i]), - ID3D10Blob_GetBufferSize(blobs[i]), - NULL, - (ID3D11VertexShader**) &shaders[i] - ); - break; - - case SpvExecutionModelFragment: - res = ID3D11Device_CreatePixelShader( - renderer->device, - ID3D10Blob_GetBufferPointer(blobs[i]), - ID3D10Blob_GetBufferSize(blobs[i]), - NULL, - (ID3D11PixelShader**) &shaders[i] - ); - break; - - case SpvExecutionModelGLCompute: - res = ID3D11Device_CreateComputeShader( - renderer->device, - ID3D10Blob_GetBufferPointer(blobs[i]), - ID3D10Blob_GetBufferSize(blobs[i]), - NULL, - (ID3D11ComputeShader**) &shaders[i] - ); - break; - } - if (FAILED(res)) - { - Refresh_LogError("D3D11 shader creation failed! Error code: %X", res); - spvc_context_destroy(context); /* free all context-related memory */ - SDL_free(shaders); - return NULL; - } - } - - /* Create the final shader module object to return */ - shaderModule = (D3D11ShaderModule*) SDL_malloc(sizeof(D3D11ShaderModule)); - shaderModule->context = context; - shaderModule->entryPoints = entryPoints; - shaderModule->numEntryPoints = numEntryPoints; - shaderModule->shaders = shaders; - shaderModule->blobs = blobs; return (Refresh_ShaderModule*) shaderModule; } @@ -1514,21 +1354,10 @@ static void D3D11_QueueDestroyShaderModule( Refresh_ShaderModule* shaderModule ) { D3D11ShaderModule *d3dShaderModule = (D3D11ShaderModule*) shaderModule; - uint32_t i; - - /* Release the D3D11 shader objects and free the arrays */ - for (i = 0; i < d3dShaderModule->numEntryPoints; i += 1) - { - ID3D11DeviceChild_Release(d3dShaderModule->shaders[i]); - ID3D10Blob_Release(d3dShaderModule->blobs[i]); - } - SDL_free(d3dShaderModule->shaders); - SDL_free(d3dShaderModule->blobs); - - /* Destroy the SPIRV-Cross context. - * This should destroy the entryPoints list as well. - */ - spvc_context_destroy(d3dShaderModule->context); + ID3D11DeviceChild_Release(d3dShaderModule->shader); + ID3D10Blob_Release(d3dShaderModule->blob); + SDL_free(d3dShaderModule->shaderSource); + SDL_free(d3dShaderModule); } static void D3D11_QueueDestroyComputePipeline( diff --git a/visualc/Refresh.vcxproj b/visualc/Refresh.vcxproj index a757695..6a37b21 100644 --- a/visualc/Refresh.vcxproj +++ b/visualc/Refresh.vcxproj @@ -61,8 +61,9 @@ Level3 Disabled - REFRESH_DRIVER_D3D11;REFRESH_DRIVER_VULKAN;SPIRV_CROSS_C_API_GLSL;SPIRV_CROSS_C_API_HLSL;SPIRV_CROSS_C_API_REFLECT;%(PreprocessorDefinitions) - ..\SPIRV-Cross;%(AdditionalIncludeDirectories) + REFRESH_DRIVER_D3D11;REFRESH_DRIVER_VULKAN;%(PreprocessorDefinitions) + + DebugFull @@ -73,10 +74,11 @@ Level3 MaxSpeed - REFRESH_DRIVER_D3D11;REFRESH_DRIVER_VULKAN;SPIRV_CROSS_C_API_GLSL;SPIRV_CROSS_C_API_HLSL;SPIRV_CROSS_C_API_REFLECT;%(PreprocessorDefinitions) + REFRESH_DRIVER_D3D11;REFRESH_DRIVER_VULKAN;%(PreprocessorDefinitions) true true - ..\SPIRV-Cross;%(AdditionalIncludeDirectories) + + true @@ -85,14 +87,6 @@ - - - - - - - - diff --git a/visualc/Refresh.vcxproj.filters b/visualc/Refresh.vcxproj.filters index e4cb70c..769e63a 100644 --- a/visualc/Refresh.vcxproj.filters +++ b/visualc/Refresh.vcxproj.filters @@ -13,30 +13,6 @@ Source Files - - Source Files\spirv-cross - - - Source Files\spirv-cross - - - Source Files\spirv-cross - - - Source Files\spirv-cross - - - Source Files\spirv-cross - - - Source Files\spirv-cross - - - Source Files\spirv-cross - - - Source Files\spirv-cross - @@ -62,8 +38,5 @@ {B2BA146C-CAA1-30BE-B7A9-F8D02673EA0C} - - {4764626f-fd8b-4a1c-8c20-fd92a1f3cb4b} - \ No newline at end of file