17ec681f3Smrg/* 27ec681f3Smrg * Copyright (C) 2018 Alyssa Rosenzweig 37ec681f3Smrg * Copyright (C) 2019-2021 Collabora, Ltd. 47ec681f3Smrg * 57ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 67ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 77ec681f3Smrg * to deal in the Software without restriction, including without limitation 87ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 97ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 107ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 117ec681f3Smrg * 127ec681f3Smrg * The above copyright notice and this permission notice (including the next 137ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 147ec681f3Smrg * Software. 157ec681f3Smrg * 167ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 177ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 197ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 207ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 217ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 227ec681f3Smrg * SOFTWARE. 237ec681f3Smrg */ 247ec681f3Smrg 257ec681f3Smrg#ifndef __PAN_BLEND_H__ 267ec681f3Smrg#define __PAN_BLEND_H__ 277ec681f3Smrg 287ec681f3Smrg#include "genxml/gen_macros.h" 297ec681f3Smrg 307ec681f3Smrg#include "util/u_dynarray.h" 317ec681f3Smrg#include "util/format/u_format.h" 327ec681f3Smrg#include "compiler/shader_enums.h" 337ec681f3Smrg#include "compiler/nir/nir.h" 347ec681f3Smrg 357ec681f3Smrg#include "panfrost/util/pan_ir.h" 367ec681f3Smrg 377ec681f3Smrgstruct MALI_BLEND_EQUATION; 387ec681f3Smrgstruct panfrost_device; 397ec681f3Smrg 407ec681f3Smrgstruct pan_blend_equation { 417ec681f3Smrg unsigned blend_enable : 1; 427ec681f3Smrg enum blend_func rgb_func : 3; 437ec681f3Smrg unsigned rgb_invert_src_factor : 1; 447ec681f3Smrg enum blend_factor rgb_src_factor : 4; 457ec681f3Smrg unsigned rgb_invert_dst_factor : 1; 467ec681f3Smrg enum blend_factor rgb_dst_factor : 4; 477ec681f3Smrg enum blend_func alpha_func : 3; 487ec681f3Smrg unsigned alpha_invert_src_factor : 1; 497ec681f3Smrg enum blend_factor alpha_src_factor : 4; 507ec681f3Smrg unsigned alpha_invert_dst_factor : 1; 517ec681f3Smrg enum blend_factor alpha_dst_factor : 4; 527ec681f3Smrg unsigned color_mask : 4; 537ec681f3Smrg}; 547ec681f3Smrg 557ec681f3Smrgstruct pan_blend_rt_state { 567ec681f3Smrg /* RT format */ 577ec681f3Smrg enum pipe_format format; 587ec681f3Smrg 597ec681f3Smrg /* Number of samples */ 607ec681f3Smrg unsigned nr_samples; 617ec681f3Smrg 627ec681f3Smrg struct pan_blend_equation equation; 637ec681f3Smrg}; 647ec681f3Smrg 657ec681f3Smrgstruct pan_blend_state { 667ec681f3Smrg bool logicop_enable; 677ec681f3Smrg enum pipe_logicop logicop_func; 687ec681f3Smrg float constants[4]; 697ec681f3Smrg unsigned rt_count; 707ec681f3Smrg struct pan_blend_rt_state rts[8]; 717ec681f3Smrg}; 727ec681f3Smrg 737ec681f3Smrgstruct pan_blend_shader_key { 747ec681f3Smrg enum pipe_format format; 757ec681f3Smrg nir_alu_type src0_type, src1_type; 767ec681f3Smrg uint32_t rt : 3; 777ec681f3Smrg uint32_t has_constants : 1; 787ec681f3Smrg uint32_t logicop_enable : 1; 797ec681f3Smrg uint32_t logicop_func:4; 807ec681f3Smrg uint32_t nr_samples : 5; 817ec681f3Smrg uint32_t padding : 18; 827ec681f3Smrg struct pan_blend_equation equation; 837ec681f3Smrg}; 847ec681f3Smrg 857ec681f3Smrgstruct pan_blend_shader_variant { 867ec681f3Smrg struct list_head node; 877ec681f3Smrg float constants[4]; 887ec681f3Smrg struct util_dynarray binary; 897ec681f3Smrg unsigned first_tag; 907ec681f3Smrg unsigned work_reg_count; 917ec681f3Smrg}; 927ec681f3Smrg 937ec681f3Smrg#define PAN_BLEND_SHADER_MAX_VARIANTS 16 947ec681f3Smrg 957ec681f3Smrgstruct pan_blend_shader { 967ec681f3Smrg struct pan_blend_shader_key key; 977ec681f3Smrg unsigned nvariants; 987ec681f3Smrg struct list_head variants; 997ec681f3Smrg}; 1007ec681f3Smrg 1017ec681f3Smrgbool 1027ec681f3Smrgpan_blend_reads_dest(const struct pan_blend_equation eq); 1037ec681f3Smrg 1047ec681f3Smrgbool 1057ec681f3Smrgpan_blend_can_fixed_function(const struct pan_blend_equation equation, 1067ec681f3Smrg bool supports_2src); 1077ec681f3Smrg 1087ec681f3Smrgbool 1097ec681f3Smrgpan_blend_is_opaque(const struct pan_blend_equation eq); 1107ec681f3Smrg 1117ec681f3Smrgunsigned 1127ec681f3Smrgpan_blend_constant_mask(const struct pan_blend_equation eq); 1137ec681f3Smrg 1147ec681f3Smrg/* Fixed-function blending only supports a single constant, so if multiple bits 1157ec681f3Smrg * are set in constant_mask, the constants must match. Therefore we may pick 1167ec681f3Smrg * just the first constant. */ 1177ec681f3Smrg 1187ec681f3Smrgstatic inline float 1197ec681f3Smrgpan_blend_get_constant(unsigned mask, const float *constants) 1207ec681f3Smrg{ 1217ec681f3Smrg return mask ? constants[ffs(mask) - 1] : 0.0; 1227ec681f3Smrg} 1237ec681f3Smrg 1247ec681f3Smrg/* v6 doesn't support blend constants in FF blend equations whatsoever, and v7 1257ec681f3Smrg * only uses the constant from RT 0 (TODO: what if it's the same constant? or a 1267ec681f3Smrg * constant is shared?) */ 1277ec681f3Smrg 1287ec681f3Smrgstatic inline bool 1297ec681f3Smrgpan_blend_supports_constant(unsigned arch, unsigned rt) 1307ec681f3Smrg{ 1317ec681f3Smrg return !((arch == 6) || (arch == 7 && rt > 0)); 1327ec681f3Smrg} 1337ec681f3Smrg 1347ec681f3Smrg/* The SOURCE_2 value is new in Bifrost */ 1357ec681f3Smrg 1367ec681f3Smrgstatic inline bool 1377ec681f3Smrgpan_blend_supports_2src(unsigned arch) 1387ec681f3Smrg{ 1397ec681f3Smrg return (arch >= 6); 1407ec681f3Smrg} 1417ec681f3Smrg 1427ec681f3Smrgbool 1437ec681f3Smrgpan_blend_is_homogenous_constant(unsigned mask, const float *constants); 1447ec681f3Smrg 1457ec681f3Smrgvoid 1467ec681f3Smrgpan_blend_to_fixed_function_equation(const struct pan_blend_equation eq, 1477ec681f3Smrg struct MALI_BLEND_EQUATION *equation); 1487ec681f3Smrg 1497ec681f3Smrguint32_t 1507ec681f3Smrgpan_pack_blend(const struct pan_blend_equation equation); 1517ec681f3Smrg 1527ec681f3Smrgvoid 1537ec681f3Smrgpan_blend_shaders_init(struct panfrost_device *dev); 1547ec681f3Smrg 1557ec681f3Smrgvoid 1567ec681f3Smrgpan_blend_shaders_cleanup(struct panfrost_device *dev); 1577ec681f3Smrg 1587ec681f3Smrg#ifdef PAN_ARCH 1597ec681f3Smrg 1607ec681f3Smrgnir_shader * 1617ec681f3SmrgGENX(pan_blend_create_shader)(const struct panfrost_device *dev, 1627ec681f3Smrg const struct pan_blend_state *state, 1637ec681f3Smrg nir_alu_type src0_type, 1647ec681f3Smrg nir_alu_type src1_type, 1657ec681f3Smrg unsigned rt); 1667ec681f3Smrg 1677ec681f3Smrg#if PAN_ARCH >= 6 1687ec681f3Smrguint64_t 1697ec681f3SmrgGENX(pan_blend_get_internal_desc)(const struct panfrost_device *dev, 1707ec681f3Smrg enum pipe_format fmt, unsigned rt, 1717ec681f3Smrg unsigned force_size, bool dithered); 1727ec681f3Smrg#endif 1737ec681f3Smrg 1747ec681f3Smrg/* Take blend_shaders.lock before calling this function and release it when 1757ec681f3Smrg * you're done with the shader variant object. 1767ec681f3Smrg */ 1777ec681f3Smrgstruct pan_blend_shader_variant * 1787ec681f3SmrgGENX(pan_blend_get_shader_locked)(const struct panfrost_device *dev, 1797ec681f3Smrg const struct pan_blend_state *state, 1807ec681f3Smrg nir_alu_type src0_type, 1817ec681f3Smrg nir_alu_type src1_type, 1827ec681f3Smrg unsigned rt); 1837ec681f3Smrg#endif 1847ec681f3Smrg 1857ec681f3Smrg#endif 186