diff --git a/assets/shaders/convert.comp.spv b/assets/shaders/convert.comp.spv new file mode 100644 index 0000000..eef316d Binary files /dev/null and b/assets/shaders/convert.comp.spv differ diff --git a/assets/shaders/gradient.comp.spv b/assets/shaders/gradient.comp.spv index 8a334e2..d29c57b 100644 Binary files a/assets/shaders/gradient.comp.spv and b/assets/shaders/gradient.comp.spv differ diff --git a/assets/shaders/gui.frag.spv b/assets/shaders/gui.frag.spv index 3b9e09f..8a577ba 100644 Binary files a/assets/shaders/gui.frag.spv and b/assets/shaders/gui.frag.spv differ diff --git a/assets/shaders/gui.vert.spv b/assets/shaders/gui.vert.spv index 96f037c..7eb8f37 100644 Binary files a/assets/shaders/gui.vert.spv and b/assets/shaders/gui.vert.spv differ diff --git a/assets/shaders/pbr.frag.spv b/assets/shaders/pbr.frag.spv index 50f1403..3b228d4 100644 Binary files a/assets/shaders/pbr.frag.spv and b/assets/shaders/pbr.frag.spv differ diff --git a/assets/shaders/pbr.vert.spv b/assets/shaders/pbr.vert.spv index 4733175..8177cce 100644 Binary files a/assets/shaders/pbr.vert.spv and b/assets/shaders/pbr.vert.spv differ diff --git a/assets/shaders/triangle.frag.spv b/assets/shaders/triangle.frag.spv index e179e70..c4a1dcf 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 b7669bd..dff15cf 100644 Binary files a/assets/shaders/triangle.vert.spv and b/assets/shaders/triangle.vert.spv differ diff --git a/src/gears/renderer.d b/src/gears/renderer.d index 3df9a51..5cf0baf 100644 --- a/src/gears/renderer.d +++ b/src/gears/renderer.d @@ -114,20 +114,31 @@ struct ShaderUniforms f32 placeholder; } -struct Material +extern(C) struct Material { + Vec4 ambient; + Vec4 diffuse; + Vec4 specular; u32 albedo_texture; u32 ambient_texture; u32 specular_texture; b32 albedo_has_texture; b32 ambient_has_texture; b32 specular_has_texture; - Vec4 ambient; - Vec4 diffuse; - Vec4 specular; f32 shininess = 0.0; } +static assert(Material.ambient.offsetof == 0, "ambient offset incorrect"); +static assert(Material.diffuse.offsetof == 16, "ambient offset incorrect"); +static assert(Material.specular.offsetof == 32, "ambient offset incorrect"); +static assert(Material.albedo_texture.offsetof == 48, "ambient offset incorrect"); +static assert(Material.ambient_texture.offsetof == 52, "ambient offset incorrect"); +static assert(Material.specular_texture.offsetof == 56, "ambient offset incorrect"); +static assert(Material.albedo_has_texture.offsetof == 60, "ambient offset incorrect"); +static assert(Material.ambient_has_texture.offsetof == 64, "ambient offset incorrect"); +static assert(Material.specular_has_texture.offsetof == 68, "ambient offset incorrect"); +static assert(Material.shininess.offsetof == 72, "ambient offset incorrect"); + struct UIVertex { Vec2 p0; @@ -399,45 +410,47 @@ LoadModel(Renderer* rd, string name) u32 w = m3d.texture[i].w; u32 h = m3d.texture[i].h; u32 ch = m3d.texture[i].f; u8[] tex_data = m3d.texture[i].d[0 .. w * h * ch]; + const(char)[] tex_name = m3d.texture[i].name[0 .. strlen(m3d.texture[i].name)]; CreateImageView(&rd.vk, &model.textures[i], w, h, ch, tex_data); tex_lookup[i] = Pop(&rd.vk, DT.SampledImage); } + Material[] mats = AllocArray!(Material)(&rd.temp_arena, m3d.nummaterial); u32[] mat_lookup = AllocArray!(u32)(&rd.temp_arena, m3d.nummaterial); model.materials = AllocArray!(Buffer)(&rd.arena, m3d.nummaterial); foreach(i; 0 .. m3d.nummaterial) { - Material mat; + const(char)[] mat_name = m3d.material[i].name[0 .. strlen(m3d.material[i].name)]; foreach(j; 0 .. m3d.material[i].numprop) { switch (m3d.material[i].prop[j].type) { - case m3dp_Ka: ConvertColor(&mat.ambient, m3d.material[i].prop[j].value.color); break; - case m3dp_Ks: ConvertColor(&mat.specular, m3d.material[i].prop[j].value.color); break; - case m3dp_Ns: mat.shininess = m3d.material[i].prop[j].value.fnum; break; + case m3dp_Ka: ConvertColor(&mats[i].ambient, m3d.material[i].prop[j].value.color); break; + case m3dp_Ks: ConvertColor(&mats[i].specular, m3d.material[i].prop[j].value.color); break; + case m3dp_Ns: mats[i].shininess = m3d.material[i].prop[j].value.fnum; break; case m3dp_map_Kd: { - mat.albedo_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; - mat.albedo_has_texture = true; + mats[i].albedo_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; + mats[i].albedo_has_texture = true; } break; case m3dp_map_Ka: { - mat.ambient_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; - mat.ambient_has_texture = true; + mats[i].ambient_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; + mats[i].ambient_has_texture = true; } break; case m3dp_map_Ks: { - mat.specular_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; - mat.specular_has_texture = true; + mats[i].specular_texture = tex_lookup[m3d.material[i].prop[j].value.textureid]; + mats[i].specular_has_texture = true; } break; default: break; } } CreateBuffer(&rd.vk, &model.materials[i], BT.Uniform, Material.sizeof, false); - assert(Transfer(&rd.vk, &model.materials[i], &mat), "LoadModel failure: Transfer error when transferring material"); + assert(Transfer(&rd.vk, &model.materials[i], &mats[i]), "LoadModel failure: Transfer error when transferring material"); mat_lookup[i] = Pop(&rd.vk, DT.Material); } @@ -460,7 +473,7 @@ LoadModel(Renderer* rd, string name) { if (last == u64.max) { - model.parts[index].mat = m3d.face[i].materialid != u32.max ? mat_lookup[m3d.face[i].materialid] : 0; + model.parts[index].mat = (m3d.face[i].materialid != u32.max) ? mat_lookup[m3d.face[i].materialid] : 0; model.parts[index].offset = 0; last = m3d.face[i].materialid; } diff --git a/src/gears/vulkan.d b/src/gears/vulkan.d index 9f08054..61d6ab1 100644 --- a/src/gears/vulkan.d +++ b/src/gears/vulkan.d @@ -13,6 +13,7 @@ import renderer; import std.math.rounding : Ceil = ceil; bool g_VLAYER_SUPPORT = false; +bool g_DEBUG_PRINTF = false; const FRAME_OVERLAP = 2; @@ -124,6 +125,7 @@ struct Buffer { VkBuffer buffer; VmaAllocation alloc; + u64 size; } struct DescBindings @@ -403,6 +405,8 @@ CreateBuffer(Vulkan* vk, Buffer* buf, BufferType type, u64 size, bool host_visib VkResult result = vmaCreateBuffer(vk.vma, &buffer_info, &alloc_info, &buf.buffer, &buf.alloc, &vma_info); // TODO: handle errors here then reallocate buffer assert(VkCheck("CreateBuffer failure: vmaCreateBuffer error", result), "CreateBuffer failure"); + + buf.size = size; } void @@ -703,6 +707,12 @@ ImmSubmit(Vulkan* vk, void delegate() fn) success = VkCheck("ImmSubmit failure: vkQueueSubmit2 error", result); } + if (success) + { + result = vkWaitForFences(vk.device, 1, &vk.imm_fence, true, 999999999); + success = VkCheck("ImmSubmit failure: vkWaitForFences post submission error", result); + } + return success; } @@ -1435,7 +1445,7 @@ SetUniform(Vulkan* vk, GlobalUniforms* globals) VkDescriptorBufferInfo buffer_info = { buffer: vk.global_buf.buffer, - range: VK_WHOLE_SIZE, + range: GlobalUniforms.sizeof, }; VkWriteDescriptorSet write = { @@ -1739,7 +1749,7 @@ WriteConvDescriptor(Vulkan* vk, Buffer* buf) { VkDescriptorBufferInfo buf_info = { buffer: buf.buffer, - range: VK_WHOLE_SIZE, + range: buf.size, }; VkWriteDescriptorSet write = { @@ -1785,7 +1795,7 @@ WriteDescriptors(Vulkan* vk, DescType type, Buffer[] buffers, u32[] indices) foreach(i, buf; buffers) { buffer_info[i].buffer = buf.buffer; - buffer_info[i].range = VK_WHOLE_SIZE; + buffer_info[i].range = buf.size; writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes[i].dstSet = vk.desc_sets[type]; @@ -2800,6 +2810,22 @@ InitInstance(Vulkan* vk) ppEnabledExtensionNames: instance_ext.ptr, }; + VkValidationFeatureEnableEXT validation_enable = VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT; + + VkValidationFeaturesEXT validation_features = { + sType: VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, + enabledValidationFeatureCount: 1, + pEnabledValidationFeatures: &validation_enable, + }; + + debug + { + if (g_VLAYER_SUPPORT && g_DEBUG_PRINTF) + { + instance_info.pNext = &validation_features; + } + } + VkResult result = vkCreateInstance(&instance_info, null, &vk.instance); success = VkCheck("vkCreateInstance failure", result); @@ -2848,14 +2874,19 @@ EnableVLayers(Vulkan* vk) if (g_VLAYER_SUPPORT) { VkDebugUtilsMessengerCreateInfoEXT info = { - sType: VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, - messageSeverity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, - messageType: VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, - pfnUserCallback: cast(PFN_vkDebugUtilsMessengerCallbackEXT)&DebugCallback, - }; + sType: VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, + messageSeverity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + messageType: VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, + pfnUserCallback: cast(PFN_vkDebugUtilsMessengerCallbackEXT)&DebugCallback, + }; + + if (g_DEBUG_PRINTF) + { + info.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; + } VkResult result = vkCreateDebugUtilsMessengerEXT(vk.instance, &info, null, &vk.dbg_msg); if (result != VK_SUCCESS) diff --git a/src/gears/vulkan_logging.d b/src/gears/vulkan_logging.d index ac02998..2accfc5 100644 --- a/src/gears/vulkan_logging.d +++ b/src/gears/vulkan_logging.d @@ -3,7 +3,7 @@ import std.stdio; import vulkan : Vulkan; import std.conv; import std.string; -import core.stdc.string : strlen; +import core.stdc.string : strlen, strcmp; extern(System) VkBool32 DebugCallback( @@ -15,6 +15,9 @@ DebugCallback( { string ms, mt; + const(char)[] msg = callback_data.pMessage[0 .. strlen(callback_data.pMessage)]; + bool debug_printf = strcmp(callback_data.pMessageIdName, "WARNING-DEBUG-PRINTF") == 0; + switch (message_severity) { case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: ms = "VERBOSE"; @@ -60,9 +63,14 @@ DebugCallback( break; } - const char[] msg = callback_data.pMessage[0 .. strlen(callback_data.pMessage)]; - - writefln("[%s: %s]\n%r\n", ms, mt, msg); + if (debug_printf) + { + writefln("SHADER PRINT: %s", msg); + } + else + { + writefln("[%s: %s]\n%r\n", ms, mt, msg); + } return VK_FALSE; } diff --git a/src/shaders/convert.comp.glsl b/src/shaders/convert.comp.glsl index 0d5c687..d30f114 100644 --- a/src/shaders/convert.comp.glsl +++ b/src/shaders/convert.comp.glsl @@ -1,6 +1,7 @@ #version 460 #extension GL_EXT_shader_8bit_storage : require +#extension GL_EXT_debug_printf : require layout (constant_id = 0) const int CHANNELS = 3; @@ -31,23 +32,28 @@ void main() if (CHANNELS == 1) { - uint index = x + (y * PC.x); + uint index = x + y * PC.x; - vec4 col = vec4(vec3(uint(src[index])), 1.0); + vec4 col = vec4(vec3(uint(src[index]) / 255.0), 1.0); + debugPrintfEXT("col = %v4f", col); imageStore(dst, ivec2(x, y), col); } else if (CHANNELS == 2) { - uint index = (x + (y * PC.x)) * 2; + uint index = (x + y * PC.x) * 2; - vec4 col = vec4(uint(src[index]), uint(src[index]), uint(src[index]), uint(src[index+1])); + float f = uint(src[index]) / 255.0; + float a = uint(src[index+1]) / 255.0; + vec4 col = vec4(f, f, f, a); + debugPrintfEXT("col = %v4f", col); imageStore(dst, ivec2(x, y), col); } else if (CHANNELS == 3) { - uint index = (x + (y * PC.x)) * 3; + uint index = (x + y * PC.x) * 3; - vec4 col = vec4(uint(src[index]), uint(src[index+1]), uint(src[index+2]), 1.0); + vec4 col = vec4(uint(src[index]) / 255.0, uint(src[index+1]) / 255.0, uint(src[index+2]) / 255.0, 1.0); + debugPrintfEXT("col = %v4f", col); imageStore(dst, ivec2(x, y), col); } } diff --git a/src/shaders/structures.layout b/src/shaders/structures.layout index 9262ee2..53f68cb 100644 --- a/src/shaders/structures.layout +++ b/src/shaders/structures.layout @@ -1,3 +1,7 @@ +// **************************************************************************** +// **** STRUCTS MUST BE PACKED IN OPTIMAL PACKING ORDER TO MATCH D STRUCTS **** +// **************************************************************************** + layout (set = 0, binding = 0) uniform GlobalUniforms { vec2 res; } G; @@ -13,15 +17,15 @@ layout (set = 0, binding = 3) uniform sampler SamplerNearest; layout (set = 1, binding = 0) uniform texture2D Textures[]; layout (set = 2, binding = 0) uniform Material { + vec4 ambient; + vec4 diffuse; + vec4 specular; uint albedo_texture; uint ambient_texture; uint specular_texture; bool albedo_has_texture; bool ambient_has_texture; bool specular_has_texture; - vec4 ambient; - vec4 diffuse; - vec4 specular; float shininess; } Materials[]; diff --git a/src/shared/util.d b/src/shared/util.d index a518157..a29e7b5 100644 --- a/src/shared/util.d +++ b/src/shared/util.d @@ -377,23 +377,17 @@ struct Vector(T, int S) { T r = 0.0; T g = 0.0; - static if (S > 2) - T b = 0.0; - static if (S > 3) - T a = 0.0; + static if (S > 2) T b = 0.0; + static if (S > 3) T a = 0.0; }; struct { T x; T y; - static if (S > 2) - T z; - static if (S > 3) - T w; + static if (S > 2) T z; + static if (S > 3) T w; }; - static if (S == 4) T[S] v; - float4 simd; } }