diff --git a/build.sh b/build.sh index b75c59f..c046154 100644 --- a/build.sh +++ b/build.sh @@ -25,8 +25,19 @@ out="-o" obj="${build}/vma.o" lib="${build}/libvma.a" -if ! [ -f libvma.a ]; then +if ! [ -f "${build}/libvma.a" ]; then $cpp_compiler $flags $src $out $obj ar rcs $lib $obj rm $obj fi + +# Convert Shader +shader="${script_dir}/convert.comp.glsl" +shader_compiler="glslc" +shader_flags="--target-spv=spv1.5 -std=460 --target-env=vulkan1.3" +shader_out="-o${build}/" +shader_stage="-fshader-stage=comp" + +base_name=$(basename -- "$shader" .glsl) + +$shader_compiler $shader_flags $shader_stage $shader "${shader_out}${base_name}.spv" diff --git a/convert.comp.glsl b/convert.comp.glsl new file mode 100644 index 0000000..1fc038d --- /dev/null +++ b/convert.comp.glsl @@ -0,0 +1,56 @@ +#version 460 + +#extension GL_EXT_shader_8bit_storage : require + +layout (constant_id = 0) const int CHANNELS = 3; + +layout (local_size_x = 32, local_size_y = 32) in; + +layout (push_constant) uniform Constants { + uint x; + uint y; +} PC; + +layout (set = 1, binding = 0, rgba32f) uniform image2D dst; + +layout (set = 1, binding = 1) buffer input_array +{ + uint8_t src[]; +}; + + +void main() +{ + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + + if (x > PC.x || y > PC.y) + { + return; + } + + if (CHANNELS == 1) + { + uint index = x + y * PC.x; + + vec4 col = vec4(vec3(uint(src[index]) / 255.0), 1.0); + imageStore(dst, ivec2(x, y), col); + } + else if (CHANNELS == 2) + { + uint index = (x + y * PC.x) * 2; + + float f = uint(src[index]) / 255.0; + float a = uint(src[index+1]) / 255.0; + vec4 col = vec4(f, f, f, a); + imageStore(dst, ivec2(x, y), col); + } + else if (CHANNELS == 3) + { + uint index = (x + y * PC.x) * 3; + + vec4 col = vec4(uint(src[index]) / 255.0, uint(src[index+1]) / 255.0, uint(src[index+2]) / 255.0, 1.0); + imageStore(dst, ivec2(x, y), col); + } +} + diff --git a/vulkan.d b/vulkan.d index 6d3f134..4ae8742 100644 --- a/vulkan.d +++ b/vulkan.d @@ -248,7 +248,7 @@ struct GfxPipelineInfo struct CompPipelineInfo { - string shader; + u8[] shader; Specialization spec; PipelineLayout layout; } @@ -390,8 +390,10 @@ struct QueueInfo bool single_queue; } +const u8[] CONVERT_SHADER = mixin(Embed(convert_shader)); + Vulkan -Init(PlatformHandles platform_handles, u64 permanent_mem, u64 frame_mem) +Init(PlatformHandles platform_handles, u64 permanent_mem, u64 frame_mem, string convert_shader) { bool success = true; @@ -552,7 +554,7 @@ InitConversionPipeline(Vulkan* vk) } ]; CompPipelineInfo conv_info = { - shader: "shaders/convert.comp.spv", + shader: CONVERT_SHADER, layout: vk.conv_pipeline_layout, spec: { data: &channels, @@ -1857,12 +1859,9 @@ CreateComputePipeline(Vulkan* vk, CompPipelineInfo* comp_info) }, }; - u8[] comp_bytes = LoadAssetData(&vk.frame_arenas[0], comp_info.shader); - assert(comp_bytes != null, "Unable to load compute shader data"); - - Result!(Shader) comp_module = BuildShader(vk, comp_bytes); - assert(comp_module.ok, "Unable to build compute shader"); - scope(exit) Destroy(vk, comp_module.value); + Shader comp_module; + assert(BuildShader(vk, &comp_module, comp_info.shader), "Unable to build compute shader"); + scope(exit) Destroy(vk, comp_module); __traits(getMember, &info.stage, "module") = comp_module.value; diff --git a/vulkan_util.d b/vulkan_util.d index 47a5cef..82e865b 100644 --- a/vulkan_util.d +++ b/vulkan_util.d @@ -278,3 +278,4 @@ AlignPow2(T)(T v, T a) { return (v + a - 1) & ~(a - 1); } +