remove bindless descriptors, delete unused shaders
This commit is contained in:
parent
92980fba0d
commit
f4a8cef602
Binary file not shown.
@ -14,10 +14,16 @@ f32 g_DELTA;
|
||||
|
||||
struct UIVertex
|
||||
{
|
||||
Vec2 p0;
|
||||
Vec2 p1;
|
||||
Vec2 dst_start;
|
||||
Vec2 dst_end;
|
||||
Vec2 src_start;
|
||||
Vec2 src_end;
|
||||
Vec4 col;
|
||||
u32 texture;
|
||||
}
|
||||
|
||||
struct UIPushConst
|
||||
{
|
||||
Vec2 res;
|
||||
}
|
||||
|
||||
struct Vertex
|
||||
@ -62,6 +68,9 @@ struct Game
|
||||
PlatformWindow* window;
|
||||
|
||||
Pipeline ui_pipeline;
|
||||
DescSetLayout ui_desc_layout;
|
||||
DescSet ui_desc_set;
|
||||
PipelineLayout ui_layout;
|
||||
|
||||
UIVertex[] ui_vertex_buf;
|
||||
u32[] ui_index_buf;
|
||||
@ -70,7 +79,6 @@ struct Game
|
||||
ImageView draw_image, depth_image;
|
||||
|
||||
GlobalUniforms globals;
|
||||
PushConst pc;
|
||||
|
||||
Timer timer;
|
||||
}
|
||||
@ -93,27 +101,31 @@ InitGame(PlatformWindow* window)
|
||||
|
||||
UVec2 ext = GetExtent(&g.rd);
|
||||
|
||||
CreateImageView(&g.rd, &g.aux_image, ext.x, ext.y, FMT.R_U32, IU.Storage);
|
||||
DescLayoutBinding[] layout_bindings = [
|
||||
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
];
|
||||
|
||||
g.ui_desc_layout = CreateDescSetLayout(&g.rd, layout_bindings);
|
||||
g.ui_desc_set = AllocDescSet(&g.rd, g.ui_desc_layout);
|
||||
g.ui_layout = CreatePipelineLayout(&g.rd, g.ui_desc_layout, UIPushConst.sizeof);
|
||||
|
||||
GfxPipelineInfo ui_info = {
|
||||
vertex_shader: "shaders/gui.vert.spv",
|
||||
frag_shader: "shaders/gui.frag.spv",
|
||||
input_rate: IR.Instance,
|
||||
input_rate_stride: UIVertex.sizeof,
|
||||
layout: g.ui_layout,
|
||||
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 },
|
||||
{ binding: 0, location: 0, format: FMT.RG_F32, offset: UIVertex.dst_start.offsetof },
|
||||
{ binding: 0, location: 1, format: FMT.RG_F32, offset: UIVertex.dst_end.offsetof },
|
||||
{ binding: 0, location: 2, format: FMT.RG_F32, offset: UIVertex.src_start.offsetof },
|
||||
{ binding: 0, location: 3, format: FMT.RG_F32, offset: UIVertex.src_end.offsetof },
|
||||
{ binding: 0, location: 4, format: FMT.RGBA_F32, offset: UIVertex.col.offsetof },
|
||||
],
|
||||
};
|
||||
|
||||
g.ui_pipeline = CreateGraphicsPipeline(&g.rd, &ui_info);
|
||||
|
||||
assert(g.aux_image.view != null);
|
||||
|
||||
UpdateAuxImage(&g.rd, &g.aux_image);
|
||||
|
||||
Reset(&g.frame_arena);
|
||||
|
||||
return g;
|
||||
@ -142,41 +154,23 @@ Cycle(Game* g)
|
||||
|
||||
Reset(&g.frame_arena);
|
||||
|
||||
ProcessInputs(g, &g.camera);
|
||||
|
||||
ResizeDrawImageIfNeeded(&g.rd, &g.aux_image);
|
||||
|
||||
UpdateAuxImage(&g.rd, &g.aux_image);
|
||||
//ProcessInputs(g, &g.camera);
|
||||
|
||||
//Sort(g, g.camera.pos, &g.model);
|
||||
|
||||
//Update(g, &g.camera);
|
||||
|
||||
Update(&g.camera);
|
||||
//Update(&g.camera);
|
||||
|
||||
BeginFrame(&g.rd);
|
||||
|
||||
PrepAuxImage(&g.rd, &g.aux_image);
|
||||
|
||||
Bind(&g.rd, &g.compute_pipeline);
|
||||
|
||||
ClearColor(&g.rd, &g.aux_image, Vec4(0.0));
|
||||
|
||||
ImageBarrier(&g.rd);
|
||||
|
||||
UVec2 ext = GetExtent(&g.rd);
|
||||
f32 aspect = (cast(f32)ext.x) / (cast(f32)ext.y);
|
||||
Mat4 projection = Perspective(90.0, aspect, 10000.0, 0.1);
|
||||
|
||||
g.globals.projection_matrix = projection;
|
||||
g.globals.view_matrix = ViewMatrix(&g.camera);
|
||||
g.globals.res.x = ext.x;
|
||||
g.globals.res.y = ext.y;
|
||||
SetUniform(&g.rd, &g.globals);
|
||||
|
||||
BeginRendering(&g.rd);
|
||||
|
||||
Bind(&g.rd, &g.ui_pipeline);
|
||||
Bind(&g.rd, g.ui_pipeline, g.ui_desc_set);
|
||||
|
||||
BindUIBuffers(&g.rd);
|
||||
|
||||
@ -196,12 +190,8 @@ pragma(inline): void
|
||||
DrawModel(Game* g, Model* model)
|
||||
{
|
||||
BindBuffers(&g.rd, &model.index_buffer, &model.vertex_buffer);
|
||||
g.pc.model_matrix = Mat4Identity();
|
||||
Translate(&g.pc.model_matrix, model.pos);
|
||||
foreach(i, part; model.parts)
|
||||
{
|
||||
g.pc.mat_id = part.mat;
|
||||
PushConstants(&g.rd, &g.pc);
|
||||
DrawIndexed(&g.rd, part.length, 1, part.offset);
|
||||
}
|
||||
}
|
||||
@ -211,7 +201,7 @@ Destroy(Game* g)
|
||||
{
|
||||
WaitIdle(&g.rd);
|
||||
|
||||
Destroy(&g.rd, &g.ui_pipeline);
|
||||
Destroy(&g.rd, g.ui_pipeline);
|
||||
Destroy(&g.rd);
|
||||
}
|
||||
|
||||
@ -318,10 +308,10 @@ Sort(Game* g, Vec3 pos, Model* model)
|
||||
void
|
||||
DrawRect(Game* g, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col)
|
||||
{
|
||||
g.ui_vertex_buf[g.ui_count].p0.x = p0_x;
|
||||
g.ui_vertex_buf[g.ui_count].p0.y = p0_y;
|
||||
g.ui_vertex_buf[g.ui_count].p1.x = p1_x;
|
||||
g.ui_vertex_buf[g.ui_count].p1.y = p1_y;
|
||||
g.ui_vertex_buf[g.ui_count].dst_start.x = p0_x;
|
||||
g.ui_vertex_buf[g.ui_count].dst_start.y = p0_y;
|
||||
g.ui_vertex_buf[g.ui_count].dst_end.x = p1_x;
|
||||
g.ui_vertex_buf[g.ui_count].dst_end.y = p1_y;
|
||||
g.ui_vertex_buf[g.ui_count].col = col;
|
||||
|
||||
u32 index_count = g.ui_count * 6;
|
||||
@ -336,6 +326,7 @@ DrawRect(Game* g, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col)
|
||||
g.ui_count += 1;
|
||||
}
|
||||
|
||||
// TODO: integrate this with vulkan again
|
||||
Model
|
||||
LoadModel(Game* g, string name)
|
||||
{
|
||||
@ -359,7 +350,7 @@ LoadModel(Game* g, string name)
|
||||
const(char)[] tex_name = m3d.texture[i].name[0 .. strlen(m3d.texture[i].name)];
|
||||
CreateImageView(&g.rd, &model.textures[i], w, h, ch, tex_data);
|
||||
|
||||
tex_lookup[i] = Pop(&g.rd, DT.SampledImage);
|
||||
//tex_lookup[i] = Pop(&g.rd, DT.SampledImage);
|
||||
}
|
||||
|
||||
Material[] mats = AllocArray!(Material)(&g.frame_arena, m3d.nummaterial);
|
||||
@ -405,7 +396,7 @@ LoadModel(Game* g, string name)
|
||||
CreateBuffer(&g.rd, &model.materials[i], BT.Uniform, Material.sizeof, false);
|
||||
assert(Transfer(&g.rd, &model.materials[i], &mats[i]), "LoadModel failure: Transfer error when transferring material");
|
||||
|
||||
mat_lookup[i] = Pop(&g.rd, DT.Material);
|
||||
//mat_lookup[i] = Pop(&g.rd, DT.Material);
|
||||
}
|
||||
|
||||
u32 mesh_count = 0;
|
||||
@ -536,8 +527,8 @@ LoadModel(Game* g, string name)
|
||||
assert(Transfer(&g.rd, &model.vertex_buffer, vertices), "LoadModel failure: Unable to transfer vertex buffer");
|
||||
assert(Transfer(&g.rd, &model.index_buffer, indices), "LoadModel failure: Unable to transfer index buffer");
|
||||
|
||||
WriteDescriptors(&g.rd, DT.Material, model.materials, mat_lookup);
|
||||
WriteDescriptors(&g.rd, DT.SampledImage, model.textures, tex_lookup);
|
||||
//WriteDescriptors(&g.rd, DT.Material, model.materials, mat_lookup);
|
||||
//WriteDescriptors(&g.rd, DT.SampledImage, model.textures, tex_lookup);
|
||||
|
||||
model.positions = positions;
|
||||
model.indices = indices;
|
||||
|
||||
@ -24,12 +24,7 @@ alias RenderPass = VkRenderPass;
|
||||
alias DescSet = VkDescriptorSet;
|
||||
alias DescSetLayout = VkDescriptorSetLayout;
|
||||
alias PipelineLayout = VkPipelineLayout;
|
||||
|
||||
struct DescLayoutBinding
|
||||
{
|
||||
VkDescriptorSetLayoutBinding binding;
|
||||
bool dynamic;
|
||||
}
|
||||
alias DescLayoutBinding = VkDescriptorSetLayoutBinding;
|
||||
|
||||
bool g_VLAYER_SUPPORT = false;
|
||||
bool g_DEBUG_PRINTF = false;
|
||||
@ -233,6 +228,7 @@ struct GfxPipelineInfo
|
||||
Specialization vert_spec;
|
||||
Specialization frag_spec;
|
||||
bool self_dependency;
|
||||
PipelineLayout layout;
|
||||
}
|
||||
|
||||
struct CompPipelineInfo
|
||||
@ -242,12 +238,6 @@ struct CompPipelineInfo
|
||||
PipelineLayout layout;
|
||||
}
|
||||
|
||||
struct PushConst
|
||||
{
|
||||
Mat4 model_matrix;
|
||||
u32 mat_id;
|
||||
}
|
||||
|
||||
enum StepInitialized : u32
|
||||
{
|
||||
Renderer = 1,
|
||||
@ -268,9 +258,7 @@ alias SI = StepInitialized;
|
||||
|
||||
enum DescType : u32
|
||||
{
|
||||
Shared = 0,
|
||||
SampledImage,
|
||||
Material,
|
||||
|
||||
|
||||
Max,
|
||||
}
|
||||
@ -348,7 +336,9 @@ struct Vulkan
|
||||
|
||||
PipelineHandles[] pipeline_handles;
|
||||
u32 pipeline_count;
|
||||
Pipeline[FRAME_OVERLAP] last_pipeline;
|
||||
VkPipeline[FRAME_OVERLAP] last_pipeline;
|
||||
DescSetLayout global_set_layout;
|
||||
DescSet global_set;
|
||||
|
||||
MappedBuffer!(u8) transfer_buf;
|
||||
MappedBuffer!(UIVertex) ui_vert_buf;
|
||||
@ -385,6 +375,7 @@ struct PipelineHandles
|
||||
VkPipeline handle;
|
||||
VkPipelineBindPoint type;
|
||||
VkPipelineLayout layout;
|
||||
Pipeline index;
|
||||
}
|
||||
|
||||
struct QueueInfo
|
||||
@ -426,10 +417,11 @@ Init(PlatformWindow* window, u64 permanent_mem, u64 frame_mem)
|
||||
if (success) success = CreateSwapchain(&vk);
|
||||
if (success) success = CreateDrawImages(&vk);
|
||||
if (success) success = InitFrameStructures(&vk);
|
||||
if (success) success = InitDescriptors(&vk);
|
||||
if (success) InitDescriptors(&vk);
|
||||
if (success) success = InitGlobalDescSet(&vk);
|
||||
if (success) InitPipelines(&vk);
|
||||
if (success) InitBuffers(&vk);
|
||||
if (success) success = InitConversionPipeline(&vk);
|
||||
if (success) InitConversionPipeline(&vk);
|
||||
if (success) InitFramebufferAndRenderPass(&vk);
|
||||
|
||||
assert(success, "Error initializing vulkan");
|
||||
@ -476,7 +468,7 @@ AllocDescSet(Vulkan* vk, DescSetLayout layout)
|
||||
{
|
||||
PushDescriptorPool(vk);
|
||||
|
||||
alloc_info = vk.active_pool;
|
||||
alloc_info.descriptorPool = vk.active_pool;
|
||||
|
||||
result = vkAllocateDescriptorSets(vk.device, &alloc_info, &set);
|
||||
VkCheckA("vkAllocateDescriptorSets failure", result); // TODO: look more into how to handle this
|
||||
@ -486,10 +478,29 @@ AllocDescSet(Vulkan* vk, DescSetLayout layout)
|
||||
}
|
||||
|
||||
PipelineLayout
|
||||
CreatePipelineLayout(Vulkan* vk, DescSetLayout[] layouts, u64 push_const_size, bool compute = false)
|
||||
CreatePipelineLayout(T)(Vulkan* vk, T layouts, u32 push_const_size, bool compute = false) if (is(T: DescSetLayout) || is(T: DescSetLayout[]))
|
||||
{
|
||||
VkShaderStageFlagBits stage = (compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
||||
DescSetLayout[] desc_layouts;
|
||||
|
||||
static if (is(T: DescSetLayout))
|
||||
{
|
||||
desc_layouts = AllocArray!(DescSetLayout)(&vk.frame_arenas[vk.frame_index], 2);
|
||||
desc_layouts[0] = vk.global_set_layout;
|
||||
desc_layouts[1] = layouts;
|
||||
}
|
||||
else static if (is(T: DescSetLayout[]))
|
||||
{
|
||||
desc_layouts = AllocArray!(DescSetLayout)(&vk.frame_arenas[vk.frame_index], layouts.length + 1);
|
||||
desc_layouts[0] = vk.global_set_layout;
|
||||
|
||||
foreach(i; 1 .. layouts.length)
|
||||
{
|
||||
desc_layouts[i] = layouts[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
VkPushConstantRange const_range = {
|
||||
offset: 0,
|
||||
size: cast(VkDeviceSize)push_const_size,
|
||||
@ -498,8 +509,8 @@ CreatePipelineLayout(Vulkan* vk, DescSetLayout[] layouts, u64 push_const_size, b
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_info = {
|
||||
sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
setLayoutCount: cast(u32)layouts.length,
|
||||
pSetLayouts: layouts.ptr,
|
||||
setLayoutCount: cast(u32)desc_layouts.length,
|
||||
pSetLayouts: desc_layouts.ptr,
|
||||
pushConstantRangeCount: (push_const_size > 0 ? 1 : 0),
|
||||
pPushConstantRanges: (push_const_size > 0 ? &const_range : null),
|
||||
};
|
||||
@ -511,19 +522,19 @@ CreatePipelineLayout(Vulkan* vk, DescSetLayout[] layouts, u64 push_const_size, b
|
||||
return layout;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
InitConversionPipeline(Vulkan* vk)
|
||||
{
|
||||
Push(vk, SI.Pipelines);
|
||||
|
||||
VkDescriptorSetLayoutBinding[] layout_bindings = [
|
||||
{ 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_DYNAMIC, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT },
|
||||
];
|
||||
|
||||
vk.conv_desc_layout = CreateDescSetLayout(vk, layout_bindings);
|
||||
vk.conv_desc_set = AllocDescSet(vk, vk.conv_desc_layout);
|
||||
vk.conv_pipeline_layout = CreatePipelineLayout(vk, [vk.conv_desc_layout], ConvPushConst.sizeof, true);
|
||||
vk.conv_pipeline_layout = CreatePipelineLayout(vk, vk.conv_desc_layout, ConvPushConst.sizeof, true);
|
||||
|
||||
u32 channels = 1;
|
||||
CompPipelineInfo conv_info = {
|
||||
@ -549,8 +560,6 @@ InitConversionPipeline(Vulkan* vk)
|
||||
|
||||
channels = 3;
|
||||
vk.rgb_to_rgba_pipeline = CreateComputePipeline(vk, &conv_info);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1133,14 +1142,14 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, Format format, ImageU
|
||||
}
|
||||
|
||||
void
|
||||
PushConstants(Vulkan* vk, PipelineLayout layout, PushConst* pc)
|
||||
PushConstants(T)(Vulkan* vk, PipelineLayout layout, T* pc)
|
||||
{
|
||||
vkCmdPushConstants(
|
||||
vk.cmds[vk.frame_index],
|
||||
layout,
|
||||
VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT|VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
0,
|
||||
PushConst.sizeof,
|
||||
T.sizeof,
|
||||
pc
|
||||
);
|
||||
}
|
||||
@ -1364,6 +1373,17 @@ Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet[] sets)
|
||||
pipeline.type,
|
||||
pipeline.layout,
|
||||
0,
|
||||
1,
|
||||
&vk.global_set,
|
||||
0,
|
||||
null
|
||||
);
|
||||
|
||||
vkCmdBindDescriptorSets(
|
||||
vk.cmds[vk.frame_index],
|
||||
pipeline.type,
|
||||
pipeline.layout,
|
||||
1,
|
||||
cast(u32)sets.length,
|
||||
sets.ptr,
|
||||
0,
|
||||
@ -1371,6 +1391,16 @@ Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet[] sets)
|
||||
);
|
||||
}
|
||||
|
||||
PipelineHandles*
|
||||
NewPipeline(Vulkan* vk)
|
||||
{
|
||||
PipelineHandles* pipeline = vk.pipeline_handles.ptr + vk.pipeline_count;
|
||||
pipeline.index = vk.pipeline_count;
|
||||
vk.pipeline_count += 1;
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
void
|
||||
Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet set)
|
||||
{
|
||||
@ -1384,6 +1414,17 @@ Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet set)
|
||||
pipeline.layout,
|
||||
0,
|
||||
1,
|
||||
&vk.global_set,
|
||||
0,
|
||||
null
|
||||
);
|
||||
|
||||
vkCmdBindDescriptorSets(
|
||||
vk.cmds[vk.frame_index],
|
||||
pipeline.type,
|
||||
pipeline.layout,
|
||||
1,
|
||||
1,
|
||||
&set,
|
||||
0,
|
||||
null
|
||||
@ -1393,10 +1434,15 @@ Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet set)
|
||||
pragma(inline): void
|
||||
BindPipeline(Vulkan* vk, PipelineHandles* pipeline)
|
||||
{
|
||||
if (vk.last_pipeline[vk.frame_index] == 0 || vk.last_pipeline[vk.frame_index] != pipeline_handle)
|
||||
if
|
||||
(
|
||||
vk.last_pipeline[vk.frame_index] == null ||
|
||||
vk.last_pipeline[vk.frame_index] == VK_NULL_HANDLE ||
|
||||
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;
|
||||
vk.last_pipeline[vk.frame_index] = pipeline.handle;
|
||||
|
||||
VkViewport viewport = {
|
||||
x: 0.0,
|
||||
@ -1562,7 +1608,9 @@ InitFramebufferAndRenderPass(Vulkan* vk)
|
||||
Pipeline
|
||||
CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
||||
{
|
||||
PipelineHandle pipeline = { type: VK_PIPELINE_BIND_POINT_GRAPHICS };
|
||||
PipelineHandles* pipeline = NewPipeline(vk);
|
||||
pipeline.type = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
pipeline.layout = build_info.layout;
|
||||
|
||||
VkDynamicState[] dyn_state = [ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR ];
|
||||
|
||||
@ -1723,12 +1771,13 @@ CreateGraphicsPipeline(Vulkan* vk, GfxPipelineInfo* build_info)
|
||||
stageCount: cast(u32)shader_info.length,
|
||||
pStages: shader_info.ptr,
|
||||
renderPass: vk.render_pass,
|
||||
layout: build_info.layout,
|
||||
};
|
||||
|
||||
VkResult result = vkCreateGraphicsPipelines(vk.device, null, 1, &create_info, null, &pipeline.handle);
|
||||
assert(VkCheck("CreateGraphicsPipeline failure", result), "Unable to build pipeline");
|
||||
|
||||
return pipeline;
|
||||
return pipeline.index;
|
||||
}
|
||||
|
||||
Pipeline
|
||||
@ -1765,12 +1814,11 @@ CreateComputePipeline(Vulkan* vk, CompPipelineInfo* comp_info)
|
||||
info.stage.pSpecializationInfo = &spec_info;
|
||||
}
|
||||
|
||||
PipelineHandles* pipeline = vk.pipeline_handles.ptr + vk.pipeline_count;
|
||||
PipelineHandles* pipeline = NewPipeline(vk);
|
||||
pipeline.type = VK_PIPELINE_BIND_POINT_COMPUTE;
|
||||
pipeline.layout = comp_info.layout;
|
||||
|
||||
Pipeline pipeline_handle = vk.pipeline_count;
|
||||
vk.pipeline_count += 1;
|
||||
Pipeline pipeline_handle = pipeline.index;
|
||||
|
||||
VkResult result = vkCreateComputePipelines(vk.device, null, 1, &info, null, &pipeline.handle);
|
||||
assert(VkCheck("CreateComputePipeline failure", result), "Unable to build pipeline");
|
||||
@ -1797,28 +1845,6 @@ ClearColor(Vulkan* vk, ImageView* view, Vec4 color)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
SetUniform(Vulkan* vk, GlobalUniforms* globals)
|
||||
{
|
||||
vk.global_buf.data[0] = *globals;
|
||||
|
||||
VkDescriptorBufferInfo buffer_info = {
|
||||
buffer: vk.global_buf.buffer,
|
||||
range: GlobalUniforms.sizeof,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet write = {
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.desc_sets[DT.Shared],
|
||||
dstBinding: 0,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC,
|
||||
descriptorCount: 1,
|
||||
pBufferInfo: &buffer_info,
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
|
||||
}
|
||||
|
||||
void
|
||||
WaitIdle(Vulkan* vk)
|
||||
{
|
||||
@ -1832,9 +1858,9 @@ Destroy(Vulkan* vk, Shader shader)
|
||||
}
|
||||
|
||||
void
|
||||
Destroy(Vulkan* vk, Pipeline* pipeline)
|
||||
Destroy(Vulkan* vk, Pipeline pipeline)
|
||||
{
|
||||
vkDestroyPipeline(vk.device, pipeline.handle, null);
|
||||
vkDestroyPipeline(vk.device, vk.pipeline_handles[pipeline].handle, null);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1927,19 +1953,19 @@ DestroyPipelines(Vulkan* vk)
|
||||
vkDestroyDescriptorSetLayout(vk.device, vk.conv_desc_layout, null);
|
||||
}
|
||||
|
||||
if (vk.r_to_rgba_pipeline.handle)
|
||||
if (vk.r_to_rgba_pipeline)
|
||||
{
|
||||
vkDestroyPipeline(vk.device, vk.r_to_rgba_pipeline.handle, null);
|
||||
vkDestroyPipeline(vk.device, vk.pipeline_handles[vk.r_to_rgba_pipeline].handle, null);
|
||||
}
|
||||
|
||||
if (vk.rg_to_rgba_pipeline.handle)
|
||||
if (vk.rg_to_rgba_pipeline)
|
||||
{
|
||||
vkDestroyPipeline(vk.device, vk.rg_to_rgba_pipeline.handle, null);
|
||||
vkDestroyPipeline(vk.device, vk.pipeline_handles[vk.rg_to_rgba_pipeline].handle, null);
|
||||
}
|
||||
|
||||
if (vk.rgb_to_rgba_pipeline.handle)
|
||||
if (vk.rgb_to_rgba_pipeline)
|
||||
{
|
||||
vkDestroyPipeline(vk.device, vk.rgb_to_rgba_pipeline.handle, null);
|
||||
vkDestroyPipeline(vk.device, vk.pipeline_handles[vk.rgb_to_rgba_pipeline].handle, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1956,13 +1982,11 @@ Destroy(Vulkan* vk, Buffer* buf)
|
||||
vmaDestroyBuffer(vk.vma, buf.buffer, buf.alloc);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
InitDescriptors(Vulkan* vk)
|
||||
{
|
||||
Push(vk, SI.DescriptorPools);
|
||||
|
||||
bool success = true;
|
||||
|
||||
PushDescriptorPool(vk);
|
||||
}
|
||||
|
||||
@ -1987,264 +2011,74 @@ PushDescriptorPool(Vulkan* vk)
|
||||
|
||||
VkDescriptorPool pool;
|
||||
VkResult result = vkCreateDescriptorPool(vk.device, &pool_info, null, &pool);
|
||||
success = VkCheck("vkCreateDescriptorPool failure", result);
|
||||
bool 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);
|
||||
PushFront(&vk.full_pools, node, null);
|
||||
}
|
||||
|
||||
vk.active_pool = pool;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
InitDescriptors(Vulkan* vk)
|
||||
InitGlobalDescSet(Vulkan* vk)
|
||||
{
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(vk.physical_device, &props);
|
||||
|
||||
VkSamplerCreateInfo sampler_info = {
|
||||
sType: VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
magFilter: VK_FILTER_NEAREST,
|
||||
minFilter: VK_FILTER_NEAREST,
|
||||
addressModeU: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
addressModeV: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
addressModeW: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
anisotropyEnable: VK_TRUE,
|
||||
maxAnisotropy: props.limits.maxSamplerAnisotropy,
|
||||
borderColor: VK_BORDER_COLOR_INT_OPAQUE_BLACK,
|
||||
compareOp: VK_COMPARE_OP_ALWAYS,
|
||||
mipmapMode: VK_SAMPLER_MIPMAP_MODE_LINEAR,
|
||||
};
|
||||
|
||||
VkResult result = vkCreateSampler(vk.device, &sampler_info, null, &vk.nearest_sampler);
|
||||
bool success = VkCheck("vkCreateSampler failure", result);
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkDescriptorSetLayoutBinding[] shared_bindings = [
|
||||
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 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: 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: 5, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
{ binding: 6, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
DescLayoutBinding[] layout_bindings = [
|
||||
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
|
||||
];
|
||||
|
||||
VkDescriptorBindingFlags[] shared_binding_flags = AllocArray!(VkDescriptorBindingFlags)(&vk.frame_arenas[0], shared_bindings.length);
|
||||
shared_binding_flags[] = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
|
||||
vk.global_set_layout = CreateDescSetLayout(vk, layout_bindings);
|
||||
vk.global_set = AllocDescSet(vk, vk.global_set_layout);
|
||||
|
||||
VkDescriptorSetLayoutBindingFlagsCreateInfo shared_flag_info = {
|
||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||
bindingCount: cast(u32)shared_binding_flags.length,
|
||||
pBindingFlags: shared_binding_flags.ptr,
|
||||
};
|
||||
WriteDrawImageDesc(vk);
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo shared_set_info = {
|
||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
pNext: &shared_flag_info,
|
||||
bindingCount: cast(u32)shared_bindings.length,
|
||||
pBindings: shared_bindings.ptr,
|
||||
flags: VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
|
||||
};
|
||||
|
||||
result = vkCreateDescriptorSetLayout(vk.device, &shared_set_info, null, &vk.desc_layouts[DT.Shared]);
|
||||
success = VkCheck("vkCreateDescriptorSetLayout failure", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkDescriptorType[DT.max] type_lookup = [
|
||||
DT.SampledImage: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
DT.Material: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
];
|
||||
|
||||
VkDescriptorBindingFlags bindless_flag = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
|
||||
|
||||
VkDescriptorSetLayoutBindingFlagsCreateInfo bindless_flag_info = {
|
||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||
bindingCount: 1,
|
||||
pBindingFlags: &bindless_flag,
|
||||
};
|
||||
|
||||
VkDescriptorSetLayoutBinding binding = {
|
||||
binding: 0,
|
||||
descriptorCount: 1024,
|
||||
stageFlags: VK_SHADER_STAGE_ALL,
|
||||
};
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo bindless_set_info = {
|
||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
pNext: &bindless_flag_info,
|
||||
bindingCount: 1,
|
||||
pBindings: &binding,
|
||||
flags: VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
|
||||
};
|
||||
|
||||
foreach(i; cast(u64)(DT.Shared+1) .. DT.max)
|
||||
{
|
||||
binding.descriptorType = type_lookup[i];
|
||||
|
||||
if (success)
|
||||
{
|
||||
result = vkCreateDescriptorSetLayout(vk.device, &bindless_set_info, null, vk.desc_layouts.ptr + i);
|
||||
success = VkCheck("vkCreateDescriptorSetLayout failure", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkDescriptorSetAllocateInfo alloc_info = {
|
||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
descriptorSetCount: cast(u32)DT.max,
|
||||
pSetLayouts: vk.desc_layouts.ptr,
|
||||
descriptorPool: vk.desc_pool,
|
||||
};
|
||||
|
||||
result = vkAllocateDescriptorSets(vk.device, &alloc_info, vk.desc_sets.ptr);
|
||||
success = VkCheck("vkAllocateDescriptorSets failure", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkPushConstantRange const_range = {
|
||||
offset: 0,
|
||||
size: cast(VkDeviceSize)PushConst.sizeof,
|
||||
stageFlags: VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT,
|
||||
};
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_info = {
|
||||
sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
setLayoutCount: cast(u32)DT.max,
|
||||
pushConstantRangeCount: 1,
|
||||
pPushConstantRanges: &const_range,
|
||||
pSetLayouts: vk.desc_layouts.ptr,
|
||||
};
|
||||
|
||||
result = vkCreatePipelineLayout(vk.device, &layout_info, null, &vk.pipeline_layout);
|
||||
success = VkCheck("vkCreatePipelineLayout failure", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(vk.physical_device, &props);
|
||||
|
||||
VkSamplerCreateInfo sampler_info = {
|
||||
sType: VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
magFilter: VK_FILTER_NEAREST,
|
||||
minFilter: VK_FILTER_NEAREST,
|
||||
addressModeU: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
addressModeV: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
addressModeW: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
anisotropyEnable: VK_TRUE,
|
||||
maxAnisotropy: props.limits.maxSamplerAnisotropy,
|
||||
borderColor: VK_BORDER_COLOR_INT_OPAQUE_BLACK,
|
||||
compareOp: VK_COMPARE_OP_ALWAYS,
|
||||
mipmapMode: VK_SAMPLER_MIPMAP_MODE_LINEAR,
|
||||
};
|
||||
|
||||
result = vkCreateSampler(vk.device, &sampler_info, null, &vk.nearest_sampler);
|
||||
success = VkCheck("vkCreateSampler failure", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkSamplerCreateInfo sampler_info = {
|
||||
sType: VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
magFilter: VK_FILTER_LINEAR,
|
||||
minFilter: VK_FILTER_LINEAR,
|
||||
addressModeU: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
addressModeV: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
addressModeW: VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
anisotropyEnable: VK_FALSE,
|
||||
compareEnable: VK_FALSE,
|
||||
borderColor: VK_BORDER_COLOR_INT_OPAQUE_BLACK,
|
||||
mipmapMode: VK_SAMPLER_MIPMAP_MODE_NEAREST,
|
||||
unnormalizedCoordinates: VK_FALSE,
|
||||
};
|
||||
|
||||
result = vkCreateSampler(vk.device, &sampler_info, null, &vk.oit_sampler);
|
||||
success = VkCheck("vkCreateSampler failure", result);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
// TODO: move this elsewhere later
|
||||
// Also add samples/supersampling scaling
|
||||
|
||||
CreateBufferView(vk, &vk.a_buffer_view, (u32.sizeof * 2) * vk.swapchain_extent.width * vk.swapchain_extent.height, FMT.RG_U32);
|
||||
|
||||
VkDescriptorBufferInfo a_buffer_info = {
|
||||
buffer: vk.a_buffer_view.buffer,
|
||||
offset: 0,
|
||||
range: VK_WHOLE_SIZE,
|
||||
};
|
||||
|
||||
VkDescriptorImageInfo aux_info = {
|
||||
sampler: vk.oit_sampler,
|
||||
imageView: vk.aux_image.view,
|
||||
imageLayout: VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
VkDescriptorImageInfo sampler_info = {
|
||||
VkDescriptorImageInfo sampler_desc_info = {
|
||||
sampler: vk.nearest_sampler,
|
||||
};
|
||||
|
||||
VkDescriptorImageInfo oit_sample_info = {
|
||||
sampler: vk.oit_sampler,
|
||||
VkWriteDescriptorSet write = {
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.global_set,
|
||||
dstBinding: 1,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
pImageInfo: &sampler_desc_info,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet[] writes = [
|
||||
{
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.desc_sets[DT.Shared],
|
||||
dstBinding: 3,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
pImageInfo: &sampler_info,
|
||||
},
|
||||
{
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.desc_sets[DT.Shared],
|
||||
dstBinding: 4,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
|
||||
pBufferInfo: &a_buffer_info,
|
||||
pTexelBufferView: &vk.a_buffer_view.view,
|
||||
},
|
||||
{
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.desc_sets[DT.Shared],
|
||||
dstBinding: 6,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
pImageInfo: &oit_sample_info,
|
||||
},
|
||||
];
|
||||
|
||||
vkUpdateDescriptorSets(vk.device, cast(u32)writes.length, writes.ptr, 0, null);
|
||||
|
||||
WriteDrawImageDesc(vk);
|
||||
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
|
||||
}
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
// TODO: better descriptor updating
|
||||
void
|
||||
UpdateAuxImage(Vulkan* vk, ImageView* view)
|
||||
{
|
||||
VkDescriptorImageInfo aux_info = {
|
||||
sampler: vk.oit_sampler,
|
||||
imageView: view.view,
|
||||
imageLayout: VK_IMAGE_LAYOUT_GENERAL,
|
||||
};
|
||||
|
||||
assert(view.view != VK_NULL_HANDLE);
|
||||
|
||||
VkWriteDescriptorSet write = {
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.desc_sets[DT.Shared],
|
||||
dstBinding: 5,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
pImageInfo: &aux_info,
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
|
||||
}
|
||||
|
||||
void
|
||||
WriteDrawImageDesc(Vulkan* vk)
|
||||
{
|
||||
@ -2255,8 +2089,8 @@ WriteDrawImageDesc(Vulkan* vk)
|
||||
|
||||
VkWriteDescriptorSet write = {
|
||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
dstSet: vk.desc_sets[DT.Shared],
|
||||
dstBinding: 2,
|
||||
dstSet: vk.global_set,
|
||||
dstBinding: 0,
|
||||
descriptorCount: 1,
|
||||
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
pImageInfo: &draw_image_info,
|
||||
@ -2305,56 +2139,6 @@ WriteConvDescriptor(Vulkan* vk, ImageView* view)
|
||||
vkUpdateDescriptorSets(vk.device, 1, &write, 0, null);
|
||||
}
|
||||
|
||||
void
|
||||
WriteDescriptors(Vulkan* vk, DescType type, Buffer[] buffers, u32[] indices)
|
||||
{
|
||||
assert(buffers.length > 0, "WriteDescriptors failure: Buffer length is 0");
|
||||
|
||||
VkDescriptorBufferInfo[] buffer_info = AllocArray!(VkDescriptorBufferInfo)(&vk.frame_arenas[vk.frame_index], buffers.length);
|
||||
VkWriteDescriptorSet[] writes = AllocArray!(VkWriteDescriptorSet)(&vk.frame_arenas[vk.frame_index], buffers.length);
|
||||
|
||||
foreach(i, buf; buffers)
|
||||
{
|
||||
buffer_info[i].buffer = buf.buffer;
|
||||
buffer_info[i].range = buf.size;
|
||||
|
||||
writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writes[i].dstSet = vk.desc_sets[type];
|
||||
writes[i].dstArrayElement = indices[i];
|
||||
writes[i].dstBinding = 0;
|
||||
writes[i].descriptorCount = 1;
|
||||
writes[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
writes[i].pBufferInfo = buffer_info.ptr + i;
|
||||
}
|
||||
|
||||
vkUpdateDescriptorSets(vk.device, cast(u32)writes.length, writes.ptr, 0, null);
|
||||
}
|
||||
|
||||
void
|
||||
WriteDescriptors(Vulkan* vk, DescType type, ImageView[] views, u32[] indices)
|
||||
{
|
||||
assert(views.length > 0, "WriteDescriptors failure: ImageView length is 0");
|
||||
|
||||
VkDescriptorImageInfo[] image_info = AllocArray!(VkDescriptorImageInfo)(&vk.frame_arenas[vk.frame_index], views.length);
|
||||
VkWriteDescriptorSet[] writes = AllocArray!(VkWriteDescriptorSet)(&vk.frame_arenas[vk.frame_index], views.length);
|
||||
|
||||
foreach(i, view; views)
|
||||
{
|
||||
image_info[i].imageView = view.view;
|
||||
image_info[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writes[i].dstSet = vk.desc_sets[type];
|
||||
writes[i].dstArrayElement = indices[i];
|
||||
writes[i].dstBinding = 0;
|
||||
writes[i].descriptorCount = 1;
|
||||
writes[i].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
writes[i].pImageInfo = image_info.ptr + i;
|
||||
}
|
||||
|
||||
vkUpdateDescriptorSets(vk.device, cast(u32)writes.length, writes.ptr, 0, null);
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
Dispatch(Vulkan* vk, VkCommandBuffer cmd)
|
||||
{
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
#include "structures.layout"
|
||||
|
||||
layout (constant_id = 0) const int CHANNELS = 3;
|
||||
|
||||
@ -11,9 +14,9 @@ layout (push_constant) uniform Constants {
|
||||
uint y;
|
||||
} PC;
|
||||
|
||||
layout (set = 0, binding = 0, rgba32f) uniform image2D dst;
|
||||
layout (set = 1, binding = 0, rgba32f) uniform image2D dst;
|
||||
|
||||
layout (set = 0, binding = 1) buffer input_array
|
||||
layout (set = 1, binding = 1) buffer input_array
|
||||
{
|
||||
uint8_t src[];
|
||||
};
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#version 460
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = vec4((float((gl_VertexIndex >> 1U) & 1U)) * 4.0 - 1.0, (float(gl_VertexIndex & 1U)) * 4.0 - 1.0, 0, 1.0);
|
||||
gl_Position = pos;
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
#define COMPOSITE_PASS
|
||||
|
||||
#include "structures.layout"
|
||||
|
||||
layout (location = 0) out vec4 FragColor;
|
||||
|
||||
void BubbleSort(inout uvec2 array[OIT_LAYERS], int n)
|
||||
{
|
||||
for(int i = (n - 2); i >= 0; --i)
|
||||
{
|
||||
for(int j = 0; j <= i; ++j)
|
||||
{
|
||||
if(uintBitsToFloat(array[j].g) >= uintBitsToFloat(array[j+1].g))
|
||||
{
|
||||
uvec2 temp = array[j+1];
|
||||
array[j+1] = array[j];
|
||||
array[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float UnPreMultSRGBToLinear(float col)
|
||||
{
|
||||
return (col < 0.04045f) ? (col / 12.92f) : pow((col + 0.055f) / 1.055f, 2.4f);
|
||||
}
|
||||
|
||||
vec4 UnPreMultSRGBToLinear(vec4 col)
|
||||
{
|
||||
col.r = UnPreMultSRGBToLinear(col.r);
|
||||
col.g = UnPreMultSRGBToLinear(col.g);
|
||||
col.b = UnPreMultSRGBToLinear(col.b);
|
||||
return col;
|
||||
}
|
||||
|
||||
void DoBlend(inout vec4 color, vec4 base_color)
|
||||
{
|
||||
color.rgb += (1 - color.a) * base_color.rgb;
|
||||
color.a += (1 - color.a) * base_color.a;
|
||||
}
|
||||
|
||||
void DoBlendPacked(inout vec4 color, uint fragment)
|
||||
{
|
||||
vec4 unpacked_color = unpackUnorm4x8(fragment);
|
||||
//unpacked_color = UnPreMultSRGBToLinear(unpacked_color);
|
||||
unpacked_color.rgb *= unpacked_color.a;
|
||||
DoBlend(color, unpacked_color);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
int store_mask = 0;
|
||||
int view_size = int(G.res.x) * int(G.res.y);
|
||||
int sample_id = 0;
|
||||
int list_pos = view_size * OIT_LAYERS * sample_id + coord.y * int(G.res.x) + coord.x;
|
||||
uvec2 array[OIT_LAYERS];
|
||||
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
int fragments = int(imageLoad(ImageAux, coord).r);
|
||||
fragments = min(OIT_LAYERS, fragments);
|
||||
|
||||
for (int i = 0; i < fragments; i++)
|
||||
{
|
||||
array[i] = imageLoad(ImageABuffer, list_pos + i * view_size).rg;
|
||||
}
|
||||
|
||||
BubbleSort(array, fragments);
|
||||
|
||||
vec4 color_sum = vec4(0.0);
|
||||
|
||||
for(int i = 0; i < fragments; i++)
|
||||
{
|
||||
DoBlendPacked(color_sum, array[i].x);
|
||||
}
|
||||
|
||||
FragColor = color_sum;
|
||||
}
|
||||
@ -1,79 +0,0 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
#include "structures.layout"
|
||||
|
||||
layout (location = 0) in struct FragDataIn {
|
||||
vec3 normal;
|
||||
vec2 uv;
|
||||
} FragData;
|
||||
|
||||
layout (location = 0, index = 0) out vec4 FragColor;
|
||||
|
||||
vec4 CalculateDirectionalLight(vec4 diff_col, vec4 diff_samp, vec4 light_col, vec3 dir, vec3 normal)
|
||||
{
|
||||
float diffuse_factor = max(dot(normal, -dir), 0.0);
|
||||
|
||||
vec4 ambient = vec4(vec3(G.ambient_color * diff_col), diff_samp.a);
|
||||
vec4 diffuse = vec4(vec3(light_col * diffuse_factor), diff_samp.a);
|
||||
|
||||
diffuse *= diff_samp;
|
||||
ambient *= diff_samp;
|
||||
|
||||
return (ambient + diffuse);
|
||||
}
|
||||
|
||||
float UnPreMultLinearToSRGB(float col)
|
||||
{
|
||||
return col < 0.0031308f ? col * 12.92f : (pow(col, 1.0f / 2.4f) * 1.055f) - 0.055f;
|
||||
}
|
||||
|
||||
vec4 UnPreMultLinearToSRGB(vec4 col)
|
||||
{
|
||||
col.r = UnPreMultLinearToSRGB(col.x);
|
||||
col.g = UnPreMultLinearToSRGB(col.x);
|
||||
col.b = UnPreMultLinearToSRGB(col.x);
|
||||
return col;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 coord = ivec2(gl_FragCoord.xy);
|
||||
int store_mask = 0;
|
||||
int view_size = int(G.res.x) * int(G.res.y);
|
||||
int sample_id = 0;
|
||||
int list_pos = view_size * OIT_LAYERS * sample_id + coord.y * int(G.res.x) + coord.x;
|
||||
|
||||
vec4 col = Materials[nonuniformEXT(PC.mat_id)].diffuse;
|
||||
vec4 tex_col = texture(sampler2D(Textures[nonuniformEXT(Materials[nonuniformEXT(PC.mat_id)].albedo_texture)], SamplerNearest), FragData.uv);
|
||||
|
||||
vec4 out_col = CalculateDirectionalLight(col, tex_col, G.light_color, G.light_direction, FragData.normal);
|
||||
out_col.a = 1.0;// Materials[nonuniformEXT(PC.mat_id)].alpha;
|
||||
|
||||
if (Materials[nonuniformEXT(PC.mat_id)].alpha_has_texture)
|
||||
{
|
||||
vec4 alpha_col = texture(sampler2D(Textures[nonuniformEXT(Materials[nonuniformEXT(PC.mat_id)].alpha_texture)], SamplerNearest), FragData.uv);
|
||||
out_col.a = alpha_col.a;
|
||||
}
|
||||
|
||||
//FragColor = out_col;
|
||||
|
||||
//TODO: set up OIT again
|
||||
vec4 srgb_col = out_col;// UnPreMultLinearToSRGB(out_col);
|
||||
|
||||
uvec4 store_value = uvec4(packUnorm4x8(srgb_col), floatBitsToUint(gl_FragCoord.z), store_mask, 0);
|
||||
|
||||
uint old_counter = imageAtomicAdd(ImageAux, coord, 1u);
|
||||
if (old_counter < OIT_LAYERS)
|
||||
{
|
||||
imageStore(ImageABuffer, list_pos + int(old_counter) * view_size, store_value);
|
||||
|
||||
FragColor = vec4(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
FragColor = vec4(0.0); //vec4(out_col.rgb * out_col.a, out_col.a); // Change to vec4(0.0) to disable tail blending
|
||||
}
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
#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 = 1) in vec4 in_tangent;
|
||||
layout (location = 2) in vec3 in_pos;
|
||||
layout (location = 3) in vec3 in_normal;
|
||||
layout (location = 4) in vec2 in_uv;
|
||||
|
||||
layout (location = 0) out struct FragDataOut {
|
||||
vec3 normal;
|
||||
vec2 uv;
|
||||
} FragData;
|
||||
|
||||
mat4 y_matrix = mat4(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, -1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0
|
||||
);
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = G.projection_matrix * G.view_matrix * PC.model_matrix * vec4(in_pos, 1.0);
|
||||
|
||||
FragData.uv = in_uv;
|
||||
FragData.normal = mat3(PC.model_matrix) * in_normal;
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
#include "structures.layout"
|
||||
|
||||
layout (location = 0) in vec3 fragColor;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = vec4(fragColor, 1.0);
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
#version 460
|
||||
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
#include "structures.layout"
|
||||
|
||||
layout (location = 0) out vec3 fragColor;
|
||||
|
||||
vec2 positions[3] = vec2[](
|
||||
vec2(0.0, -0.5),
|
||||
vec2(0.5, 0.5),
|
||||
vec2(-0.5, 0.5)
|
||||
);
|
||||
|
||||
vec3 colors[3] = vec3[](
|
||||
vec3(1.0, 0.0, 0.0),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
vec3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||
fragColor = colors[gl_VertexIndex];
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user