summaryrefslogtreecommitdiff
path: root/video.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'video.cpp')
-rw-r--r--video.cpp363
1 files changed, 284 insertions, 79 deletions
diff --git a/video.cpp b/video.cpp
index 4a79adb..ba6fd7c 100644
--- a/video.cpp
+++ b/video.cpp
@@ -6,6 +6,7 @@
#define max_buffers 1024
#define max_vertex_formats 64
#define max_rpos 64
+#define max_fbos 64
#define max_pipelines 64
#define max_descriptor_sets 64
#define max_shaders 32
@@ -203,11 +204,42 @@ static VkFormat get_vk_format(Texture_Format fmt) {
case texture_format_rgb16f: return VK_FORMAT_R16G16B16_SFLOAT;
case texture_format_rgb32f: return VK_FORMAT_R32G32B32_SFLOAT;
case texture_format_rgba8i: return VK_FORMAT_R8G8B8A8_UNORM;
+ case texture_format_rgba8i_srgb: return VK_FORMAT_R8G8B8A8_SRGB;
+ case texture_format_bgra8i_srgb: return VK_FORMAT_B8G8R8A8_SRGB;
case texture_format_rgba16f: return VK_FORMAT_R16G16B16A16_SFLOAT;
case texture_format_rgba32f: return VK_FORMAT_R32G32B32A32_SFLOAT;
case texture_format_bc1: return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
- default: assert(0); return VK_FORMAT_UNDEFINED;
+ case texture_format_d16: return VK_FORMAT_D16_UNORM;
+ case texture_format_d24s8: return VK_FORMAT_D24_UNORM_S8_UINT;
+ case texture_format_d32: return VK_FORMAT_D32_SFLOAT;
+ case texture_format_count: break;
}
+ assert(0);
+ return VK_FORMAT_UNDEFINED;
+}
+
+static VkImageUsageFlags get_texture_usage(int flags) {
+ VkImageUsageFlags f = 0;
+ if (flags & Texture_Flags::sampleable)
+ f |= VK_IMAGE_USAGE_SAMPLED_BIT;
+ if (flags & Texture_Flags::colour_target)
+ f |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ if (flags & Texture_Flags::depth_stencil_target)
+ f |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ if (flags & Texture_Flags::copy_src)
+ f |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ if (flags & Texture_Flags::copy_dst)
+ f |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ return f;
+}
+
+static VkImageAspectFlags get_image_aspect(int flags) {
+ VkImageUsageFlags f = 0;
+ if (flags & Texture_Flags::depth_stencil_target)
+ f |= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+ else
+ f |= VK_IMAGE_ASPECT_COLOR_BIT;
+ return f;
}
VkImageLayout state_to_image_layout(Resource_State s) {
@@ -446,6 +478,7 @@ struct Shader_Vk : public Shader, public Late_Terminated {
};
struct Renderpass_Vk;
+struct Framebuffer_Vk;
struct Context_Vk : public Context {
int state;
Device_Vk* dev;
@@ -463,8 +496,10 @@ struct Context_Vk : public Context {
void release();
void destroy();
- Renderpass_Vk& begin_rp(const Render_Pass& rp);
- void end_rp(Renderpass_Vk& rpo);
+ std::pair<Renderpass_Vk&, Framebuffer_Vk&> begin_rp(
+ const Render_Pass& rp
+ );
+ void end_rp(Renderpass_Vk& rpo, Framebuffer_Vk& fbo);
};
struct Texture_Vk : public Texture, public Late_Terminated {
@@ -520,7 +555,14 @@ struct Rpo_Key {
bool operator==(const Rpo_Key& other) const {
return
is_first == other.is_first &&
- rpo == other.rpo;
+ rpo.layout_eq(other.rpo);
+ }
+};
+
+struct Fbo_Key {
+ Render_Pass rpo;
+ bool operator==(const Fbo_Key& other) const {
+ return rpo.resources_eq(other.rpo);
}
};
@@ -546,8 +588,6 @@ struct Dso_Key {
struct Renderpass_Vk {
VkRenderPass rpo;
- VkFramebuffer fbo;
- VkClearValue clear;
int age;
void on_submit() {
@@ -556,8 +596,23 @@ struct Renderpass_Vk {
VkAttachmentLoadOp load_op_from_mode(Clear_Mode m);
- void init_rp(Device_Vk* dev, const Rpo_Key& rp);
- void init_fb(Device_Vk* dev, const Render_Pass& rp);
+ void init(Device_Vk* dev, const Rpo_Key& rp);
+ void destroy(Device_Vk* dev);
+};
+
+struct Framebuffer_Vk {
+ VkFramebuffer fbo;
+ int age;
+
+ void on_submit() {
+ age = 0;
+ }
+
+ void init(
+ Device_Vk* dev,
+ const Renderpass_Vk& rpo,
+ const Render_Pass& rp
+ );
void destroy(Device_Vk* dev);
};
@@ -626,6 +681,8 @@ struct Pipeline_Vk {
const Pipeline& desc
);
+ static VkCompareOp get_compare_op(Depth_Mode m);
+
void on_submit() {
age = 0;
}
@@ -673,10 +730,18 @@ struct Sampler_Vk : public Late_Terminated {
template<>
struct Hash_Function<Rpo_Key> {
size_t operator()(const Rpo_Key& k) const {
- return (size_t)fnv1a64_2(fnv1a64(
- (uint8_t*)&k.rpo,
- sizeof k.rpo
- ), (uint8_t*)&k.is_first, 1);
+ return (size_t)fnv1a64_2(
+ k.rpo.layout_hash,
+ (uint8_t*)&k.is_first,
+ 1
+ );
+ }
+};
+
+template<>
+struct Hash_Function<Fbo_Key> {
+ size_t operator()(const Fbo_Key& k) const {
+ return k.rpo.resource_hash;
}
};
@@ -736,13 +801,6 @@ struct Hash_Function<Sampler_Id> {
}
};
-template<>
-struct std::hash<Render_Pass> {
- size_t operator()(const Render_Pass& rp) const {
- return (size_t)fnv1a64((uint8_t*)&rp, sizeof rp);
- }
-};
-
struct Shader_Loader : public Asset_Loader {
Device_Vk* dev;
void init(Device_Vk* d);
@@ -818,6 +876,7 @@ struct Device_Vk : public Device {
uint32_t sampler_count;
Hash_Map<Rpo_Key, Renderpass_Vk, max_rpos> rpo_cache;
+ Hash_Map<Fbo_Key, Framebuffer_Vk, max_fbos> fbo_cache;
Hash_Map<Pso_Key, Pipeline_Vk, max_pipelines> pso_cache;
Hash_Map<Dso_Key, Descriptor_Set_Vk, max_descriptor_sets> dso_cache;
@@ -825,6 +884,8 @@ struct Device_Vk : public Device {
uint32_t terminator_index;
bool first_rp;
+ Texture_Id depth;
+
Texture_Id alloc_texture();
Buffer_Id alloc_buffer();
Vertex_Format_Id alloc_vf();
@@ -846,6 +907,14 @@ struct Device_Vk : public Device {
Renderpass_Vk& create_rpo(const Rpo_Key& rp);
Renderpass_Vk& get_rpo(const Rpo_Key& rp);
+ Framebuffer_Vk& create_fbo(
+ const Renderpass_Vk& rpo,
+ const Fbo_Key& fb
+ );
+ Framebuffer_Vk& get_fbo(
+ const Renderpass_Vk& rpo,
+ const Fbo_Key& fb
+ );
Pipeline_Vk& create_pso(const Pso_Key& pip);
Pipeline_Vk& get_pso(const Pso_Key& pop);
Descriptor_Set_Vk& create_dso(
@@ -860,6 +929,7 @@ struct Device_Vk : public Device {
void collect_garbage();
void queue_destroy(Late_Terminated* obj);
void create_terminators();
+ void create_depth(int w, int h);
int find_memory_type(
uint32_t filter,
@@ -1175,6 +1245,7 @@ void Device_Vk::init_internal() {
samplers.init();
sampler_count = 1;
rpo_cache.init();
+ fbo_cache.init();
pso_cache.init();
dso_cache.init();
shader_loader.init(this);
@@ -1198,6 +1269,8 @@ void Device_Vk::init_internal() {
contexts[i].state = context_state_avail;
swapchain.init(*app, this);
create_terminators();
+ depth = 0;
+ create_depth(app->w, app->h);
}
void Device_Vk::create_terminators() {
@@ -1216,14 +1289,29 @@ void Device_Vk::create_terminators() {
}
}
+void Device_Vk::create_depth(int w, int h) {
+ if (depth)
+ destroy_texture(depth);
+ depth = create_texture(
+ texture_format_d24s8,
+ Texture_Flags::sampleable | Texture_Flags::depth_stencil_target,
+ w,
+ h,
+ 0
+ );
+}
+
void Device_Vk::deinit_internal() {
int i, image_count = swapchain.image_count;
vkDeviceWaitIdle(dev);
+ destroy_texture(depth);
swapchain.destroy(this);
deinit_swap_cap(this, &swap_cap);
app_destroy_vk_surface(app, inst, surf);
for (auto i : rpo_cache)
i.second.destroy(this);
+ for (auto i : fbo_cache)
+ i.second.destroy(this);
for (auto i : pso_cache)
i.second.destroy(this);
for (auto i : dso_cache)
@@ -1255,20 +1343,13 @@ void Device_Vk::on_resize_internal(int w, int h) {
get_swap_cap(this, phys_dev, surf, &swap_cap);
swapchain.recreate(*app, this);
create_terminators();
+ create_depth(w, h);
}
Renderpass_Vk& Device_Vk::create_rpo(const Rpo_Key& k) {
- VkClearValue clear{};
- auto& rp = k.rpo;
- clear.color.float32[0] = (float)rp.clear.r / 255.0f;
- clear.color.float32[1] = (float)rp.clear.g / 255.0f;
- clear.color.float32[2] = (float)rp.clear.b / 255.0f;
- clear.color.float32[3] = (float)rp.clear.a / 255.0f;
Renderpass_Vk rpo;
- rpo.init_rp(this, k);
- rpo.init_fb(this, rp);
+ rpo.init(this, k);
rpo.age = 0;
- rpo.clear = clear;
return rpo_cache.set(k, rpo);
}
@@ -1279,6 +1360,27 @@ Renderpass_Vk& Device_Vk::get_rpo(const Rpo_Key& rp) {
return *rpo;
}
+Framebuffer_Vk& Device_Vk::create_fbo(
+ const Renderpass_Vk& rpo,
+ const Fbo_Key& k
+) {
+ auto& fb = k.rpo;
+ Framebuffer_Vk fbo;
+ fbo.init(this, rpo, fb);
+ fbo.age = 0;
+ return fbo_cache.set(k, fbo);
+}
+
+Framebuffer_Vk& Device_Vk::get_fbo(
+ const Renderpass_Vk& rpo,
+ const Fbo_Key& fb
+) {
+ Framebuffer_Vk* fbo = fbo_cache.get(fb);
+ if (!fbo)
+ return create_fbo(rpo, fb);
+ return *fbo;
+}
+
Pipeline_Vk& Device_Vk::create_pso(const Pso_Key& pip) {
Pipeline_Vk pso;
pso.age = 0;
@@ -1313,11 +1415,6 @@ Descriptor_Set_Vk& Device_Vk::get_dso(
return *dso;
}
-void Renderpass_Vk::destroy(Device_Vk* dev) {
- vkDestroyRenderPass(dev->dev, rpo, &dev->ac);
- vkDestroyFramebuffer(dev->dev, fbo, &dev->ac);
-}
-
void Device_Vk::collect_garbage() {
int max_age = swapchain.image_count + 3;
for (const auto& i: rpo_cache) {
@@ -1328,6 +1425,14 @@ void Device_Vk::collect_garbage() {
rpo_cache.remove(i.first);
}
}
+ for (const auto& i: fbo_cache) {
+ auto& fb = i.second;
+ fb.age++;
+ if (fb.age > max_age) {
+ fb.destroy(this);
+ fbo_cache.remove(i.first);
+ }
+ }
for (const auto& i: pso_cache) {
auto& pip = i.second;
pip.age++;
@@ -1377,39 +1482,63 @@ VkAttachmentLoadOp Renderpass_Vk::load_op_from_mode(
return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
}
-void Renderpass_Vk::init_rp(
+void Renderpass_Vk::init(
Device_Vk* dev,
const Rpo_Key& rpk
) {
VkRenderPassCreateInfo ri{};
- VkAttachmentDescription ad{};
- VkAttachmentReference ar{};
+ VkAttachmentDescription ads[2];
+ VkAttachmentReference car, dar;
VkSubpassDescription sd{};
VkResult r;
auto& rp = rpk.rpo;
-
- ad.format = dev->swapchain.format.format;
- ad.samples = VK_SAMPLE_COUNT_1_BIT;
- ad.loadOp = load_op_from_mode(rp.mode);
- ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- ad.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
- ad.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- if (rpk.is_first)
- ad.initialLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
- else
- ad.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- ad.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-
- ar.attachment = 0;
- ar.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ bool has_depth = rp.depth.id;
+ int count = 0, i, c = rp.colour_count;
+ zero(ads, sizeof ads);
+ for (i = 0; i < c; i++) {
+ int index = count++;
+ auto& colour = rp.colours[i];
+ auto& ad = ads[index];
+ ad.format = get_vk_format(colour.fmt);
+ ad.samples = VK_SAMPLE_COUNT_1_BIT;
+ ad.loadOp = load_op_from_mode(colour.mode);
+ ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ ad.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ ad.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ if (rpk.is_first)
+ ad.initialLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ else
+ ad.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ ad.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ car.attachment = index;
+ car.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ }
+ if (has_depth) {
+ int i = count++;
+ auto& ad = ads[i];
+ ad.format = get_vk_format(dev->get_texture(rp.depth.id).fmt);
+ ad.samples = VK_SAMPLE_COUNT_1_BIT;
+ ad.loadOp = load_op_from_mode(rp.depth.mode);
+ ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ ad.stencilLoadOp = ad.loadOp;
+ ad.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
+ if (rpk.is_first)
+ ad.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ else
+ ad.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ ad.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ dar.attachment = i;
+ dar.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+ }
sd.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
sd.colorAttachmentCount = 1;
- sd.pColorAttachments = &ar;
+ sd.pColorAttachments = &car;
+ sd.pDepthStencilAttachment = has_depth? &dar: 0;
ri.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
- ri.attachmentCount = 1;
- ri.pAttachments = &ad;
+ ri.attachmentCount = count;
+ ri.pAttachments = ads;
ri.subpassCount = 1;
ri.pSubpasses = &sd;
@@ -1420,21 +1549,42 @@ void Renderpass_Vk::init_rp(
}
}
-void Renderpass_Vk::init_fb(
+void Renderpass_Vk::destroy(Device_Vk* dev) {
+ vkDestroyRenderPass(dev->dev, rpo, &dev->ac);
+}
+
+void Framebuffer_Vk::init(
Device_Vk* dev,
+ const Renderpass_Vk& rpo,
const Render_Pass& rp
) {
- const Texture_Vk& texture =
- *(const Texture_Vk*)&dev->get_texture(rp.target);
+ bool has_depth = rp.depth.id;
+ int i, count = 0, w, h;
+ VkImageView atts[2];
VkResult r;
VkFramebufferCreateInfo fbi{};
+ for (i = 0; i < rp.colour_count; i++) {
+ const auto& tar = rp.colours[i];
+ const Texture_Vk& texture =
+ *(const Texture_Vk*)&dev->get_texture(tar.id);
+ atts[count++] = texture.view;
+ w = texture.w;
+ h = texture.h;
+ }
+ if (has_depth) {
+ const Texture_Vk& texture =
+ *(const Texture_Vk*)&dev->get_texture(rp.depth.id);
+ atts[count++] = texture.view;
+ w = texture.w;
+ h = texture.h;
+ }
fbi.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
- fbi.renderPass = rpo;
- fbi.width = texture.w;
- fbi.height = texture.h;
+ fbi.renderPass = rpo.rpo;
+ fbi.width = w;
+ fbi.height = h;
fbi.layers = 1;
- fbi.attachmentCount = 1;
- fbi.pAttachments = &texture.view;
+ fbi.attachmentCount = count;
+ fbi.pAttachments = atts;
r = vkCreateFramebuffer(dev->dev, &fbi, &dev->ac, &fbo);
if (r != VK_SUCCESS) {
print_err("Failed to create a framebuffer.\n");
@@ -1442,6 +1592,10 @@ void Renderpass_Vk::init_fb(
}
}
+void Framebuffer_Vk::destroy(Device_Vk* dev) {
+ vkDestroyFramebuffer(dev->dev, fbo, &dev->ac);
+}
+
static int get_image_count(const Swap_Cap& s) {
const VkSurfaceCapabilitiesKHR& cap = s.cap;
return cap.minImageCount + (cap.minImageCount < cap.maxImageCount);
@@ -1479,7 +1633,7 @@ static VkImageView make_view(
Device_Vk* dev,
VkImage image,
VkFormat fmt,
- VkImageAspectFlagBits flags
+ VkImageAspectFlags flags
) {
VkImageViewCreateInfo vi{};
VkResult r;
@@ -1568,6 +1722,7 @@ Texture_Id Swapchain::create_image(
tex.view = view;
tex.w = w;
tex.h = h;
+ tex.fmt = texture_format_bgra8i_srgb;
tex.alias = true;
return id;
}
@@ -1716,6 +1871,10 @@ Texture_Id Device::get_backbuffer() {
return ((Device_Vk*)this)->backbuffer_id;
}
+Texture_Id Device::get_depth_target() {
+ return ((Device_Vk*)this)->depth;
+}
+
Texture& Device::get_texture(Texture_Id id) {
return ((Device_Vk*)this)->textures[id];
}
@@ -1802,7 +1961,7 @@ void Context::submit(
Descriptor_Set_Vk* dso = 0;
if (p.descriptor_count)
dso = &dev->get_dso(pso, *(Dso_Key*)&p);
- auto& rpo = ctx->begin_rp(rp);
+ auto [rpo, fbo] = ctx->begin_rp(rp);
Texture_Vk& target = *(Texture_Vk*)&dev->get_texture(
dev->get_backbuffer()
);
@@ -1855,7 +2014,7 @@ void Context::submit(
draw.first_instance
);
}
- ctx->end_rp(rpo);
+ ctx->end_rp(rpo, fbo);
pso.on_submit();
if (dso)
dso->on_submit();
@@ -2003,33 +2162,56 @@ void Context::transition(Texture_Id id, Resource_State state) {
);
}
-Renderpass_Vk& Context_Vk::begin_rp(const Render_Pass& rp) {
+std::pair<Renderpass_Vk&, Framebuffer_Vk&> Context_Vk::begin_rp(
+ const Render_Pass& rp
+) {
Renderpass_Vk& rpo = dev->get_rpo({ dev->first_rp, rp});
+ Framebuffer_Vk& fbo = dev->get_fbo(rpo, { rp });
VkRenderPassBeginInfo rpbi{};
+ VkClearValue clears[max_colour_attachments + 1];
+ int i, c = rp.colour_count, clear_count = 0;
+ bool has_depth = rp.depth.id;
+ for (i = 0; i < c; i++) {
+ VkClearValue clear{};
+ const auto& tar = rp.colours[i];
+ const auto col = tar.clear.colour;
+ clear.color.float32[0] = (float)col.r / 255.0f;
+ clear.color.float32[1] = (float)col.g / 255.0f;
+ clear.color.float32[2] = (float)col.b / 255.0f;
+ clear.color.float32[3] = (float)col.a / 255.0f;
+ clears[clear_count++] = clear;
+ }
+ if (has_depth) {
+ VkClearValue dc{};
+ dc.depthStencil.depth = rp.depth.clear.depth;
+ dc.depthStencil.stencil = 0; /* todo */
+ clears[clear_count++] = dc;
+ }
rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rpbi.renderPass = rpo.rpo;
- rpbi.framebuffer = rpo.fbo;
+ rpbi.framebuffer = fbo.fbo;
rpbi.renderArea.extent = dev->swapchain.size;
- rpbi.clearValueCount = rp.mode == Clear_Mode::clear? 1: 0;
- rpbi.pClearValues = &rpo.clear;
+ rpbi.clearValueCount = clear_count;
+ rpbi.pClearValues = clears;
vkCmdBeginRenderPass(
cb,
&rpbi,
VK_SUBPASS_CONTENTS_INLINE
);
dev->first_rp = false;
- return rpo;
+ return { rpo, fbo };
}
-void Context_Vk::end_rp(Renderpass_Vk& rpo) {
+void Context_Vk::end_rp(Renderpass_Vk& rpo, Framebuffer_Vk& fbo) {
vkCmdEndRenderPass(cb);
rpo.on_submit();
+ fbo.on_submit();
}
void Context::submit(const Render_Pass& rp) {
Context_Vk* ctx = (Context_Vk*)this;
- auto& rpo = ctx->begin_rp(rp);
- ctx->end_rp(rpo);
+ auto [rpo, fbo] = ctx->begin_rp(rp);
+ ctx->end_rp(rpo, fbo);
}
void Context_Vk::init_pool() {
@@ -2305,9 +2487,9 @@ void Pipeline_Vk::init_depthstencil(
(void)desc;
zero(&ds, sizeof ds);
ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
- ds.depthTestEnable = VK_FALSE;
- ds.depthWriteEnable = VK_FALSE;
- ds.depthCompareOp = VK_COMPARE_OP_LESS;
+ ds.depthTestEnable = desc.depth_test;
+ ds.depthWriteEnable = desc.depth_write;
+ ds.depthCompareOp = get_compare_op(desc.depth_mode);
ds.depthBoundsTestEnable = VK_FALSE;
ds.stencilTestEnable = VK_FALSE;
info.pDepthStencilState = &ds;
@@ -2403,6 +2585,20 @@ void Pipeline_Vk::init_descriptors(
}
}
+VkCompareOp Pipeline_Vk::get_compare_op(Depth_Mode m) {
+ switch (m) {
+ case Depth_Mode::less: return VK_COMPARE_OP_LESS;
+ case Depth_Mode::less_equal: return VK_COMPARE_OP_LESS_OR_EQUAL;
+ case Depth_Mode::equal: return VK_COMPARE_OP_EQUAL;
+ case Depth_Mode::greater: return VK_COMPARE_OP_GREATER;
+ case Depth_Mode::greater_equal: return VK_COMPARE_OP_GREATER_OR_EQUAL;
+ case Depth_Mode::always: return VK_COMPARE_OP_ALWAYS;
+ case Depth_Mode::never: return VK_COMPARE_OP_NEVER;
+ }
+ assert(0);
+ return VK_COMPARE_OP_LESS;
+}
+
void Pipeline_Vk::init_layout(
Device_Vk* dev,
const Pipeline& desc
@@ -2903,6 +3099,7 @@ Buffer& Device::get_buffer(Buffer_Id id) {
Texture_Id Device::create_texture(
Texture_Format fmt,
+ int flags,
int w,
int h,
Buffer_Id init
@@ -2913,6 +3110,7 @@ Texture_Id Device::create_texture(
Texture_Id id = dev->alloc_texture();
Texture_Vk& tex = *(Texture_Vk*)&dev->get_texture(id);
VkMemoryRequirements req;
+ VkImageAspectFlags aspect = get_image_aspect(flags);
tex.state = Resource_State::undefined;
ii.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
ii.imageType = VK_IMAGE_TYPE_2D;
@@ -2924,7 +3122,7 @@ Texture_Id Device::create_texture(
ii.format = get_vk_format(fmt);
ii.tiling = VK_IMAGE_TILING_OPTIMAL;
ii.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- ii.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
+ ii.usage = get_texture_usage(flags);
ii.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
ii.samples = VK_SAMPLE_COUNT_1_BIT;
r = vkCreateImage(dev->dev, &ii, &dev->ac, &tex.image);
@@ -2957,12 +3155,13 @@ Texture_Id Device::create_texture(
vkBindImageMemory(dev->dev, tex.image, tex.memory, 0);
tex.w = w;
tex.h = h;
+ tex.fmt = fmt;
tex.alias = false;
tex.view = make_view(
dev,
tex.image,
ii.format,
- VK_IMAGE_ASPECT_COLOR_BIT
+ aspect
);
if (init) {
Context& ctx = dev->acquire();
@@ -3170,7 +3369,13 @@ Asset* Texture_Loader::load(Arena* a, Arena* s, Pack_File* f) {
pack_read(f, data, size);
{
Buffer_Id buf = upload(data, size);
- Texture_Id tex = dev->create_texture(fmt, w, h, buf);
+ Texture_Id tex = dev->create_texture(
+ fmt,
+ Texture_Flags::sampleable | Texture_Flags::copy_dst,
+ w,
+ h,
+ buf
+ );
dev->destroy_buffer(buf);
return &dev->get_texture(tex);
}