From e8a40e04a90a6a6efa818f2ea390dca2a81879fd Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 21 Jun 2026 00:53:03 +0100 Subject: [PATCH] Load shaders and create shader module --- assets/shader.slang | 74 ++++++++++++++++++++++----------------------- build | 2 +- main.cpp | 61 +++++++++++++++++++++++++++++++++++++ run | 2 +- 4 files changed, 100 insertions(+), 39 deletions(-) diff --git a/assets/shader.slang b/assets/shader.slang index 1f7484e..997f2d5 100644 --- a/assets/shader.slang +++ b/assets/shader.slang @@ -5,57 +5,57 @@ */ struct VSInput { - float3 Pos; - float3 Normal; + float3 Pos; + float3 Normal; float2 UV; }; Sampler2D textures[]; struct ShaderData { - float4x4 projection; - float4x4 view; - float4x4 model[3]; - float4 lightPos; - uint32_t selected; + float4x4 projection; + float4x4 view; + float4x4 model[3]; + float4 lightPos; + uint32_t selected; }; struct VSOutput { - float4 Pos : SV_POSITION; - float3 Normal; - float2 UV; - float3 Factor; - float3 LightVec; - float3 ViewVec; - uint32_t InstanceIndex; + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 Factor; + float3 LightVec; + float3 ViewVec; + uint32_t InstanceIndex; }; [shader("vertex")] VSOutput main(VSInput input, uniform ShaderData *shaderData, uint instanceIndex : SV_VulkanInstanceID) { - VSOutput output; - float4x4 modelMat = shaderData->model[instanceIndex]; - output.Normal = mul((float3x3)mul(shaderData->view, modelMat), input.Normal); - output.UV = input.UV; - output.Pos = mul(shaderData->projection, mul(shaderData->view, mul(modelMat, float4(input.Pos.xyz, 1.0)))); - output.Factor = (shaderData->selected == instanceIndex ? 3.0f : 1.0f); - output.InstanceIndex = instanceIndex; - // Calculate view vectors required for lighting - float4 fragPos = mul(mul(shaderData->view, modelMat), float4(input.Pos.xyz, 1.0)); - output.LightVec = shaderData->lightPos.xyz - fragPos.xyz; - output.ViewVec = -fragPos.xyz; - return output; + VSOutput output; + float4x4 modelMat = shaderData->model[instanceIndex]; + output.Normal = mul((float3x3)mul(shaderData->view, modelMat), input.Normal); + output.UV = input.UV; + output.Pos = mul(shaderData->projection, mul(shaderData->view, mul(modelMat, float4(input.Pos.xyz, 1.0)))); + output.Factor = (shaderData->selected == instanceIndex ? 3.0f : 1.0f); + output.InstanceIndex = instanceIndex; + // Calculate view vectors required for lighting + float4 fragPos = mul(mul(shaderData->view, modelMat), float4(input.Pos.xyz, 1.0)); + output.LightVec = shaderData->lightPos.xyz - fragPos.xyz; + output.ViewVec = -fragPos.xyz; + return output; } [shader("fragment")] float4 main(VSOutput input) { - // Phong lighting - float3 N = normalize(input.Normal); - float3 L = normalize(input.LightVec); - float3 V = normalize(input.ViewVec); - float3 R = reflect(-L, N); - float3 diffuse = max(dot(N, L), 0.0025); - float3 specular = pow(max(dot(R, V), 0.0), 16.0) * 0.75; - // Sample from texture - float3 color = textures[NonUniformResourceIndex(input.InstanceIndex)].Sample(input.UV).rgb * input.Factor; - return float4(diffuse * color.rgb + specular, 1.0); -} \ No newline at end of file + // Phong lighting + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0025); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * 0.75; + // Sample from texture + float3 color = textures[NonUniformResourceIndex(input.InstanceIndex)].Sample(input.UV).rgb * input.Factor; + return float4(diffuse * color.rgb + specular, 1.0); +} diff --git a/build b/build index 6239d48..0f12fc5 100755 --- a/build +++ b/build @@ -18,7 +18,7 @@ build_ktx () { build_app () { bear -- clang++ -g -c -Wno-nullability-completeness -DVK_NO_PROTOTYPES -I$VULKAN_SDK/include -Ivendor/include vulkan_profiles/vulkan_profiles.cpp main.cpp bear -a -- clang -g -c -DVK_NO_PROTOTYPES -Ivulkan_profiles -I$VULKAN_SDK/include $VULKAN_SDK/include/volk/volk.c wapp/wapp.c - bear -a -- clang++ -g -DVK_NO_PROTOTYPES -Lvendor/lib -lSDL3 -lglm -ltinyobjloader -lktx -o main *.o + bear -a -- clang++ -g -DVK_NO_PROTOTYPES -L$VULKAN_SDK/lib -Lvendor/lib -lSDL3 -lglm -ltinyobjloader -lktx -lslang -o main *.o } clean_obj () { diff --git a/main.cpp b/main.cpp index e4145e9..34848cf 100644 --- a/main.cpp +++ b/main.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #define VMA_IMPLEMENTATION #include @@ -87,6 +89,8 @@ typedef VkCommandBuffer *VkCommandBufferArray; typedef Texture *TextureArray; typedef VkDescriptorImageInfo *VkDescriptorImageInfoArray; typedef VkBufferImageCopy *VkBufferImageCopyArray; +typedef slang::TargetDesc *SlangTargetDescArray; +typedef slang::CompilerOptionEntry *SlangCompOptEntryArray; // }}} // {{{ Helper Function Declarations @@ -138,6 +142,8 @@ wapp_intern VkDescriptorImageInfoArray tex_descriptors; wapp_intern VkDescriptorSetLayout desc_set_layout_tex = VK_NULL_HANDLE; wapp_intern VkDescriptorPool desc_pool = VK_NULL_HANDLE; wapp_intern VkDescriptorSet desc_set_tex = VK_NULL_HANDLE; +wapp_intern Slang::ComPtr slang_global_session; +wapp_intern VkShaderModule shader_module = VK_NULL_HANDLE; // }}} int main() { @@ -900,6 +906,60 @@ int main() { wapp_mem_arena_allocator_temp_end(&arena); + // {{{ Shaders + // {{{ Runtime Compile Shaders + // {{{ Initialise Slang Session + // Global session: the connection between the application and the Slang library + slang::createGlobalSession(slang_global_session.writeRef()); + + // {{{ Define Compilation Scope + slang::TargetDesc target = {}; + target.format = SLANG_SPIRV; + target.profile = {slang_global_session->findProfile("spirv_1_4")}; + + SlangTargetDescArray slang_targets = wapp_array_with_capacity(slang::TargetDesc, 8, ARRAY_INIT_NONE); + wapp_array_append_capped(slang::TargetDesc, slang_targets, &target); + + slang::CompilerOptionEntry entry = {}; + entry.name = slang::CompilerOptionName::EmitSpirvDirectly; + entry.value = {slang::CompilerOptionValueKind::Int, 1}; + + SlangCompOptEntryArray slang_options = wapp_array_with_capacity(slang::CompilerOptionEntry, 8, ARRAY_INIT_NONE); + wapp_array_append_capped(slang::CompilerOptionEntry, slang_options, &entry); + // }}} + + // {{{ Create Session + slang::SessionDesc slang_session_desc = {}; + slang_session_desc.targets = slang_targets; + slang_session_desc.targetCount = wapp_array_count(slang_targets); + slang_session_desc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR; + slang_session_desc.compilerOptionEntries = slang_options; + slang_session_desc.compilerOptionEntryCount = wapp_array_count(slang_options); + + Slang::ComPtr slang_session; + slang_global_session->createSession(slang_session_desc, slang_session.writeRef()); + // }}} + // }}} + + // {{{ Load Shader Code + Slang::ComPtr slang_module { + slang_session->loadModuleFromSource("triangle", "assets/shader.slang", nullptr, nullptr), + }; + + Slang::ComPtr spirv; + slang_module->getTargetCode(0, spirv.writeRef()); + // }}} + // }}} + + // {{{ Create Shader Module + VkShaderModuleCreateInfo module_create_info = {}; + module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + module_create_info.codeSize = spirv->getBufferSize(); + module_create_info.pCode = (u32 *)spirv->getBufferPointer(); + check(vkCreateShaderModule(device, &module_create_info, NULL, &shader_module)); + // }}} + // }}} + // {{{ Render Loop SDL_Event event = {}; while (running) { @@ -919,6 +979,7 @@ int main() { // }}} // {{{ Cleanup + vkDestroyShaderModule(device, shader_module, NULL); vkDestroyDescriptorPool(device, desc_pool, NULL); vkDestroyDescriptorSetLayout(device, desc_set_layout_tex, NULL); for (u32 i = 0; i < wapp_array_count(textures); ++i) { diff --git a/run b/run index 5bff6ee..d71b3a0 100755 --- a/run +++ b/run @@ -1,3 +1,3 @@ #!/bin/bash -LD_LIBRARY_PATH=vendor/lib/:$LD_LIBRARY_PATH ./main +LD_LIBRARY_PATH=$VULKAN_SDK/lib:vendor/lib/:$LD_LIBRARY_PATH ./main