rework descriptors
This commit is contained in:
parent
38f7bcf3d6
commit
64673b1bf4
550
vulkan.d
550
vulkan.d
@ -3,6 +3,8 @@ import vulkan_logging;
|
||||
import vulkan_util;
|
||||
import std.stdio;
|
||||
import std.algorithm.comparison;
|
||||
import std.algorithm.searching : canFind;
|
||||
import std.traits : isPointer;
|
||||
import core.stdc.string : strcmp, memcpy;
|
||||
import core.stdc.stdio : Printf = printf;
|
||||
import std.format : sformat;
|
||||
@ -222,33 +224,27 @@ enum ImageLayout : VkImageLayout
|
||||
|
||||
alias IL = ImageLayout;
|
||||
|
||||
struct Image
|
||||
{
|
||||
VkImage image;
|
||||
VmaAllocation alloc;
|
||||
Format format;
|
||||
VkImageLayout layout;
|
||||
u32 w;
|
||||
u32 h;
|
||||
bool depth_image;
|
||||
ImageUsage usage;
|
||||
}
|
||||
|
||||
struct BufferView
|
||||
{
|
||||
Buffer base;
|
||||
VkBufferView view;
|
||||
Format format;
|
||||
|
||||
alias base this;
|
||||
}
|
||||
|
||||
struct ImageView
|
||||
{
|
||||
Image base;
|
||||
VkImage image;
|
||||
VkImageView view;
|
||||
VmaAllocation alloc;
|
||||
Format format;
|
||||
ImageUsage usage;
|
||||
ImageLayout shader_layout;
|
||||
|
||||
alias base this;
|
||||
ImageLayout layout;
|
||||
u32 w;
|
||||
u32 h;
|
||||
u32 ch;
|
||||
}
|
||||
|
||||
struct Buffer
|
||||
@ -262,18 +258,46 @@ struct Descriptor
|
||||
{
|
||||
union
|
||||
{
|
||||
Buffer buf;
|
||||
Image image;
|
||||
ImageView view;
|
||||
BufferView buf_view;
|
||||
Buffer buffer;
|
||||
ImageView image;
|
||||
BufferView buffer_view;
|
||||
VkSampler sampler;
|
||||
}
|
||||
};
|
||||
DescType type;
|
||||
u32 binding;
|
||||
u32 index;
|
||||
bool array_elem;
|
||||
}
|
||||
|
||||
static assert(Descriptor.buffer.buffer.offsetof == Descriptor.buffer_view.base.buffer.offsetof);
|
||||
|
||||
struct DescInfo
|
||||
{
|
||||
DescType type;
|
||||
u32 binding;
|
||||
u32 index;
|
||||
Format format;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 w, h, ch;
|
||||
ImageUsage usage;
|
||||
};
|
||||
struct
|
||||
{
|
||||
u64 size;
|
||||
BufferType buffer_type;
|
||||
bool host_visible;
|
||||
};
|
||||
struct
|
||||
{
|
||||
MipmapMode mipmap_mode;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
alias Desc = Descriptor;
|
||||
|
||||
enum MipmapMode : VkSamplerMipmapMode
|
||||
{
|
||||
Nearest = VK_SAMPLER_MIPMAP_MODE_NEAREST,
|
||||
@ -434,7 +458,7 @@ struct Vulkan
|
||||
|
||||
VkRenderPass render_pass;
|
||||
VkFramebuffer framebuffer;
|
||||
ImageView[] present_images;
|
||||
Descriptor[] present_images;
|
||||
u32 image_index;
|
||||
|
||||
Descriptor draw_image;
|
||||
@ -535,7 +559,7 @@ struct Vulkan
|
||||
return this.submit_sems[this.image_index];
|
||||
}
|
||||
|
||||
@property ref ImageView
|
||||
@property ref Descriptor
|
||||
present_image()
|
||||
{
|
||||
return this.present_images[this.image_index];
|
||||
@ -662,15 +686,7 @@ CreatePipelineLayout(T)(T layouts, u32 push_const_size, bool compute = false) if
|
||||
}
|
||||
|
||||
void
|
||||
CreateBuffer(Descriptor* desc, BufferType type, u64 size, bool host_visible, DescType desc_type, u32 binding)
|
||||
{
|
||||
desc.type = desc_type;
|
||||
desc.binding = binding;
|
||||
CreateBuffer(&desc.buf, type, size, host_visible);
|
||||
}
|
||||
|
||||
void
|
||||
CreateBuffer(Buffer* buf, BufferType type, u64 size, bool host_visible)
|
||||
CreateBuffer(Buffer* buffer, BufferType type, u64 size, bool host_visible)
|
||||
{
|
||||
assert(type != BT.None, "CreateBuffer failure: type is None");
|
||||
|
||||
@ -705,11 +721,11 @@ CreateBuffer(Buffer* buf, BufferType type, u64 size, bool host_visible)
|
||||
}
|
||||
|
||||
VmaAllocationInfo vma_info;
|
||||
VkResult result = vmaCreateBuffer(g_vk.vma, &buffer_info, &alloc_info, &buf.buffer, &buf.alloc, &vma_info);
|
||||
VkResult result = vmaCreateBuffer(g_vk.vma, &buffer_info, &alloc_info, &buffer.buffer, &buffer.alloc, &vma_info);
|
||||
// TODO: handle errors here then reallocate buffer
|
||||
VkCheck("CreateBuffer failure: vmaCreateBuffer error", result);
|
||||
|
||||
buf.size = size;
|
||||
buffer.size = size;
|
||||
}
|
||||
|
||||
void
|
||||
@ -805,7 +821,7 @@ BeginRendering()
|
||||
Transition(g_vk.cmd, &g_vk.draw_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
Transition(g_vk.cmd, &g_vk.depth_image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
|
||||
|
||||
VkImage image = g_vk.present_image.image;
|
||||
VkImage image = g_vk.present_image.image.image;
|
||||
Transition(g_vk.cmd, image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
VkClearValue[2] clear_color = [
|
||||
@ -846,12 +862,6 @@ GetAspect()
|
||||
return cast(f32)(g_vk.swapchain_extent.width) / cast(f32)(g_vk.swapchain_extent.height);
|
||||
}
|
||||
|
||||
void
|
||||
PrepAuxImage(ImageView* view)
|
||||
{
|
||||
Transition(g_vk.cmd, view, VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
|
||||
void
|
||||
PrepComputeDrawImage()
|
||||
{
|
||||
@ -873,7 +883,7 @@ SubmitAndPresent()
|
||||
g_vk.frame_index = (g_vk.frame_index + 1) % FRAME_OVERLAP;
|
||||
}
|
||||
|
||||
VkImage image = g_vk.present_image.image;
|
||||
VkImage image = g_vk.present_image.image.image;
|
||||
VkSemaphore acquire_sem = g_vk.acquire_sem;
|
||||
VkSemaphore submit_sem = g_vk.submit_sem;
|
||||
|
||||
@ -885,7 +895,7 @@ SubmitAndPresent()
|
||||
};
|
||||
|
||||
// TODO: Find out how to copy from same dimension images (pretty sure its not blitting)
|
||||
Copy(g_vk.cmd, &g_vk.draw_image.view.base, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent);
|
||||
Copy(g_vk.cmd, &g_vk.draw_image, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, extent, extent);
|
||||
|
||||
Transition(g_vk.cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
|
||||
@ -1007,13 +1017,13 @@ ImmSubmitFinish()
|
||||
}
|
||||
|
||||
bool
|
||||
ImmSubmit(Image* image, VkBufferImageCopy copy, void function(Image*, VkBufferImageCopy) fn)
|
||||
ImmSubmit(Descriptor* desc, VkBufferImageCopy copy, void function(Descriptor*, VkBufferImageCopy) fn)
|
||||
{
|
||||
bool success = ImmSubmitStart();
|
||||
|
||||
if(success)
|
||||
{
|
||||
fn(image, copy);
|
||||
fn(desc, copy);
|
||||
|
||||
VkResult result = vkEndCommandBuffer(g_vk.imm_cmd);
|
||||
success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result);
|
||||
@ -1028,13 +1038,13 @@ ImmSubmit(Image* image, VkBufferImageCopy copy, void function(Image*, VkBufferIm
|
||||
}
|
||||
|
||||
bool
|
||||
ImmSubmit(Buffer* buf, VkBufferCopy copy, void function(Buffer*, VkBufferCopy) fn)
|
||||
ImmSubmit(Descriptor* desc, VkBufferCopy copy, void function(Descriptor*, VkBufferCopy) fn)
|
||||
{
|
||||
bool success = ImmSubmitStart();
|
||||
|
||||
if(success)
|
||||
{
|
||||
fn(buf, copy);
|
||||
fn(desc, copy);
|
||||
|
||||
VkResult result = vkEndCommandBuffer(g_vk.imm_cmd);
|
||||
success = VkCheck("ImmSubmit failure: vkEndCommandBuffer error", result);
|
||||
@ -1061,70 +1071,111 @@ WaitForTransfers()
|
||||
}
|
||||
|
||||
void
|
||||
CreateImageView(Descriptor* view, u32 w, u32 h, u32 ch, u8[] data, DescType type = DT.Image, u32 binding, u32 index)
|
||||
CreateDescriptor(T = u8[])(Descriptor* desc, DescInfo info, T data = null) if(is(T: u8[]) || isPointer!(T))
|
||||
{
|
||||
view.array_elem = true;
|
||||
view.index = index;
|
||||
CreateImageView(view, w, h, ch, data, type, binding);
|
||||
enum DescType[] image_types = [DT.CombinedSampler, DT.Image, DT.StorageImage, DT.InputAttach];
|
||||
enum DescType[] texel_types = [DT.UniformTexelBuf, DT.StorageTexelBuf];
|
||||
enum DescType[] buffer_types = [DT.Uniform, DT.DynamicUniform, DT.Storage, DT.DynamicStorage];
|
||||
|
||||
desc.type = info.type;
|
||||
desc.binding = info.binding;
|
||||
desc.index = info.index;
|
||||
|
||||
if(canFind(image_types, info.type))
|
||||
{
|
||||
desc.image.usage = info.usage;
|
||||
desc.image.format = info.format;
|
||||
desc.image.layout = IL.Undefined;
|
||||
desc.image.w = info.w;
|
||||
desc.image.h = info.h;
|
||||
desc.image.ch = info.ch;
|
||||
|
||||
static if(is(T: u8[]))
|
||||
{
|
||||
if(data.length)
|
||||
{
|
||||
CreateImageView(desc, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateImageView(desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateImageView(desc);
|
||||
}
|
||||
}
|
||||
else if(canFind(texel_types, info.type))
|
||||
{
|
||||
desc.buffer_view.size = info.size;
|
||||
desc.buffer_view.format = info.format;
|
||||
|
||||
CreateBufferView(desc);
|
||||
|
||||
if(data)
|
||||
{
|
||||
Transfer(desc, data);
|
||||
}
|
||||
}
|
||||
else if(canFind(buffer_types, info.type))
|
||||
{
|
||||
CreateBuffer(&desc.buffer, info.buffer_type, info.size, info.host_visible);
|
||||
|
||||
if(data)
|
||||
{
|
||||
Transfer(desc, data);
|
||||
}
|
||||
}
|
||||
else if(info.type == DT.Sampler)
|
||||
{
|
||||
CreateSampler(desc, info.mipmap_mode);
|
||||
}
|
||||
else assert(false, "Unknown descriptor type in CreateDescriptor");
|
||||
}
|
||||
|
||||
void
|
||||
CreateImageView(Descriptor* view, u32 w, u32 h, u32 ch, u8[] data, DescType type = DT.Image, u32 binding)
|
||||
CreateImageView(Descriptor* desc, u8[] data)
|
||||
{
|
||||
ImageDescCheck(type);
|
||||
view.type = type;
|
||||
view.binding = binding;
|
||||
CreateImageView(&view.view, w, h, ch, data);
|
||||
}
|
||||
CreateImageView(desc);
|
||||
|
||||
void
|
||||
CreateImageViewTex(Descriptor* desc, u32 w, u32 h, DescType type = DT.Image, u32 binding, u32 index)
|
||||
if(desc.image.ch == 4)
|
||||
{
|
||||
desc.array_elem = true;
|
||||
desc.index = index;
|
||||
CreateImageViewTex(desc, w, h, type, binding);
|
||||
}
|
||||
|
||||
void
|
||||
CreateImageViewTex(Descriptor* desc, u32 w, u32 h, DescType type = DT.Image, u32 binding)
|
||||
{
|
||||
ImageDescCheck(type);
|
||||
desc.type = type;
|
||||
desc.binding = binding;
|
||||
CreateImageView(&desc.view, w, h, FMT.RGBA_UNORM, IU.Texture);
|
||||
}
|
||||
|
||||
void
|
||||
CreateImageView(ImageView* view, u32 w, u32 h, u32 ch, u8[] data)
|
||||
{
|
||||
CreateImageView(view, w, h, FMT.RGBA_UNORM, IU.Texture);
|
||||
|
||||
if(ch == 4)
|
||||
{
|
||||
bool result = Transfer(view, data, w, h);
|
||||
bool result = Transfer!(true)(desc, data);
|
||||
assert(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
Descriptor buf;
|
||||
CreateBuffer(&buf, BT.Storage, w * h * ch, false, DT.Storage, 1);
|
||||
bool result = Transfer(&buf.buf, data);
|
||||
CreateDescriptor(&buf, DescInfo(
|
||||
type: DT.Storage,
|
||||
buffer_type: BT.Storage,
|
||||
size: desc.image.w * desc.image.h * desc.image.ch,
|
||||
binding: 1,
|
||||
));
|
||||
bool result = Transfer(&buf.buffer, data);
|
||||
assert(result, "CreateImageView failure: Buffer Transfer error");
|
||||
|
||||
Descriptor conv_view;
|
||||
CreateImageView(&conv_view, w, h, FMT.RGBA_F32, IU.Convert, DT.StorageImage, 0);
|
||||
CreateDescriptor(&conv_view, DescInfo(
|
||||
type: DT.StorageImage,
|
||||
w: desc.image.w,
|
||||
h: desc.image.h,
|
||||
format: FMT.RGBA_F32,
|
||||
usage: IU.Convert,
|
||||
));
|
||||
|
||||
Write(g_vk.conv_desc_set, [conv_view, buf]);
|
||||
|
||||
BeginComputePass();
|
||||
|
||||
Pipeline pipeline = ch == 1 ? g_vk.r_to_rgba_pipeline :
|
||||
ch == 2 ? g_vk.rg_to_rgba_pipeline :
|
||||
Pipeline pipeline = desc.image.ch == 1 ? g_vk.r_to_rgba_pipeline :
|
||||
desc.image.ch == 2 ? g_vk.rg_to_rgba_pipeline :
|
||||
g_vk.rgb_to_rgba_pipeline;
|
||||
|
||||
Bind(pipeline, g_vk.conv_desc_set, true);
|
||||
|
||||
ConvPushConst pc = { x: w, y: h };
|
||||
ConvPushConst pc = { x: desc.image.w, y: desc.image.h };
|
||||
|
||||
vkCmdPushConstants(
|
||||
g_vk.comp_cmd,
|
||||
@ -1139,12 +1190,12 @@ CreateImageView(ImageView* view, u32 w, u32 h, u32 ch, u8[] data)
|
||||
|
||||
Dispatch(g_vk.comp_cmd);
|
||||
|
||||
Transition(g_vk.comp_cmd, view, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
Transition(g_vk.comp_cmd, desc, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
VkExtent2D extent = { width: w, height: h };
|
||||
Copy(g_vk.comp_cmd, &conv_view.view.base, &view.base, extent, extent);
|
||||
VkExtent2D extent = { width: desc.image.w, height: desc.image.h };
|
||||
Copy(g_vk.comp_cmd, &conv_view, desc, extent, extent);
|
||||
|
||||
Transition(g_vk.comp_cmd, view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
Transition(g_vk.comp_cmd, desc, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
FinishComputePass();
|
||||
|
||||
@ -1157,26 +1208,8 @@ CreateImageView(ImageView* view, u32 w, u32 h, u32 ch, u8[] data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CreateImageView(Descriptor* desc, u32 w, u32 h, Format format, ImageUsage usage, DescType type, u32 binding, u32 index)
|
||||
{
|
||||
desc.array_elem = true;
|
||||
desc.index = index;
|
||||
CreateImageView(desc, w, h, format, usage, type, binding);
|
||||
}
|
||||
|
||||
void
|
||||
CreateImageView(Descriptor* desc, u32 w, u32 h, Format format, ImageUsage usage, DescType type, u32 binding)
|
||||
{
|
||||
ImageDescCheck(type);
|
||||
desc.type = type;
|
||||
desc.binding = binding;
|
||||
CreateImageView(&desc.view, w, h, format, usage);
|
||||
}
|
||||
|
||||
void
|
||||
CreateImageView(ImageView* view, u32 w, u32 h, Format format, ImageUsage usage)
|
||||
CreateImageView(Descriptor* desc)
|
||||
{
|
||||
VmaAllocationCreateInfo alloc_info = {
|
||||
usage: VMA_MEMORY_USAGE_GPU_ONLY,
|
||||
@ -1188,14 +1221,14 @@ CreateImageView(ImageView* view, u32 w, u32 h, Format format, ImageUsage usage)
|
||||
imageType: VK_IMAGE_TYPE_2D,
|
||||
mipLevels: 1,
|
||||
arrayLayers: 1,
|
||||
format: format,
|
||||
format: desc.image.format,
|
||||
tiling: VK_IMAGE_TILING_OPTIMAL,
|
||||
initialLayout: VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
usage: usage,
|
||||
usage: desc.image.usage,
|
||||
samples: VK_SAMPLE_COUNT_1_BIT,
|
||||
extent: {
|
||||
width: w,
|
||||
height: h,
|
||||
width: desc.image.w,
|
||||
height: desc.image.h,
|
||||
depth: 1,
|
||||
},
|
||||
};
|
||||
@ -1208,42 +1241,37 @@ CreateImageView(ImageView* view, u32 w, u32 h, Format format, ImageUsage usage)
|
||||
image_info.pQueueFamilyIndices = indices.ptr;
|
||||
}
|
||||
|
||||
VkResult result = vmaCreateImage(g_vk.vma, &image_info, &alloc_info, &view.image, &view.alloc, null);
|
||||
VkResult result = vmaCreateImage(g_vk.vma, &image_info, &alloc_info, &desc.image.image, &desc.image.alloc, null);
|
||||
// TODO: handle errors and realloc
|
||||
VkCheck("CreateImageView failure: vmaCreateImage error", result);
|
||||
|
||||
VkImageViewCreateInfo view_info = {
|
||||
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
image: view.image,
|
||||
image: desc.image.image,
|
||||
viewType: VK_IMAGE_VIEW_TYPE_2D,
|
||||
format: format,
|
||||
format: desc.image.format,
|
||||
subresourceRange: {
|
||||
aspectMask: (usage == IU.Depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT),
|
||||
aspectMask: (desc.image.usage == IU.Depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT),
|
||||
levelCount: 1,
|
||||
layerCount: 1,
|
||||
},
|
||||
};
|
||||
|
||||
result = vkCreateImageView(g_vk.device, &view_info, null, &view.view);
|
||||
result = vkCreateImageView(g_vk.device, &view_info, null, &desc.image.view);
|
||||
// TODO: also handle here
|
||||
VkCheck("CreateImageView failure: vkCreateImageView error", result);
|
||||
|
||||
view.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
view.format = format;
|
||||
view.w = w;
|
||||
view.h = h;
|
||||
view.depth_image = usage == IU.Depth;
|
||||
view.usage = usage;
|
||||
|
||||
if(usage == IU.Draw || usage == IU.Depth || usage == IU.Convert)
|
||||
if(desc.image.usage == IU.Draw || desc.image.usage == IU.Depth || desc.image.usage == IU.Convert)
|
||||
{
|
||||
view.shader_layout = IL.General;
|
||||
desc.image.shader_layout = IL.General;
|
||||
}
|
||||
else if(usage == IU.Texture)
|
||||
else if(desc.image.usage == IU.Texture)
|
||||
{
|
||||
view.shader_layout = IL.ReadOnly;
|
||||
desc.image.shader_layout = IL.ReadOnly;
|
||||
}
|
||||
else assert(false, "Unimplemented usage");
|
||||
|
||||
desc.image.layout = IL.Undefined;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1290,22 +1318,19 @@ FinishComputePass()
|
||||
}
|
||||
|
||||
void
|
||||
CreateBufferView(Descriptor* desc, u64 size, Format format, DescType type, u32 binding)
|
||||
CreateBufferView(Descriptor* desc)
|
||||
{
|
||||
CreateBuffer(&desc.buf_view.base, BT.BufferView, size, false);
|
||||
CreateBuffer(&desc.buffer_view.base, BT.BufferView, desc.buffer_view.size, false);
|
||||
|
||||
VkBufferViewCreateInfo info = {
|
||||
sType: VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
|
||||
buffer: desc.buf_view.buffer,
|
||||
format: format,
|
||||
range: size,
|
||||
buffer: desc.buffer_view.buffer,
|
||||
format: desc.buffer_view.format,
|
||||
range: desc.buffer_view.size,
|
||||
};
|
||||
|
||||
VkResult result = vkCreateBufferView(g_vk.device, &info, null, &desc.buf_view.view);
|
||||
VkResult result = vkCreateBufferView(g_vk.device, &info, null, &desc.buffer_view.view);
|
||||
VkCheckA("CreateBufferView failure: vkCreateBufferView failed", result);
|
||||
|
||||
desc.binding = binding;
|
||||
desc.buf_view.size = size;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1349,54 +1374,20 @@ ImageBarrier()
|
||||
}
|
||||
|
||||
bool
|
||||
Transfer(T)(Buffer* buf, T[] data)
|
||||
Transfer(T, U)(T* dst, U[] data)
|
||||
{
|
||||
static if(is(T: Descriptor))
|
||||
{
|
||||
Buffer* buffer = &dst.buffer;
|
||||
}
|
||||
else static if(is(T: Buffer))
|
||||
{
|
||||
Buffer* buffer = dst;
|
||||
}
|
||||
else static assert(false, "Invalid type for transfer target");
|
||||
|
||||
u8[] u8_data = (cast(u8*)(data.ptr))[0 .. T.sizeof * data.length];
|
||||
return Transfer(buf, u8_data);
|
||||
}
|
||||
|
||||
bool
|
||||
Transfer(Buffer* buf, u8[] data)
|
||||
{
|
||||
bool success = TransferReady();
|
||||
|
||||
u64 copied = 0;
|
||||
while(copied != data.length && success)
|
||||
{
|
||||
if(copied != 0)
|
||||
{
|
||||
success = TransferReady();
|
||||
if(!success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u64 transfer_length = cast(u64)g_vk.transfer_buf.data.length;
|
||||
u64 data_length = cast(u64)data.length - copied;
|
||||
u64 copy_length = transfer_length > data_length ? data_length : transfer_length;
|
||||
|
||||
g_vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length];
|
||||
|
||||
auto fn = function(Buffer* buf, VkBufferCopy copy)
|
||||
{
|
||||
vkCmdCopyBuffer(g_vk.imm_cmd, g_vk.transfer_buf.buffer, buf.buffer, 1, ©);
|
||||
};
|
||||
|
||||
VkBufferCopy copy = {
|
||||
srcOffset: 0,
|
||||
dstOffset: copied,
|
||||
size: copy_length,
|
||||
};
|
||||
|
||||
success = ImmSubmit(buf, copy, fn);
|
||||
|
||||
copied += copy_length;
|
||||
}
|
||||
|
||||
WaitForTransfers();
|
||||
|
||||
return success;
|
||||
return Transfer(buffer, u8_data);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1437,13 +1428,7 @@ TransferReady()
|
||||
}
|
||||
|
||||
bool
|
||||
Transfer(ImageView* view, u8[] data, u32 w, u32 h)
|
||||
{
|
||||
return Transfer(&view.base, data, w, h);
|
||||
}
|
||||
|
||||
bool
|
||||
Transfer(Image* image, u8[] data, u32 w, u32 h)
|
||||
Transfer(bool image)(Descriptor* desc, u8[] data)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
@ -1456,32 +1441,47 @@ Transfer(Image* image, u8[] data, u32 w, u32 h)
|
||||
|
||||
g_vk.transfer_buf.data[0 .. copy_length] = data[copied .. copy_length];
|
||||
|
||||
auto fn = function(Image* image, VkBufferImageCopy copy)
|
||||
static if(image)
|
||||
{
|
||||
Transition(g_vk.imm_cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
auto fn = function(Descriptor* desc, VkBufferImageCopy copy)
|
||||
{
|
||||
Transition(g_vk.imm_cmd, desc, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
vkCmdCopyBufferToImage(g_vk.imm_cmd, g_vk.transfer_buf.buffer, image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
||||
vkCmdCopyBufferToImage(g_vk.imm_cmd, g_vk.transfer_buf.buffer, desc.image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©);
|
||||
|
||||
Transition(g_vk.imm_cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
Transition(g_vk.imm_cmd, desc, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
};
|
||||
|
||||
VkBufferImageCopy copy = {
|
||||
bufferRowLength: w,
|
||||
bufferImageHeight: h,
|
||||
bufferRowLength: desc.image.w,
|
||||
bufferImageHeight: desc.image.h,
|
||||
imageSubresource: {
|
||||
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
layerCount: 1,
|
||||
},
|
||||
imageExtent: {
|
||||
width: w,
|
||||
height: h,
|
||||
width: desc.image.w,
|
||||
height: desc.image.h,
|
||||
depth: 1,
|
||||
},
|
||||
bufferOffset: copied,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
auto fn = function(Descriptor* desc, VkBufferCopy copy)
|
||||
{
|
||||
vkCmdCopyBuffer(g_vk.imm_cmd, g_vk.transfer_buf.buffer, desc.buffer.buffer, 1, ©);
|
||||
};
|
||||
|
||||
success = ImmSubmit(image, copy, fn);
|
||||
VkBufferCopy copy = {
|
||||
srcOffset: 0,
|
||||
dstOffset: copied,
|
||||
size: copy_length,
|
||||
};
|
||||
}
|
||||
|
||||
success = ImmSubmit(desc, copy, fn);
|
||||
copied += copy_length;
|
||||
}
|
||||
|
||||
@ -1491,15 +1491,15 @@ Transfer(Image* image, u8[] data, u32 w, u32 h)
|
||||
}
|
||||
|
||||
void
|
||||
Copy(VkCommandBuffer cmd, Image* src, Image* dst, VkExtent2D src_ext, VkExtent2D dst_ext)
|
||||
Copy(VkCommandBuffer cmd, Descriptor* src, Descriptor* dst, VkExtent2D src_ext, VkExtent2D dst_ext)
|
||||
{
|
||||
Copy(cmd, src.image, dst.image, src.layout, dst.layout, src_ext, dst_ext);
|
||||
Copy(cmd, src.image.image, dst.image.image, src.image.layout, dst.image.layout, src_ext, dst_ext);
|
||||
}
|
||||
|
||||
void
|
||||
Copy(VkCommandBuffer cmd, Image* src, VkImage dst, VkImageLayout dst_layout, VkExtent2D src_ext, VkExtent2D dst_ext)
|
||||
Copy(VkCommandBuffer cmd, Descriptor* src, VkImage dst, VkImageLayout dst_layout, VkExtent2D src_ext, VkExtent2D dst_ext)
|
||||
{
|
||||
Copy(cmd, src.image, dst, src.layout, dst_layout, src_ext, dst_ext);
|
||||
Copy(cmd, src.image.image, dst, src.image.layout, dst_layout, src_ext, dst_ext);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1696,6 +1696,12 @@ ResetScissor(VkCommandBuffer cmd = cast(VkCommandBuffer)VK_NULL_HANDLE)
|
||||
vkCmdSetScissor(cmd, 0, 1, &scissor);
|
||||
}
|
||||
|
||||
void
|
||||
Transition(VkCommandBuffer cmd, Descriptor* desc, VkImageLayout new_layout)
|
||||
{
|
||||
ImageDescCheck(desc);
|
||||
Transition(cmd, desc.image.image, desc.image.layout, new_layout);
|
||||
}
|
||||
|
||||
void
|
||||
Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout)
|
||||
@ -1727,16 +1733,14 @@ Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkI
|
||||
vkCmdPipelineBarrier2(cmd, &dep_info);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
ImageDescCheck(Descriptor* desc)
|
||||
{
|
||||
ImageDescCheck(desc.type);
|
||||
return ImageDescCheck(desc.type);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
ImageDescCheck(DescType desc_type)
|
||||
{
|
||||
debug
|
||||
{
|
||||
bool match;
|
||||
enum types = [DT.CombinedSampler, DT.Image, DT.StorageImage, DT.InputAttach];
|
||||
@ -1745,29 +1749,7 @@ ImageDescCheck(DescType desc_type)
|
||||
match |= desc_type == type;
|
||||
}
|
||||
|
||||
assert(match, "Unable to transition non image");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Transition(VkCommandBuffer cmd, Descriptor* desc, VkImageLayout new_layout)
|
||||
{
|
||||
ImageDescCheck(desc);
|
||||
Transition(cmd, &desc.view, new_layout);
|
||||
}
|
||||
|
||||
void
|
||||
Transition(VkCommandBuffer cmd, ImageView* view, VkImageLayout new_layout)
|
||||
{
|
||||
Transition(cmd, view.image, view.layout, new_layout);
|
||||
view.layout = new_layout;
|
||||
}
|
||||
|
||||
void
|
||||
Transition(VkCommandBuffer cmd, Image* image, VkImageLayout new_layout)
|
||||
{
|
||||
Transition(cmd, image.image, image.layout, new_layout);
|
||||
image.layout = new_layout;
|
||||
return match;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1787,6 +1769,7 @@ bool
|
||||
CreateGraphicsPipeline(Pipeline* pipeline_handle, GfxPipelineInfo* build_info)
|
||||
{
|
||||
PipelineHandles* pipeline = NewPipeline();
|
||||
|
||||
pipeline.type = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
pipeline.layout = build_info.layout;
|
||||
|
||||
@ -1839,8 +1822,8 @@ CreateGraphicsPipeline(Pipeline* pipeline_handle, GfxPipelineInfo* build_info)
|
||||
VkPipelineRenderingCreateInfo rendering_info = {
|
||||
sType: VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||
colorAttachmentCount: 1,
|
||||
pColorAttachmentFormats: cast(VkFormat*)&g_vk.draw_image.view.format,
|
||||
depthAttachmentFormat: g_vk.depth_image.view.format,
|
||||
pColorAttachmentFormats: cast(VkFormat*)&g_vk.draw_image.image.format,
|
||||
depthAttachmentFormat: g_vk.depth_image.image.format,
|
||||
};
|
||||
|
||||
VkPipelineColorBlendAttachmentState blend_state = {
|
||||
@ -2043,24 +2026,17 @@ ClearColor(f32[4] color)
|
||||
|
||||
void
|
||||
ClearColor(Descriptor* desc, f32[4] color)
|
||||
{
|
||||
ImageDescCheck(desc);
|
||||
ClearColor(&desc.view, color);
|
||||
}
|
||||
|
||||
void
|
||||
ClearColor(ImageView* view, f32[4] color)
|
||||
{
|
||||
VkImageSubresourceRange clear_range = {
|
||||
aspectMask: (view.depth_image ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT),
|
||||
aspectMask: (desc.image.usage == IU.Depth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT),
|
||||
levelCount: 1,
|
||||
layerCount: 1,
|
||||
};
|
||||
|
||||
vkCmdClearColorImage(
|
||||
g_vk.cmd,
|
||||
view.image,
|
||||
view.layout,
|
||||
desc.image.image,
|
||||
desc.image.layout,
|
||||
cast(VkClearColorValue*)color,
|
||||
1,
|
||||
&clear_range
|
||||
@ -2150,11 +2126,7 @@ PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc)
|
||||
write.dstSet = set.handle;
|
||||
write.dstBinding = desc.binding;
|
||||
write.descriptorCount = 1;
|
||||
|
||||
if(desc.array_elem)
|
||||
{
|
||||
write.dstArrayElement = desc.index;
|
||||
}
|
||||
|
||||
switch(desc.type) with(DescType)
|
||||
{
|
||||
@ -2162,22 +2134,22 @@ PrepareWrite(VkWriteDescriptorSet* write, DescSet set, Descriptor* desc)
|
||||
{
|
||||
VkDescriptorImageInfo* info = Alloc!(VkDescriptorImageInfo)(arena);
|
||||
|
||||
info.imageView = desc.view.view;
|
||||
info.imageLayout = desc.view.shader_layout;
|
||||
info.imageView = desc.image.view;
|
||||
info.imageLayout = desc.image.shader_layout;
|
||||
write.pImageInfo = info;
|
||||
} break;
|
||||
case Uniform, Storage:
|
||||
{
|
||||
VkDescriptorBufferInfo* info = Alloc!(VkDescriptorBufferInfo)(arena);
|
||||
|
||||
info.buffer = desc.buf.buffer;
|
||||
info.buffer = desc.buffer.buffer;
|
||||
info.offset = cast(VkDeviceSize)0;
|
||||
info.range = cast(VkDeviceSize)desc.buf.size;
|
||||
info.range = cast(VkDeviceSize)desc.buffer.size;
|
||||
write.pBufferInfo = info;
|
||||
} break;
|
||||
case UniformTexelBuf, StorageTexelBuf:
|
||||
{
|
||||
write.pTexelBufferView = &desc.buf_view.view;
|
||||
write.pTexelBufferView = &desc.buffer_view.view;
|
||||
} break;
|
||||
case Sampler:
|
||||
{
|
||||
@ -2371,8 +2343,8 @@ SelectSwapchainFormats()
|
||||
g_vk.present_mode = present_mode;
|
||||
}
|
||||
|
||||
Descriptor
|
||||
CreateSampler(MipmapMode mode, u32 binding)
|
||||
void
|
||||
CreateSampler(Descriptor* desc, MipmapMode mode)
|
||||
{
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(g_vk.physical_device, &props);
|
||||
@ -2391,15 +2363,8 @@ CreateSampler(MipmapMode mode, u32 binding)
|
||||
mipmapMode: mode,
|
||||
};
|
||||
|
||||
Descriptor sampler = {
|
||||
type: DT.Sampler,
|
||||
binding: binding,
|
||||
};
|
||||
|
||||
VkResult result = vkCreateSampler(g_vk.device, &sampler_info, null, &sampler.sampler);
|
||||
VkResult result = vkCreateSampler(g_vk.device, &sampler_info, null, &desc.sampler);
|
||||
VkCheckA("vkCreateSampler failure", result);
|
||||
|
||||
return sampler;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2413,8 +2378,8 @@ CreateDrawImages()
|
||||
u32 w = g_vk.swapchain_extent.width;
|
||||
u32 h = g_vk.swapchain_extent.height;
|
||||
|
||||
CreateImageView(&g_vk.draw_image, w, h, draw_format, IU.Draw, DT.StorageImage, 0);
|
||||
CreateImageView(&g_vk.depth_image, w, h, depth_format, IU.Depth, DT.Image, 0);
|
||||
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));
|
||||
|
||||
return success;
|
||||
}
|
||||
@ -2448,12 +2413,12 @@ CreateSwapchain()
|
||||
surface: g_vk.surface,
|
||||
imageFormat: g_vk.surface_format.format,
|
||||
imageColorSpace: g_vk.surface_format.colorSpace,
|
||||
preTransform: cap.currentTransform,
|
||||
presentMode: g_vk.present_mode,
|
||||
imageExtent: {
|
||||
width: w,
|
||||
height: h,
|
||||
},
|
||||
preTransform: cap.currentTransform,
|
||||
presentMode: g_vk.present_mode,
|
||||
};
|
||||
|
||||
VkResult result = vkCreateSwapchainKHR(g_vk.device, &info, null, &g_vk.swapchain);
|
||||
@ -2465,7 +2430,7 @@ CreateSwapchain()
|
||||
vkGetSwapchainImagesKHR(g_vk.device, g_vk.swapchain, &count, images.ptr);
|
||||
VkImageView[] views = Alloc!(VkImageView)(arena, count);
|
||||
|
||||
g_vk.present_images = Alloc!(ImageView)(&g_vk.arena, count);
|
||||
g_vk.present_images = Alloc!(Descriptor)(&g_vk.arena, count);
|
||||
|
||||
VkImageViewCreateInfo view_info = {
|
||||
sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
@ -2485,18 +2450,17 @@ CreateSwapchain()
|
||||
},
|
||||
};
|
||||
|
||||
VkFramebufferCreateInfo framebuffer_info = {
|
||||
sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
};
|
||||
VkFramebufferCreateInfo framebuffer_info = { sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO };
|
||||
|
||||
foreach(i, image; g_vk.present_images)
|
||||
foreach(i; 0 .. g_vk.present_images.length)
|
||||
{
|
||||
g_vk.present_images[i].image = images[i];
|
||||
g_vk.present_images[i].format = cast(Format)g_vk.surface_format.format;
|
||||
g_vk.present_images[i].image.image = images[i];
|
||||
g_vk.present_images[i].image.format = cast(Format)g_vk.surface_format.format;
|
||||
|
||||
view_info.image = images[i];
|
||||
view_info.format = g_vk.surface_format.format;
|
||||
|
||||
result = vkCreateImageView(g_vk.device, &view_info, null, &g_vk.present_images[i].view);
|
||||
result = vkCreateImageView(g_vk.device, &view_info, null, &g_vk.present_images[i].image.view);
|
||||
success = VkCheck("vkCreateImageView failure", result);
|
||||
}
|
||||
|
||||
@ -2537,7 +2501,7 @@ CreateFramebuffer()
|
||||
sType: VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
renderPass: g_vk.render_pass,
|
||||
attachmentCount: 2,
|
||||
pAttachments: [g_vk.draw_image.view.view, g_vk.depth_image.view.view],
|
||||
pAttachments: [g_vk.draw_image.image.view, g_vk.depth_image.image.view],
|
||||
width: g_vk.swapchain_extent.width,
|
||||
height: g_vk.swapchain_extent.height,
|
||||
layers: 1,
|
||||
@ -2571,33 +2535,33 @@ Destroy(Descriptor* desc)
|
||||
} break;
|
||||
case DT.CombinedSampler, DT.Image, DT.StorageImage, DT.InputAttach:
|
||||
{
|
||||
if(desc.view.view)
|
||||
if(desc.image.view)
|
||||
{
|
||||
vkDestroyImageView(g_vk.device, desc.view.view, null);
|
||||
vkDestroyImageView(g_vk.device, desc.image.view, null);
|
||||
}
|
||||
|
||||
if(desc.view.image)
|
||||
if(desc.image.image)
|
||||
{
|
||||
vmaDestroyImage(g_vk.vma, desc.view.image, desc.view.alloc);
|
||||
vmaDestroyImage(g_vk.vma, desc.image.image, desc.image.alloc);
|
||||
}
|
||||
} break;
|
||||
case DT.UniformTexelBuf, DT.StorageTexelBuf:
|
||||
{
|
||||
if(desc.buf_view.view)
|
||||
if(desc.buffer_view.view)
|
||||
{
|
||||
vkDestroyBufferView(g_vk.device, desc.buf_view.view, null);
|
||||
vkDestroyBufferView(g_vk.device, desc.buffer_view.view, null);
|
||||
}
|
||||
|
||||
if(desc.buf_view.buffer)
|
||||
if(desc.buffer_view.buffer)
|
||||
{
|
||||
vmaDestroyBuffer(g_vk.vma, desc.buf_view.buffer, desc.buf_view.alloc);
|
||||
vmaDestroyBuffer(g_vk.vma, desc.buffer_view.buffer, desc.buffer_view.alloc);
|
||||
}
|
||||
} break;
|
||||
case DT.Uniform, DT.DynamicUniform, DT.Storage, DT.DynamicStorage:
|
||||
{
|
||||
if(desc.buf.buffer)
|
||||
if(desc.buffer.buffer)
|
||||
{
|
||||
vmaDestroyBuffer(g_vk.vma, desc.buf.buffer, desc.buf.alloc);
|
||||
vmaDestroyBuffer(g_vk.vma, desc.buffer.buffer, desc.buffer.alloc);
|
||||
}
|
||||
} break;
|
||||
default: assert(false, "Unsupported descriptor Destroy call");
|
||||
@ -2643,13 +2607,13 @@ Destroy(VkSurfaceKHR surface, VkInstance instance)
|
||||
}
|
||||
|
||||
void
|
||||
Destroy(VkSwapchainKHR swapchain, ImageView[] views, VkDevice device)
|
||||
Destroy(VkSwapchainKHR swapchain, Descriptor[] images, VkDevice device)
|
||||
{
|
||||
foreach(view; views)
|
||||
foreach(ref image; images)
|
||||
{
|
||||
if(view.view)
|
||||
if(image.image.view)
|
||||
{
|
||||
vkDestroyImageView(device, view.view, null);
|
||||
vkDestroyImageView(device, image.image.view, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3341,7 +3305,7 @@ Init(PlatformHandles platform_handles, u64 permanent_mem, u64 frame_mem)
|
||||
|
||||
VkAttachmentDescription[2] attach_descriptions = [
|
||||
{
|
||||
format: g_vk.draw_image.view.format,
|
||||
format: g_vk.draw_image.image.format,
|
||||
samples: VK_SAMPLE_COUNT_1_BIT,
|
||||
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
||||
@ -3351,7 +3315,7 @@ Init(PlatformHandles platform_handles, u64 permanent_mem, u64 frame_mem)
|
||||
finalLayout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
},
|
||||
{
|
||||
format: g_vk.depth_image.view.format,
|
||||
format: g_vk.depth_image.image.format,
|
||||
samples: VK_SAMPLE_COUNT_1_BIT,
|
||||
loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
storeOp: VK_ATTACHMENT_STORE_OP_STORE,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user