Compare commits
6 Commits
f1584919fc
...
7ddb49ccd8
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ddb49ccd8 | |||
| 462e211726 | |||
| 5c1a73b428 | |||
| 1ed5c0f933 | |||
| 7b94b91e1f | |||
| b0202cfcea |
@ -2,23 +2,23 @@
|
|||||||
|
|
||||||
#extension GL_EXT_shader_8bit_storage : require
|
#extension GL_EXT_shader_8bit_storage : require
|
||||||
|
|
||||||
layout (local_size_x = 32, local_size_y = 32) in;
|
|
||||||
|
|
||||||
layout (constant_id = 0) const int CHANNELS = 3;
|
layout (constant_id = 0) const int CHANNELS = 3;
|
||||||
|
|
||||||
layout (push_constant) uniform Constants
|
layout (local_size_x = 32, local_size_y = 32) in;
|
||||||
{
|
|
||||||
|
layout (push_constant) uniform Constants {
|
||||||
uint x;
|
uint x;
|
||||||
uint y;
|
uint y;
|
||||||
} PC;
|
} 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[];
|
uint8_t src[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
uint x = gl_GlobalInvocationID.x;
|
uint x = gl_GlobalInvocationID.x;
|
||||||
@ -33,23 +33,23 @@ void main()
|
|||||||
{
|
{
|
||||||
uint index = x + y * PC.x;
|
uint index = x + y * PC.x;
|
||||||
|
|
||||||
vec4 col = vec4(vec3(uint(src[index]) / 255.0), 1.0);
|
vec4 col = vec4(vec3(uint(src[index]) / 255.0), 1.0);
|
||||||
imageStore(dst, ivec2(x, y), col);
|
imageStore(dst, ivec2(x, y), col);
|
||||||
}
|
}
|
||||||
else if(CHANNELS == 2)
|
else if(CHANNELS == 2)
|
||||||
{
|
{
|
||||||
uint index = (x + y * PC.x) * 2;
|
uint index = (x + y * PC.x) * 2;
|
||||||
|
|
||||||
float f = uint(src[index]) / 255.0;
|
float f = uint(src[index]) / 255.0;
|
||||||
float a = uint(src[index+1]) / 255.0;
|
float a = uint(src[index+1]) / 255.0;
|
||||||
vec4 col = vec4(f, f, f, a);
|
vec4 col = vec4(f, f, f, a);
|
||||||
imageStore(dst, ivec2(x, y), col);
|
imageStore(dst, ivec2(x, y), col);
|
||||||
}
|
}
|
||||||
else if(CHANNELS == 3)
|
else if(CHANNELS == 3)
|
||||||
{
|
{
|
||||||
uint index = (x + y * PC.x) * 3;
|
uint index = (x + y * PC.x) * 3;
|
||||||
|
|
||||||
vec4 col = vec4(uint(src[index]) / 255.0, uint(src[index+1]) / 255.0, uint(src[index+2]) / 255.0, 1.0);
|
vec4 col = vec4(uint(src[index]) / 255.0, uint(src[index+1]) / 255.0, uint(src[index+2]) / 255.0, 1.0);
|
||||||
imageStore(dst, ivec2(x, y), col);
|
imageStore(dst, ivec2(x, y), col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
356
vulkan/vulkan.d
356
vulkan/vulkan.d
@ -35,7 +35,12 @@ alias DescSetLayout = VkDescriptorSetLayout;
|
|||||||
alias PipelineLayout = VkPipelineLayout;
|
alias PipelineLayout = VkPipelineLayout;
|
||||||
alias DescLayoutBinding = VkDescriptorSetLayoutBinding;
|
alias DescLayoutBinding = VkDescriptorSetLayoutBinding;
|
||||||
alias DescWrite = VkWriteDescriptorSet;
|
alias DescWrite = VkWriteDescriptorSet;
|
||||||
alias DescSet = VkDescriptorSet;
|
|
||||||
|
struct DescSet
|
||||||
|
{
|
||||||
|
VkDescriptorSet handle;
|
||||||
|
u32 dynamic_count;
|
||||||
|
}
|
||||||
|
|
||||||
bool g_VLAYER_SUPPORT = false;
|
bool g_VLAYER_SUPPORT = false;
|
||||||
|
|
||||||
@ -488,12 +493,12 @@ struct Vulkan
|
|||||||
bool recreate_swapchain;
|
bool recreate_swapchain;
|
||||||
|
|
||||||
VkRenderPass render_pass;
|
VkRenderPass render_pass;
|
||||||
VkFramebuffer[] framebuffers;
|
VkFramebuffer framebuffer;
|
||||||
u32 image_index;
|
|
||||||
Descriptor[] present_images;
|
Descriptor[] present_images;
|
||||||
Descriptor depth_image;
|
u32 image_index;
|
||||||
Format present_image_format;
|
|
||||||
|
|
||||||
|
Descriptor draw_image;
|
||||||
|
Descriptor depth_image;
|
||||||
|
|
||||||
VkCommandPool[FRAME_OVERLAP] cmd_pools;
|
VkCommandPool[FRAME_OVERLAP] cmd_pools;
|
||||||
VkCommandBuffer[FRAME_OVERLAP] cmds;
|
VkCommandBuffer[FRAME_OVERLAP] cmds;
|
||||||
@ -516,6 +521,8 @@ struct Vulkan
|
|||||||
PipelineHandles[] pipeline_handles;
|
PipelineHandles[] pipeline_handles;
|
||||||
u32 pipeline_count;
|
u32 pipeline_count;
|
||||||
VkPipeline[FRAME_OVERLAP] last_pipelines;
|
VkPipeline[FRAME_OVERLAP] last_pipelines;
|
||||||
|
DescSetLayout global_set_layout;
|
||||||
|
DescSet global_set;
|
||||||
|
|
||||||
MappedBuffer!(u8) transfer_buf;
|
MappedBuffer!(u8) transfer_buf;
|
||||||
|
|
||||||
@ -534,19 +541,77 @@ struct Vulkan
|
|||||||
f32[4] color_clear;
|
f32[4] color_clear;
|
||||||
f32[4] depth_clear;
|
f32[4] depth_clear;
|
||||||
|
|
||||||
@property VkCommandPool cmd_pool() => this.cmd_pools[this.frame_index];
|
@property VkCommandPool
|
||||||
@property VkCommandBuffer cmd() => this.cmds[this.frame_index];
|
cmd_pool()
|
||||||
@property VkSemaphore acquire_sem() => this.acquire_sems[this.frame_index];
|
{
|
||||||
@property VkSemaphore* acquire_sem_ptr() => this.acquire_sems.ptr + this.frame_index;
|
return this.cmd_pools[this.frame_index];
|
||||||
@property VkFence render_fence() => this.render_fences[this.frame_index];
|
}
|
||||||
@property VkFence* render_fence_ptr() => this.render_fences.ptr + this.frame_index;
|
|
||||||
@property VkPipeline last_pipeline() => this.last_pipelines[this.frame_index];
|
@property VkCommandBuffer
|
||||||
@property VkPipeline last_pipeline(VkPipeline pipeline) => this.last_pipelines[this.frame_index] = pipeline;
|
cmd()
|
||||||
@property VkSemaphore submit_sem() => this.submit_sems[this.image_index];
|
{
|
||||||
@property ref Descriptor present_image() => this.present_images[this.image_index];
|
return this.cmds[this.frame_index];
|
||||||
@property Descriptor* present_image_ptr() => this.present_images.ptr + this.image_index;
|
}
|
||||||
@property VkFramebuffer framebuffer() => this.framebuffers[this.image_index];
|
|
||||||
@property Arena* frame_arena() => &this.frame_arenas[this.frame_index];
|
@property VkSemaphore
|
||||||
|
acquire_sem()
|
||||||
|
{
|
||||||
|
return this.acquire_sems[this.frame_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@property VkSemaphore*
|
||||||
|
acquire_sem_ptr()
|
||||||
|
{
|
||||||
|
return this.acquire_sems.ptr + this.frame_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property VkFence
|
||||||
|
render_fence()
|
||||||
|
{
|
||||||
|
return this.render_fences[this.frame_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@property VkFence*
|
||||||
|
render_fence_ptr()
|
||||||
|
{
|
||||||
|
return this.render_fences.ptr + this.frame_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property VkPipeline
|
||||||
|
last_pipeline()
|
||||||
|
{
|
||||||
|
return this.last_pipelines[this.frame_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@property VkPipeline
|
||||||
|
last_pipeline(VkPipeline pipeline)
|
||||||
|
{
|
||||||
|
return this.last_pipelines[this.frame_index] = pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property VkSemaphore
|
||||||
|
submit_sem()
|
||||||
|
{
|
||||||
|
return this.submit_sems[this.image_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@property ref Descriptor
|
||||||
|
present_image()
|
||||||
|
{
|
||||||
|
return this.present_images[this.image_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@property Descriptor*
|
||||||
|
present_image_ptr()
|
||||||
|
{
|
||||||
|
return this.present_images.ptr + this.image_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arena*
|
||||||
|
FrameArena()
|
||||||
|
{
|
||||||
|
return &this.frame_arenas[this.frame_index];
|
||||||
|
}
|
||||||
|
|
||||||
alias queues this;
|
alias queues this;
|
||||||
}
|
}
|
||||||
@ -599,7 +664,7 @@ CreateDescSetLayout(DescLayoutBinding[] bindings)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DescSet
|
DescSet
|
||||||
AllocDescSet(DescSetLayout layout)
|
AllocDescSet(DescSetLayout layout, u32 dynamic_count = 0)
|
||||||
{
|
{
|
||||||
VkDescriptorSetAllocateInfo alloc_info = {
|
VkDescriptorSetAllocateInfo alloc_info = {
|
||||||
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
@ -608,15 +673,15 @@ AllocDescSet(DescSetLayout layout)
|
|||||||
descriptorPool: g_vk.active_pool,
|
descriptorPool: g_vk.active_pool,
|
||||||
};
|
};
|
||||||
|
|
||||||
DescSet set;
|
DescSet set = { dynamic_count: dynamic_count };
|
||||||
VkResult result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set);
|
VkResult result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set.handle);
|
||||||
if(result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL)
|
if(result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL)
|
||||||
{
|
{
|
||||||
PushDescriptorPool();
|
PushDescriptorPool();
|
||||||
|
|
||||||
alloc_info.descriptorPool = g_vk.active_pool;
|
alloc_info.descriptorPool = g_vk.active_pool;
|
||||||
|
|
||||||
result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set);
|
result = vkAllocateDescriptorSets(g_vk.device, &alloc_info, &set.handle);
|
||||||
VkCheckA("vkAllocateDescriptorSets failure", result);
|
VkCheckA("vkAllocateDescriptorSets failure", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,17 +693,23 @@ CreatePipelineLayout(T)(T layouts, u32 push_const_size, bool compute = false) if
|
|||||||
{
|
{
|
||||||
VkShaderStageFlagBits stage = (compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
VkShaderStageFlagBits stage = (compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
|
|
||||||
u32 desc_layouts_length = 1;
|
DescSetLayout[] desc_layouts;
|
||||||
DescSetLayout* desc_layouts;
|
|
||||||
|
|
||||||
static if(is(T: DescSetLayout))
|
static if(is(T: DescSetLayout))
|
||||||
{
|
{
|
||||||
desc_layouts = &layouts;
|
desc_layouts = Alloc!(DescSetLayout)(g_vk.FrameArena(), 2);
|
||||||
|
desc_layouts[0] = g_vk.global_set_layout;
|
||||||
|
desc_layouts[1] = layouts;
|
||||||
}
|
}
|
||||||
else static if(is(T: DescSetLayout[]))
|
else static if(is(T: DescSetLayout[]))
|
||||||
{
|
{
|
||||||
desc_layouts_length = cast(u32)layouts.length;
|
desc_layouts = Alloc!(DescSetLayout)(g_vk.FrameArena(), layouts.length + 1);
|
||||||
desc_layouts = layouts.ptr;
|
desc_layouts[0] = g_vk.global_set_layout;
|
||||||
|
|
||||||
|
foreach(i; 0 .. layouts.length)
|
||||||
|
{
|
||||||
|
desc_layouts[i+1] = layouts[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPushConstantRange const_range = {
|
VkPushConstantRange const_range = {
|
||||||
@ -649,8 +720,8 @@ CreatePipelineLayout(T)(T layouts, u32 push_const_size, bool compute = false) if
|
|||||||
|
|
||||||
VkPipelineLayoutCreateInfo layout_info = {
|
VkPipelineLayoutCreateInfo layout_info = {
|
||||||
sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
setLayoutCount: desc_layouts_length,
|
setLayoutCount: cast(u32)desc_layouts.length,
|
||||||
pSetLayouts: desc_layouts,
|
pSetLayouts: desc_layouts.ptr,
|
||||||
pushConstantRangeCount: (push_const_size > 0 ? 1 : 0),
|
pushConstantRangeCount: (push_const_size > 0 ? 1 : 0),
|
||||||
pPushConstantRanges: (push_const_size > 0 ? &const_range : null),
|
pPushConstantRanges: (push_const_size > 0 ? &const_range : null),
|
||||||
};
|
};
|
||||||
@ -760,7 +831,7 @@ BeginFrame()
|
|||||||
result = vkResetFences(g_vk.device, 1, g_vk.render_fence_ptr);
|
result = vkResetFences(g_vk.device, 1, g_vk.render_fence_ptr);
|
||||||
VkCheckA("BeginFrame failure: vkResetFences error", result);
|
VkCheckA("BeginFrame failure: vkResetFences error", result);
|
||||||
|
|
||||||
Reset(g_vk.frame_arena);
|
Reset(g_vk.FrameArena());
|
||||||
|
|
||||||
// ?? dont know why this is 3 (should have commented it)
|
// ?? dont know why this is 3 (should have commented it)
|
||||||
for(u64 i = 0; i < 3; i += 1)
|
for(u64 i = 0; i < 3; i += 1)
|
||||||
@ -809,9 +880,11 @@ SetClearColors(f32[4] color_clear, f32[4] depth_clear)
|
|||||||
void
|
void
|
||||||
BeginRendering()
|
BeginRendering()
|
||||||
{
|
{
|
||||||
Transition(g_vk.cmd, g_vk.present_image_ptr, IL.ColorAttach);
|
Transition(g_vk.cmd, &g_vk.draw_image, IL.ColorAttach);
|
||||||
Transition(g_vk.cmd, &g_vk.depth_image, IL.DepthAttach);
|
Transition(g_vk.cmd, &g_vk.depth_image, IL.DepthAttach);
|
||||||
|
|
||||||
|
Transition(g_vk.cmd, g_vk.present_image_ptr, IL.TransferDst);
|
||||||
|
|
||||||
VkClearValue[2] clear_color = [
|
VkClearValue[2] clear_color = [
|
||||||
{ color: { float32: g_vk.color_clear } },
|
{ color: { float32: g_vk.color_clear } },
|
||||||
{ color: { float32: g_vk.depth_clear } },
|
{ color: { float32: g_vk.depth_clear } },
|
||||||
@ -849,21 +922,9 @@ GetAspect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PrepComputeImage(Descriptor* descriptor)
|
PrepComputeDrawImage()
|
||||||
{
|
{
|
||||||
Transition(g_vk.cmd, descriptor, IL.General);
|
Transition(g_vk.cmd, &g_vk.draw_image, IL.General);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CopyToPresentImage(Descriptor* descriptor, UVec2 extent)
|
|
||||||
{
|
|
||||||
Transition(g_vk.cmd, descriptor, IL.TransferSrc);
|
|
||||||
Transition(g_vk.cmd, g_vk.present_image_ptr, IL.TransferDst);
|
|
||||||
|
|
||||||
VkExtent2D src_extent = { width: extent.x, height: extent.y };
|
|
||||||
VkExtent2D dst_extent = { width: g_vk.swapchain_extent.width, height: g_vk.swapchain_extent.height };
|
|
||||||
|
|
||||||
Copy(g_vk.cmd, descriptor, g_vk.present_image_ptr, src_extent, dst_extent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -875,10 +936,27 @@ FinishRendering()
|
|||||||
void
|
void
|
||||||
SubmitAndPresent()
|
SubmitAndPresent()
|
||||||
{
|
{
|
||||||
|
scope(exit)
|
||||||
|
{
|
||||||
|
g_vk.last_pipeline = null;
|
||||||
|
g_vk.frame_index = (g_vk.frame_index + 1) % FRAME_OVERLAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImage image = g_vk.present_image.image.image;
|
||||||
VkSemaphore acquire_sem = g_vk.acquire_sem;
|
VkSemaphore acquire_sem = g_vk.acquire_sem;
|
||||||
VkSemaphore submit_sem = g_vk.submit_sem;
|
VkSemaphore submit_sem = g_vk.submit_sem;
|
||||||
|
|
||||||
Transition(g_vk.cmd, g_vk.present_image_ptr, IL.PresentSrc);
|
Transition(g_vk.cmd, &g_vk.draw_image, IL.TransferSrc);
|
||||||
|
|
||||||
|
VkExtent2D extent = {
|
||||||
|
width: g_vk.swapchain_extent.width,
|
||||||
|
height: g_vk.swapchain_extent.height,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Find out how to copy from same dimension images (pretty sure its not blitting)
|
||||||
|
Copy(g_vk.cmd, &g_vk.draw_image, image, IL.TransferDst, extent, extent);
|
||||||
|
|
||||||
|
Transition(g_vk.cmd, image, IL.TransferDst, IL.PresentSrc);
|
||||||
|
|
||||||
VkResult result = vkEndCommandBuffer(g_vk.cmd);
|
VkResult result = vkEndCommandBuffer(g_vk.cmd);
|
||||||
VkCheckA("FinishFrame failure: vkEndCommandBuffer error", result);
|
VkCheckA("FinishFrame failure: vkEndCommandBuffer error", result);
|
||||||
@ -938,9 +1016,6 @@ SubmitAndPresent()
|
|||||||
{
|
{
|
||||||
g_vk.frame_started = false;
|
g_vk.frame_started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_vk.last_pipeline = null;
|
|
||||||
g_vk.frame_index = (g_vk.frame_index + 1) % FRAME_OVERLAP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1326,7 +1401,7 @@ CreateBufferView(Descriptor* desc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PushConstants(T)(Pipeline pipeline_id, T* pc, bool compute = false)
|
PushConstants(T)(Pipeline pipeline_id, T* pc)
|
||||||
{
|
{
|
||||||
assert(pipeline_id > 0, "PushConstants pipeline_id == 0");
|
assert(pipeline_id > 0, "PushConstants pipeline_id == 0");
|
||||||
PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_id;
|
PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_id;
|
||||||
@ -1335,7 +1410,7 @@ PushConstants(T)(Pipeline pipeline_id, T* pc, bool compute = false)
|
|||||||
VK_SHADER_STAGE_COMPUTE_BIT);
|
VK_SHADER_STAGE_COMPUTE_BIT);
|
||||||
|
|
||||||
vkCmdPushConstants(
|
vkCmdPushConstants(
|
||||||
compute ? g_vk.comp_cmd : g_vk.cmd,
|
g_vk.cmd,
|
||||||
pipeline.layout,
|
pipeline.layout,
|
||||||
stage,
|
stage,
|
||||||
0,
|
0,
|
||||||
@ -1503,21 +1578,50 @@ Bind(Pipeline pipeline_handle, DescSet[] sets, bool compute = false)
|
|||||||
{
|
{
|
||||||
assert(pipeline_handle > 0, "Bind failure: pipeline is 0");
|
assert(pipeline_handle > 0, "Bind failure: pipeline is 0");
|
||||||
|
|
||||||
VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd);
|
VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd);
|
||||||
PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_handle;
|
PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_handle;
|
||||||
BindPipeline(cmd, pipeline);
|
BindPipeline(cmd, pipeline);
|
||||||
|
|
||||||
u32[] offsets;
|
u32[] offsets;
|
||||||
|
if(g_vk.global_set.dynamic_count > 0)
|
||||||
|
{
|
||||||
|
offsets = Alloc!(u32)(g_vk.FrameArena(), g_vk.global_set.dynamic_count);
|
||||||
|
}
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(
|
vkCmdBindDescriptorSets(
|
||||||
cmd,
|
cmd,
|
||||||
pipeline.type,
|
pipeline.type,
|
||||||
pipeline.layout,
|
pipeline.layout,
|
||||||
0,
|
0,
|
||||||
cast(u32)sets.length,
|
1,
|
||||||
sets.ptr,
|
&g_vk.global_set.handle,
|
||||||
0,
|
cast(u32)offsets.length,
|
||||||
null
|
offsets.ptr
|
||||||
|
);
|
||||||
|
|
||||||
|
u32 offset_count;
|
||||||
|
VkDescriptorSet[] handles = Alloc!(VkDescriptorSet)(g_vk.FrameArena(), sets.length);
|
||||||
|
|
||||||
|
foreach(i, set; sets)
|
||||||
|
{
|
||||||
|
handles[i] = set.handle;
|
||||||
|
offset_count += set.dynamic_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(offset_count > 0)
|
||||||
|
{
|
||||||
|
offsets = Alloc!(u32)(g_vk.FrameArena(), offset_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets(
|
||||||
|
cmd,
|
||||||
|
pipeline.type,
|
||||||
|
pipeline.layout,
|
||||||
|
1,
|
||||||
|
cast(u32)handles.length,
|
||||||
|
handles.ptr,
|
||||||
|
cast(u32)offsets.length,
|
||||||
|
offsets.ptr
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1536,19 +1640,41 @@ Bind(Pipeline pipeline_handle, DescSet set, bool compute = false)
|
|||||||
{
|
{
|
||||||
assert(pipeline_handle > 0, "Bind failure: pipeline is 0");
|
assert(pipeline_handle > 0, "Bind failure: pipeline is 0");
|
||||||
|
|
||||||
VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd);
|
VkCommandBuffer cmd = (compute ? g_vk.comp_cmd : g_vk.cmd);
|
||||||
PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_handle;
|
PipelineHandles* pipeline = g_vk.pipeline_handles.ptr + pipeline_handle;
|
||||||
BindPipeline(cmd, pipeline);
|
BindPipeline(cmd, pipeline);
|
||||||
|
|
||||||
|
u32[] offsets;
|
||||||
|
if(g_vk.global_set.dynamic_count > 0)
|
||||||
|
{
|
||||||
|
offsets = Alloc!(u32)(g_vk.FrameArena(), g_vk.global_set.dynamic_count);
|
||||||
|
}
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(
|
vkCmdBindDescriptorSets(
|
||||||
cmd,
|
cmd,
|
||||||
pipeline.type,
|
pipeline.type,
|
||||||
pipeline.layout,
|
pipeline.layout,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
&set,
|
&g_vk.global_set.handle,
|
||||||
0,
|
cast(u32)offsets.length,
|
||||||
null
|
offsets.ptr
|
||||||
|
);
|
||||||
|
|
||||||
|
if(set.dynamic_count > 0)
|
||||||
|
{
|
||||||
|
offsets = Alloc!(u32)(g_vk.FrameArena(), set.dynamic_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets(
|
||||||
|
cmd,
|
||||||
|
pipeline.type,
|
||||||
|
pipeline.layout,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
&set.handle,
|
||||||
|
cast(u32)offsets.length,
|
||||||
|
offsets.ptr
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1730,7 +1856,7 @@ CreateGraphicsPipeline(Pipeline* pipeline_handle, 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: cast(VkFormat*)&g_vk.present_image_format,
|
pColorAttachmentFormats: cast(VkFormat*)&g_vk.draw_image.image.format,
|
||||||
depthAttachmentFormat: g_vk.depth_image.image.format,
|
depthAttachmentFormat: g_vk.depth_image.image.format,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1928,8 +2054,8 @@ ClearDepth(f32[4] color = [0.0, 0.0, 0.0, 0.0])
|
|||||||
void
|
void
|
||||||
ClearColor(f32[4] color)
|
ClearColor(f32[4] color)
|
||||||
{
|
{
|
||||||
Transition(g_vk.cmd, g_vk.present_image_ptr, IL.TransferDst);
|
Transition(g_vk.cmd, &g_vk.draw_image, IL.TransferDst);
|
||||||
ClearColor(g_vk.present_image_ptr, color);
|
ClearColor(&g_vk.draw_image, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2027,11 +2153,11 @@ PushDescriptorPool()
|
|||||||
void
|
void
|
||||||
PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc)
|
PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc)
|
||||||
{
|
{
|
||||||
Arena* arena = g_vk.frame_arena;
|
Arena* arena = g_vk.FrameArena();
|
||||||
|
|
||||||
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
write.descriptorType = desc.type;
|
write.descriptorType = desc.type;
|
||||||
write.dstSet = set;
|
write.dstSet = set.handle;
|
||||||
write.dstBinding = desc.binding;
|
write.dstBinding = desc.binding;
|
||||||
write.descriptorCount = 1;
|
write.descriptorCount = 1;
|
||||||
write.dstArrayElement = desc.index;
|
write.dstArrayElement = desc.index;
|
||||||
@ -2073,7 +2199,7 @@ PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc)
|
|||||||
void
|
void
|
||||||
Write(DescSet set, Descriptor[] descs)
|
Write(DescSet set, Descriptor[] descs)
|
||||||
{
|
{
|
||||||
Arena* arena = g_vk.frame_arena;
|
Arena* arena = g_vk.FrameArena();
|
||||||
|
|
||||||
VkWriteDescriptorSet[] writes = Alloc!(VkWriteDescriptorSet)(arena, descs.length);
|
VkWriteDescriptorSet[] writes = Alloc!(VkWriteDescriptorSet)(arena, descs.length);
|
||||||
|
|
||||||
@ -2105,7 +2231,7 @@ WriteConvDescriptor(Buffer* buf)
|
|||||||
|
|
||||||
VkWriteDescriptorSet write = {
|
VkWriteDescriptorSet write = {
|
||||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
dstSet: g_vk.conv_desc_set,
|
dstSet: g_vk.conv_desc_set.handle,
|
||||||
dstBinding: 1,
|
dstBinding: 1,
|
||||||
descriptorCount: 1,
|
descriptorCount: 1,
|
||||||
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
@ -2125,7 +2251,7 @@ WriteConvDescriptor(ImageView* view)
|
|||||||
|
|
||||||
VkWriteDescriptorSet write = {
|
VkWriteDescriptorSet write = {
|
||||||
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
dstSet: g_vk.conv_desc_set,
|
dstSet: g_vk.conv_desc_set.handle,
|
||||||
dstBinding: 0,
|
dstBinding: 0,
|
||||||
descriptorCount: 1,
|
descriptorCount: 1,
|
||||||
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||||
@ -2146,13 +2272,7 @@ Dispatch(VkCommandBuffer cmd)
|
|||||||
void
|
void
|
||||||
Dispatch()
|
Dispatch()
|
||||||
{
|
{
|
||||||
Dispatch(g_vk.comp_cmd);
|
Dispatch(g_vk.cmd);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
WaitForCompute()
|
|
||||||
{
|
|
||||||
vkWaitForFences(g_vk.device, 1, &g_vk.comp_fence, VK_TRUE, u64.max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2299,12 +2419,13 @@ CreateSampler(Descriptor* desc, DescInfo* info)
|
|||||||
void
|
void
|
||||||
CreateDrawImages()
|
CreateDrawImages()
|
||||||
{
|
{
|
||||||
g_vk.present_image_format = cast(Format)GetDrawImageFormat();
|
Format draw_format = cast(Format)GetDrawImageFormat();
|
||||||
Format depth_format = cast(Format)VK_FORMAT_D32_SFLOAT;
|
Format depth_format = cast(Format)VK_FORMAT_D32_SFLOAT;
|
||||||
|
|
||||||
u32 w = g_vk.swapchain_extent.width;
|
u32 w = g_vk.swapchain_extent.width;
|
||||||
u32 h = g_vk.swapchain_extent.height;
|
u32 h = g_vk.swapchain_extent.height;
|
||||||
|
|
||||||
|
CreateDescriptor(&g_vk.draw_image, DescInfo(type: DT.StorageImage, format: draw_format, usage: IU.Draw, w: w, h: h, binding: 0));
|
||||||
CreateDescriptor(&g_vk.depth_image, DescInfo(type: DT.Image, format: depth_format, usage: IU.Depth, w: w, h: h, binding: 0));
|
CreateDescriptor(&g_vk.depth_image, DescInfo(type: DT.Image, format: depth_format, usage: IU.Depth, w: w, h: h, binding: 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2312,7 +2433,7 @@ bool
|
|||||||
CreateSwapchain()
|
CreateSwapchain()
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
Arena* arena = g_vk.frame_arena;
|
Arena* arena = g_vk.FrameArena();
|
||||||
|
|
||||||
VkSurfaceCapabilitiesKHR cap;
|
VkSurfaceCapabilitiesKHR cap;
|
||||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vk.physical_device, g_vk.surface, &cap);
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vk.physical_device, g_vk.surface, &cap);
|
||||||
@ -2406,37 +2527,33 @@ RecreateSwapchain()
|
|||||||
vkDeviceWaitIdle(g_vk.device);
|
vkDeviceWaitIdle(g_vk.device);
|
||||||
|
|
||||||
Destroy(g_vk.swapchain, g_vk.present_images, g_vk.device);
|
Destroy(g_vk.swapchain, g_vk.present_images, g_vk.device);
|
||||||
|
Destroy(&g_vk.draw_image);
|
||||||
Destroy(&g_vk.depth_image);
|
Destroy(&g_vk.depth_image);
|
||||||
foreach(i; 0 .. g_vk.framebuffers.length)
|
vkDestroyFramebuffer(g_vk.device, g_vk.framebuffer, null);
|
||||||
{
|
|
||||||
vkDestroyFramebuffer(g_vk.device, g_vk.framebuffers[i], null);
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateSwapchain();
|
CreateSwapchain();
|
||||||
CreateDrawImages();
|
CreateDrawImages();
|
||||||
CreateFramebuffers();
|
Write(g_vk.global_set, &g_vk.draw_image);
|
||||||
|
CreateFramebuffer();
|
||||||
|
|
||||||
g_vk.recreate_swapchain = false;
|
g_vk.recreate_swapchain = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CreateFramebuffers()
|
CreateFramebuffer()
|
||||||
{
|
{
|
||||||
foreach(i; 0 .. g_vk.framebuffers.length)
|
VkFramebufferCreateInfo framebuffer_info = {
|
||||||
{
|
sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||||
VkFramebufferCreateInfo framebuffer_info = {
|
renderPass: g_vk.render_pass,
|
||||||
sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
attachmentCount: 2,
|
||||||
renderPass: g_vk.render_pass,
|
pAttachments: [g_vk.draw_image.image.view, g_vk.depth_image.image.view],
|
||||||
attachmentCount: 2,
|
width: g_vk.swapchain_extent.width,
|
||||||
pAttachments: [g_vk.present_images[i].image.view, g_vk.depth_image.image.view],
|
height: g_vk.swapchain_extent.height,
|
||||||
width: g_vk.swapchain_extent.width,
|
layers: 1,
|
||||||
height: g_vk.swapchain_extent.height,
|
};
|
||||||
layers: 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
VkResult result = vkCreateFramebuffer(g_vk.device, &framebuffer_info, null, &g_vk.framebuffers[i]);
|
VkResult result = vkCreateFramebuffer(g_vk.device, &framebuffer_info, null, &g_vk.framebuffer);
|
||||||
VkCheckA("vkCreateFramebuffer failure", result);
|
VkCheckA("vkCreateFramebuffer failure", result);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2564,7 +2681,7 @@ PrintShaderDisassembly(Pipeline pipeline_id, VkShaderStageFlagBits stage)
|
|||||||
VkResult result = vkGetShaderInfoAMD(g_vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, null);
|
VkResult result = vkGetShaderInfoAMD(g_vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, null);
|
||||||
if(result == VK_SUCCESS)
|
if(result == VK_SUCCESS)
|
||||||
{
|
{
|
||||||
u8[] buf = Alloc!(u8)(g_vk.frame_arena, size);
|
u8[] buf = Alloc!(u8)(g_vk.FrameArena(), size);
|
||||||
vkGetShaderInfoAMD(g_vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, buf.ptr);
|
vkGetShaderInfoAMD(g_vk.device, pipeline.handle, stage, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, &size, buf.ptr);
|
||||||
Logf("DISASSEMBLY:\n%r", buf);
|
Logf("DISASSEMBLY:\n%r", buf);
|
||||||
}
|
}
|
||||||
@ -3236,8 +3353,24 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem)
|
|||||||
|
|
||||||
if(success)
|
if(success)
|
||||||
{
|
{
|
||||||
PushDescriptorPool();
|
PushDescriptorPool();
|
||||||
|
|
||||||
|
if(success)
|
||||||
|
{
|
||||||
|
DescLayoutBinding[2] 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 },
|
||||||
|
];
|
||||||
|
|
||||||
|
g_vk.global_set_layout = CreateDescSetLayout(layout_bindings);
|
||||||
|
g_vk.global_set = AllocDescSet(g_vk.global_set_layout);
|
||||||
|
|
||||||
|
Write(g_vk.global_set, [g_vk.draw_image]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(success)
|
||||||
|
{
|
||||||
g_vk.pipeline_handles = Alloc!(PipelineHandles)(&g_vk.arena, 128);
|
g_vk.pipeline_handles = Alloc!(PipelineHandles)(&g_vk.arena, 128);
|
||||||
g_vk.pipeline_count += 1;
|
g_vk.pipeline_count += 1;
|
||||||
|
|
||||||
@ -3245,15 +3378,15 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem)
|
|||||||
g_vk.transfer_buf = CreateMappedBuffer!(u8)(BT.Staging, transfer_size);
|
g_vk.transfer_buf = CreateMappedBuffer!(u8)(BT.Staging, transfer_size);
|
||||||
|
|
||||||
VkDescriptorSetLayoutBinding[2] layout_bindings = [
|
VkDescriptorSetLayoutBinding[2] 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 },
|
||||||
];
|
];
|
||||||
|
|
||||||
g_vk.conv_desc_layout = CreateDescSetLayout(layout_bindings);
|
g_vk.conv_desc_layout = CreateDescSetLayout(layout_bindings);
|
||||||
g_vk.conv_desc_set = AllocDescSet(g_vk.conv_desc_layout);
|
g_vk.conv_desc_set = AllocDescSet(g_vk.conv_desc_layout);
|
||||||
g_vk.conv_pipeline_layout = CreatePipelineLayout(g_vk.conv_desc_layout, ConvPushConst.sizeof, true);
|
g_vk.conv_pipeline_layout = CreatePipelineLayout(g_vk.conv_desc_layout, ConvPushConst.sizeof, true);
|
||||||
|
|
||||||
u32 channels;
|
u32 channels = 1;
|
||||||
SpecEntry[1] entries = [
|
SpecEntry[1] entries = [
|
||||||
{
|
{
|
||||||
constantID: 0,
|
constantID: 0,
|
||||||
@ -3272,19 +3405,18 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
channels = 1;
|
g_vk.r_to_rgba_pipeline = CreateComputePipeline(&conv_info);
|
||||||
g_vk.r_to_rgba_pipeline = CreateComputePipeline(&conv_info);
|
|
||||||
|
|
||||||
channels = 2;
|
channels = 2;
|
||||||
g_vk.rg_to_rgba_pipeline = CreateComputePipeline(&conv_info);
|
g_vk.rg_to_rgba_pipeline = CreateComputePipeline(&conv_info);
|
||||||
|
|
||||||
channels = 3;
|
channels = 3;
|
||||||
g_vk.rgb_to_rgba_pipeline = CreateComputePipeline(&conv_info);
|
g_vk.rgb_to_rgba_pipeline = CreateComputePipeline(&conv_info);
|
||||||
|
|
||||||
|
|
||||||
VkAttachmentDescription[2] attach_descriptions = [
|
VkAttachmentDescription[2] attach_descriptions = [
|
||||||
{
|
{
|
||||||
format: g_vk.present_images[0].image.format,
|
format: g_vk.draw_image.image.format,
|
||||||
samples: VK_SAMPLE_COUNT_1_BIT,
|
samples: VK_SAMPLE_COUNT_1_BIT,
|
||||||
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
|
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
@ -3343,9 +3475,7 @@ Init(VulkanBuildInfo build_info, u64 permanent_mem, u64 frame_mem)
|
|||||||
VkResult result = vkCreateRenderPass(g_vk.device, &pass_info, null, &g_vk.render_pass);
|
VkResult result = vkCreateRenderPass(g_vk.device, &pass_info, null, &g_vk.render_pass);
|
||||||
VkCheckA("vkCreateRenderPass failure", result);
|
VkCheckA("vkCreateRenderPass failure", result);
|
||||||
|
|
||||||
g_vk.framebuffers = Alloc!(VkFramebuffer)(&g_vk.arena, g_vk.present_images.length);
|
CreateFramebuffer();
|
||||||
|
|
||||||
CreateFramebuffers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(success, "Error initializing vulkan");
|
assert(success, "Error initializing vulkan");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user