Path: blob/21.2-virgl/src/gallium/auxiliary/postprocess/pp_mlaa.c
4561 views
/**1* Copyright (C) 2010 Jorge Jimenez ([email protected])2* Copyright (C) 2010 Belen Masia ([email protected])3* Copyright (C) 2010 Jose I. Echevarria ([email protected])4* Copyright (C) 2010 Fernando Navarro ([email protected])5* Copyright (C) 2010 Diego Gutierrez ([email protected])6* Copyright (C) 2011 Lauri Kasanen ([email protected])7* All rights reserved.8*9* Redistribution and use in source and binary forms, with or without10* modification, are permitted provided that the following conditions are met:11*12* 1. Redistributions of source code must retain the above copyright notice,13* this list of conditions and the following disclaimer.14*15* 2. Redistributions in binary form must reproduce the following statement:16*17* "Uses Jimenez's MLAA. Copyright (C) 2010 by Jorge Jimenez, Belen Masia,18* Jose I. Echevarria, Fernando Navarro and Diego Gutierrez."19*20* Only for use in the Mesa project, this point 2 is filled by naming the21* technique Jimenez's MLAA in the Mesa config options.22*23* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS24* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,25* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR26* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS27* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR28* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF29* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS30* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN31* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)32* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE33* POSSIBILITY OF SUCH DAMAGE.34*35* The views and conclusions contained in the software and documentation are36* those of the authors and should not be interpreted as representing official37* policies, either expressed or implied, of the copyright holders.38*/3940#include "pipe/p_compiler.h"4142#include "postprocess/postprocess.h"43#include "postprocess/pp_mlaa.h"44#include "postprocess/pp_filters.h"45#include "postprocess/pp_private.h"4647#include "util/u_box.h"48#include "util/u_sampler.h"49#include "util/u_inlines.h"50#include "util/u_memory.h"51#include "util/u_string.h"52#include "pipe/p_screen.h"5354#define IMM_SPACE 805556static float constants[] = { 1, 1, 0, 0 };57static unsigned int dimensions[2] = { 0, 0 };5859/** Run function of the MLAA filter. */60static void61pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in,62struct pipe_resource *out, unsigned int n, bool iscolor)63{6465struct pp_program *p = ppq->p;6667struct pipe_depth_stencil_alpha_state mstencil;68struct pipe_sampler_view v_tmp, *arr[3];6970unsigned int w = 0;71unsigned int h = 0;7273const struct pipe_stencil_ref ref = { {1} };7475/* Insufficient initialization checks. */76assert(p);77assert(ppq);78assert(ppq->areamaptex);79assert(ppq->inner_tmp);80assert(ppq->shaders[n]);8182w = p->framebuffer.width;83h = p->framebuffer.height;8485memset(&mstencil, 0, sizeof(mstencil));8687cso_set_stencil_ref(p->cso, ref);8889/* Init the pixel size constant */90if (dimensions[0] != p->framebuffer.width ||91dimensions[1] != p->framebuffer.height) {92constants[0] = 1.0f / p->framebuffer.width;93constants[1] = 1.0f / p->framebuffer.height;9495dimensions[0] = p->framebuffer.width;96dimensions[1] = p->framebuffer.height;97}9899struct pipe_constant_buffer cb;100cb.buffer = NULL;101cb.buffer_offset = 0;102cb.buffer_size = sizeof(constants);103cb.user_buffer = constants;104105struct pipe_context *pipe = ppq->p->pipe;106pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, false, &cb);107pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, false, &cb);108109mstencil.stencil[0].enabled = 1;110mstencil.stencil[0].valuemask = mstencil.stencil[0].writemask = ~0;111mstencil.stencil[0].func = PIPE_FUNC_ALWAYS;112mstencil.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;113mstencil.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;114mstencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;115116p->framebuffer.zsbuf = ppq->stencils;117118/* First pass: depth edge detection */119if (iscolor)120pp_filter_setup_in(p, in);121else122pp_filter_setup_in(p, ppq->depth);123124pp_filter_setup_out(p, ppq->inner_tmp[0]);125126pp_filter_set_fb(p);127pp_filter_misc_state(p);128cso_set_depth_stencil_alpha(p->cso, &mstencil);129p->pipe->clear(p->pipe, PIPE_CLEAR_STENCIL | PIPE_CLEAR_COLOR0, NULL,130&p->clear_color, 0, 0);131132{133const struct pipe_sampler_state *samplers[] = {&p->sampler_point};134cso_set_samplers(p->cso, PIPE_SHADER_FRAGMENT, 1, samplers);135}136pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, &p->view);137138cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][1]); /* offsetvs */139cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][2]);140141pp_filter_draw(p);142pp_filter_end_pass(p);143144145/* Second pass: blend weights */146/* Sampler order: areamap, edgesmap, edgesmapL (reversed, thx compiler) */147mstencil.stencil[0].func = PIPE_FUNC_EQUAL;148mstencil.stencil[0].zpass_op = PIPE_STENCIL_OP_KEEP;149cso_set_depth_stencil_alpha(p->cso, &mstencil);150151pp_filter_setup_in(p, ppq->areamaptex);152pp_filter_setup_out(p, ppq->inner_tmp[1]);153154u_sampler_view_default_template(&v_tmp, ppq->inner_tmp[0],155ppq->inner_tmp[0]->format);156arr[1] = arr[2] = p->pipe->create_sampler_view(p->pipe,157ppq->inner_tmp[0], &v_tmp);158159pp_filter_set_clear_fb(p);160161{162const struct pipe_sampler_state *samplers[] =163{&p->sampler_point, &p->sampler_point, &p->sampler};164cso_set_samplers(p->cso, PIPE_SHADER_FRAGMENT, 3, samplers);165}166167arr[0] = p->view;168pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 3, 0, arr);169170cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][0]); /* passvs */171cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][3]);172173pp_filter_draw(p);174pp_filter_end_pass(p);175pipe_sampler_view_reference(&arr[1], NULL);176177178/* Third pass: smoothed edges */179/* Sampler order: colormap, blendmap (wtf compiler) */180pp_filter_setup_in(p, ppq->inner_tmp[1]);181pp_filter_setup_out(p, out);182183pp_filter_set_fb(p);184185/* Blit the input to the output */186pp_blit(p->pipe, in, 0, 0,187w, h, 0, p->framebuffer.cbufs[0],1880, 0, w, h);189190u_sampler_view_default_template(&v_tmp, in, in->format);191arr[0] = p->pipe->create_sampler_view(p->pipe, in, &v_tmp);192193{194const struct pipe_sampler_state *samplers[] =195{&p->sampler_point, &p->sampler_point};196cso_set_samplers(p->cso, PIPE_SHADER_FRAGMENT, 2, samplers);197}198199arr[1] = p->view;200pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, 0, arr);201202cso_set_vertex_shader_handle(p->cso, ppq->shaders[n][1]); /* offsetvs */203cso_set_fragment_shader_handle(p->cso, ppq->shaders[n][4]);204205p->blend.rt[0].blend_enable = 1;206cso_set_blend(p->cso, &p->blend);207208pp_filter_draw(p);209pp_filter_end_pass(p);210pipe_sampler_view_reference(&arr[0], NULL);211212p->blend.rt[0].blend_enable = 0;213p->framebuffer.zsbuf = NULL;214}215216/** The init function of the MLAA filter. */217static bool218pp_jimenezmlaa_init_run(struct pp_queue_t *ppq, unsigned int n,219unsigned int val, bool iscolor)220{221222struct pipe_box box;223struct pipe_resource res;224char *tmp_text = NULL;225226tmp_text = CALLOC(sizeof(blend2fs_1) + sizeof(blend2fs_2) +227IMM_SPACE, sizeof(char));228229if (!tmp_text) {230pp_debug("Failed to allocate shader space\n");231return FALSE;232}233234pp_debug("mlaa: using %u max search steps\n", val);235236sprintf(tmp_text, "%s"237"IMM FLT32 { %.8f, 0.0000, 0.0000, 0.0000}\n"238"%s\n", blend2fs_1, (float) val, blend2fs_2);239240memset(&res, 0, sizeof(res));241242res.target = PIPE_TEXTURE_2D;243res.format = PIPE_FORMAT_R8G8_UNORM;244res.width0 = res.height0 = 165;245res.bind = PIPE_BIND_SAMPLER_VIEW;246res.usage = PIPE_USAGE_DEFAULT;247res.depth0 = res.array_size = res.nr_samples = res.nr_storage_samples = 1;248249if (!ppq->p->screen->is_format_supported(ppq->p->screen, res.format,250res.target, 1, 1, res.bind))251pp_debug("Areamap format not supported\n");252253ppq->areamaptex = ppq->p->screen->resource_create(ppq->p->screen, &res);254255if (ppq->areamaptex == NULL) {256pp_debug("Failed to allocate area map texture\n");257goto fail;258}259260u_box_2d(0, 0, 165, 165, &box);261262ppq->p->pipe->texture_subdata(ppq->p->pipe, ppq->areamaptex, 0,263PIPE_MAP_WRITE, &box,264areamap, 165 * 2, sizeof(areamap));265266ppq->shaders[n][1] = pp_tgsi_to_state(ppq->p->pipe, offsetvs, true,267"offsetvs");268if (iscolor)269ppq->shaders[n][2] = pp_tgsi_to_state(ppq->p->pipe, color1fs,270false, "color1fs");271else272ppq->shaders[n][2] = pp_tgsi_to_state(ppq->p->pipe, depth1fs,273false, "depth1fs");274ppq->shaders[n][3] = pp_tgsi_to_state(ppq->p->pipe, tmp_text, false,275"blend2fs");276ppq->shaders[n][4] = pp_tgsi_to_state(ppq->p->pipe, neigh3fs, false,277"neigh3fs");278279FREE(tmp_text);280281return TRUE;282283fail:284285FREE(tmp_text);286287/*288* Call the common free function for destruction of partially initialized289* resources.290*/291pp_jimenezmlaa_free(ppq, n);292293return FALSE;294}295296/** Short wrapper to init the depth version. */297bool298pp_jimenezmlaa_init(struct pp_queue_t *ppq, unsigned int n, unsigned int val)299{300return pp_jimenezmlaa_init_run(ppq, n, val, false);301}302303/** Short wrapper to init the color version. */304bool305pp_jimenezmlaa_init_color(struct pp_queue_t *ppq, unsigned int n,306unsigned int val)307{308return pp_jimenezmlaa_init_run(ppq, n, val, true);309}310311/** Short wrapper to run the depth version. */312void313pp_jimenezmlaa(struct pp_queue_t *ppq, struct pipe_resource *in,314struct pipe_resource *out, unsigned int n)315{316if (!ppq->depth) {317return;318}319pp_jimenezmlaa_run(ppq, in, out, n, false);320}321322/** Short wrapper to run the color version. */323void324pp_jimenezmlaa_color(struct pp_queue_t *ppq, struct pipe_resource *in,325struct pipe_resource *out, unsigned int n)326{327pp_jimenezmlaa_run(ppq, in, out, n, true);328}329330331/**332* Short wrapper to free the mlaa filter resources. Shaders are freed in333* the common code in pp_free.334*/335void336pp_jimenezmlaa_free(struct pp_queue_t *ppq, unsigned int n)337{338pipe_resource_reference(&ppq->areamaptex, NULL);339}340341342343