/*
 * © Copyright 2018 Alyssa Rosenzweig
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include <stdio.h>
#include "pan_blend_shaders.h"
#include "pan_util.h"
#include "midgard/midgard_compile.h"
#include "compiler/nir/nir_builder.h"
#include "nir/nir_lower_blend.h"
#include "panfrost/util/pan_lower_framebuffer.h"
#include "gallium/auxiliary/util/u_blend.h"
#include "util/u_memory.h"

/*
 * Implements the command stream portion of programmatic blend shaders.
 *
 * On Midgard, common blending operations are accelerated by the fixed-function
 * blending pipeline. Panfrost supports this fast path via the code in
 * pan_blending.c. Nevertheless, uncommon blend modes (including some seemingly
 * simple modes present in ES2) require "blend shaders", a special internal
 * shader type used for programmable blending.
 *
 * Blend shaders operate during the normal blending time, but they bypass the
 * fixed-function blending pipeline and instead go straight to the Midgard
 * shader cores. The shaders themselves are essentially just fragment shaders,
 * making heavy use of uint8 arithmetic to manipulate RGB values for the
 * framebuffer.
 *
 * As is typical with Midgard, shader binaries must be accompanied by
 * information about the first tag (ORed with the bottom nibble of address,
 * like usual) and work registers. Work register count is assumed to be less
 * than or equal to the coresponding fragment shader's work count. This
 * suggests that blend shader invocation is tied to fragment shader
 * execution.
 *
 * The shaders themselves use the standard ISA. The source pixel colour,
 * including alpha, is preloaded into r0 as a vec4 of float32. The destination
 * pixel colour must be loaded explicitly via load/store ops, possibly
 * performing conversions in software. The blended colour must be stored with a
 * fragment writeout in the correct framebuffer format, either in software or
 * via conversion opcodes on the load/store pipe.
 *
 * Blend shaders hardcode constants. Naively, this requires recompilation each
 * time the blend color changes, which is a performance risk. Accordingly, we
 * 'cheat' a bit: instead of loading the constant, we compile a shader with a
 * dummy constant, exporting the offset to the immediate in the shader binary,
 * storing this generic binary and metadata in the CSO itself at CSO create
 * time.
 *
 * We then hot patch in the color into this shader at attachment / color change
 * time, allowing for CSO create to be the only expensive operation
 * (compilation).
 */

static nir_lower_blend_options
nir_make_options(const struct pipe_blend_state *blend, unsigned i)
{
        nir_lower_blend_options options = { 0 };

        if (blend->logicop_enable) {
            options.logicop_enable = true;
            options.logicop_func = blend->logicop_func;
            return options;
        }

        options.logicop_enable = false;

        if (!blend->independent_blend_enable)
                i = 0;

        /* If blend is disabled, we just use replace mode */

        nir_lower_blend_channel rgb = {
                .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 = 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.rgb = rgb;
        options.alpha = alpha;

        options.colormask = blend->rt[i].colormask;

        return options;
}

static nir_ssa_def *
nir_iclamp(nir_builder *b, nir_ssa_def *v, int32_t lo, int32_t hi)
{
        return nir_imin(b, nir_imax(b, v, nir_imm_int(b, lo)), nir_imm_int(b, hi));
}

struct panfrost_blend_shader
panfrost_compile_blend_shader(
        struct panfrost_context *ctx,
        struct pipe_blend_state *cso,
        enum pipe_format format,
        unsigned rt)
{
        struct panfrost_device *dev = pan_device(ctx->base.screen);
        struct panfrost_blend_shader res;

        res.ctx = ctx;

        /* Build the shader */

        nir_shader *shader = nir_shader_create(NULL, MESA_SHADER_FRAGMENT, &midgard_nir_options, NULL);
        nir_function *fn = nir_function_create(shader, "main");
        nir_function_impl *impl = nir_function_impl_create(fn);

        const struct util_format_description *format_desc =
                util_format_description(format);

        nir_alu_type T = pan_unpacked_type_for_format(format_desc);
        enum glsl_base_type g =
                (T == nir_type_float16) ? GLSL_TYPE_FLOAT16 :
                (T == nir_type_float32) ? GLSL_TYPE_FLOAT :
                (T == nir_type_int8) ? GLSL_TYPE_INT8 :
                (T == nir_type_int16) ? GLSL_TYPE_INT16 :
                (T == nir_type_int32) ? GLSL_TYPE_INT :
                (T == nir_type_uint8) ? GLSL_TYPE_UINT8 :
                (T == nir_type_uint16) ? GLSL_TYPE_UINT16 :
                (T == nir_type_uint32) ? GLSL_TYPE_UINT :
                GLSL_TYPE_FLOAT;

        /* Create the blend variables */

        nir_variable *c_src = nir_variable_create(shader, nir_var_shader_in, glsl_vector_type(GLSL_TYPE_FLOAT, 4), "gl_Color");
        nir_variable *c_src1 = nir_variable_create(shader, nir_var_shader_in, glsl_vector_type(GLSL_TYPE_FLOAT, 4), "gl_Color1");
        nir_variable *c_out = nir_variable_create(shader, nir_var_shader_out, glsl_vector_type(g, 4), "gl_FragColor");

        c_src->data.location = VARYING_SLOT_COL0;
        c_src1->data.location = VARYING_SLOT_VAR0;
        c_out->data.location = FRAG_RESULT_COLOR;

        c_src1->data.driver_location = 1;

        /* Setup nir_builder */

        nir_builder _b;
        nir_builder *b = &_b;
        nir_builder_init(b, impl);
        b->cursor = nir_before_block(nir_start_block(impl));

        /* Setup inputs */

        nir_ssa_def *s_src[] = {nir_load_var(b, c_src), nir_load_var(b, c_src1)};

        for (int i = 0; i < ARRAY_SIZE(s_src); ++i) {
                if (T == nir_type_float16)
                        s_src[i] = nir_f2f16(b, s_src[i]);
                else if (T == nir_type_int16)
                        s_src[i] = nir_i2i16(b, nir_iclamp(b, s_src[i], -32768, 32767));
                else if (T == nir_type_uint16)
                        s_src[i] = nir_u2u16(b, nir_umin(b, s_src[i], nir_imm_int(b, 65535)));
                else if (T == nir_type_int8)
                        s_src[i] = nir_i2i8(b, nir_iclamp(b, s_src[i], -128, 127));
                else if (T == nir_type_uint8)
                        s_src[i] = nir_u2u8(b, nir_umin(b, s_src[i], nir_imm_int(b, 255)));
        }

        /* Build a trivial blend shader */
        nir_store_var(b, c_out, s_src[0], 0xFF);

        nir_lower_blend_options options =
                nir_make_options(cso, rt);
        options.format = format;
        options.src1 = s_src[1];

        if (T == nir_type_float16)
                options.half = true;

        NIR_PASS_V(shader, nir_lower_blend, options);

        /* Compile the built shader */

        panfrost_program program;

        struct panfrost_compile_inputs inputs = {
                .gpu_id = dev->gpu_id,
                .is_blend = true,
                .blend.rt = rt,
                .rt_formats = {format},
        };

        midgard_compile_shader_nir(shader, &program, &inputs);

        /* Allow us to patch later */
        res.patch_index = program.blend_patch_offset;
        res.first_tag = program.first_tag;
        res.size = program.compiled.size;
        res.buffer = program.compiled.data;
        res.work_count = program.work_register_count;

        return res;
}
