#include "pan_util.h"
#include "midgard/midgard_compile.h"
#include "compiler/nir/nir_builder.h"
-#include "midgard/nir_lower_blend.h"
+#include "nir/nir_lower_blend.h"
#include "gallium/auxiliary/util/u_blend.h"
+#include "util/u_memory.h"
/*
* Implements the command stream portion of programmatic blend shaders.
nir_lower_blend_options options;
for (unsigned i = 0; i < nr_cbufs; ++i) {
+ /* If blend is disabled, we just use replace mode */
+
nir_lower_blend_channel rgb = {
- .func = util_blend_func_to_shader(blend->rt[i].rgb_func),
- .src_factor = util_blend_factor_to_shader(blend->rt[i].rgb_src_factor),
- .dst_factor = util_blend_factor_to_shader(blend->rt[i].rgb_dst_factor),
- .invert_src_factor = util_blend_factor_is_inverted(blend->rt[i].rgb_src_factor),
- .invert_dst_factor = util_blend_factor_is_inverted(blend->rt[i].rgb_dst_factor)
+ .func = BLEND_FUNC_ADD,
+ .src_factor = BLEND_FACTOR_ZERO,
+ .invert_src_factor = true,
+ .dst_factor = BLEND_FACTOR_ZERO,
+ .invert_dst_factor = false
};
- nir_lower_blend_channel alpha = {
- .func = util_blend_func_to_shader(blend->rt[i].alpha_func),
- .src_factor = util_blend_factor_to_shader(blend->rt[i].alpha_src_factor),
- .dst_factor = util_blend_factor_to_shader(blend->rt[i].alpha_dst_factor),
- .invert_src_factor = util_blend_factor_is_inverted(blend->rt[i].alpha_src_factor),
- .invert_dst_factor = util_blend_factor_is_inverted(blend->rt[i].alpha_dst_factor)
- };
+ nir_lower_blend_channel alpha = rgb;
+
+ if (blend->rt[i].blend_enable) {
+ rgb.func = util_blend_func_to_shader(blend->rt[i].rgb_func);
+ rgb.src_factor = util_blend_factor_to_shader(blend->rt[i].rgb_src_factor);
+ rgb.dst_factor = util_blend_factor_to_shader(blend->rt[i].rgb_dst_factor);
+ rgb.invert_src_factor = util_blend_factor_is_inverted(blend->rt[i].rgb_src_factor);
+ rgb.invert_dst_factor = util_blend_factor_is_inverted(blend->rt[i].rgb_dst_factor);
+
+ alpha.func = util_blend_func_to_shader(blend->rt[i].alpha_func);
+ alpha.src_factor = util_blend_factor_to_shader(blend->rt[i].alpha_src_factor);
+ alpha.dst_factor = util_blend_factor_to_shader(blend->rt[i].alpha_dst_factor);
+ alpha.invert_src_factor = util_blend_factor_is_inverted(blend->rt[i].alpha_src_factor);
+ alpha.invert_dst_factor = util_blend_factor_is_inverted(blend->rt[i].alpha_dst_factor);
+ }
options.rt[i].rgb = rgb;
options.rt[i].alpha = alpha;
return options;
}
-void
-panfrost_make_blend_shader(
- struct panfrost_context *ctx,
- struct panfrost_blend_state *cso,
- const struct pipe_blend_color *blend_color,
- enum pipe_format format)
+struct panfrost_blend_shader
+panfrost_compile_blend_shader(
+ struct panfrost_context *ctx,
+ struct pipe_blend_state *cso,
+ enum pipe_format format)
{
+ struct panfrost_blend_shader res;
+
/* Build the shader */
nir_shader *shader = nir_shader_create(NULL, MESA_SHADER_FRAGMENT, &midgard_nir_options, NULL);
nir_store_var(b, c_out, s_src, 0xFF);
nir_lower_blend_options options =
- nir_make_options(&cso->base, 1);
+ nir_make_options(cso, 1);
NIR_PASS_V(shader, nir_lower_blend, options);
NIR_PASS_V(shader, nir_lower_framebuffer, format);
int size = program.compiled.size;
uint8_t *dst = program.compiled.data;
- /* Hot patch in constant color */
+ res.shader.cpu = mem_dup(dst, size);
+ res.shader.gpu = panfrost_upload(&ctx->shaders, dst, size);
- if (program.blend_patch_offset >= 0) {
- float *hot_color = (float *) (dst + program.blend_patch_offset);
-
- for (int c = 0; c < 4; ++c)
- hot_color[c] = blend_color->color[c];
- }
-
- cso->blend_shader = panfrost_upload(&ctx->shaders, dst, size, true) | program.first_tag;
+ /* At least two work registers are needed due to an encoding quirk */
+ res.work_count = MAX2(program.work_register_count, 2);
- /* We need to switch to shader mode */
- cso->has_blend_shader = true;
+ /* Allow us to patch later */
+ res.patch_index = program.blend_patch_offset;
+ res.first_tag = program.first_tag;
+ res.size = size;
- /* At least two work registers are needed due to an encoding quirk */
- cso->blend_work_count = MAX2(program.work_register_count, 2);
+ return res;
}