1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * Copyright 2008 VMware, Inc. All rights reserved. 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 9bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 10bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 11bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 12bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 13bf215546Sopenharmony_ci * the following conditions: 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 16bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 17bf215546Sopenharmony_ci * of the Software. 18bf215546Sopenharmony_ci * 19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26bf215546Sopenharmony_ci * 27bf215546Sopenharmony_ci **************************************************************************/ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci/* Vertices are just an array of floats, with all the attributes 30bf215546Sopenharmony_ci * packed. We currently assume a layout like: 31bf215546Sopenharmony_ci * 32bf215546Sopenharmony_ci * attr[0][0..3] - window position 33bf215546Sopenharmony_ci * attr[1..n][0..3] - remaining attributes. 34bf215546Sopenharmony_ci * 35bf215546Sopenharmony_ci * Attributes are assumed to be 4 floats wide but are packed so that 36bf215546Sopenharmony_ci * all the enabled attributes run contiguously. 37bf215546Sopenharmony_ci */ 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#include "util/u_math.h" 40bf215546Sopenharmony_ci#include "util/u_memory.h" 41bf215546Sopenharmony_ci#include "pipe/p_defines.h" 42bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h" 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci#include "sp_context.h" 45bf215546Sopenharmony_ci#include "sp_state.h" 46bf215546Sopenharmony_ci#include "sp_quad.h" 47bf215546Sopenharmony_ci#include "sp_quad_pipe.h" 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistruct quad_shade_stage 51bf215546Sopenharmony_ci{ 52bf215546Sopenharmony_ci struct quad_stage stage; /**< base class */ 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci /* no other fields at this time */ 55bf215546Sopenharmony_ci}; 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci/** 59bf215546Sopenharmony_ci * Execute fragment shader for the four fragments in the quad. 60bf215546Sopenharmony_ci * \return TRUE if quad is alive, FALSE if all four pixels are killed 61bf215546Sopenharmony_ci */ 62bf215546Sopenharmony_cistatic inline boolean 63bf215546Sopenharmony_cishade_quad(struct quad_stage *qs, struct quad_header *quad) 64bf215546Sopenharmony_ci{ 65bf215546Sopenharmony_ci struct softpipe_context *softpipe = qs->softpipe; 66bf215546Sopenharmony_ci struct tgsi_exec_machine *machine = softpipe->fs_machine; 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci if (softpipe->active_statistics_queries) { 69bf215546Sopenharmony_ci softpipe->pipeline_statistics.ps_invocations += 70bf215546Sopenharmony_ci util_bitcount(quad->inout.mask); 71bf215546Sopenharmony_ci } 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci /* run shader */ 74bf215546Sopenharmony_ci machine->flatshade_color = softpipe->rasterizer->flatshade ? TRUE : FALSE; 75bf215546Sopenharmony_ci return softpipe->fs_variant->run( softpipe->fs_variant, machine, quad, softpipe->early_depth ); 76bf215546Sopenharmony_ci} 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_cistatic void 81bf215546Sopenharmony_cicoverage_quad(struct quad_stage *qs, struct quad_header *quad) 82bf215546Sopenharmony_ci{ 83bf215546Sopenharmony_ci struct softpipe_context *softpipe = qs->softpipe; 84bf215546Sopenharmony_ci uint cbuf; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci /* loop over colorbuffer outputs */ 87bf215546Sopenharmony_ci for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) { 88bf215546Sopenharmony_ci float (*quadColor)[4] = quad->output.color[cbuf]; 89bf215546Sopenharmony_ci unsigned j; 90bf215546Sopenharmony_ci for (j = 0; j < TGSI_QUAD_SIZE; j++) { 91bf215546Sopenharmony_ci assert(quad->input.coverage[j] >= 0.0); 92bf215546Sopenharmony_ci assert(quad->input.coverage[j] <= 1.0); 93bf215546Sopenharmony_ci quadColor[3][j] *= quad->input.coverage[j]; 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci } 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci/** 100bf215546Sopenharmony_ci * Shade/write an array of quads 101bf215546Sopenharmony_ci * Called via quad_stage::run() 102bf215546Sopenharmony_ci */ 103bf215546Sopenharmony_cistatic void 104bf215546Sopenharmony_cishade_quads(struct quad_stage *qs, 105bf215546Sopenharmony_ci struct quad_header *quads[], 106bf215546Sopenharmony_ci unsigned nr) 107bf215546Sopenharmony_ci{ 108bf215546Sopenharmony_ci struct softpipe_context *softpipe = qs->softpipe; 109bf215546Sopenharmony_ci struct tgsi_exec_machine *machine = softpipe->fs_machine; 110bf215546Sopenharmony_ci unsigned i, nr_quads = 0; 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, 113bf215546Sopenharmony_ci softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], 114bf215546Sopenharmony_ci softpipe->const_buffer_size[PIPE_SHADER_FRAGMENT]); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci machine->InterpCoefs = quads[0]->coef; 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci for (i = 0; i < nr; i++) { 119bf215546Sopenharmony_ci /* Only omit this quad from the output list if all the fragments 120bf215546Sopenharmony_ci * are killed _AND_ it's not the first quad in the list. 121bf215546Sopenharmony_ci * The first quad is special in the (optimized) depth-testing code: 122bf215546Sopenharmony_ci * the quads' Z coordinates are step-wise interpolated with respect 123bf215546Sopenharmony_ci * to the first quad in the list. 124bf215546Sopenharmony_ci * For multi-pass algorithms we need to produce exactly the same 125bf215546Sopenharmony_ci * Z values in each pass. If interpolation starts with different quads 126bf215546Sopenharmony_ci * we can get different Z values for the same (x,y). 127bf215546Sopenharmony_ci */ 128bf215546Sopenharmony_ci if (!shade_quad(qs, quads[i]) && i > 0) 129bf215546Sopenharmony_ci continue; /* quad totally culled/killed */ 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci if (/*do_coverage*/ 0) 132bf215546Sopenharmony_ci coverage_quad( qs, quads[i] ); 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci quads[nr_quads++] = quads[i]; 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci if (nr_quads) 138bf215546Sopenharmony_ci qs->next->run(qs->next, quads, nr_quads); 139bf215546Sopenharmony_ci} 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci/** 143bf215546Sopenharmony_ci * Per-primitive (or per-begin?) setup 144bf215546Sopenharmony_ci */ 145bf215546Sopenharmony_cistatic void 146bf215546Sopenharmony_cishade_begin(struct quad_stage *qs) 147bf215546Sopenharmony_ci{ 148bf215546Sopenharmony_ci qs->next->begin(qs->next); 149bf215546Sopenharmony_ci} 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_cistatic void 153bf215546Sopenharmony_cishade_destroy(struct quad_stage *qs) 154bf215546Sopenharmony_ci{ 155bf215546Sopenharmony_ci FREE( qs ); 156bf215546Sopenharmony_ci} 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_cistruct quad_stage * 160bf215546Sopenharmony_cisp_quad_shade_stage( struct softpipe_context *softpipe ) 161bf215546Sopenharmony_ci{ 162bf215546Sopenharmony_ci struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); 163bf215546Sopenharmony_ci if (!qss) 164bf215546Sopenharmony_ci goto fail; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci qss->stage.softpipe = softpipe; 167bf215546Sopenharmony_ci qss->stage.begin = shade_begin; 168bf215546Sopenharmony_ci qss->stage.run = shade_quads; 169bf215546Sopenharmony_ci qss->stage.destroy = shade_destroy; 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci return &qss->stage; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_cifail: 174bf215546Sopenharmony_ci FREE(qss); 175bf215546Sopenharmony_ci return NULL; 176bf215546Sopenharmony_ci} 177