Path: blob/21.2-virgl/src/gallium/drivers/i915/i915_state_dynamic.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 "i915_batch.h"28#include "i915_context.h"29#include "i915_reg.h"30#include "i915_state.h"31#include "i915_state_inlines.h"3233#include "util/u_memory.h"34#include "util/u_pack_color.h"3536/* State that we have chosen to store in the DYNAMIC segment of the37* i915 indirect state mechanism.38*39* Can't cache these in the way we do the static state, as there is no40* start/size in the command packet, instead an 'end' value that gets41* incremented.42*43* Additionally, there seems to be a requirement to re-issue the full44* (active) state every time a 4kb boundary is crossed.45*/4647static inline void48set_dynamic(struct i915_context *i915, unsigned offset, const unsigned state)49{50if (i915->current.dynamic[offset] == state)51return;5253i915->current.dynamic[offset] = state;54i915->dynamic_dirty |= 1 << offset;55i915->hardware_dirty |= I915_HW_DYNAMIC;56}5758static inline void59set_dynamic_array(struct i915_context *i915, unsigned offset,60const unsigned *src, unsigned dwords)61{62unsigned i;6364if (!memcmp(src, &i915->current.dynamic[offset], dwords * 4))65return;6667for (i = 0; i < dwords; i++) {68i915->current.dynamic[offset + i] = src[i];69i915->dynamic_dirty |= 1 << (offset + i);70}7172i915->hardware_dirty |= I915_HW_DYNAMIC;73}7475/***********************************************************************76* Modes4: stencil masks and logicop77*/78static void79upload_MODES4(struct i915_context *i915)80{81bool stencil_ccw = i915_stencil_ccw(i915);8283unsigned modes4 = 0;8485/* I915_NEW_STENCIL86*/87if (stencil_ccw)88modes4 |= i915->depth_stencil->stencil_modes4_ccw;89else90modes4 |= i915->depth_stencil->stencil_modes4_cw;9192/* I915_NEW_BLEND93*/94modes4 |= i915->blend->modes4;9596set_dynamic(i915, I915_DYNAMIC_MODES4, modes4);97}9899const struct i915_tracked_state i915_upload_MODES4 = {100"MODES4", upload_MODES4,101I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL | I915_NEW_RASTERIZER};102103/***********************************************************************104*/105static void106upload_BFO(struct i915_context *i915)107{108bool stencil_ccw = i915_stencil_ccw(i915);109110unsigned bfo[2];111if (stencil_ccw) {112bfo[0] = i915->depth_stencil->bfo_ccw[0];113bfo[1] = i915->depth_stencil->bfo_ccw[1];114} else {115bfo[0] = i915->depth_stencil->bfo_cw[0];116bfo[1] = i915->depth_stencil->bfo_cw[1];117}118/* I don't get it only allowed to set a ref mask when the enable bit is set?119*/120if (bfo[0] & BFO_ENABLE_STENCIL_REF) {121bfo[0] |= i915->stencil_ref.ref_value[!stencil_ccw]122<< BFO_STENCIL_REF_SHIFT;123}124125set_dynamic_array(i915, I915_DYNAMIC_BFO_0, bfo, 2);126}127128const struct i915_tracked_state i915_upload_BFO = {129"BFO", upload_BFO, I915_NEW_DEPTH_STENCIL | I915_NEW_RASTERIZER};130131/***********************************************************************132*/133static void134upload_BLENDCOLOR(struct i915_context *i915)135{136unsigned bc[2];137138memset(bc, 0, sizeof(bc));139140/* I915_NEW_BLEND141*/142{143const float *color = i915->blend_color.color;144145bc[0] = _3DSTATE_CONST_BLEND_COLOR_CMD;146bc[1] = pack_ui32_float4(color[i915->current.color_swizzle[2]],147color[i915->current.color_swizzle[1]],148color[i915->current.color_swizzle[0]],149color[i915->current.color_swizzle[3]]);150}151152set_dynamic_array(i915, I915_DYNAMIC_BC_0, bc, 2);153}154155const struct i915_tracked_state i915_upload_BLENDCOLOR = {156"BLENDCOLOR", upload_BLENDCOLOR, I915_NEW_BLEND | I915_NEW_COLOR_SWIZZLE};157158/***********************************************************************159*/160static void161upload_IAB(struct i915_context *i915)162{163unsigned iab = 0;164165if (i915->blend) {166struct i915_surface *cbuf = i915_surface(i915->framebuffer.cbufs[0]);167if (cbuf && cbuf->alpha_in_g)168iab |= i915->blend->iab_alpha_in_g;169else if (cbuf && cbuf->alpha_is_x)170iab |= i915->blend->iab_alpha_is_x;171else172iab |= i915->blend->iab;173}174175set_dynamic(i915, I915_DYNAMIC_IAB, iab);176}177178const struct i915_tracked_state i915_upload_IAB = {179"IAB", upload_IAB, I915_NEW_BLEND | I915_NEW_FRAMEBUFFER};180181/***********************************************************************182*/183static void184upload_DEPTHSCALE(struct i915_context *i915)185{186set_dynamic_array(i915, I915_DYNAMIC_DEPTHSCALE_0,187&i915->rasterizer->ds[0].u, 2);188}189190const struct i915_tracked_state i915_upload_DEPTHSCALE = {191"DEPTHSCALE", upload_DEPTHSCALE, I915_NEW_RASTERIZER};192193/***********************************************************************194* Polygon stipple195*196* The i915 supports a 4x4 stipple natively, GL wants 32x32.197* Fortunately stipple is usually a repeating pattern.198*199* XXX: does stipple pattern need to be adjusted according to200* the window position?201*202* XXX: possibly need workaround for conform paths test.203*/204static void205upload_STIPPLE(struct i915_context *i915)206{207unsigned st[2];208209st[0] = _3DSTATE_STIPPLE;210st[1] = 0;211212/* I915_NEW_RASTERIZER213*/214if (i915->rasterizer)215st[1] |= i915->rasterizer->st;216217/* I915_NEW_STIPPLE218*/219{220const ubyte *mask = (const ubyte *)i915->poly_stipple.stipple;221ubyte p[4];222223p[0] = mask[12] & 0xf;224p[1] = mask[8] & 0xf;225p[2] = mask[4] & 0xf;226p[3] = mask[0] & 0xf;227228/* Not sure what to do about fallbacks, so for now just dont:229*/230st[1] |= ((p[0] << 0) | (p[1] << 4) | (p[2] << 8) | (p[3] << 12));231}232233set_dynamic_array(i915, I915_DYNAMIC_STP_0, st, 2);234}235236const struct i915_tracked_state i915_upload_STIPPLE = {237"STIPPLE", upload_STIPPLE, I915_NEW_RASTERIZER | I915_NEW_STIPPLE};238239/***********************************************************************240* Scissor enable241*/242static void243upload_SCISSOR_ENABLE(struct i915_context *i915)244{245set_dynamic(i915, I915_DYNAMIC_SC_ENA_0, i915->rasterizer->sc[0]);246}247248const struct i915_tracked_state i915_upload_SCISSOR_ENABLE = {249"SCISSOR ENABLE", upload_SCISSOR_ENABLE, I915_NEW_RASTERIZER};250251/***********************************************************************252* Scissor rect253*/254static void255upload_SCISSOR_RECT(struct i915_context *i915)256{257unsigned x1 = i915->scissor.minx;258unsigned y1 = i915->scissor.miny;259unsigned x2 = i915->scissor.maxx - 1;260unsigned y2 = i915->scissor.maxy - 1;261unsigned sc[3];262263sc[0] = _3DSTATE_SCISSOR_RECT_0_CMD;264sc[1] = (y1 << 16) | (x1 & 0xffff);265sc[2] = (y2 << 16) | (x2 & 0xffff);266267set_dynamic_array(i915, I915_DYNAMIC_SC_RECT_0, sc, 3);268}269270const struct i915_tracked_state i915_upload_SCISSOR_RECT = {271"SCISSOR RECT", upload_SCISSOR_RECT, I915_NEW_SCISSOR};272273/***********************************************************************274*/275static const struct i915_tracked_state *atoms[] = {276&i915_upload_MODES4, &i915_upload_BFO,277&i915_upload_BLENDCOLOR, &i915_upload_IAB,278&i915_upload_DEPTHSCALE, &i915_upload_STIPPLE,279&i915_upload_SCISSOR_ENABLE, &i915_upload_SCISSOR_RECT};280281/* These will be dynamic indirect state commands, but for now just end282* up on the batch buffer with everything else.283*/284static void285update_dynamic(struct i915_context *i915)286{287int i;288289for (i = 0; i < ARRAY_SIZE(atoms); i++)290if (i915->dirty & atoms[i]->dirty)291atoms[i]->update(i915);292}293294struct i915_tracked_state i915_hw_dynamic = {295"dynamic", update_dynamic,296~0 /* all state atoms, because we do internal checking */297};298299300