Path: blob/21.2-virgl/src/gallium/drivers/i915/i915_state_derived.c
4570 views
/**************************************************************************1*2* Copyright 2003 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#include "draw/draw_context.h"28#include "draw/draw_vertex.h"29#include "pipe/p_shader_tokens.h"30#include "util/u_memory.h"31#include "i915_context.h"32#include "i915_debug.h"33#include "i915_fpc.h"34#include "i915_reg.h"35#include "i915_state.h"3637static uint32_t38find_mapping(const struct i915_fragment_shader *fs, int unit)39{40int i;41for (i = 0; i < I915_TEX_UNITS; i++) {42if (fs->generic_mapping[i] == unit)43return i;44}45debug_printf("Mapping not found\n");46return 0;47}4849/***********************************************************************50* Determine the hardware vertex layout.51* Depends on vertex/fragment shader state.52*/53static void54calculate_vertex_layout(struct i915_context *i915)55{56const struct i915_fragment_shader *fs = i915->fs;57struct vertex_info vinfo;58bool texCoords[I915_TEX_UNITS], colors[2], fog, needW, face;59uint32_t i;60int src;6162memset(texCoords, 0, sizeof(texCoords));63colors[0] = colors[1] = fog = needW = face = false;64memset(&vinfo, 0, sizeof(vinfo));6566/* Determine which fragment program inputs are needed. Setup HW vertex67* layout below, in the HW-specific attribute order.68*/69for (i = 0; i < fs->info.num_inputs; i++) {70switch (fs->info.input_semantic_name[i]) {71case TGSI_SEMANTIC_POSITION: {72uint32_t unit = I915_SEMANTIC_POS;73texCoords[find_mapping(fs, unit)] = true;74} break;75case TGSI_SEMANTIC_COLOR:76assert(fs->info.input_semantic_index[i] < 2);77colors[fs->info.input_semantic_index[i]] = true;78break;79case TGSI_SEMANTIC_GENERIC: {80/* texcoords/varyings/other generic */81uint32_t unit = fs->info.input_semantic_index[i];8283texCoords[find_mapping(fs, unit)] = true;84needW = true;85} break;86case TGSI_SEMANTIC_FOG:87fog = true;88break;89case TGSI_SEMANTIC_FACE:90face = true;91break;92default:93debug_printf("Unknown input type %d\n",94fs->info.input_semantic_name[i]);95assert(0);96}97}9899/* pos */100src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);101if (needW) {102draw_emit_vertex_attr(&vinfo, EMIT_4F, src);103vinfo.hwfmt[0] |= S4_VFMT_XYZW;104vinfo.attrib[0].emit = EMIT_4F;105} else {106draw_emit_vertex_attr(&vinfo, EMIT_3F, src);107vinfo.hwfmt[0] |= S4_VFMT_XYZ;108vinfo.attrib[0].emit = EMIT_3F;109}110111/* point size. if not emitted here, then point size comes from LIS4. */112if (i915->rasterizer->templ.point_size_per_vertex) {113src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_PSIZE, 0);114if (src != -1) {115draw_emit_vertex_attr(&vinfo, EMIT_1F, src);116vinfo.hwfmt[0] |= S4_VFMT_POINT_WIDTH;117}118}119120/* primary color */121if (colors[0]) {122src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);123draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, src);124vinfo.hwfmt[0] |= S4_VFMT_COLOR;125}126127/* secondary color */128if (colors[1]) {129src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);130draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, src);131vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;132}133134/* fog coord, not fog blend factor */135if (fog) {136src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0);137draw_emit_vertex_attr(&vinfo, EMIT_1F, src);138vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;139}140141/* texcoords/varyings */142for (i = 0; i < I915_TEX_UNITS; i++) {143uint32_t hwtc;144if (texCoords[i]) {145hwtc = TEXCOORDFMT_4D;146if (fs->generic_mapping[i] == I915_SEMANTIC_POS) {147src =148draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);149} else {150src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC,151fs->generic_mapping[i]);152}153draw_emit_vertex_attr(&vinfo, EMIT_4F, src);154} else {155hwtc = TEXCOORDFMT_NOT_PRESENT;156}157vinfo.hwfmt[1] |= hwtc << (i * 4);158}159160/* front/back face */161if (face) {162uint32_t slot = find_mapping(fs, I915_SEMANTIC_FACE);163debug_printf("Front/back face is broken\n");164/* XXX Because of limitations in the draw module, currently src will be 0165* for SEMANTIC_FACE, so this aliases to POS. We need to fix in the draw166* module by adding an extra shader output.167*/168src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FACE, 0);169draw_emit_vertex_attr(&vinfo, EMIT_1F, src);170vinfo.hwfmt[1] &= ~(TEXCOORDFMT_NOT_PRESENT << (slot * 4));171vinfo.hwfmt[1] |= TEXCOORDFMT_1D << (slot * 4);172}173174draw_compute_vertex_size(&vinfo);175176if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {177/* Need to set this flag so that the LIS2/4 registers get set.178* It also means the i915_update_immediate() function must be called179* after this one, in i915_update_derived().180*/181i915->dirty |= I915_NEW_VERTEX_FORMAT;182183memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo));184}185}186187struct i915_tracked_state i915_update_vertex_layout = {188"vertex_layout", calculate_vertex_layout,189I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS};190191/***********************************************************************192*/193static struct i915_tracked_state *atoms[] = {194&i915_update_vertex_layout, &i915_hw_samplers, &i915_hw_immediate,195&i915_hw_dynamic, &i915_hw_fs, &i915_hw_framebuffer,196&i915_hw_dst_buf_vars, &i915_hw_constants, NULL,197};198199void200i915_update_derived(struct i915_context *i915)201{202int i;203204if (I915_DBG_ON(DBG_ATOMS))205i915_dump_dirty(i915, __FUNCTION__);206207if (!i915->fs) {208i915->dirty &= ~(I915_NEW_FS_CONSTANTS | I915_NEW_FS);209i915->hardware_dirty &= ~(I915_HW_PROGRAM | I915_HW_CONSTANTS);210}211212if (!i915->vs)213i915->dirty &= ~I915_NEW_VS;214215if (!i915->blend)216i915->dirty &= ~I915_NEW_BLEND;217218if (!i915->rasterizer)219i915->dirty &= ~I915_NEW_RASTERIZER;220221if (!i915->depth_stencil)222i915->dirty &= ~I915_NEW_DEPTH_STENCIL;223224for (i = 0; atoms[i]; i++)225if (atoms[i]->dirty & i915->dirty)226atoms[i]->update(i915);227228i915->dirty = 0;229}230231232