diff --git a/assets/shaders/gradient.comp.spv b/assets/shaders/gradient.comp.spv new file mode 100644 index 0000000..49ba2be Binary files /dev/null and b/assets/shaders/gradient.comp.spv differ diff --git a/assets/shaders/triangle.frag.spv b/assets/shaders/triangle.frag.spv index c9fb610..d039d54 100644 Binary files a/assets/shaders/triangle.frag.spv and b/assets/shaders/triangle.frag.spv differ diff --git a/assets/shaders/triangle.vert.spv b/assets/shaders/triangle.vert.spv index 291e27e..44718ec 100644 Binary files a/assets/shaders/triangle.vert.spv and b/assets/shaders/triangle.vert.spv differ diff --git a/dub.json b/dub.json index 59f9655..ed5e37b 100644 --- a/dub.json +++ b/dub.json @@ -13,7 +13,7 @@ "sourcePaths": ["src/gears", "src/shared", "src/generated"], "libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++"], "libs-windows": [], - "preGenerateCommands-linux": ["./build-vma.sh", "build/Packer"], + "preGenerateCommands-linux": ["./build-vma.sh", "build/Codegen", "dub main:packer", "build/Packer"], "preGenerateCommands-windows": [], }, { @@ -26,6 +26,7 @@ "sourceFiles-linux": ["build/libxxhash.a", "build/libstb_image.a", "build/libm3d.a"], "preGenerateCommands-linux": ["./build-vma.sh"], "preGenerateCommands-windows": [], + "dflags-dmd": ["-P=-DXXH_VECTOR=0", "-P=-DSTBI_NO_SIMD", "-P=-DXXH_NO_PREFTECH"], }, { "name": "codegen", @@ -38,6 +39,7 @@ "preGenerateCommands-linux": ["./build-vma.sh"], "preGenerateCommands-windows": [], "versions": ["codegen"], + "dflags-dmd": ["-P=-DXXH_VECTOR=0", "-P=-DSTBI_NO_SIMD", "-P=-DXXH_NO_PREFTECH"], } ] } diff --git a/src/gears/main.d b/src/gears/main.d index 2f4ad84..4b30387 100644 --- a/src/gears/main.d +++ b/src/gears/main.d @@ -35,5 +35,21 @@ void main() auto pipeline = vk.CreateGraphicsPipeline(&vulkan, &pipeline_info); + u8[] comp_bytes = ap.LoadAssetData("shaders/gradient.comp"); + assert(comp_bytes != null, "Unable to load compute shader data"); + + auto comp_module = vk.BuildShader(&vulkan, comp_bytes); + assert(comp_module.ok, "Unable to build compute shader"); + + auto comp_pipeline = vk.CreateComputePipeline(&vulkan, comp_module.value); + + vk.Destroy(&vulkan, comp_module.value); + vk.Destroy(&vulkan, comp_pipeline); + + vk.Destroy(&vulkan, vert_module.value); + vk.Destroy(&vulkan, frag_module.value); + vk.Destroy(&vulkan, pipeline); + vk.Destroy(&vulkan); } + diff --git a/src/gears/renderer.d b/src/gears/renderer.d index 226df72..1c9a3f8 100644 --- a/src/gears/renderer.d +++ b/src/gears/renderer.d @@ -28,3 +28,5 @@ struct GfxPipelineInfo u32 input_rate_stride; Attribute[] vertex_attributes; } + + diff --git a/src/gears/vulkan.d b/src/gears/vulkan.d index 759ae5a..aeb3adc 100644 --- a/src/gears/vulkan.d +++ b/src/gears/vulkan.d @@ -228,7 +228,7 @@ BuildShader(Vulkan* vk, u8[] bytes) return shader; } -VkPipeline +Pipeline CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info) { VkDynamicState[] dyn_state = [ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR ]; @@ -274,6 +274,8 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info) VkPipelineRenderingCreateInfo rendering_info = { sType: VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, colorAttachmentCount: 1, + pColorAttachmentFormats: &vk.draw_image.base.format, + depthAttachmentFormat: vk.depth_image.base.format, }; VkPipelineColorBlendAttachmentState blend_state = { @@ -349,16 +351,41 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info) return pipeline; } -VkPipeline -CreateComputePipeline(Vulkan* vk, string shader) + +Pipeline +CreateComputePipeline(Vulkan* vk, Shader shader) { + VkComputePipelineCreateInfo info = { + sType: VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + layout: vk.pipeline_layout, + stage: { + sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + stage: VK_SHADER_STAGE_COMPUTE_BIT, + pName: "main", + }, + }; + + __traits(getMember, &info.stage, "module") = shader; + VkPipeline pipeline; - - + VkResult result = vkCreateComputePipelines(vk.device, null, 1, &info, null, &pipeline); + assert(VkCheck("CreateComputePipeline failure", result), "Unable to build pipeline"); return pipeline; } +void +Destroy(Vulkan* vk, Shader shader) +{ + vkDestroyShaderModule(vk.device, shader, null); +} + +void +Destroy(Vulkan* vk, Pipeline pipeline) +{ + vkDestroyPipeline(vk.device, pipeline, null); +} + void Destroy(Vulkan* vk) { diff --git a/src/gears/vulkan_logging.d b/src/gears/vulkan_logging.d index 76a1cfc..47c2fb3 100644 --- a/src/gears/vulkan_logging.d +++ b/src/gears/vulkan_logging.d @@ -3,6 +3,7 @@ import std.stdio; import vulkan : Vulkan; import std.conv; import std.string; +import core.stdc.string : strlen; VkBool32 DebugCallback( @@ -59,7 +60,7 @@ DebugCallback( break; } - string msg = to!string(callback_data.pMessage); + const char[] msg = callback_data.pMessage[0 .. strlen(callback_data.pMessage)]; writefln("[%s: %s]\n%r\n", ms, mt, msg); diff --git a/src/generated/assets_codegen.d b/src/generated/assets_codegen.d index eea100f..ac1a0c0 100644 --- a/src/generated/assets_codegen.d +++ b/src/generated/assets_codegen.d @@ -27,16 +27,19 @@ static immutable u64[] MODEL_HASHES = [ static immutable string[] SHADER_FILES = [ "shaders/triangle.vert.spv", + "shaders/gradient.comp.spv", "shaders/triangle.frag.spv", ]; static immutable string[] SHADER_NAMES = [ "shaders/triangle.vert", + "shaders/gradient.comp", "shaders/triangle.frag", ]; static immutable u64[] SHADER_HASHES = [ 8769314645675479020, + 16130483095684998267, 6282520872716708711, ]; diff --git a/src/shaders/gradient.comp.glsl b/src/shaders/gradient.comp.glsl new file mode 100644 index 0000000..0d838e5 --- /dev/null +++ b/src/shaders/gradient.comp.glsl @@ -0,0 +1,27 @@ +#version 460 + +#extension GL_EXT_buffer_reference : require +#extension GL_GOOGLE_include_directive : require + +#include "structures.layout" + +layout (local_size_x = 16, local_size_y = 16) in; + +void main() +{ + ivec2 texel_coord = ivec2(gl_GlobalInvocationID.xy); + ivec2 size = imageSize(DrawImage); + + if (texel_coord.x < size. x && texel_coord.y < size.y) + { + vec4 color = vec4(0.0); + + if (gl_GlobalInvocationID.x != 0 && gl_LocalInvocationID.y != 0) + { + color.x = float(texel_coord.x) / size.x; + color.y = float(texel_coord.y) / size.y; + } + + imageStore(DrawImage, texel_coord, color); + } +} diff --git a/src/shaders/structures.layout b/src/shaders/structures.layout new file mode 100644 index 0000000..f6788dc --- /dev/null +++ b/src/shaders/structures.layout @@ -0,0 +1,33 @@ +struct Vertex { + vec4 pos; +}; + +layout (buffer_reference, std430) readonly buffer VertexBuffer { + Vertex vertices[]; +}; + +layout (set = 0, binding = 0) uniform GlobalUniforms { + vec2 res; +} G; + +layout (set = 0, binding = 1) uniform ShaderUniforms { + float placeholder; +} S; + +layout (rgba16f, set = 0, binding = 2) uniform image2D DrawImage; + +layout (set = 0, binding = 3) uniform sampler SamplerNearest; + +layout (set = 1, binding = 0) uniform texture2D Textures[]; + +layout (set = 2, binding = 0) uniform Material { + float placeholder; +} Materials[]; + +layout (set = 3, binding = 0) uniform Mesh { + VertexBuffer buf; +} Meshes[]; + +layout (push_constant) uniform Constants { + float placeholder; +} PC; diff --git a/src/shaders/triangle.frag.glsl b/src/shaders/triangle.frag.glsl index ad91eb6..e752f65 100644 --- a/src/shaders/triangle.frag.glsl +++ b/src/shaders/triangle.frag.glsl @@ -1,5 +1,11 @@ #version 460 +#extension GL_EXT_buffer_reference : require +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_nonuniform_qualifier : require + +#include "structures.layout" + layout (location = 0) in vec3 fragColor; layout (location = 0) out vec4 outColor; diff --git a/src/shaders/triangle.vert.glsl b/src/shaders/triangle.vert.glsl index 18e8b61..cc359d2 100644 --- a/src/shaders/triangle.vert.glsl +++ b/src/shaders/triangle.vert.glsl @@ -1,5 +1,11 @@ #version 460 +#extension GL_EXT_buffer_reference : require +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_nonuniform_qualifier : require + +#include "structures.layout" + layout (location = 0) out vec3 fragColor; vec2 positions[3] = vec2[](