Path: blob/21.2-virgl/src/gallium/drivers/softpipe/sp_fs_exec.c
4570 views
/**************************************************************************1*2* Copyright 2007 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627/**28* Execute fragment shader using the TGSI interpreter.29*/3031#include "sp_context.h"32#include "sp_state.h"33#include "sp_fs.h"34#include "sp_quad.h"3536#include "pipe/p_state.h"37#include "pipe/p_defines.h"38#include "util/u_memory.h"39#include "tgsi/tgsi_exec.h"40#include "tgsi/tgsi_parse.h"414243/**44* Subclass of sp_fragment_shader_variant45*/46struct sp_exec_fragment_shader47{48struct sp_fragment_shader_variant base;49/* No other members for now */50};515253static void54exec_prepare( const struct sp_fragment_shader_variant *var,55struct tgsi_exec_machine *machine,56struct tgsi_sampler *sampler,57struct tgsi_image *image,58struct tgsi_buffer *buffer )59{60/*61* Bind tokens/shader to the interpreter's machine state.62*/63tgsi_exec_machine_bind_shader(machine,64var->tokens,65sampler, image, buffer);66}67686970/**71* Compute quad X,Y,Z,W for the four fragments in a quad.72*73* This should really be part of the compiled shader.74*/75static void76setup_pos_vector(const struct tgsi_interp_coef *coef,77float x, float y,78struct tgsi_exec_vector *quadpos)79{80uint chan;81/* do X */82quadpos->xyzw[0].f[0] = x;83quadpos->xyzw[0].f[1] = x + 1;84quadpos->xyzw[0].f[2] = x;85quadpos->xyzw[0].f[3] = x + 1;8687/* do Y */88quadpos->xyzw[1].f[0] = y;89quadpos->xyzw[1].f[1] = y;90quadpos->xyzw[1].f[2] = y + 1;91quadpos->xyzw[1].f[3] = y + 1;9293/* do Z and W for all fragments in the quad */94for (chan = 2; chan < 4; chan++) {95const float dadx = coef->dadx[chan];96const float dady = coef->dady[chan];97const float a0 = coef->a0[chan] + dadx * x + dady * y;98quadpos->xyzw[chan].f[0] = a0;99quadpos->xyzw[chan].f[1] = a0 + dadx;100quadpos->xyzw[chan].f[2] = a0 + dady;101quadpos->xyzw[chan].f[3] = a0 + dadx + dady;102}103}104105106/* TODO: hide the machine struct in here somewhere, remove from this107* interface:108*/109static unsigned110exec_run( const struct sp_fragment_shader_variant *var,111struct tgsi_exec_machine *machine,112struct quad_header *quad,113bool early_depth_test )114{115/* Compute X, Y, Z, W vals for this quad */116setup_pos_vector(quad->posCoef,117(float)quad->input.x0, (float)quad->input.y0,118&machine->QuadPos);119120/* convert 0 to 1.0 and 1 to -1.0 */121machine->Face = (float) (quad->input.facing * -2 + 1);122123machine->NonHelperMask = quad->inout.mask;124quad->inout.mask &= tgsi_exec_machine_run( machine, 0 );125if (quad->inout.mask == 0)126return FALSE;127128/* store outputs */129{130const ubyte *sem_name = var->info.output_semantic_name;131const ubyte *sem_index = var->info.output_semantic_index;132const uint n = var->info.num_outputs;133uint i;134for (i = 0; i < n; i++) {135switch (sem_name[i]) {136case TGSI_SEMANTIC_COLOR:137{138uint cbuf = sem_index[i];139140assert(sizeof(quad->output.color[cbuf]) ==141sizeof(machine->Outputs[i]));142143/* copy float[4][4] result */144memcpy(quad->output.color[cbuf],145&machine->Outputs[i],146sizeof(quad->output.color[0]) );147}148break;149case TGSI_SEMANTIC_POSITION:150{151uint j;152153if (!early_depth_test) {154for (j = 0; j < 4; j++)155quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j];156}157}158break;159case TGSI_SEMANTIC_STENCIL:160{161uint j;162if (!early_depth_test) {163for (j = 0; j < 4; j++)164quad->output.stencil[j] = (unsigned)machine->Outputs[i].xyzw[1].u[j];165}166}167break;168}169}170}171172return TRUE;173}174175176static void177exec_delete(struct sp_fragment_shader_variant *var,178struct tgsi_exec_machine *machine)179{180if (machine->Tokens == var->tokens) {181tgsi_exec_machine_bind_shader(machine, NULL, NULL, NULL, NULL);182}183184FREE( (void *) var->tokens );185FREE(var);186}187188189struct sp_fragment_shader_variant *190softpipe_create_fs_variant_exec(struct softpipe_context *softpipe)191{192struct sp_exec_fragment_shader *shader;193194shader = CALLOC_STRUCT(sp_exec_fragment_shader);195if (!shader)196return NULL;197198shader->base.prepare = exec_prepare;199shader->base.run = exec_run;200shader->base.delete = exec_delete;201202return &shader->base;203}204205206