gui pipeline setup, misc vulkan work
This commit is contained in:
parent
b89d01984c
commit
82df45e488
Binary file not shown.
BIN
assets/shaders/gui.frag.spv
Normal file
BIN
assets/shaders/gui.frag.spv
Normal file
Binary file not shown.
BIN
assets/shaders/gui.vert.spv
Normal file
BIN
assets/shaders/gui.vert.spv
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -10,6 +10,7 @@ import p = platform;
|
|||||||
alias Shader = VkShaderModule;
|
alias Shader = VkShaderModule;
|
||||||
alias Pipeline = vk.PipelineHandle;
|
alias Pipeline = vk.PipelineHandle;
|
||||||
alias Attribute = VkVertexInputAttributeDescription;
|
alias Attribute = VkVertexInputAttributeDescription;
|
||||||
|
alias Buffer = VkBuffer;
|
||||||
|
|
||||||
enum InputRate : int
|
enum InputRate : int
|
||||||
{
|
{
|
||||||
@ -17,7 +18,9 @@ enum InputRate : int
|
|||||||
Instance = VK_VERTEX_INPUT_RATE_INSTANCE,
|
Instance = VK_VERTEX_INPUT_RATE_INSTANCE,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Format: int
|
alias IR = InputRate;
|
||||||
|
|
||||||
|
enum Format: VkFormat
|
||||||
{
|
{
|
||||||
UINT = VK_FORMAT_R32_UINT,
|
UINT = VK_FORMAT_R32_UINT,
|
||||||
R_F32 = VK_FORMAT_R32_SFLOAT,
|
R_F32 = VK_FORMAT_R32_SFLOAT,
|
||||||
@ -26,6 +29,20 @@ enum Format: int
|
|||||||
RGBA_F32 = VK_FORMAT_R32G32B32A32_SFLOAT,
|
RGBA_F32 = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alias FMT = Format;
|
||||||
|
|
||||||
|
enum BufferType : int
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Vertex = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||||
|
Index = VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||||
|
Uniform = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||||
|
Storage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
|
Staging = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||||
|
}
|
||||||
|
|
||||||
|
alias BT = BufferType;
|
||||||
|
|
||||||
enum PipelineType : int
|
enum PipelineType : int
|
||||||
{
|
{
|
||||||
Graphics,
|
Graphics,
|
||||||
@ -36,8 +53,8 @@ alias PT = PipelineType;
|
|||||||
|
|
||||||
struct GfxPipelineInfo
|
struct GfxPipelineInfo
|
||||||
{
|
{
|
||||||
Shader vertex_shader;
|
string vertex_shader;
|
||||||
Shader frag_shader;
|
string frag_shader;
|
||||||
InputRate input_rate;
|
InputRate input_rate;
|
||||||
u32 input_rate_stride;
|
u32 input_rate_stride;
|
||||||
Attribute[] vertex_attributes;
|
Attribute[] vertex_attributes;
|
||||||
@ -47,8 +64,55 @@ struct Renderer
|
|||||||
{
|
{
|
||||||
vk.Vulkan vulkan;
|
vk.Vulkan vulkan;
|
||||||
p.Window* window;
|
p.Window* window;
|
||||||
|
|
||||||
|
GlobalUniforms globals;
|
||||||
|
UIVertex[] ui_vertex_buf;
|
||||||
|
u32[] ui_index_buf;
|
||||||
|
u32 ui_count;
|
||||||
|
|
||||||
Pipeline triangle_pipeline;
|
Pipeline triangle_pipeline;
|
||||||
Pipeline compute_pipeline;
|
Pipeline compute_pipeline;
|
||||||
|
Pipeline ui_pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GlobalUniforms
|
||||||
|
{
|
||||||
|
Vec2 res;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ShaderUniforms
|
||||||
|
{
|
||||||
|
f32 placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UIVertex
|
||||||
|
{
|
||||||
|
Vec2 p0;
|
||||||
|
Vec2 p1;
|
||||||
|
Vec4 col;
|
||||||
|
u32 texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
Vec3 pos;
|
||||||
|
Vec3 n;
|
||||||
|
Vec2 uv;
|
||||||
|
u32 col;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MeshPart
|
||||||
|
{
|
||||||
|
u32 mat;
|
||||||
|
u32 offset;
|
||||||
|
u32 length;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Model
|
||||||
|
{
|
||||||
|
Buffer vertex_buffer;
|
||||||
|
Buffer index_buffer;
|
||||||
|
MeshPart[] parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer
|
Renderer
|
||||||
@ -60,9 +124,30 @@ Init(p.Window* window)
|
|||||||
Renderer rd = {
|
Renderer rd = {
|
||||||
vulkan: vk_result.value,
|
vulkan: vk_result.value,
|
||||||
window: window,
|
window: window,
|
||||||
|
ui_vertex_buf: vk.GetUIVertexBuffer(&vk_result.value),
|
||||||
|
ui_index_buf: vk.GetUIIndexBuffer(&vk_result.value),
|
||||||
};
|
};
|
||||||
|
|
||||||
rd.triangle_pipeline = BuildGfxPipeline(&rd, "shaders/triangle.vert", "shaders/triangle.frag");
|
GfxPipelineInfo triangle_info = {
|
||||||
|
vertex_shader: "shaders/triangle.vert",
|
||||||
|
frag_shader: "shaders/triangle.frag",
|
||||||
|
};
|
||||||
|
|
||||||
|
GfxPipelineInfo ui_info = {
|
||||||
|
vertex_shader: "shaders/gui.vert",
|
||||||
|
frag_shader: "shaders/gui.frag",
|
||||||
|
input_rate: IR.Instance,
|
||||||
|
input_rate_stride: UIVertex.sizeof,
|
||||||
|
vertex_attributes: [
|
||||||
|
{ binding: 0, location: 0, format: FMT.RG_F32, offset: 0 },
|
||||||
|
{ binding: 0, location: 1, format: FMT.RG_F32, offset: UIVertex.p1.offsetof },
|
||||||
|
{ binding: 0, location: 2, format: FMT.RGBA_F32, offset: UIVertex.col.offsetof },
|
||||||
|
{ binding: 0, location: 3, format: FMT.UINT, offset: UIVertex.texture.offsetof },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
rd.triangle_pipeline = BuildGfxPipeline(&rd, &triangle_info);
|
||||||
|
rd.ui_pipeline = BuildGfxPipeline(&rd, &ui_info);
|
||||||
rd.compute_pipeline = BuildCompPipeline(&rd, "shaders/gradient.comp");
|
rd.compute_pipeline = BuildCompPipeline(&rd, "shaders/gradient.comp");
|
||||||
|
|
||||||
return rd;
|
return rd;
|
||||||
@ -73,16 +158,28 @@ Cycle(Renderer* rd)
|
|||||||
{
|
{
|
||||||
bool success = vk.BeginFrame(&rd.vulkan);
|
bool success = vk.BeginFrame(&rd.vulkan);
|
||||||
|
|
||||||
|
rd.ui_count = 0;
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
vk.Bind(&rd.vulkan, rd.compute_pipeline);
|
vk.Bind(&rd.vulkan, rd.compute_pipeline);
|
||||||
|
|
||||||
|
vk.SetUniform(&rd.vulkan, &rd.globals);
|
||||||
|
|
||||||
|
DrawRect(rd, 150.0, 300.0, 200.0, 350.0, Vec4(r: 0.0, g: 0.0, b: 1.0, a: 1.0));
|
||||||
|
|
||||||
vk.PrepCompute(&rd.vulkan);
|
vk.PrepCompute(&rd.vulkan);
|
||||||
|
|
||||||
vk.Dispatch(&rd.vulkan);
|
vk.Dispatch(&rd.vulkan);
|
||||||
|
|
||||||
vk.BeginRender(&rd.vulkan);
|
vk.BeginRender(&rd.vulkan);
|
||||||
|
|
||||||
|
vk.Bind(&rd.vulkan, rd.ui_pipeline);
|
||||||
|
|
||||||
|
vk.BindUIBuffers(&rd.vulkan);
|
||||||
|
|
||||||
|
vk.DrawIndexed(&rd.vulkan, 6, rd.ui_count);
|
||||||
|
|
||||||
vk.Bind(&rd.vulkan, rd.triangle_pipeline);
|
vk.Bind(&rd.vulkan, rd.triangle_pipeline);
|
||||||
|
|
||||||
vk.Draw(&rd.vulkan, 3, 1);
|
vk.Draw(&rd.vulkan, 3, 1);
|
||||||
@ -93,51 +190,37 @@ Cycle(Renderer* rd)
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipeline
|
void
|
||||||
BuildGfxPipeline(Renderer* rd, string vertex, string fragment)
|
DrawRect(Renderer* rd, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col)
|
||||||
{
|
{
|
||||||
u8[] vert_bytes = ap.LoadAssetData(vertex);
|
rd.ui_vertex_buf[rd.ui_count].p0.x = p0_x;
|
||||||
u8[] frag_bytes = ap.LoadAssetData(fragment);
|
rd.ui_vertex_buf[rd.ui_count].p0.y = p0_y;
|
||||||
|
rd.ui_vertex_buf[rd.ui_count].p1.x = p1_x;
|
||||||
scope(exit)
|
rd.ui_vertex_buf[rd.ui_count].p1.y = p1_y;
|
||||||
{
|
rd.ui_vertex_buf[rd.ui_count].col = col;
|
||||||
ap.UnloadAssetData(vertex);
|
|
||||||
ap.UnloadAssetData(fragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(vert_bytes && frag_bytes, "Unable to load shaders");
|
u32 index_count = rd.ui_count * 6;
|
||||||
|
|
||||||
Result!(Shader) vert_module = vk.BuildShader(&rd.vulkan, vert_bytes);
|
rd.ui_index_buf[index_count+0] = index_count+0;
|
||||||
Result!(Shader) frag_module = vk.BuildShader(&rd.vulkan, frag_bytes);
|
rd.ui_index_buf[index_count+1] = index_count+1;
|
||||||
|
rd.ui_index_buf[index_count+2] = index_count+2;
|
||||||
|
rd.ui_index_buf[index_count+3] = index_count+1;
|
||||||
|
rd.ui_index_buf[index_count+4] = index_count+2;
|
||||||
|
rd.ui_index_buf[index_count+5] = index_count+3;
|
||||||
|
|
||||||
assert(vert_module.ok && frag_module.ok, "Unable to build vulkan shaders");
|
rd.ui_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
scope(exit)
|
Pipeline
|
||||||
{
|
BuildGfxPipeline(Renderer* rd, GfxPipelineInfo* info)
|
||||||
vk.Destroy(&rd.vulkan, vert_module.value);
|
{
|
||||||
vk.Destroy(&rd.vulkan, frag_module.value);
|
return vk.CreateGraphicsPipeline(&rd.vulkan, info);
|
||||||
}
|
|
||||||
|
|
||||||
GfxPipelineInfo pipeline_info = {
|
|
||||||
vertex_shader: vert_module.value,
|
|
||||||
frag_shader: frag_module.value,
|
|
||||||
};
|
|
||||||
|
|
||||||
return vk.CreateGraphicsPipeline(&rd.vulkan, &pipeline_info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipeline
|
Pipeline
|
||||||
BuildCompPipeline(Renderer* rd, string compute)
|
BuildCompPipeline(Renderer* rd, string compute)
|
||||||
{
|
{
|
||||||
u8[] comp_bytes = ap.LoadAssetData(compute);
|
return vk.CreateComputePipeline(&rd.vulkan, compute);
|
||||||
assert(comp_bytes != null, "Unable to load compute shader data");
|
|
||||||
scope(exit) ap.UnloadAssetData(compute);
|
|
||||||
|
|
||||||
Result!(Shader) comp_module = vk.BuildShader(&rd.vulkan, comp_bytes);
|
|
||||||
assert(comp_module.ok, "Unable to build compute shader");
|
|
||||||
scope(exit) vk.Destroy(&rd.vulkan, comp_module.value);
|
|
||||||
|
|
||||||
return vk.CreateComputePipeline(&rd.vulkan, comp_module.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -147,3 +230,5 @@ Destroy(Renderer* rd)
|
|||||||
vk.Destroy(&rd.vulkan, rd.compute_pipeline);
|
vk.Destroy(&rd.vulkan, rd.compute_pipeline);
|
||||||
vk.Destroy(&rd.vulkan);
|
vk.Destroy(&rd.vulkan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,9 +5,10 @@ import std.stdio;
|
|||||||
import std.algorithm.comparison;
|
import std.algorithm.comparison;
|
||||||
import core.stdc.string : strcmp;
|
import core.stdc.string : strcmp;
|
||||||
import std.format : sformat;
|
import std.format : sformat;
|
||||||
import u = util : HashTable, Result, Logf, Log;
|
import u = util : HashTable, Result, Logf, Log, MB;
|
||||||
import a = alloc;
|
import a = alloc;
|
||||||
import p = platform;
|
import p = platform;
|
||||||
|
import ap = assets;
|
||||||
import renderer;
|
import renderer;
|
||||||
import std.math.rounding : Ceil = ceil;
|
import std.math.rounding : Ceil = ceil;
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ enum StepInitialized : u32
|
|||||||
Surface,
|
Surface,
|
||||||
Device,
|
Device,
|
||||||
Vma,
|
Vma,
|
||||||
MappedBuffers, // TODO
|
Buffers,
|
||||||
FrameStructures,
|
FrameStructures,
|
||||||
Swapchain,
|
Swapchain,
|
||||||
DrawImages,
|
DrawImages,
|
||||||
@ -82,7 +83,6 @@ enum DescType : u32
|
|||||||
Shared = 0,
|
Shared = 0,
|
||||||
SampledImage,
|
SampledImage,
|
||||||
Material,
|
Material,
|
||||||
Mesh,
|
|
||||||
|
|
||||||
Max,
|
Max,
|
||||||
}
|
}
|
||||||
@ -106,6 +106,23 @@ struct ImageView
|
|||||||
{
|
{
|
||||||
Image base;
|
Image base;
|
||||||
VkImageView view;
|
VkImageView view;
|
||||||
|
|
||||||
|
alias base this;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MappedBuffer(T)
|
||||||
|
{
|
||||||
|
Buffer base;
|
||||||
|
T[] data;
|
||||||
|
u64 offset;
|
||||||
|
|
||||||
|
alias base this;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Buffer
|
||||||
|
{
|
||||||
|
VkBuffer buffer;
|
||||||
|
VmaAllocation alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DescBindings
|
struct DescBindings
|
||||||
@ -165,7 +182,15 @@ struct Vulkan
|
|||||||
|
|
||||||
VkPipelineLayout pipeline_layout;
|
VkPipelineLayout pipeline_layout;
|
||||||
|
|
||||||
|
MappedBuffer!(u8) transfer_buf;
|
||||||
|
MappedBuffer!(UIVertex) ui_vert_buf;
|
||||||
|
MappedBuffer!(u32) ui_index_buf;
|
||||||
|
MappedBuffer!(GlobalUniforms) global_buf;
|
||||||
|
MappedBuffer!(ShaderUniforms) shader_buf;
|
||||||
|
|
||||||
QueueInfo queues;
|
QueueInfo queues;
|
||||||
|
|
||||||
|
alias queues this;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PipelineHandle
|
struct PipelineHandle
|
||||||
@ -214,6 +239,7 @@ Init(p.Window* window, u64 permanent_mem, u64 frame_mem)
|
|||||||
if (success) success = CreateDrawImages(&vk);
|
if (success) success = CreateDrawImages(&vk);
|
||||||
if (success) success = InitFrameStructures(&vk);
|
if (success) success = InitFrameStructures(&vk);
|
||||||
if (success) success = InitDescriptors(&vk);
|
if (success) success = InitDescriptors(&vk);
|
||||||
|
if (success) InitBuffers(&vk);
|
||||||
|
|
||||||
u.Result!(Vulkan) result = {
|
u.Result!(Vulkan) result = {
|
||||||
ok: success,
|
ok: success,
|
||||||
@ -223,10 +249,106 @@ Init(p.Window* window, u64 permanent_mem, u64 frame_mem)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Buffer
|
||||||
|
CreateBuffer(Vulkan* vk, BufferType type, u64 size, bool host_visible)
|
||||||
|
{
|
||||||
|
assert(type != BT.None, "CreateBuffer failure: type is None");
|
||||||
|
|
||||||
|
VkBufferCreateInfo buffer_info = {
|
||||||
|
sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
usage: type,
|
||||||
|
size: size,
|
||||||
|
};
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo alloc_info = {
|
||||||
|
usage: VMA_MEMORY_USAGE_UNKNOWN,
|
||||||
|
flags: VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (host_visible)
|
||||||
|
{
|
||||||
|
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||||
|
alloc_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer_info.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||||
|
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vk.queues.gfx_index != vk.queues.tfer_index)
|
||||||
|
{
|
||||||
|
buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
buffer_info.queueFamilyIndexCount = 2;
|
||||||
|
buffer_info.pQueueFamilyIndices = cast(const u32*)[vk.queues.gfx_index, vk.queues.tfer_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
VmaAllocationInfo vma_info;
|
||||||
|
Buffer buf;
|
||||||
|
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");
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InitBuffers(Vulkan* vk)
|
||||||
|
{
|
||||||
|
Push(vk, SI.Buffers);
|
||||||
|
|
||||||
|
vk.global_buf = CreateMappedBuffer!(GlobalUniforms)(vk, BT.Uniform, 1);
|
||||||
|
|
||||||
|
u64 transfer_size = MB(64);
|
||||||
|
vk.transfer_buf = CreateMappedBuffer!(u8)(vk, BT.Staging, transfer_size);
|
||||||
|
|
||||||
|
u64 ui_size = MB(30);
|
||||||
|
vk.ui_vert_buf = CreateMappedBuffer!(UIVertex)(vk, BT.Vertex, ui_size / UIVertex.sizeof);
|
||||||
|
vk.ui_index_buf = CreateMappedBuffer!(u32)(vk, BT.Index, ui_size / u32.sizeof);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BindUIBuffers(Vulkan* vk)
|
||||||
|
{
|
||||||
|
VkDeviceSize offset = 0;
|
||||||
|
|
||||||
|
vkCmdBindIndexBuffer(vk.cmds[vk.frame_index], vk.ui_index_buf.buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||||
|
vkCmdBindVertexBuffers(vk.cmds[vk.frame_index], 0, 1, &vk.ui_vert_buf.buffer, &offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
MappedBuffer!(T)
|
||||||
|
CreateMappedBuffer(T)(Vulkan* vk, BufferType type, u64 count)
|
||||||
|
{
|
||||||
|
MappedBuffer!(T) buf;
|
||||||
|
buf.base = CreateBuffer(vk, type, T.sizeof * count, true);
|
||||||
|
buf.data = MapBuffer!(T)(vk, &buf.base, count);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
T[]
|
||||||
|
MapBuffer(T)(Vulkan* vk, Buffer* buffer, u64 count)
|
||||||
|
{
|
||||||
|
void* ptr;
|
||||||
|
vmaMapMemory(vk.vma, buffer.alloc, &ptr);
|
||||||
|
return (cast(T*)ptr)[0 .. count];
|
||||||
|
}
|
||||||
|
|
||||||
VkImage
|
VkImage
|
||||||
CurrentImage(Vulkan* vk)
|
CurrentImage(Vulkan* vk)
|
||||||
{
|
{
|
||||||
return vk.present_images[vk.image_index].base.image;
|
return vk.present_images[vk.image_index].image;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIVertex[]
|
||||||
|
GetUIVertexBuffer(Vulkan* vk)
|
||||||
|
{
|
||||||
|
return vk.ui_vert_buf.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32[]
|
||||||
|
GetUIIndexBuffer(Vulkan* vk)
|
||||||
|
{
|
||||||
|
return vk.ui_index_buf.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -279,8 +401,8 @@ void
|
|||||||
BeginRender(Vulkan* vk)
|
BeginRender(Vulkan* vk)
|
||||||
{
|
{
|
||||||
// TODO: probably get rid of these
|
// TODO: probably get rid of these
|
||||||
Transition(vk.cmds[vk.frame_index], &vk.draw_image.base, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
Transition(vk.cmds[vk.frame_index], &vk.draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
Transition(vk.cmds[vk.frame_index], &vk.depth_image.base, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
|
Transition(vk.cmds[vk.frame_index], &vk.depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
VkImage image = CurrentImage(vk);
|
VkImage image = CurrentImage(vk);
|
||||||
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
@ -288,7 +410,7 @@ BeginRender(Vulkan* vk)
|
|||||||
VkRenderingAttachmentInfo col_attach = {
|
VkRenderingAttachmentInfo col_attach = {
|
||||||
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
imageView: vk.draw_image.view,
|
imageView: vk.draw_image.view,
|
||||||
imageLayout: vk.draw_image.base.layout,
|
imageLayout: vk.draw_image.layout,
|
||||||
loadOp: VK_ATTACHMENT_LOAD_OP_LOAD, // CLEAR instead of LOAD if wanting to clear colors, also clearColor value (or whatever)
|
loadOp: VK_ATTACHMENT_LOAD_OP_LOAD, // CLEAR instead of LOAD if wanting to clear colors, also clearColor value (or whatever)
|
||||||
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
};
|
};
|
||||||
@ -296,7 +418,7 @@ BeginRender(Vulkan* vk)
|
|||||||
VkRenderingAttachmentInfo depth_attach = {
|
VkRenderingAttachmentInfo depth_attach = {
|
||||||
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
sType: VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
imageView: vk.depth_image.view,
|
imageView: vk.depth_image.view,
|
||||||
imageLayout: vk.depth_image.base.layout,
|
imageLayout: vk.depth_image.layout,
|
||||||
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
|
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
};
|
};
|
||||||
@ -345,7 +467,7 @@ FinishFrame(Vulkan* vk)
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Find out how to copy from same dimension images
|
// TODO: Find out how to copy from same dimension images
|
||||||
Copy(vk.cmds[vk.frame_index], vk.draw_image.base.image, image, extent, extent);
|
Copy(vk.cmds[vk.frame_index], vk.draw_image.image, image, extent, extent);
|
||||||
|
|
||||||
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
Transition(vk.cmds[vk.frame_index], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
|
|
||||||
@ -424,6 +546,135 @@ DrawIndexed(Vulkan* vk, u32 index_count, u32 instance_count)
|
|||||||
vkCmdDrawIndexed(vk.cmds[vk.frame_index], index_count, instance_count, 0, 0, 0);
|
vkCmdDrawIndexed(vk.cmds[vk.frame_index], index_count, instance_count, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ImmSubmit(Vulkan* vk, void delegate() fn)
|
||||||
|
{
|
||||||
|
VkResult result = vkWaitForFences(vk.device, 1, &vk.imm_fence, true, 999999999);
|
||||||
|
bool success = VkCheck("ImmSubmit failure: vkWaitForFences error", result);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
result = vkResetFences(vk.device, 1, &vk.imm_fence);
|
||||||
|
success = VkCheck("ImmSubmit failure: vkResetFences error", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
result = vkResetCommandBuffer(vk.imm_cmd, 0);
|
||||||
|
success = VkCheck("ImmSubmit failure: vkResetCommandBuffer error", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool imm_started;
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
VkCommandBufferBeginInfo cmd_info = {
|
||||||
|
sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||||
|
flags: VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
result = vkBeginCommandBuffer(vk.imm_cmd, &cmd_info);
|
||||||
|
imm_started = success = VkCheck("ImmSubmit failure: vkBeginCommandBuffer error", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
fn();
|
||||||
|
|
||||||
|
result = vkEndCommandBuffer(vk.imm_cmd);
|
||||||
|
success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
VkCommandBufferSubmitInfo cmd_info = {
|
||||||
|
sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
|
||||||
|
commandBuffer: vk.imm_cmd,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkSubmitInfo2 submit_info = {
|
||||||
|
sType: VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
|
||||||
|
commandBufferInfoCount: 1,
|
||||||
|
pCommandBufferInfos: &cmd_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
result = vkQueueSubmit2(vk.tfer_queue, 1, &submit_info, vk.imm_fence);
|
||||||
|
success = VkCheck("ImmSubmit failure: vkQueueSubmit2 error", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Transfer(Vulkan* vk, Buffer* buf, u8[] data)
|
||||||
|
{
|
||||||
|
u64 copied = 0;
|
||||||
|
while(copied != data.length)
|
||||||
|
{
|
||||||
|
u64 transfer_length = cast(u64)vk.transfer_buf.data.length;
|
||||||
|
u64 data_length = cast(u64)data.length - copied;
|
||||||
|
u64 copy_length = transfer_length > data_length ? data_length : transfer_length;
|
||||||
|
|
||||||
|
vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length];
|
||||||
|
|
||||||
|
auto fn = delegate()
|
||||||
|
{
|
||||||
|
VkBufferCopy copy = {
|
||||||
|
srcOffset: 0,
|
||||||
|
dstOffset: copied,
|
||||||
|
size: copy_length,
|
||||||
|
};
|
||||||
|
|
||||||
|
vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, ©);
|
||||||
|
};
|
||||||
|
|
||||||
|
ImmSubmit(vk, fn);
|
||||||
|
|
||||||
|
copied += copy_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Transfer(Vulkan* vk, Image* image, u8[] data, u32 w, u32 h)
|
||||||
|
{
|
||||||
|
u64 copied = 0;
|
||||||
|
while(copied != data.length)
|
||||||
|
{
|
||||||
|
u64 transfer_length = cast(u64)vk.transfer_buf.data.length;
|
||||||
|
u64 data_length = cast(u64)data.length - copied;
|
||||||
|
u64 copy_length = transfer_length > data_length ? data_length : transfer_length;
|
||||||
|
|
||||||
|
vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length];
|
||||||
|
|
||||||
|
auto fn = delegate()
|
||||||
|
{
|
||||||
|
VkBufferImageCopy copy = {
|
||||||
|
bufferRowLength: w,
|
||||||
|
bufferImageHeight: h,
|
||||||
|
imageSubresource: {
|
||||||
|
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
layerCount: 1,
|
||||||
|
},
|
||||||
|
imageExtent: {
|
||||||
|
width: w,
|
||||||
|
height: h,
|
||||||
|
depth: 1,
|
||||||
|
},
|
||||||
|
bufferOffset: copied,
|
||||||
|
};
|
||||||
|
|
||||||
|
Transition(vk.imm_cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
|
vkCmdCopyBufferToImage(vk.imm_cmd, vk.transfer_buf.buffer, image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
||||||
|
|
||||||
|
Transition(vk.imm_cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
};
|
||||||
|
|
||||||
|
ImmSubmit(vk, fn);
|
||||||
|
|
||||||
|
copied += copy_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma(inline): void
|
pragma(inline): void
|
||||||
Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext)
|
Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext)
|
||||||
{
|
{
|
||||||
@ -532,8 +783,8 @@ Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkI
|
|||||||
pragma(inline): void
|
pragma(inline): void
|
||||||
Transition(VkCommandBuffer cmd, ImageView* view, VkImageLayout new_layout)
|
Transition(VkCommandBuffer cmd, ImageView* view, VkImageLayout new_layout)
|
||||||
{
|
{
|
||||||
Transition(cmd, view.base.image, view.base.layout, new_layout);
|
Transition(cmd, view.image, view.layout, new_layout);
|
||||||
view.base.layout = new_layout;
|
view.layout = new_layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma(inline): void
|
pragma(inline): void
|
||||||
@ -606,8 +857,8 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
|||||||
VkPipelineRenderingCreateInfo rendering_info = {
|
VkPipelineRenderingCreateInfo rendering_info = {
|
||||||
sType: VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||||
colorAttachmentCount: 1,
|
colorAttachmentCount: 1,
|
||||||
pColorAttachmentFormats: &vk.draw_image.base.format,
|
pColorAttachmentFormats: &vk.draw_image.format,
|
||||||
depthAttachmentFormat: vk.depth_image.base.format,
|
depthAttachmentFormat: vk.depth_image.format,
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState blend_state = {
|
VkPipelineColorBlendAttachmentState blend_state = {
|
||||||
@ -656,8 +907,30 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
__traits(getMember, shader_info.ptr + 0, "module") = build_info.vertex_shader;
|
u8[] vert_bytes = ap.LoadAssetData(build_info.vertex_shader);
|
||||||
__traits(getMember, shader_info.ptr + 1, "module") = build_info.frag_shader;
|
u8[] frag_bytes = ap.LoadAssetData(build_info.frag_shader);
|
||||||
|
|
||||||
|
scope(exit)
|
||||||
|
{
|
||||||
|
ap.UnloadAssetData(build_info.vertex_shader);
|
||||||
|
ap.UnloadAssetData(build_info.frag_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(vert_bytes && frag_bytes, "Unable to load shaders");
|
||||||
|
|
||||||
|
Result!(Shader) vert_module = BuildShader(vk, vert_bytes);
|
||||||
|
Result!(Shader) frag_module = BuildShader(vk, frag_bytes);
|
||||||
|
|
||||||
|
assert(vert_module.ok && frag_module.ok, "Unable to build vulkan shaders");
|
||||||
|
|
||||||
|
scope(exit)
|
||||||
|
{
|
||||||
|
Destroy(vk, vert_module.value);
|
||||||
|
Destroy(vk, frag_module.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
__traits(getMember, shader_info.ptr + 0, "module") = vert_module.value;
|
||||||
|
__traits(getMember, shader_info.ptr + 1, "module") = frag_module.value;
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo create_info = {
|
VkGraphicsPipelineCreateInfo create_info = {
|
||||||
sType: VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
@ -683,9 +956,8 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Pipeline
|
Pipeline
|
||||||
CreateComputePipeline(Vulkan* vk, Shader shader)
|
CreateComputePipeline(Vulkan* vk, string shader)
|
||||||
{
|
{
|
||||||
VkComputePipelineCreateInfo info = {
|
VkComputePipelineCreateInfo info = {
|
||||||
sType: VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||||
@ -697,7 +969,15 @@ CreateComputePipeline(Vulkan* vk, Shader shader)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
__traits(getMember, &info.stage, "module") = shader;
|
u8[] comp_bytes = ap.LoadAssetData(shader);
|
||||||
|
assert(comp_bytes != null, "Unable to load compute shader data");
|
||||||
|
scope(exit) ap.UnloadAssetData(shader);
|
||||||
|
|
||||||
|
Result!(Shader) comp_module = BuildShader(vk, comp_bytes);
|
||||||
|
assert(comp_module.ok, "Unable to build compute shader");
|
||||||
|
scope(exit) Destroy(vk, comp_module.value);
|
||||||
|
|
||||||
|
__traits(getMember, &info.stage, "module") = comp_module.value;
|
||||||
|
|
||||||
PipelineHandle pipeline = { type: VK_PIPELINE_BIND_POINT_COMPUTE };
|
PipelineHandle pipeline = { type: VK_PIPELINE_BIND_POINT_COMPUTE };
|
||||||
VkResult result = vkCreateComputePipelines(vk.device, null, 1, &info, null, &pipeline.handle);
|
VkResult result = vkCreateComputePipelines(vk.device, null, 1, &info, null, &pipeline.handle);
|
||||||
@ -706,6 +986,31 @@ CreateComputePipeline(Vulkan* vk, Shader shader)
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetUniform(Vulkan* vk, GlobalUniforms* globals)
|
||||||
|
{
|
||||||
|
globals.res.x = vk.swapchain_extent.width;
|
||||||
|
globals.res.y = vk.swapchain_extent.height;
|
||||||
|
|
||||||
|
vk.global_buf.data[0] = *globals;
|
||||||
|
|
||||||
|
VkDescriptorBufferInfo buffer_info = {
|
||||||
|
buffer: vk.global_buf.buffer,
|
||||||
|
range: VK_WHOLE_SIZE,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkWriteDescriptorSet write = {
|
||||||
|
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
dstSet: vk.desc_sets[DT.Shared],
|
||||||
|
dstBinding: 0,
|
||||||
|
descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
|
descriptorCount: 1,
|
||||||
|
pBufferInfo: &buffer_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Destroy(Vulkan* vk, Shader shader)
|
Destroy(Vulkan* vk, Shader shader)
|
||||||
{
|
{
|
||||||
@ -757,12 +1062,28 @@ Destroy(Vulkan* vk)
|
|||||||
case SI.Descriptors:
|
case SI.Descriptors:
|
||||||
Destroy(vk.desc_pool, vk.desc_layouts, vk.pipeline_layout, vk.nearest_sampler, vk.device);
|
Destroy(vk.desc_pool, vk.desc_layouts, vk.pipeline_layout, vk.nearest_sampler, vk.device);
|
||||||
break;
|
break;
|
||||||
|
case SI.Buffers:
|
||||||
|
Destroy(vk, &vk.transfer_buf);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Destroy(T)(Vulkan* vk, MappedBuffer!(T)* buf)
|
||||||
|
{
|
||||||
|
vmaUnmapMemory(vk.vma, buf.alloc);
|
||||||
|
Destroy(vk, &buf.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Destroy(Vulkan* vk, Buffer* buf)
|
||||||
|
{
|
||||||
|
vmaDestroyBuffer(vk.vma, buf.buffer, buf.alloc);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InitDescriptors(Vulkan* vk)
|
InitDescriptors(Vulkan* vk)
|
||||||
{
|
{
|
||||||
@ -824,7 +1145,6 @@ InitDescriptors(Vulkan* vk)
|
|||||||
VkDescriptorType[DT.max] type_lookup = [
|
VkDescriptorType[DT.max] type_lookup = [
|
||||||
DT.SampledImage: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
DT.SampledImage: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
DT.Material: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
DT.Material: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
DT.Mesh: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
VkDescriptorBindingFlags bindless_flag = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
|
VkDescriptorBindingFlags bindless_flag = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
|
||||||
@ -1145,14 +1465,14 @@ CreateDrawImages(Vulkan* vk)
|
|||||||
format: draw_format,
|
format: draw_format,
|
||||||
};
|
};
|
||||||
|
|
||||||
VkResult result = vmaCreateImage(vk.vma, &image_info, &alloc_info, &vk.draw_image.base.image, &vk.draw_image.base.alloc, null);
|
VkResult result = vmaCreateImage(vk.vma, &image_info, &alloc_info, &vk.draw_image.image, &vk.draw_image.alloc, null);
|
||||||
success = VkCheck("vmaCreateImage failure", result);
|
success = VkCheck("vmaCreateImage failure", result);
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
VkImageViewCreateInfo view_info = {
|
VkImageViewCreateInfo view_info = {
|
||||||
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
image: vk.draw_image.base.image,
|
image: vk.draw_image.image,
|
||||||
format: draw_format,
|
format: draw_format,
|
||||||
viewType: VK_IMAGE_VIEW_TYPE_2D,
|
viewType: VK_IMAGE_VIEW_TYPE_2D,
|
||||||
subresourceRange: {
|
subresourceRange: {
|
||||||
@ -1182,7 +1502,7 @@ CreateDrawImages(Vulkan* vk)
|
|||||||
extent: vk.swapchain_extent,
|
extent: vk.swapchain_extent,
|
||||||
};
|
};
|
||||||
|
|
||||||
result = vmaCreateImage(vk.vma, &depth_image_info, &alloc_info, &vk.depth_image.base.image, &vk.depth_image.base.alloc, null);
|
result = vmaCreateImage(vk.vma, &depth_image_info, &alloc_info, &vk.depth_image.image, &vk.depth_image.alloc, null);
|
||||||
success = VkCheck("vmaCreateImage failure", result);
|
success = VkCheck("vmaCreateImage failure", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1190,7 +1510,7 @@ CreateDrawImages(Vulkan* vk)
|
|||||||
{
|
{
|
||||||
VkImageViewCreateInfo depth_view_info = {
|
VkImageViewCreateInfo depth_view_info = {
|
||||||
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||||
image: vk.depth_image.base.image,
|
image: vk.depth_image.image,
|
||||||
viewType: VK_IMAGE_VIEW_TYPE_2D,
|
viewType: VK_IMAGE_VIEW_TYPE_2D,
|
||||||
format: depth_format,
|
format: depth_format,
|
||||||
subresourceRange: {
|
subresourceRange: {
|
||||||
@ -1206,10 +1526,10 @@ CreateDrawImages(Vulkan* vk)
|
|||||||
success = VkCheck("vmaCreateImageView failure", result);
|
success = VkCheck("vmaCreateImageView failure", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
vk.draw_image.base.format = draw_format;
|
vk.draw_image.format = draw_format;
|
||||||
vk.draw_image.base.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
vk.draw_image.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
vk.depth_image.base.format = depth_format;
|
vk.depth_image.format = depth_format;
|
||||||
vk.depth_image.base.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
vk.depth_image.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -1310,7 +1630,7 @@ CreateSwapchain(Vulkan* vk)
|
|||||||
|
|
||||||
foreach(i, image; vk.present_images)
|
foreach(i, image; vk.present_images)
|
||||||
{
|
{
|
||||||
vk.present_images[i].base.image = images[i];
|
vk.present_images[i].image = images[i];
|
||||||
view_info.image = images[i];
|
view_info.image = images[i];
|
||||||
view_info.format = vk.surface_format.format;
|
view_info.format = vk.surface_format.format;
|
||||||
|
|
||||||
@ -1771,9 +2091,9 @@ Destroy(ImageView* view, VkDevice device, VmaAllocator vma)
|
|||||||
vkDestroyImageView(device, view.view, null);
|
vkDestroyImageView(device, view.view, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view.base.image)
|
if (view.image)
|
||||||
{
|
{
|
||||||
vmaDestroyImage(vma, view.base.image, view.base.alloc);
|
vmaDestroyImage(vma, view.image, view.alloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,19 +26,25 @@ static immutable u64[] MODEL_HASHES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
static immutable string[] SHADER_FILES = [
|
static immutable string[] SHADER_FILES = [
|
||||||
|
"shaders/gui.frag.spv",
|
||||||
"shaders/triangle.vert.spv",
|
"shaders/triangle.vert.spv",
|
||||||
|
"shaders/gui.vert.spv",
|
||||||
"shaders/gradient.comp.spv",
|
"shaders/gradient.comp.spv",
|
||||||
"shaders/triangle.frag.spv",
|
"shaders/triangle.frag.spv",
|
||||||
];
|
];
|
||||||
|
|
||||||
static immutable string[] SHADER_NAMES = [
|
static immutable string[] SHADER_NAMES = [
|
||||||
|
"shaders/gui.frag",
|
||||||
"shaders/triangle.vert",
|
"shaders/triangle.vert",
|
||||||
|
"shaders/gui.vert",
|
||||||
"shaders/gradient.comp",
|
"shaders/gradient.comp",
|
||||||
"shaders/triangle.frag",
|
"shaders/triangle.frag",
|
||||||
];
|
];
|
||||||
|
|
||||||
static immutable u64[] SHADER_HASHES = [
|
static immutable u64[] SHADER_HASHES = [
|
||||||
|
15780387719315455808,
|
||||||
8769314645675479020,
|
8769314645675479020,
|
||||||
|
14797956403837654625,
|
||||||
16130483095684998267,
|
16130483095684998267,
|
||||||
6282520872716708711,
|
6282520872716708711,
|
||||||
];
|
];
|
||||||
|
|||||||
18
src/shaders/gui.frag.glsl
Normal file
18
src/shaders/gui.frag.glsl
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#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 vec4 in_color;
|
||||||
|
layout (location = 1) in vec2 in_uv;
|
||||||
|
layout (location = 2) flat in uint in_image;
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 out_frag_col;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
out_frag_col = in_color;
|
||||||
|
}
|
||||||
46
src/shaders/gui.vert.glsl
Normal file
46
src/shaders/gui.vert.glsl
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#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 vec2 in_gui_pos_0;
|
||||||
|
layout (location = 1) in vec2 in_gui_pos_1;
|
||||||
|
layout (location = 2) in vec4 in_col;
|
||||||
|
layout (location = 3) in uint in_image;
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 out_color;
|
||||||
|
layout (location = 1) out vec2 out_uv;
|
||||||
|
layout (location = 2) out uint out_image;
|
||||||
|
|
||||||
|
vec2 uvs[] = {
|
||||||
|
vec2(0.0, 1.0),
|
||||||
|
vec2(0.0, 0.0),
|
||||||
|
vec2(1.0, 1.0),
|
||||||
|
vec2(1.0, 0.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
vec2 rotate(vec2 coords, float theta)
|
||||||
|
{
|
||||||
|
return mat2(cos(theta), sin(theta), -sin(theta), cos(theta)) * coords;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Draw with 6 indices, gl_VertexIndex will use the appropriate index, iterates through 0-3 and not 0-5
|
||||||
|
vec2 dst_pos = gl_VertexIndex == 0 ? vec2(in_gui_pos_0.x, in_gui_pos_1.y) :
|
||||||
|
gl_VertexIndex == 1 ? vec2(in_gui_pos_0.x, in_gui_pos_0.y) :
|
||||||
|
gl_VertexIndex == 2 ? vec2(in_gui_pos_1.x, in_gui_pos_1.y) :
|
||||||
|
gl_VertexIndex == 3 ? vec2(in_gui_pos_1.x, in_gui_pos_0.y) : vec2(0.0, 0.0);
|
||||||
|
|
||||||
|
out_uv = uvs[gl_VertexIndex];
|
||||||
|
out_color = in_col;
|
||||||
|
out_image = in_image;
|
||||||
|
|
||||||
|
gl_Position = vec4(2 * dst_pos.x / G.res.x - 1,
|
||||||
|
2 * dst_pos.y / G.res.y - 1,
|
||||||
|
0,
|
||||||
|
1);
|
||||||
|
}
|
||||||
@ -1,11 +1,3 @@
|
|||||||
struct Vertex {
|
|
||||||
vec4 pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout (buffer_reference, std430) readonly buffer VertexBuffer {
|
|
||||||
Vertex vertices[];
|
|
||||||
};
|
|
||||||
|
|
||||||
layout (set = 0, binding = 0) uniform GlobalUniforms {
|
layout (set = 0, binding = 0) uniform GlobalUniforms {
|
||||||
vec2 res;
|
vec2 res;
|
||||||
} G;
|
} G;
|
||||||
@ -24,10 +16,6 @@ layout (set = 2, binding = 0) uniform Material {
|
|||||||
float placeholder;
|
float placeholder;
|
||||||
} Materials[];
|
} Materials[];
|
||||||
|
|
||||||
layout (set = 3, binding = 0) uniform Mesh {
|
|
||||||
VertexBuffer buf;
|
|
||||||
} Meshes[];
|
|
||||||
|
|
||||||
layout (push_constant) uniform Constants {
|
layout (push_constant) uniform Constants {
|
||||||
float placeholder;
|
float placeholder;
|
||||||
} PC;
|
} PC;
|
||||||
|
|||||||
@ -41,6 +41,12 @@ struct ModelMeta
|
|||||||
u64 index_count;
|
u64 index_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TexData
|
||||||
|
{
|
||||||
|
void* data;
|
||||||
|
TexMeta meta;
|
||||||
|
}
|
||||||
|
|
||||||
struct TexMeta
|
struct TexMeta
|
||||||
{
|
{
|
||||||
u32 w;
|
u32 w;
|
||||||
@ -146,3 +152,5 @@ UnloadAssetData(string name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import includes;
|
|||||||
import std.stdio;
|
import std.stdio;
|
||||||
import core.stdc.string : memset;
|
import core.stdc.string : memset;
|
||||||
import a = alloc;
|
import a = alloc;
|
||||||
|
import core.simd;
|
||||||
|
|
||||||
void
|
void
|
||||||
Logf(Args...)(string fmt, Args args)
|
Logf(Args...)(string fmt, Args args)
|
||||||
@ -313,3 +314,45 @@ Hash(string str)
|
|||||||
{
|
{
|
||||||
return xxh3_64bits_withSeed(str.ptr, str.length, HASH_SEED);
|
return xxh3_64bits_withSeed(str.ptr, str.length, HASH_SEED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Matrix(T, int S)
|
||||||
|
{
|
||||||
|
T[S][S] m;
|
||||||
|
alias m this;
|
||||||
|
}
|
||||||
|
|
||||||
|
alias Mat2 = Matrix!(f32, 2);
|
||||||
|
alias Mat3 = Matrix!(f32, 3);
|
||||||
|
alias Mat4 = Matrix!(f32, 4);
|
||||||
|
|
||||||
|
struct Vector(T, int S)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
T r = 0.0;
|
||||||
|
T g = 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 == 4)
|
||||||
|
T[S] v;
|
||||||
|
float4 simd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alias Vec2 = Vector!(f32, 2);
|
||||||
|
alias Vec3 = Vector!(f32, 3);
|
||||||
|
alias Vec4 = Vector!(f32, 4);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user