commit before deleting shaders
This commit is contained in:
parent
194149f8dd
commit
92980fba0d
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
131
src/gears/game.d
131
src/gears/game.d
@ -61,33 +61,18 @@ struct Game
|
|||||||
|
|
||||||
PlatformWindow* window;
|
PlatformWindow* window;
|
||||||
|
|
||||||
Pipeline pbr_pipeline;
|
|
||||||
Pipeline triangle_pipeline;
|
|
||||||
Pipeline compute_pipeline;
|
|
||||||
Pipeline ui_pipeline;
|
Pipeline ui_pipeline;
|
||||||
Pipeline oit_pipeline;
|
|
||||||
|
|
||||||
UIVertex[] ui_vertex_buf;
|
UIVertex[] ui_vertex_buf;
|
||||||
u32[] ui_index_buf;
|
u32[] ui_index_buf;
|
||||||
u32 ui_count;
|
u32 ui_count;
|
||||||
|
|
||||||
ImageView draw_image, depth_image;
|
ImageView draw_image, depth_image;
|
||||||
ImageView aux_image;
|
|
||||||
|
|
||||||
GlobalUniforms globals;
|
GlobalUniforms globals;
|
||||||
PushConst pc;
|
PushConst pc;
|
||||||
|
|
||||||
Timer timer;
|
Timer timer;
|
||||||
|
|
||||||
Camera camera;
|
|
||||||
|
|
||||||
Model tree;
|
|
||||||
Model rock;
|
|
||||||
Model magic_rock;
|
|
||||||
Model log;
|
|
||||||
Model stump;
|
|
||||||
|
|
||||||
SLList!(Model) models;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Game
|
Game
|
||||||
@ -110,11 +95,6 @@ InitGame(PlatformWindow* window)
|
|||||||
|
|
||||||
CreateImageView(&g.rd, &g.aux_image, ext.x, ext.y, FMT.R_U32, IU.Storage);
|
CreateImageView(&g.rd, &g.aux_image, ext.x, ext.y, FMT.R_U32, IU.Storage);
|
||||||
|
|
||||||
GfxPipelineInfo triangle_info = {
|
|
||||||
vertex_shader: "shaders/triangle.vert.spv",
|
|
||||||
frag_shader: "shaders/triangle.frag.spv",
|
|
||||||
};
|
|
||||||
|
|
||||||
GfxPipelineInfo ui_info = {
|
GfxPipelineInfo ui_info = {
|
||||||
vertex_shader: "shaders/gui.vert.spv",
|
vertex_shader: "shaders/gui.vert.spv",
|
||||||
frag_shader: "shaders/gui.frag.spv",
|
frag_shader: "shaders/gui.frag.spv",
|
||||||
@ -128,39 +108,7 @@ InitGame(PlatformWindow* window)
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
GfxPipelineInfo pbr_info = {
|
|
||||||
vertex_shader: "shaders/pbr.vert.spv",
|
|
||||||
frag_shader: "shaders/pbr.frag.spv",
|
|
||||||
input_rate_stride: Vertex.sizeof,
|
|
||||||
vertex_attributes: [
|
|
||||||
{ binding: 0, location: 0, format: FMT.RGBA_F32, offset: 0 },
|
|
||||||
{ binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.tangent.offsetof },
|
|
||||||
{ binding: 0, location: 2, format: FMT.RGB_F32, offset: Vertex.pos.offsetof },
|
|
||||||
{ binding: 0, location: 3, format: FMT.RGB_F32, offset: Vertex.normal.offsetof },
|
|
||||||
{ binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.uv.offsetof },
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
GfxPipelineInfo oit_info = {
|
|
||||||
vertex_shader: "shaders/full_screen_triangle.vert.spv",
|
|
||||||
frag_shader: "shaders/oit.frag.spv",
|
|
||||||
};
|
|
||||||
|
|
||||||
CompPipelineInfo gradient_info = {
|
|
||||||
shader: "shaders/gradient.comp.spv",
|
|
||||||
};
|
|
||||||
|
|
||||||
g.pbr_pipeline = CreateGraphicsPipeline(&g.rd, &pbr_info);
|
|
||||||
g.triangle_pipeline = CreateGraphicsPipeline(&g.rd, &triangle_info);
|
|
||||||
g.ui_pipeline = CreateGraphicsPipeline(&g.rd, &ui_info);
|
g.ui_pipeline = CreateGraphicsPipeline(&g.rd, &ui_info);
|
||||||
g.oit_pipeline = CreateGraphicsPipeline(&g.rd, &oit_info);
|
|
||||||
g.compute_pipeline = CreateComputePipeline(&g.rd, &gradient_info);
|
|
||||||
|
|
||||||
g.rock = LoadModel(&g, "models/BigRock01.m3d");
|
|
||||||
g.tree = LoadModel(&g, "models/Tree01.m3d");
|
|
||||||
g.magic_rock = LoadModel(&g, "models/MagicRock01.m3d");
|
|
||||||
g.log = LoadModel(&g, "models/Log01.m3d");
|
|
||||||
g.stump = LoadModel(&g, "models/Stump01.m3d");
|
|
||||||
|
|
||||||
assert(g.aux_image.view != null);
|
assert(g.aux_image.view != null);
|
||||||
|
|
||||||
@ -184,50 +132,6 @@ Copy(Model* dst, Model* src)
|
|||||||
void
|
void
|
||||||
ProcessInputs(Game* g, Camera* cam)
|
ProcessInputs(Game* g, Camera* cam)
|
||||||
{
|
{
|
||||||
foreach(i; 0 .. g.window.inputs.count)
|
|
||||||
{
|
|
||||||
InputEvent event = g.window.inputs.events[i];
|
|
||||||
switch(event.key)
|
|
||||||
{
|
|
||||||
case Input.One:
|
|
||||||
{
|
|
||||||
Node!(Model)* node = Alloc!(Node!(Model));
|
|
||||||
Copy(&node.value, &g.tree);
|
|
||||||
node.value.pos = cam.pos;
|
|
||||||
PushFront(&g.models, node, null);
|
|
||||||
} break;
|
|
||||||
case Input.Two:
|
|
||||||
{
|
|
||||||
Node!(Model)* node = Alloc!(Node!(Model));
|
|
||||||
Copy(&node.value, &g.rock);
|
|
||||||
node.value.pos = cam.pos;
|
|
||||||
PushFront(&g.models, node, null);
|
|
||||||
} break;
|
|
||||||
case Input.Three:
|
|
||||||
{
|
|
||||||
Node!(Model)* node = Alloc!(Node!(Model));
|
|
||||||
Copy(&node.value, &g.magic_rock);
|
|
||||||
node.value.pos = cam.pos;
|
|
||||||
PushFront(&g.models, node, null);
|
|
||||||
} break;
|
|
||||||
case Input.Four:
|
|
||||||
{
|
|
||||||
Node!(Model)* node = Alloc!(Node!(Model));
|
|
||||||
Copy(&node.value, &g.log);
|
|
||||||
node.value.pos = cam.pos;
|
|
||||||
PushFront(&g.models, node, null);
|
|
||||||
} break;
|
|
||||||
case Input.Five:
|
|
||||||
{
|
|
||||||
Node!(Model)* node = Alloc!(Node!(Model));
|
|
||||||
Copy(&node.value, &g.stump);
|
|
||||||
node.value.pos = cam.pos;
|
|
||||||
PushFront(&g.models, node, null);
|
|
||||||
} break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleInputs(cam, &g.window.inputs);
|
HandleInputs(cam, &g.window.inputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,30 +180,6 @@ Cycle(Game* g)
|
|||||||
|
|
||||||
BindUIBuffers(&g.rd);
|
BindUIBuffers(&g.rd);
|
||||||
|
|
||||||
Bind(&g.rd, &g.triangle_pipeline);
|
|
||||||
|
|
||||||
Bind(&g.rd, &g.pbr_pipeline);
|
|
||||||
|
|
||||||
g.pc.model_matrix = Mat4Identity();
|
|
||||||
|
|
||||||
Node!(Model)* model = g.models.first;
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
if (model == null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawModel(g, &model.value);
|
|
||||||
model = model.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageBarrier(&g.rd);
|
|
||||||
|
|
||||||
Bind(&g.rd, &g.oit_pipeline);
|
|
||||||
|
|
||||||
Draw(&g.rd, 3, 1);
|
|
||||||
|
|
||||||
FinishRendering(&g.rd);
|
FinishRendering(&g.rd);
|
||||||
|
|
||||||
//ImageBarrier(&g.rd);
|
//ImageBarrier(&g.rd);
|
||||||
@ -330,17 +210,8 @@ void
|
|||||||
Destroy(Game* g)
|
Destroy(Game* g)
|
||||||
{
|
{
|
||||||
WaitIdle(&g.rd);
|
WaitIdle(&g.rd);
|
||||||
Destroy(&g.rd, &g.pbr_pipeline);
|
|
||||||
Destroy(&g.rd, &g.triangle_pipeline);
|
|
||||||
Destroy(&g.rd, &g.ui_pipeline);
|
Destroy(&g.rd, &g.ui_pipeline);
|
||||||
Destroy(&g.rd, &g.compute_pipeline);
|
|
||||||
|
|
||||||
Destroy(&g.rd, &g.rock);
|
|
||||||
Destroy(&g.rd, &g.tree);
|
|
||||||
Destroy(&g.rd, &g.magic_rock);
|
|
||||||
Destroy(&g.rd, &g.log);
|
|
||||||
Destroy(&g.rd, &g.stump);
|
|
||||||
|
|
||||||
Destroy(&g.rd);
|
Destroy(&g.rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,15 +17,26 @@ import math;
|
|||||||
alias InitRenderer = Init;
|
alias InitRenderer = Init;
|
||||||
alias Renderer = Vulkan;
|
alias Renderer = Vulkan;
|
||||||
alias Shader = VkShaderModule;
|
alias Shader = VkShaderModule;
|
||||||
alias Pipeline = PipelineHandle;
|
alias Pipeline = u32;
|
||||||
alias Attribute = VkVertexInputAttributeDescription;
|
alias Attribute = VkVertexInputAttributeDescription;
|
||||||
alias SpecEntry = VkSpecializationMapEntry;
|
alias SpecEntry = VkSpecializationMapEntry;
|
||||||
alias RenderPass = VkRenderPass;
|
alias RenderPass = VkRenderPass;
|
||||||
|
alias DescSet = VkDescriptorSet;
|
||||||
|
alias DescSetLayout = VkDescriptorSetLayout;
|
||||||
|
alias PipelineLayout = VkPipelineLayout;
|
||||||
|
|
||||||
|
struct DescLayoutBinding
|
||||||
|
{
|
||||||
|
VkDescriptorSetLayoutBinding binding;
|
||||||
|
bool dynamic;
|
||||||
|
}
|
||||||
|
|
||||||
bool g_VLAYER_SUPPORT = false;
|
bool g_VLAYER_SUPPORT = false;
|
||||||
bool g_DEBUG_PRINTF = false;
|
bool g_DEBUG_PRINTF = false;
|
||||||
|
|
||||||
const FRAME_OVERLAP = 2;
|
const FRAME_OVERLAP = 2;
|
||||||
|
const MAX_SETS = 1000;
|
||||||
|
const DESC_ARRAY_SIZE = 256;
|
||||||
|
|
||||||
version(linux)
|
version(linux)
|
||||||
{
|
{
|
||||||
@ -189,6 +200,7 @@ struct Buffer
|
|||||||
VkBuffer buffer;
|
VkBuffer buffer;
|
||||||
VmaAllocation alloc;
|
VmaAllocation alloc;
|
||||||
u64 size;
|
u64 size;
|
||||||
|
bool dynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ShaderUniforms
|
struct ShaderUniforms
|
||||||
@ -227,7 +239,7 @@ struct CompPipelineInfo
|
|||||||
{
|
{
|
||||||
string shader;
|
string shader;
|
||||||
Specialization spec;
|
Specialization spec;
|
||||||
VkPipelineLayout *layout;
|
PipelineLayout layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PushConst
|
struct PushConst
|
||||||
@ -248,7 +260,7 @@ enum StepInitialized : u32
|
|||||||
FrameStructures,
|
FrameStructures,
|
||||||
Swapchain,
|
Swapchain,
|
||||||
DrawImages,
|
DrawImages,
|
||||||
Descriptors,
|
DescriptorPools,
|
||||||
Pipelines,
|
Pipelines,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,16 +340,15 @@ struct Vulkan
|
|||||||
VkCommandBuffer imm_cmd;
|
VkCommandBuffer imm_cmd;
|
||||||
VkFence imm_fence;
|
VkFence imm_fence;
|
||||||
|
|
||||||
VkDescriptorPool desc_pool;
|
VkDescriptorPool active_pool;
|
||||||
VkDescriptorSet[DT.max] desc_sets;
|
SLList!(VkDescriptorPool) full_pools;
|
||||||
VkDescriptorSetLayout[DT.max] desc_layouts;
|
|
||||||
DescBindings[DT.max] desc_bindings;
|
|
||||||
|
|
||||||
VkSampler nearest_sampler;
|
VkSampler nearest_sampler;
|
||||||
VkSampler oit_sampler;
|
VkSampler oit_sampler;
|
||||||
|
|
||||||
VkPipeline[FRAME_OVERLAP] last_pipeline;
|
PipelineHandles[] pipeline_handles;
|
||||||
VkPipelineLayout pipeline_layout;
|
u32 pipeline_count;
|
||||||
|
Pipeline[FRAME_OVERLAP] last_pipeline;
|
||||||
|
|
||||||
MappedBuffer!(u8) transfer_buf;
|
MappedBuffer!(u8) transfer_buf;
|
||||||
MappedBuffer!(UIVertex) ui_vert_buf;
|
MappedBuffer!(UIVertex) ui_vert_buf;
|
||||||
@ -347,9 +358,9 @@ struct Vulkan
|
|||||||
|
|
||||||
QueueInfo queues;
|
QueueInfo queues;
|
||||||
|
|
||||||
PipelineHandle r_to_rgba_pipeline;
|
Pipeline r_to_rgba_pipeline;
|
||||||
PipelineHandle rg_to_rgba_pipeline;
|
Pipeline rg_to_rgba_pipeline;
|
||||||
PipelineHandle rgb_to_rgba_pipeline;
|
Pipeline rgb_to_rgba_pipeline;
|
||||||
VkDescriptorSet conv_desc_set;
|
VkDescriptorSet conv_desc_set;
|
||||||
VkDescriptorSetLayout conv_desc_layout;
|
VkDescriptorSetLayout conv_desc_layout;
|
||||||
VkPipelineLayout conv_pipeline_layout;
|
VkPipelineLayout conv_pipeline_layout;
|
||||||
@ -369,10 +380,11 @@ struct ConvPushConst
|
|||||||
u32 y;
|
u32 y;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PipelineHandle
|
struct PipelineHandles
|
||||||
{
|
{
|
||||||
VkPipeline handle;
|
VkPipeline handle;
|
||||||
VkPipelineBindPoint type;
|
VkPipelineBindPoint type;
|
||||||
|
VkPipelineLayout layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QueueInfo
|
struct QueueInfo
|
||||||
@ -415,6 +427,7 @@ Init(PlatformWindow* 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) InitPipelines(&vk);
|
||||||
if (success) InitBuffers(&vk);
|
if (success) InitBuffers(&vk);
|
||||||
if (success) success = InitConversionPipeline(&vk);
|
if (success) success = InitConversionPipeline(&vk);
|
||||||
if (success) InitFramebufferAndRenderPass(&vk);
|
if (success) InitFramebufferAndRenderPass(&vk);
|
||||||
@ -424,76 +437,98 @@ Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem)
|
|||||||
return vk;
|
return vk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InitPipelines(Vulkan* vk)
|
||||||
|
{
|
||||||
|
vk.pipeline_handles = AllocArray!(PipelineHandles)(&vk.arena, 128);
|
||||||
|
vk.pipeline_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescSetLayout
|
||||||
|
CreateDescSetLayout(Vulkan* vk, DescLayoutBinding[] bindings)
|
||||||
|
{
|
||||||
|
VkDescriptorSetLayoutCreateInfo layout_info = {
|
||||||
|
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
|
bindingCount: cast(u32)bindings.length,
|
||||||
|
pBindings: bindings.ptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
DescSetLayout layout;
|
||||||
|
VkResult result = vkCreateDescriptorSetLayout(vk.device, &layout_info, null, &layout);
|
||||||
|
VkCheckA("vkCreateDescriptorSetLayout failure", result);
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescSet
|
||||||
|
AllocDescSet(Vulkan* vk, DescSetLayout layout)
|
||||||
|
{
|
||||||
|
VkDescriptorSetAllocateInfo alloc_info = {
|
||||||
|
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
|
descriptorSetCount: 1,
|
||||||
|
pSetLayouts: &layout,
|
||||||
|
descriptorPool: vk.active_pool,
|
||||||
|
};
|
||||||
|
|
||||||
|
DescSet set;
|
||||||
|
VkResult result = vkAllocateDescriptorSets(vk.device, &alloc_info, &set);
|
||||||
|
if (result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL)
|
||||||
|
{
|
||||||
|
PushDescriptorPool(vk);
|
||||||
|
|
||||||
|
alloc_info = vk.active_pool;
|
||||||
|
|
||||||
|
result = vkAllocateDescriptorSets(vk.device, &alloc_info, &set);
|
||||||
|
VkCheckA("vkAllocateDescriptorSets failure", result); // TODO: look more into how to handle this
|
||||||
|
}
|
||||||
|
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipelineLayout
|
||||||
|
CreatePipelineLayout(Vulkan* vk, DescSetLayout[] layouts, u64 push_const_size, bool compute = false)
|
||||||
|
{
|
||||||
|
VkShaderStageFlagBits stage = (compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
|
|
||||||
|
VkPushConstantRange const_range = {
|
||||||
|
offset: 0,
|
||||||
|
size: cast(VkDeviceSize)push_const_size,
|
||||||
|
stageFlags: stage,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineLayoutCreateInfo layout_info = {
|
||||||
|
sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
|
setLayoutCount: cast(u32)layouts.length,
|
||||||
|
pSetLayouts: layouts.ptr,
|
||||||
|
pushConstantRangeCount: (push_const_size > 0 ? 1 : 0),
|
||||||
|
pPushConstantRanges: (push_const_size > 0 ? &const_range : null),
|
||||||
|
};
|
||||||
|
|
||||||
|
PipelineLayout layout;
|
||||||
|
VkResult result = vkCreatePipelineLayout(vk.device, &layout_info, null, &layout);
|
||||||
|
VkCheckA("CreatePipelineLayout failure", result);
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InitConversionPipeline(Vulkan* vk)
|
InitConversionPipeline(Vulkan* vk)
|
||||||
{
|
{
|
||||||
Push(vk, SI.Pipelines);
|
Push(vk, SI.Pipelines);
|
||||||
|
|
||||||
VkDescriptorBindingFlags[] binding_flags;
|
|
||||||
binding_flags[] = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
|
|
||||||
|
|
||||||
VkDescriptorSetLayoutBindingFlagsCreateInfo flag_info = {
|
|
||||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
|
||||||
bindingCount: cast(u32)binding_flags.length,
|
|
||||||
pBindingFlags: binding_flags.ptr,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkDescriptorSetLayoutBinding[] layout_bindings = [
|
VkDescriptorSetLayoutBinding[] layout_bindings = [
|
||||||
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT },
|
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT },
|
||||||
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT },
|
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT },
|
||||||
];
|
];
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo set_info = {
|
vk.conv_desc_layout = CreateDescSetLayout(vk, layout_bindings);
|
||||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
vk.conv_desc_set = AllocDescSet(vk, vk.conv_desc_layout);
|
||||||
pNext: &flag_info,
|
vk.conv_pipeline_layout = CreatePipelineLayout(vk, [vk.conv_desc_layout], ConvPushConst.sizeof, true);
|
||||||
bindingCount: cast(u32)layout_bindings.length,
|
|
||||||
pBindings: layout_bindings.ptr,
|
|
||||||
flags: VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkResult result = vkCreateDescriptorSetLayout(vk.device, &set_info, null, &vk.conv_desc_layout);
|
|
||||||
bool success = VkCheck("InitConversionPipeline failure: vkCreateDescriptorSetLayout error", result);
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
VkDescriptorSetAllocateInfo alloc_info = {
|
|
||||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
|
||||||
descriptorSetCount: 1,
|
|
||||||
pSetLayouts: &vk.conv_desc_layout,
|
|
||||||
descriptorPool: vk.desc_pool,
|
|
||||||
};
|
|
||||||
|
|
||||||
result = vkAllocateDescriptorSets(vk.device, &alloc_info, &vk.conv_desc_set);
|
|
||||||
success = VkCheck("InitConversionPipeline failure: vkAllocateDescriptorSets error", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
VkPushConstantRange const_range = {
|
|
||||||
offset: 0,
|
|
||||||
size: cast(VkDeviceSize)ConvPushConst.sizeof,
|
|
||||||
stageFlags: VK_SHADER_STAGE_COMPUTE_BIT,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo layout_info = {
|
|
||||||
sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
|
||||||
setLayoutCount: 1,
|
|
||||||
pSetLayouts: &vk.conv_desc_layout,
|
|
||||||
pushConstantRangeCount: 1,
|
|
||||||
pPushConstantRanges: &const_range,
|
|
||||||
};
|
|
||||||
|
|
||||||
result = vkCreatePipelineLayout(vk.device, &layout_info, null, &vk.conv_pipeline_layout);
|
|
||||||
success = VkCheck("InitConversionPipeline failure: vkCreatePipelineLayout error", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
u32 channels = 1;
|
u32 channels = 1;
|
||||||
|
|
||||||
CompPipelineInfo conv_info = {
|
CompPipelineInfo conv_info = {
|
||||||
shader: "shaders/convert.comp.spv",
|
shader: "shaders/convert.comp.spv",
|
||||||
layout: &vk.conv_pipeline_layout,
|
layout: vk.conv_pipeline_layout,
|
||||||
spec: {
|
spec: {
|
||||||
data: &channels,
|
data: &channels,
|
||||||
size: u32.sizeof,
|
size: u32.sizeof,
|
||||||
@ -514,20 +549,21 @@ InitConversionPipeline(Vulkan* vk)
|
|||||||
|
|
||||||
channels = 3;
|
channels = 3;
|
||||||
vk.rgb_to_rgba_pipeline = CreateComputePipeline(vk, &conv_info);
|
vk.rgb_to_rgba_pipeline = CreateComputePipeline(vk, &conv_info);
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CreateBuffer(Vulkan* vk, Buffer* buf, BufferType type, u64 size, bool host_visible)
|
CreateBuffer(Vulkan* vk, Buffer* buf, BufferType type, u64 size, bool host_visible, bool dynamic = false)
|
||||||
{
|
{
|
||||||
assert(type != BT.None, "CreateBuffer failure: type is None");
|
assert(type != BT.None, "CreateBuffer failure: type is None");
|
||||||
|
|
||||||
|
u64 buffer_size = (dynamic ? size * FRAME_OVERLAP : size);
|
||||||
|
|
||||||
VkBufferCreateInfo buffer_info = {
|
VkBufferCreateInfo buffer_info = {
|
||||||
sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
usage: type,
|
usage: type,
|
||||||
size: size,
|
size: buffer_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
VmaAllocationCreateInfo alloc_info = {
|
VmaAllocationCreateInfo alloc_info = {
|
||||||
@ -558,7 +594,8 @@ CreateBuffer(Vulkan* vk, Buffer* buf, BufferType type, u64 size, bool host_visib
|
|||||||
// TODO: handle errors here then reallocate buffer
|
// TODO: handle errors here then reallocate buffer
|
||||||
assert(VkCheck("CreateBuffer failure: vmaCreateBuffer error", result), "CreateBuffer failure");
|
assert(VkCheck("CreateBuffer failure: vmaCreateBuffer error", result), "CreateBuffer failure");
|
||||||
|
|
||||||
buf.size = size;
|
buf.size = buffer_size;
|
||||||
|
buf.dynamic = dynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -932,22 +969,11 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, u32 ch, u8[] data)
|
|||||||
|
|
||||||
BeginComputePass(vk);
|
BeginComputePass(vk);
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(
|
Pipeline pipeline = ch == 1 ? vk.r_to_rgba_pipeline :
|
||||||
vk.comp_cmd,
|
ch == 2 ? vk.rg_to_rgba_pipeline :
|
||||||
VK_PIPELINE_BIND_POINT_COMPUTE,
|
vk.rgb_to_rgba_pipeline;
|
||||||
vk.conv_pipeline_layout,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
&vk.conv_desc_set,
|
|
||||||
0,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
VkPipeline pipeline = ch == 1 ? vk.r_to_rgba_pipeline.handle :
|
Bind(vk, pipeline, vk.conv_desc_set);
|
||||||
ch == 2 ? vk.rg_to_rgba_pipeline.handle :
|
|
||||||
vk.rgb_to_rgba_pipeline.handle;
|
|
||||||
|
|
||||||
vkCmdBindPipeline(vk.comp_cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
|
|
||||||
|
|
||||||
ConvPushConst pc = {
|
ConvPushConst pc = {
|
||||||
x: w,
|
x: w,
|
||||||
@ -1106,68 +1132,12 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format, ImageU
|
|||||||
view.usage = usage;
|
view.usage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32
|
|
||||||
Pop(Vulkan* vk, DescType type)
|
|
||||||
{
|
|
||||||
DescBindings* bindings = vk.desc_bindings.ptr + type;
|
|
||||||
|
|
||||||
assert(bindings.count > 0, "Pop failure: no free bindings remaining");
|
|
||||||
bindings.count -= 1;
|
|
||||||
|
|
||||||
return bindings.free[bindings.count];
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Push(Vulkan* vk, u32 index, DescType type)
|
PushConstants(Vulkan* vk, PipelineLayout layout, PushConst* pc)
|
||||||
{
|
|
||||||
DescBindings* bindings = vk.desc_bindings.ptr + type;
|
|
||||||
|
|
||||||
bindings.free[bindings.count] = index;
|
|
||||||
bindings.count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32
|
|
||||||
Pop(Vulkan* vk, string name, DescType type)
|
|
||||||
{
|
|
||||||
DescBindings* bindings = vk.desc_bindings.ptr + type;
|
|
||||||
|
|
||||||
u32 index;
|
|
||||||
auto result = bindings.lookup_table[name];
|
|
||||||
if (!result.ok)
|
|
||||||
{
|
|
||||||
// TODO: handle unbinding assets (maybe)
|
|
||||||
assert(bindings.count > 0, "Pop failure: no free bindings remaining");
|
|
||||||
bindings.count -= 1;
|
|
||||||
index = bindings.free[bindings.count];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
index = result.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Push(Vulkan* vk, string name, DescType type)
|
|
||||||
{
|
|
||||||
DescBindings* bindings = vk.desc_bindings.ptr + type;
|
|
||||||
auto result = Delete(&bindings.lookup_table, name);
|
|
||||||
if (result.ok)
|
|
||||||
{
|
|
||||||
assert(bindings.count < bindings.free.length, "Push failure: attempt to push a binding into a full stack");
|
|
||||||
|
|
||||||
bindings.free[bindings.count] = result.value;
|
|
||||||
bindings.count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PushConstants(Vulkan* vk, PushConst* pc)
|
|
||||||
{
|
{
|
||||||
vkCmdPushConstants(
|
vkCmdPushConstants(
|
||||||
vk.cmds[vk.frame_index],
|
vk.cmds[vk.frame_index],
|
||||||
vk.pipeline_layout,
|
layout,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT|VK_SHADER_STAGE_COMPUTE_BIT,
|
VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT|VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
0,
|
0,
|
||||||
PushConst.sizeof,
|
PushConst.sizeof,
|
||||||
@ -1383,24 +1353,50 @@ Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkImageLayout src_layout, Vk
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Bind(Vulkan* vk, PipelineHandle* pipeline)
|
Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet[] sets)
|
||||||
{
|
{
|
||||||
if (vk.last_pipeline[vk.frame_index] == null || vk.last_pipeline[vk.frame_index] != pipeline.handle)
|
assert(pipeline_handle > 0, "Bind failure: pipeline is 0");
|
||||||
{
|
PipelineHandles* pipeline = vk.pipeline_handles.ptr + pipeline_handle;
|
||||||
vkCmdBindPipeline(vk.cmds[vk.frame_index], pipeline.type, pipeline.handle);
|
BindPipeline(vk, pipeline);
|
||||||
vk.last_pipeline[vk.frame_index] = pipeline.handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(
|
vkCmdBindDescriptorSets(
|
||||||
vk.cmds[vk.frame_index],
|
vk.cmds[vk.frame_index],
|
||||||
pipeline.type,
|
pipeline.type,
|
||||||
vk.pipeline_layout,
|
pipeline.layout,
|
||||||
0,
|
0,
|
||||||
cast(u32)vk.desc_sets.length,
|
cast(u32)sets.length,
|
||||||
vk.desc_sets.ptr,
|
sets.ptr,
|
||||||
0,
|
0,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet set)
|
||||||
|
{
|
||||||
|
assert(pipeline_handle > 0, "Bind failure: pipeline is 0");
|
||||||
|
PipelineHandles* pipeline = vk.pipeline_handles.ptr + pipeline_handle;
|
||||||
|
BindPipeline(vk, pipeline);
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets(
|
||||||
|
vk.cmds[vk.frame_index],
|
||||||
|
pipeline.type,
|
||||||
|
pipeline.layout,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
&set,
|
||||||
|
0,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma(inline): void
|
||||||
|
BindPipeline(Vulkan* vk, PipelineHandles* pipeline)
|
||||||
|
{
|
||||||
|
if (vk.last_pipeline[vk.frame_index] == 0 || vk.last_pipeline[vk.frame_index] != pipeline_handle)
|
||||||
|
{
|
||||||
|
vkCmdBindPipeline(vk.cmds[vk.frame_index], pipeline.type, pipeline.handle);
|
||||||
|
vk.last_pipeline[vk.frame_index] = pipeline_handle;
|
||||||
|
|
||||||
VkViewport viewport = {
|
VkViewport viewport = {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
@ -1422,6 +1418,7 @@ Bind(Vulkan* vk, PipelineHandle* pipeline)
|
|||||||
|
|
||||||
vkCmdSetScissor(vk.cmds[vk.frame_index], 0, 1, &scissor);
|
vkCmdSetScissor(vk.cmds[vk.frame_index], 0, 1, &scissor);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma(inline): void
|
pragma(inline): void
|
||||||
Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout)
|
Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout)
|
||||||
@ -1725,7 +1722,6 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
|||||||
pDynamicState: &dyn_info,
|
pDynamicState: &dyn_info,
|
||||||
stageCount: cast(u32)shader_info.length,
|
stageCount: cast(u32)shader_info.length,
|
||||||
pStages: shader_info.ptr,
|
pStages: shader_info.ptr,
|
||||||
layout: vk.pipeline_layout,
|
|
||||||
renderPass: vk.render_pass,
|
renderPass: vk.render_pass,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1740,7 +1736,7 @@ CreateComputePipeline(Vulkan* vk, CompPipelineInfo* comp_info)
|
|||||||
{
|
{
|
||||||
VkComputePipelineCreateInfo info = {
|
VkComputePipelineCreateInfo info = {
|
||||||
sType: VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||||
layout: comp_info.layout ? *comp_info.layout : vk.pipeline_layout,
|
layout: comp_info.layout,
|
||||||
stage: {
|
stage: {
|
||||||
sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||||
stage: VK_SHADER_STAGE_COMPUTE_BIT,
|
stage: VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
@ -1769,11 +1765,17 @@ CreateComputePipeline(Vulkan* vk, CompPipelineInfo* comp_info)
|
|||||||
info.stage.pSpecializationInfo = &spec_info;
|
info.stage.pSpecializationInfo = &spec_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
PipelineHandle pipeline = { type: VK_PIPELINE_BIND_POINT_COMPUTE };
|
PipelineHandles* pipeline = vk.pipeline_handles.ptr + vk.pipeline_count;
|
||||||
|
pipeline.type = VK_PIPELINE_BIND_POINT_COMPUTE;
|
||||||
|
pipeline.layout = comp_info.layout;
|
||||||
|
|
||||||
|
Pipeline pipeline_handle = vk.pipeline_count;
|
||||||
|
vk.pipeline_count += 1;
|
||||||
|
|
||||||
VkResult result = vkCreateComputePipelines(vk.device, null, 1, &info, null, &pipeline.handle);
|
VkResult result = vkCreateComputePipelines(vk.device, null, 1, &info, null, &pipeline.handle);
|
||||||
assert(VkCheck("CreateComputePipeline failure", result), "Unable to build pipeline");
|
assert(VkCheck("CreateComputePipeline failure", result), "Unable to build pipeline");
|
||||||
|
|
||||||
return pipeline;
|
return pipeline_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1809,7 +1811,7 @@ SetUniform(Vulkan* vk, GlobalUniforms* globals)
|
|||||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
dstSet: vk.desc_sets[DT.Shared],
|
dstSet: vk.desc_sets[DT.Shared],
|
||||||
dstBinding: 0,
|
dstBinding: 0,
|
||||||
descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
|
||||||
descriptorCount: 1,
|
descriptorCount: 1,
|
||||||
pBufferInfo: &buffer_info,
|
pBufferInfo: &buffer_info,
|
||||||
};
|
};
|
||||||
@ -1874,8 +1876,8 @@ Destroy(Vulkan* vk)
|
|||||||
Destroy(vk, &vk.draw_image);
|
Destroy(vk, &vk.draw_image);
|
||||||
Destroy(vk, &vk.depth_image);
|
Destroy(vk, &vk.depth_image);
|
||||||
break;
|
break;
|
||||||
case SI.Descriptors:
|
case SI.DescriptorPools:
|
||||||
Destroy(vk.desc_pool, vk.desc_layouts, vk.pipeline_layout, vk.nearest_sampler, vk.device);
|
DestroyDescriptorPools(vk);
|
||||||
break;
|
break;
|
||||||
case SI.Buffers:
|
case SI.Buffers:
|
||||||
Destroy(vk, &vk.transfer_buf);
|
Destroy(vk, &vk.transfer_buf);
|
||||||
@ -1893,6 +1895,25 @@ Destroy(Vulkan* vk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DestroyDescriptorPools(Vulkan* vk)
|
||||||
|
{
|
||||||
|
vkDestroyDescriptorPool(vk.device, vk.active_pool, null);
|
||||||
|
|
||||||
|
Node!(VkDescriptorPool)* node = vk.full_pools.first;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if (node == null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroyDescriptorPool(vk.device, node.value, null);
|
||||||
|
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DestroyPipelines(Vulkan* vk)
|
DestroyPipelines(Vulkan* vk)
|
||||||
{
|
{
|
||||||
@ -1938,15 +1959,21 @@ Destroy(Vulkan* vk, Buffer* buf)
|
|||||||
bool
|
bool
|
||||||
InitDescriptors(Vulkan* vk)
|
InitDescriptors(Vulkan* vk)
|
||||||
{
|
{
|
||||||
Push(vk, SI.Descriptors);
|
Push(vk, SI.DescriptorPools);
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
|
PushDescriptorPool(vk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PushDescriptorPool(Vulkan* vk)
|
||||||
|
{
|
||||||
VkDescriptorPoolSize[] pool_sizes = [
|
VkDescriptorPoolSize[] pool_sizes = [
|
||||||
{ type: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, descriptorCount: 4096 },
|
{ type: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, descriptorCount: 4096 },
|
||||||
{ type: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 4096 },
|
{ type: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 4096 },
|
||||||
{ type: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 4096 },
|
{ type: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, descriptorCount: 4096 },
|
||||||
{ type: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptorCount: 4096 },
|
{ type: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, descriptorCount: 4096 },
|
||||||
{ type: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 4096 },
|
{ type: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 4096 },
|
||||||
{ type: VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, descriptorCount: 4096 },
|
{ type: VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, descriptorCount: 4096 },
|
||||||
];
|
];
|
||||||
@ -1955,18 +1982,36 @@ InitDescriptors(Vulkan* vk)
|
|||||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
poolSizeCount: cast(u32)pool_sizes.length,
|
poolSizeCount: cast(u32)pool_sizes.length,
|
||||||
pPoolSizes: pool_sizes.ptr,
|
pPoolSizes: pool_sizes.ptr,
|
||||||
maxSets: 12,
|
maxSets: MAX_SETS,
|
||||||
flags: VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VkResult result = vkCreateDescriptorPool(vk.device, &pool_info, null, &vk.desc_pool);
|
VkDescriptorPool pool;
|
||||||
|
VkResult result = vkCreateDescriptorPool(vk.device, &pool_info, null, &pool);
|
||||||
success = VkCheck("vkCreateDescriptorPool failure", result);
|
success = VkCheck("vkCreateDescriptorPool failure", result);
|
||||||
|
assert(success, "vkCreateDescriptorPool error");
|
||||||
|
|
||||||
|
if (vk.active_pool == null || vk.active_pool == VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
Node!(VkDescriptorPool)* node = Alloc!(Node!(VkDescriptorPool));
|
||||||
|
node.value = vk.active_pool;
|
||||||
|
PushFront(&g.full_pools, node, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
vk.active_pool = pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
InitDescriptors(Vulkan* vk)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
VkDescriptorSetLayoutBinding[] shared_bindings = [
|
VkDescriptorSetLayoutBinding[] shared_bindings = [
|
||||||
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||||
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||||
{ binding: 2, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
{ binding: 2, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||||
{ binding: 3, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
{ binding: 3, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||||
{ binding: 4, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
{ binding: 4, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||||
@ -2069,26 +2114,6 @@ InitDescriptors(Vulkan* vk)
|
|||||||
success = VkCheck("vkCreatePipelineLayout failure", result);
|
success = VkCheck("vkCreatePipelineLayout failure", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
foreach(i; cast(u64)DT.min .. cast(u64)DT.max)
|
|
||||||
{
|
|
||||||
vk.desc_bindings[i].lookup_table = CreateHashTable!(string, u32)(8);
|
|
||||||
|
|
||||||
u32 DESC_MAX_BINDINGS = 512;
|
|
||||||
vk.desc_bindings[i].free = AllocArray!(u32)(&vk.arena, DESC_MAX_BINDINGS);
|
|
||||||
|
|
||||||
u32 free_count = 0;
|
|
||||||
for(i32 j = DESC_MAX_BINDINGS-1; j >= 0; j -= 1)
|
|
||||||
{
|
|
||||||
vk.desc_bindings[i].free[j] = cast(u32)free_count;
|
|
||||||
free_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
vk.desc_bindings[i].count = free_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceProperties props;
|
VkPhysicalDeviceProperties props;
|
||||||
|
|||||||
@ -1,17 +1,19 @@
|
|||||||
#version 460
|
#version 460
|
||||||
|
|
||||||
#extension GL_GOOGLE_include_directive : require
|
#extension GL_GOOGLE_include_directive : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : require
|
|
||||||
|
|
||||||
#include "structures.layout"
|
#include "structures.layout"
|
||||||
|
#include "gui.layout"
|
||||||
|
|
||||||
layout (location = 0) in vec4 in_color;
|
layout (location = 0) in struct FragDataIn {
|
||||||
layout (location = 1) in vec2 in_uv;
|
vec4 color;
|
||||||
layout (location = 2) flat in uint in_image;
|
vec2 uv;
|
||||||
|
} FragData;
|
||||||
|
|
||||||
layout (location = 0) out vec4 out_frag_col;
|
layout (location = 0) out vec4 FragColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
out_frag_col = in_color;
|
vec4 tex_color = texture(sampler2D(SpriteAtlas, SamplerNearest), FragData.uv);
|
||||||
|
FragColor = FragData.color * tex_color;
|
||||||
}
|
}
|
||||||
|
|||||||
5
src/shaders/gui.layout
Normal file
5
src/shaders/gui.layout
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
layout (set = 1, binding = 0) uniform texture2D SpriteAtlas;
|
||||||
|
|
||||||
|
layout (push_constant) uniform Constants {
|
||||||
|
vec2 res;
|
||||||
|
} PC;
|
||||||
@ -1,25 +1,27 @@
|
|||||||
#version 460
|
#version 460
|
||||||
|
|
||||||
#extension GL_GOOGLE_include_directive : require
|
#extension GL_GOOGLE_include_directive : require
|
||||||
#extension GL_EXT_nonuniform_qualifier : require
|
|
||||||
|
|
||||||
#include "structures.layout"
|
#include "structures.layout"
|
||||||
|
#include "gui.layout"
|
||||||
|
|
||||||
layout (location = 0) in vec2 in_gui_pos_0;
|
layout (location = 0) in vec2 in_dst_start;
|
||||||
layout (location = 1) in vec2 in_gui_pos_1;
|
layout (location = 1) in vec2 in_dst_end;
|
||||||
layout (location = 2) in vec4 in_col;
|
layout (location = 2) in vec2 in_src_start;
|
||||||
layout (location = 3) in uint in_image;
|
layout (location = 3) in vec2 in_src_end;
|
||||||
|
layout (location = 4) in vec4 in_col;
|
||||||
|
|
||||||
layout (location = 0) out vec4 out_color;
|
layout (location = 0) out struct FragDataOut {
|
||||||
layout (location = 1) out vec2 out_uv;
|
vec4 color;
|
||||||
layout (location = 2) out uint out_image;
|
vec2 uv;
|
||||||
|
} FragData;
|
||||||
|
|
||||||
vec2 uvs[] = {
|
vec2 Vertices[4] = vec2[4](
|
||||||
vec2(0.0, 1.0),
|
vec2(-1.0, -1.0),
|
||||||
vec2(0.0, 0.0),
|
vec2(-1.0, +1.0),
|
||||||
vec2(1.0, 1.0),
|
vec2(+1.0, -1.0),
|
||||||
vec2(1.0, 0.0)
|
vec2(+1.0, +1.0)
|
||||||
};
|
);
|
||||||
|
|
||||||
vec2 rotate(vec2 coords, float theta)
|
vec2 rotate(vec2 coords, float theta)
|
||||||
{
|
{
|
||||||
@ -28,18 +30,24 @@ vec2 rotate(vec2 coords, float theta)
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Draw with 6 indices, gl_VertexIndex will use the appropriate index, iterates through 0-3 and not 0-5
|
ivec2 tex_size = textureSize(sampler2D(SpriteAtlas, SamplerNearest), 0);
|
||||||
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];
|
vec2 dst_half_size = (in_dst_end - in_dst_start) / 2;
|
||||||
out_color = in_col;
|
vec2 dst_center = (in_dst_end + in_dst_start) / 2;
|
||||||
out_image = in_image;
|
vec2 dst_pos = (Vertices[gl_VertexIndex] * dst_half_size + dst_center);
|
||||||
|
|
||||||
gl_Position = vec4(2 * dst_pos.x / G.res.x - 1,
|
vec2 src_half_size = (in_src_end - in_src_start) / 2;
|
||||||
2 * dst_pos.y / G.res.y - 1,
|
vec2 src_center = (in_src_end + in_src_start) / 2;
|
||||||
|
vec2 src_pos = (Vertices[gl_VertexIndex] * src_half_size + src_center);
|
||||||
|
|
||||||
|
FragData.color = in_col;
|
||||||
|
FragData.uv = vec2(
|
||||||
|
in_src_start.x / tex_size.x,
|
||||||
|
in_src_start
|
||||||
|
);
|
||||||
|
|
||||||
|
gl_Position = vec4(2 * dst_pos.x / PC.res.x - 1,
|
||||||
|
2 * dst_pos.y / PC.res.y - 1,
|
||||||
0,
|
0,
|
||||||
1);
|
1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,9 +58,8 @@ void main()
|
|||||||
out_col.a = alpha_col.a;
|
out_col.a = alpha_col.a;
|
||||||
}
|
}
|
||||||
|
|
||||||
FragColor = out_col;
|
//FragColor = out_col;
|
||||||
|
|
||||||
/*
|
|
||||||
//TODO: set up OIT again
|
//TODO: set up OIT again
|
||||||
vec4 srgb_col = out_col;// UnPreMultLinearToSRGB(out_col);
|
vec4 srgb_col = out_col;// UnPreMultLinearToSRGB(out_col);
|
||||||
|
|
||||||
@ -75,7 +74,6 @@ void main()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FragColor = vec4(out_col.rgb * out_col.a, out_col.a); // Change to vec4(0.0) to disable tail blending
|
FragColor = vec4(0.0); //vec4(out_col.rgb * out_col.a, out_col.a); // Change to vec4(0.0) to disable tail blending
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,31 @@
|
|||||||
|
|
||||||
#include "structures.layout"
|
#include "structures.layout"
|
||||||
|
|
||||||
|
layout (set = 1, binding = 0) uniform texture2D AlbedoTexture;
|
||||||
|
|
||||||
|
layout (set = 1, binding = 1) uniform texture2D AmbientTexture;
|
||||||
|
|
||||||
|
layout (set = 1, binding = 2) uniform texture2D SpecularTexture;
|
||||||
|
|
||||||
|
layout (set = 1, binding = 3) uniform texture2D AlphaTexture;
|
||||||
|
|
||||||
|
layout (set = 1, binding = 4) uniform Material {
|
||||||
|
vec4 ambient;
|
||||||
|
vec4 diffuse;
|
||||||
|
vec4 specular;
|
||||||
|
bool albedo_has_texture;
|
||||||
|
bool ambient_has_texture;
|
||||||
|
bool specular_has_texture;
|
||||||
|
bool alpha_has_texture;
|
||||||
|
float shininess;
|
||||||
|
float alpha;
|
||||||
|
} Materials[];
|
||||||
|
|
||||||
|
layout (push_constant) uniform Constants {
|
||||||
|
mat4 model_matrix;
|
||||||
|
uint mat_id;
|
||||||
|
} PC;
|
||||||
|
|
||||||
layout (location = 0) in vec4 in_col;
|
layout (location = 0) in vec4 in_col;
|
||||||
layout (location = 1) in vec4 in_tangent;
|
layout (location = 1) in vec4 in_tangent;
|
||||||
layout (location = 2) in vec3 in_pos;
|
layout (location = 2) in vec3 in_pos;
|
||||||
|
|||||||
@ -1,60 +1,4 @@
|
|||||||
// ****************************************************************************
|
layout (rgba16f, set = 0, binding = 0) uniform image2D DrawImage;
|
||||||
// **** STRUCTS MUST BE PACKED IN OPTIMAL PACKING ORDER TO MATCH D STRUCTS ****
|
|
||||||
// ****************************************************************************
|
|
||||||
|
|
||||||
#define OIT_LAYERS 8
|
layout (set = 0, binding = 1) uniform sampler SamplerNearest;
|
||||||
|
|
||||||
layout (set = 0, binding = 0) uniform GlobalUniforms {
|
|
||||||
mat4 view_matrix;
|
|
||||||
mat4 projection_matrix;
|
|
||||||
mat4 projection_view;
|
|
||||||
vec4 light_color;
|
|
||||||
vec4 ambient_color;
|
|
||||||
vec3 light_direction;
|
|
||||||
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;
|
|
||||||
|
|
||||||
#ifdef COMPOSITE_PASS
|
|
||||||
|
|
||||||
layout (set = 0, binding = 4, rg32ui) uniform restrict readonly uimageBuffer ImageABuffer;
|
|
||||||
|
|
||||||
layout (set = 0, binding = 5, r32ui) uniform restrict readonly uimage2D ImageAux;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
layout (set = 0, binding = 4, rg32ui) uniform coherent uimageBuffer ImageABuffer;
|
|
||||||
|
|
||||||
layout (set = 0, binding = 5, r32ui) uniform coherent uimage2D ImageAux;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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;
|
|
||||||
uint alpha_texture;
|
|
||||||
bool albedo_has_texture;
|
|
||||||
bool ambient_has_texture;
|
|
||||||
bool specular_has_texture;
|
|
||||||
bool alpha_has_texture;
|
|
||||||
float shininess;
|
|
||||||
float alpha;
|
|
||||||
} Materials[];
|
|
||||||
|
|
||||||
layout (push_constant) uniform Constants {
|
|
||||||
mat4 model_matrix;
|
|
||||||
uint mat_id;
|
|
||||||
} PC;
|
|
||||||
|
|||||||
@ -8,6 +8,23 @@ import core.simd;
|
|||||||
import std.conv;
|
import std.conv;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
|
||||||
|
struct TrackedSlice(T)
|
||||||
|
{
|
||||||
|
T[] slice;
|
||||||
|
u32 free_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
alias TSlice = TrackedSlice;
|
||||||
|
|
||||||
|
TSlice!(T)
|
||||||
|
InitTrackedSlice(T)(u32 length)
|
||||||
|
{
|
||||||
|
TSlice!(T) tslice;
|
||||||
|
tslice.slice = AllocArray!(T[])(length);
|
||||||
|
|
||||||
|
return tslice;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Logf(Args...)(string fmt, Args args)
|
Logf(Args...)(string fmt, Args args)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user