diff options
author | quou <quou@disroot.org> | 2024-12-29 22:41:55 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2024-12-29 22:41:55 +1100 |
commit | 80b8a59afce450a87af7ca4082529d899b639779 (patch) | |
tree | 2204e24aff7665ca53b1f4ffca82ce7e0493a771 | |
parent | 4123d42aee69537f6fcede748a5d7b88277ef4af (diff) |
alpha blending
-rw-r--r-- | pipeline.cpp | 39 | ||||
-rw-r--r-- | ui.cpp | 5 | ||||
-rw-r--r-- | video.cpp | 80 | ||||
-rw-r--r-- | video.hpp | 45 |
4 files changed, 153 insertions, 16 deletions
diff --git a/pipeline.cpp b/pipeline.cpp index 015a5dd..a3ea553 100644 --- a/pipeline.cpp +++ b/pipeline.cpp @@ -165,6 +165,38 @@ void Pipeline_Builder::depth(bool test, bool write, Depth_Mode mode) { pip->depth_mode = mode; } +void Pipeline_Builder::blend( + Blend_Mode mode, + Blend_Factor src, + Blend_Factor dst +) { + blend( + mode, + src, + dst, + mode, + src, + dst + ); +} + +void Pipeline_Builder::blend( + Blend_Mode mode_col, + Blend_Factor src_col, + Blend_Factor dst_col, + Blend_Mode mode_alpha, + Blend_Factor src_alpha, + Blend_Factor dst_alpha +) { + pip->blend_enable = true; + pip->blend_mode = mode_col; + pip->blend_src = src_col; + pip->blend_dst = dst_col; + pip->blend_mode_alpha = mode_alpha; + pip->blend_src_alpha = src_alpha; + pip->blend_dst_alpha = dst_alpha; +} + void Pipeline_Builder::shader(Shader_Id s) { pip->shader = s; } @@ -226,6 +258,13 @@ Pipeline& Pipeline_Builder::build() { h(pip->pipeline_hash, pip->depth_test); h(pip->pipeline_hash, pip->depth_write); h(pip->pipeline_hash, pip->depth_mode); + h(pip->pipeline_hash, pip->blend_enable); + h(pip->pipeline_hash, pip->blend_mode); + h(pip->pipeline_hash, pip->blend_mode_alpha); + h(pip->pipeline_hash, pip->blend_src); + h(pip->pipeline_hash, pip->blend_dst); + h(pip->pipeline_hash, pip->blend_src_alpha); + h(pip->pipeline_hash, pip->blend_dst_alpha); { int i, e = pip->descriptor_count; pip->descriptor_resource_hash = fnv1a64(0, 0); @@ -272,6 +272,11 @@ void UI::render(Arena* s, Texture_Id target) { pb.begin(); pb.shader(shader); pb.vertex_format(vertex_format); + pb.blend( + Blend_Mode::add, + Blend_Factor::src_alpha, + Blend_Factor::inv_src_colour + ); pb.cbuffer(shader_info.config_binding, config_buf); pb.texture(shader_info.atlas_binding, atlas, sampler); Pipeline& pip = pb.build(); @@ -277,6 +277,35 @@ static VkFormat get_vk_format(Texture_Format fmt) { return VK_FORMAT_UNDEFINED; } +static VkBlendFactor get_vk_blend_factor(Blend_Factor mode) { + switch (mode) { + case Blend_Factor::zero: return VK_BLEND_FACTOR_ZERO; + case Blend_Factor::one: return VK_BLEND_FACTOR_ONE; + case Blend_Factor::src_colour: return VK_BLEND_FACTOR_SRC_COLOR; + case Blend_Factor::inv_src_colour: return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; + case Blend_Factor::dst_colour: return VK_BLEND_FACTOR_DST_COLOR; + case Blend_Factor::inv_dst_colour: return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; + case Blend_Factor::src_alpha: return VK_BLEND_FACTOR_SRC_ALPHA; + case Blend_Factor::inv_src_alpha: return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + case Blend_Factor::dst_alpha: return VK_BLEND_FACTOR_DST_ALPHA; + case Blend_Factor::inv_dst_alpha: return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; + } + assert(0); + return VK_BLEND_FACTOR_ONE; +} + +static VkBlendOp get_vk_blend_op(Blend_Mode mode) { + switch (mode) { + case Blend_Mode::add: return VK_BLEND_OP_ADD; + case Blend_Mode::subtract: return VK_BLEND_OP_SUBTRACT; + case Blend_Mode::reverse_subtract: return VK_BLEND_OP_SUBTRACT; + case Blend_Mode::min: return VK_BLEND_OP_MIN; + case Blend_Mode::max: return VK_BLEND_OP_MAX; + } + assert(0); + return VK_BLEND_OP_ADD; +} + static VkImageUsageFlags get_texture_usage(int flags) { VkImageUsageFlags f = 0; if (flags & Texture_Flags::sampleable) @@ -734,6 +763,7 @@ struct Pipeline_Vk { Arena& scope, Device_Vk* dev, VkGraphicsPipelineCreateInfo& info, + const Render_Pass& rp, const Pipeline& desc ); void init_layout( @@ -2621,6 +2651,7 @@ void Pipeline_Vk::init_blending( Arena& scope, Device_Vk* dev, VkGraphicsPipelineCreateInfo& info, + const Render_Pass& rp, const Pipeline& desc ) { VkPipelineColorBlendStateCreateInfo& bi = @@ -2628,26 +2659,45 @@ void Pipeline_Vk::init_blending( &scope, sizeof bi ); - VkPipelineColorBlendAttachmentState& abs = - *(VkPipelineColorBlendAttachmentState*)arena_alloc( - &scope, - sizeof abs - ); + VkPipelineColorBlendAttachmentState* abs; (void)dev; (void)desc; zero(&bi, sizeof bi); - zero(&abs, sizeof abs); - abs.colorWriteMask = - VK_COLOR_COMPONENT_R_BIT | - VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | - VK_COLOR_COMPONENT_A_BIT; - abs.blendEnable = VK_FALSE; + if (rp.colour_count) { + int i, c = rp.colour_count; + abs = + (VkPipelineColorBlendAttachmentState*)arena_alloc( + &scope, + sizeof abs * c + ); + zero(abs, sizeof *abs); + for (i = 0; i < c; i++) { + auto& ab = abs[i]; + ab.colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT; + ab.blendEnable = desc.blend_enable; + if (desc.blend_enable) { + ab.srcColorBlendFactor = + get_vk_blend_factor(desc.blend_src); + ab.dstColorBlendFactor = + get_vk_blend_factor(desc.blend_dst); + ab.srcAlphaBlendFactor = + get_vk_blend_factor(desc.blend_src_alpha); + ab.dstAlphaBlendFactor = + get_vk_blend_factor(desc.blend_dst_alpha); + ab.colorBlendOp = get_vk_blend_op(desc.blend_mode); + ab.alphaBlendOp = get_vk_blend_op(desc.blend_mode_alpha); + } + } + } bi.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; bi.flags = 0; bi.logicOpEnable = VK_FALSE; - bi.attachmentCount = 1; - bi.pAttachments = &abs; + bi.attachmentCount = rp.colour_count; + bi.pAttachments = abs; info.pColorBlendState = &bi; } @@ -2764,7 +2814,7 @@ void Pipeline_Vk::init(Device_Vk* dev, const Pso_Key& key) { init_rasterisation(scope, dev, info, desc); init_msaa(scope, dev, info, desc); init_depthstencil(scope, dev, info, desc); - init_blending(scope, dev, info, desc); + init_blending(scope, dev, info, key.rpo.rpo, desc); info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; info.flags = 0; info.renderPass = dev->get_rpo(key.rpo).rpo; @@ -83,13 +83,40 @@ enum class Depth_Mode { never }; +enum class Blend_Factor { + zero, + one, + src_colour, + inv_src_colour, + dst_colour, + inv_dst_colour, + src_alpha, + inv_src_alpha, + dst_alpha, + inv_dst_alpha +}; + +enum class Blend_Mode { + add, + subtract, + reverse_subtract, + min, + max +}; + + struct Pipeline { uint64_t pipeline_hash; uint64_t descriptor_resource_hash; int viewport[4]; int scissor[4]; bool depth_test, depth_write; + bool blend_enable; Depth_Mode depth_mode; + Blend_Factor blend_src, blend_dst; + Blend_Mode blend_mode; + Blend_Factor blend_src_alpha, blend_dst_alpha; + Blend_Mode blend_mode_alpha; Vertex_Format_Id vertex_format; Shader_Id shader; Descriptor descriptors[pipeline_max_descriptors]; @@ -109,7 +136,14 @@ struct Pipeline { scissor[3] == other.scissor[3] && depth_test == other.depth_test && depth_write == other.depth_write && - depth_mode == other.depth_mode; + depth_mode == other.depth_mode && + blend_enable == other.blend_enable && + blend_src == other.blend_src && + blend_dst == other.blend_dst && + blend_src_alpha == other.blend_src_alpha && + blend_dst_alpha == other.blend_dst_alpha && + blend_mode == other.blend_mode && + blend_mode_alpha == other.blend_mode_alpha; } bool desc_layout_eq(const Pipeline& other) const { @@ -257,6 +291,15 @@ struct Pipeline_Builder { void viewport(float x, float y, float w, float h); void scissor(float x, float y, float w, float h); void depth(bool test, bool write, Depth_Mode mode); + void blend(Blend_Mode mode, Blend_Factor src, Blend_Factor dst); + void blend( + Blend_Mode mode_col, + Blend_Factor src_col, + Blend_Factor dst_col, + Blend_Mode mode_alpha, + Blend_Factor src_alpha, + Blend_Factor dst_alpha + ); void shader(Shader_Id s); void vertex_format(Vertex_Format_Id vf); void texture(int binding, Texture_Id t, Sampler_Id s); |