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