summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pipeline.cpp39
-rw-r--r--ui.cpp5
-rw-r--r--video.cpp80
-rw-r--r--video.hpp45
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);
diff --git a/ui.cpp b/ui.cpp
index 8264576..f6caedd 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -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();
diff --git a/video.cpp b/video.cpp
index 1d71034..586a78e 100644
--- a/video.cpp
+++ b/video.cpp
@@ -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;
diff --git a/video.hpp b/video.hpp
index 9a5dbe3..9b64543 100644
--- a/video.hpp
+++ b/video.hpp
@@ -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);