Path: blob/21.2-virgl/src/gallium/drivers/r300/r300_state.c
4570 views
/*1* Copyright 2008 Corbin Simpson <[email protected]>2* Copyright 2009 Marek Olšák <[email protected]>3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* on the rights to use, copy, modify, merge, publish, distribute, sub8* license, and/or sell copies of the Software, and to permit persons to whom9* the Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL18* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,19* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR20* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE21* USE OR OTHER DEALINGS IN THE SOFTWARE. */2223#include "draw/draw_context.h"2425#include "util/u_framebuffer.h"26#include "util/half_float.h"27#include "util/u_helpers.h"28#include "util/u_math.h"29#include "util/u_memory.h"30#include "util/u_pack_color.h"31#include "util/u_transfer.h"32#include "util/u_blend.h"3334#include "tgsi/tgsi_parse.h"3536#include "pipe/p_config.h"3738#include "r300_cb.h"39#include "r300_context.h"40#include "r300_emit.h"41#include "r300_reg.h"42#include "r300_screen.h"43#include "r300_screen_buffer.h"44#include "r300_state_inlines.h"45#include "r300_fs.h"46#include "r300_texture.h"47#include "r300_vs.h"4849/* r300_state: Functions used to initialize state context by translating50* Gallium state objects into semi-native r300 state objects. */5152#define UPDATE_STATE(cso, atom) \53if (cso != atom.state) { \54atom.state = cso; \55r300_mark_atom_dirty(r300, &(atom)); \56}5758static boolean blend_discard_if_src_alpha_0(unsigned srcRGB, unsigned srcA,59unsigned dstRGB, unsigned dstA)60{61/* If the blend equation is ADD or REVERSE_SUBTRACT,62* SRC_ALPHA == 0, and the following state is set, the colorbuffer63* will not be changed.64* Notice that the dst factors are the src factors inverted. */65return (srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||66srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||67srcRGB == PIPE_BLENDFACTOR_ZERO) &&68(srcA == PIPE_BLENDFACTOR_SRC_COLOR ||69srcA == PIPE_BLENDFACTOR_SRC_ALPHA ||70srcA == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||71srcA == PIPE_BLENDFACTOR_ZERO) &&72(dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||73dstRGB == PIPE_BLENDFACTOR_ONE) &&74(dstA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||75dstA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||76dstA == PIPE_BLENDFACTOR_ONE);77}7879static boolean blend_discard_if_src_alpha_1(unsigned srcRGB, unsigned srcA,80unsigned dstRGB, unsigned dstA)81{82/* If the blend equation is ADD or REVERSE_SUBTRACT,83* SRC_ALPHA == 1, and the following state is set, the colorbuffer84* will not be changed.85* Notice that the dst factors are the src factors inverted. */86return (srcRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||87srcRGB == PIPE_BLENDFACTOR_ZERO) &&88(srcA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||89srcA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||90srcA == PIPE_BLENDFACTOR_ZERO) &&91(dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||92dstRGB == PIPE_BLENDFACTOR_ONE) &&93(dstA == PIPE_BLENDFACTOR_SRC_COLOR ||94dstA == PIPE_BLENDFACTOR_SRC_ALPHA ||95dstA == PIPE_BLENDFACTOR_ONE);96}9798static boolean blend_discard_if_src_color_0(unsigned srcRGB, unsigned srcA,99unsigned dstRGB, unsigned dstA)100{101/* If the blend equation is ADD or REVERSE_SUBTRACT,102* SRC_COLOR == (0,0,0), and the following state is set, the colorbuffer103* will not be changed.104* Notice that the dst factors are the src factors inverted. */105return (srcRGB == PIPE_BLENDFACTOR_SRC_COLOR ||106srcRGB == PIPE_BLENDFACTOR_ZERO) &&107(srcA == PIPE_BLENDFACTOR_ZERO) &&108(dstRGB == PIPE_BLENDFACTOR_INV_SRC_COLOR ||109dstRGB == PIPE_BLENDFACTOR_ONE) &&110(dstA == PIPE_BLENDFACTOR_ONE);111}112113static boolean blend_discard_if_src_color_1(unsigned srcRGB, unsigned srcA,114unsigned dstRGB, unsigned dstA)115{116/* If the blend equation is ADD or REVERSE_SUBTRACT,117* SRC_COLOR == (1,1,1), and the following state is set, the colorbuffer118* will not be changed.119* Notice that the dst factors are the src factors inverted. */120return (srcRGB == PIPE_BLENDFACTOR_INV_SRC_COLOR ||121srcRGB == PIPE_BLENDFACTOR_ZERO) &&122(srcA == PIPE_BLENDFACTOR_ZERO) &&123(dstRGB == PIPE_BLENDFACTOR_SRC_COLOR ||124dstRGB == PIPE_BLENDFACTOR_ONE) &&125(dstA == PIPE_BLENDFACTOR_ONE);126}127128static boolean blend_discard_if_src_alpha_color_0(unsigned srcRGB, unsigned srcA,129unsigned dstRGB, unsigned dstA)130{131/* If the blend equation is ADD or REVERSE_SUBTRACT,132* SRC_ALPHA_COLOR == (0,0,0,0), and the following state is set,133* the colorbuffer will not be changed.134* Notice that the dst factors are the src factors inverted. */135return (srcRGB == PIPE_BLENDFACTOR_SRC_COLOR ||136srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||137srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||138srcRGB == PIPE_BLENDFACTOR_ZERO) &&139(srcA == PIPE_BLENDFACTOR_SRC_COLOR ||140srcA == PIPE_BLENDFACTOR_SRC_ALPHA ||141srcA == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||142srcA == PIPE_BLENDFACTOR_ZERO) &&143(dstRGB == PIPE_BLENDFACTOR_INV_SRC_COLOR ||144dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||145dstRGB == PIPE_BLENDFACTOR_ONE) &&146(dstA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||147dstA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||148dstA == PIPE_BLENDFACTOR_ONE);149}150151static boolean blend_discard_if_src_alpha_color_1(unsigned srcRGB, unsigned srcA,152unsigned dstRGB, unsigned dstA)153{154/* If the blend equation is ADD or REVERSE_SUBTRACT,155* SRC_ALPHA_COLOR == (1,1,1,1), and the following state is set,156* the colorbuffer will not be changed.157* Notice that the dst factors are the src factors inverted. */158return (srcRGB == PIPE_BLENDFACTOR_INV_SRC_COLOR ||159srcRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||160srcRGB == PIPE_BLENDFACTOR_ZERO) &&161(srcA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||162srcA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||163srcA == PIPE_BLENDFACTOR_ZERO) &&164(dstRGB == PIPE_BLENDFACTOR_SRC_COLOR ||165dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||166dstRGB == PIPE_BLENDFACTOR_ONE) &&167(dstA == PIPE_BLENDFACTOR_SRC_COLOR ||168dstA == PIPE_BLENDFACTOR_SRC_ALPHA ||169dstA == PIPE_BLENDFACTOR_ONE);170}171172static unsigned blend_discard_conditionally(unsigned eqRGB, unsigned eqA,173unsigned dstRGB, unsigned dstA,174unsigned srcRGB, unsigned srcA)175{176unsigned blend_control = 0;177178/* Optimization: discard pixels which don't change the colorbuffer.179*180* The code below is non-trivial and some math is involved.181*182* Discarding pixels must be disabled when FP16 AA is enabled.183* This is a hardware bug. Also, this implementation wouldn't work184* with FP blending enabled and equation clamping disabled.185*186* Equations other than ADD are rarely used and therefore won't be187* optimized. */188if ((eqRGB == PIPE_BLEND_ADD || eqRGB == PIPE_BLEND_REVERSE_SUBTRACT) &&189(eqA == PIPE_BLEND_ADD || eqA == PIPE_BLEND_REVERSE_SUBTRACT)) {190/* ADD: X+Y191* REVERSE_SUBTRACT: Y-X192*193* The idea is:194* If X = src*srcFactor = 0 and Y = dst*dstFactor = 1,195* then CB will not be changed.196*197* Given the srcFactor and dstFactor variables, we can derive198* what src and dst should be equal to and discard appropriate199* pixels.200*/201if (blend_discard_if_src_alpha_0(srcRGB, srcA, dstRGB, dstA)) {202blend_control |= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0;203} else if (blend_discard_if_src_alpha_1(srcRGB, srcA,204dstRGB, dstA)) {205blend_control |= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_1;206} else if (blend_discard_if_src_color_0(srcRGB, srcA,207dstRGB, dstA)) {208blend_control |= R300_DISCARD_SRC_PIXELS_SRC_COLOR_0;209} else if (blend_discard_if_src_color_1(srcRGB, srcA,210dstRGB, dstA)) {211blend_control |= R300_DISCARD_SRC_PIXELS_SRC_COLOR_1;212} else if (blend_discard_if_src_alpha_color_0(srcRGB, srcA,213dstRGB, dstA)) {214blend_control |=215R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_0;216} else if (blend_discard_if_src_alpha_color_1(srcRGB, srcA,217dstRGB, dstA)) {218blend_control |=219R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_1;220}221}222return blend_control;223}224225/* The hardware colormask is clunky a must be swizzled depending on the format.226* This was figured out by trial-and-error. */227static unsigned bgra_cmask(unsigned mask)228{229return ((mask & PIPE_MASK_R) << 2) |230((mask & PIPE_MASK_B) >> 2) |231(mask & (PIPE_MASK_G | PIPE_MASK_A));232}233234static unsigned rgba_cmask(unsigned mask)235{236return mask & PIPE_MASK_RGBA;237}238239static unsigned rrrr_cmask(unsigned mask)240{241return (mask & PIPE_MASK_R) |242((mask & PIPE_MASK_R) << 1) |243((mask & PIPE_MASK_R) << 2) |244((mask & PIPE_MASK_R) << 3);245}246247static unsigned aaaa_cmask(unsigned mask)248{249return ((mask & PIPE_MASK_A) >> 3) |250((mask & PIPE_MASK_A) >> 2) |251((mask & PIPE_MASK_A) >> 1) |252(mask & PIPE_MASK_A);253}254255static unsigned grrg_cmask(unsigned mask)256{257return ((mask & PIPE_MASK_R) << 1) |258((mask & PIPE_MASK_R) << 2) |259((mask & PIPE_MASK_G) >> 1) |260((mask & PIPE_MASK_G) << 2);261}262263static unsigned arra_cmask(unsigned mask)264{265return ((mask & PIPE_MASK_R) << 1) |266((mask & PIPE_MASK_R) << 2) |267((mask & PIPE_MASK_A) >> 3) |268(mask & PIPE_MASK_A);269}270271static unsigned blend_read_enable(unsigned eqRGB, unsigned eqA,272unsigned dstRGB, unsigned dstA,273unsigned srcRGB, unsigned srcA,274boolean src_alpha_optz)275{276unsigned blend_control = 0;277278/* Optimization: some operations do not require the destination color.279*280* When SRC_ALPHA_SATURATE is used, colorbuffer reads must be enabled,281* otherwise blending gives incorrect results. It seems to be282* a hardware bug. */283if (eqRGB == PIPE_BLEND_MIN || eqA == PIPE_BLEND_MIN ||284eqRGB == PIPE_BLEND_MAX || eqA == PIPE_BLEND_MAX ||285dstRGB != PIPE_BLENDFACTOR_ZERO ||286dstA != PIPE_BLENDFACTOR_ZERO ||287util_blend_factor_uses_dest(srcRGB, false) ||288util_blend_factor_uses_dest(srcA, true)) {289/* Enable reading from the colorbuffer. */290blend_control |= R300_READ_ENABLE;291292if (src_alpha_optz) {293/* Optimization: Depending on incoming pixels, we can294* conditionally disable the reading in hardware... */295if (eqRGB != PIPE_BLEND_MIN && eqA != PIPE_BLEND_MIN &&296eqRGB != PIPE_BLEND_MAX && eqA != PIPE_BLEND_MAX) {297/* Disable reading if SRC_ALPHA == 0. */298if ((dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||299dstRGB == PIPE_BLENDFACTOR_ZERO) &&300(dstA == PIPE_BLENDFACTOR_SRC_COLOR ||301dstA == PIPE_BLENDFACTOR_SRC_ALPHA ||302dstA == PIPE_BLENDFACTOR_ZERO) &&303(srcRGB != PIPE_BLENDFACTOR_DST_COLOR &&304srcRGB != PIPE_BLENDFACTOR_DST_ALPHA &&305srcRGB != PIPE_BLENDFACTOR_INV_DST_COLOR &&306srcRGB != PIPE_BLENDFACTOR_INV_DST_ALPHA)) {307blend_control |= R500_SRC_ALPHA_0_NO_READ;308}309310/* Disable reading if SRC_ALPHA == 1. */311if ((dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||312dstRGB == PIPE_BLENDFACTOR_ZERO) &&313(dstA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||314dstA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||315dstA == PIPE_BLENDFACTOR_ZERO) &&316(srcRGB != PIPE_BLENDFACTOR_DST_COLOR &&317srcRGB != PIPE_BLENDFACTOR_DST_ALPHA &&318srcRGB != PIPE_BLENDFACTOR_INV_DST_COLOR &&319srcRGB != PIPE_BLENDFACTOR_INV_DST_ALPHA)) {320blend_control |= R500_SRC_ALPHA_1_NO_READ;321}322}323}324}325return blend_control;326}327328/* Create a new blend state based on the CSO blend state.329*330* This encompasses alpha blending, logic/raster ops, and blend dithering. */331static void* r300_create_blend_state(struct pipe_context* pipe,332const struct pipe_blend_state* state)333{334struct r300_screen* r300screen = r300_screen(pipe->screen);335struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);336uint32_t blend_control = 0; /* R300_RB3D_CBLEND: 0x4e04 */337uint32_t blend_control_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */338uint32_t blend_control_noalpha = 0; /* R300_RB3D_CBLEND: 0x4e04 */339uint32_t blend_control_noalpha_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */340uint32_t alpha_blend_control = 0; /* R300_RB3D_ABLEND: 0x4e08 */341uint32_t alpha_blend_control_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */342uint32_t alpha_blend_control_noalpha = 0; /* R300_RB3D_ABLEND: 0x4e08 */343uint32_t alpha_blend_control_noalpha_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */344uint32_t rop = 0; /* R300_RB3D_ROPCNTL: 0x4e18 */345uint32_t dither = 0; /* R300_RB3D_DITHER_CTL: 0x4e50 */346int i;347348const unsigned eqRGB = state->rt[0].rgb_func;349const unsigned srcRGB = state->rt[0].rgb_src_factor;350const unsigned dstRGB = state->rt[0].rgb_dst_factor;351352const unsigned eqA = state->rt[0].alpha_func;353const unsigned srcA = state->rt[0].alpha_src_factor;354const unsigned dstA = state->rt[0].alpha_dst_factor;355356unsigned srcRGBX = srcRGB;357unsigned dstRGBX = dstRGB;358CB_LOCALS;359360blend->state = *state;361362/* force DST_ALPHA to ONE where we can */363switch (srcRGBX) {364case PIPE_BLENDFACTOR_DST_ALPHA:365srcRGBX = PIPE_BLENDFACTOR_ONE;366break;367case PIPE_BLENDFACTOR_INV_DST_ALPHA:368srcRGBX = PIPE_BLENDFACTOR_ZERO;369break;370}371372switch (dstRGBX) {373case PIPE_BLENDFACTOR_DST_ALPHA:374dstRGBX = PIPE_BLENDFACTOR_ONE;375break;376case PIPE_BLENDFACTOR_INV_DST_ALPHA:377dstRGBX = PIPE_BLENDFACTOR_ZERO;378break;379}380381/* Get blending register values. */382if (state->rt[0].blend_enable) {383unsigned blend_eq, blend_eq_noclamp;384385/* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha,386* this is just the crappy D3D naming */387blend_control = blend_control_noclamp =388R300_ALPHA_BLEND_ENABLE |389( r300_translate_blend_factor(srcRGB) << R300_SRC_BLEND_SHIFT) |390( r300_translate_blend_factor(dstRGB) << R300_DST_BLEND_SHIFT);391392blend_control_noalpha = blend_control_noalpha_noclamp =393R300_ALPHA_BLEND_ENABLE |394( r300_translate_blend_factor(srcRGBX) << R300_SRC_BLEND_SHIFT) |395( r300_translate_blend_factor(dstRGBX) << R300_DST_BLEND_SHIFT);396397blend_eq = r300_translate_blend_function(eqRGB, TRUE);398blend_eq_noclamp = r300_translate_blend_function(eqRGB, FALSE);399400blend_control |= blend_eq;401blend_control_noalpha |= blend_eq;402blend_control_noclamp |= blend_eq_noclamp;403blend_control_noalpha_noclamp |= blend_eq_noclamp;404405/* Optimization: some operations do not require the destination color. */406blend_control |= blend_read_enable(eqRGB, eqA, dstRGB, dstA,407srcRGB, srcA, r300screen->caps.is_r500);408blend_control_noclamp |= blend_read_enable(eqRGB, eqA, dstRGB, dstA,409srcRGB, srcA, FALSE);410blend_control_noalpha |= blend_read_enable(eqRGB, eqA, dstRGBX, dstA,411srcRGBX, srcA, r300screen->caps.is_r500);412blend_control_noalpha_noclamp |= blend_read_enable(eqRGB, eqA, dstRGBX, dstA,413srcRGBX, srcA, FALSE);414415/* Optimization: discard pixels which don't change the colorbuffer.416* It cannot be used with FP16 AA. */417blend_control |= blend_discard_conditionally(eqRGB, eqA, dstRGB, dstA,418srcRGB, srcA);419blend_control_noalpha |= blend_discard_conditionally(eqRGB, eqA, dstRGBX, dstA,420srcRGBX, srcA);421422/* separate alpha */423if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {424blend_control |= R300_SEPARATE_ALPHA_ENABLE;425blend_control_noclamp |= R300_SEPARATE_ALPHA_ENABLE;426427alpha_blend_control = alpha_blend_control_noclamp =428(r300_translate_blend_factor(srcA) << R300_SRC_BLEND_SHIFT) |429(r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT);430alpha_blend_control |= r300_translate_blend_function(eqA, TRUE);431alpha_blend_control_noclamp |= r300_translate_blend_function(eqA, FALSE);432}433if (srcA != srcRGBX || dstA != dstRGBX || eqA != eqRGB) {434blend_control_noalpha |= R300_SEPARATE_ALPHA_ENABLE;435blend_control_noalpha_noclamp |= R300_SEPARATE_ALPHA_ENABLE;436437alpha_blend_control_noalpha = alpha_blend_control_noalpha_noclamp =438(r300_translate_blend_factor(srcA) << R300_SRC_BLEND_SHIFT) |439(r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT);440alpha_blend_control_noalpha |= r300_translate_blend_function(eqA, TRUE);441alpha_blend_control_noalpha_noclamp |= r300_translate_blend_function(eqA, FALSE);442}443}444445/* PIPE_LOGICOP_* don't need to be translated, fortunately. */446if (state->logicop_enable) {447rop = R300_RB3D_ROPCNTL_ROP_ENABLE |448(state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;449}450451/* Neither fglrx nor classic r300 ever set this, regardless of dithering452* state. Since it's an optional implementation detail, we can leave it453* out and never dither.454*455* This could be revisited if we ever get quality or conformance hints.456*457if (state->dither) {458dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT |459R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT;460}461*/462463/* Build a command buffer. */464{465unsigned (*func[COLORMASK_NUM_SWIZZLES])(unsigned) = {466bgra_cmask,467rgba_cmask,468rrrr_cmask,469aaaa_cmask,470grrg_cmask,471arra_cmask,472bgra_cmask,473rgba_cmask474};475476for (i = 0; i < COLORMASK_NUM_SWIZZLES; i++) {477boolean has_alpha = i != COLORMASK_RGBX && i != COLORMASK_BGRX;478479BEGIN_CB(blend->cb_clamp[i], 8);480OUT_CB_REG(R300_RB3D_ROPCNTL, rop);481OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);482OUT_CB(has_alpha ? blend_control : blend_control_noalpha);483OUT_CB(has_alpha ? alpha_blend_control : alpha_blend_control_noalpha);484OUT_CB(func[i](state->rt[0].colormask));485OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);486END_CB;487}488}489490/* Build a command buffer (for RGBA16F). */491BEGIN_CB(blend->cb_noclamp, 8);492OUT_CB_REG(R300_RB3D_ROPCNTL, rop);493OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);494OUT_CB(blend_control_noclamp);495OUT_CB(alpha_blend_control_noclamp);496OUT_CB(rgba_cmask(state->rt[0].colormask));497OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);498END_CB;499500/* Build a command buffer (for RGB16F). */501BEGIN_CB(blend->cb_noclamp_noalpha, 8);502OUT_CB_REG(R300_RB3D_ROPCNTL, rop);503OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);504OUT_CB(blend_control_noalpha_noclamp);505OUT_CB(alpha_blend_control_noalpha_noclamp);506OUT_CB(rgba_cmask(state->rt[0].colormask));507OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);508END_CB;509510/* The same as above, but with no colorbuffer reads and writes. */511BEGIN_CB(blend->cb_no_readwrite, 8);512OUT_CB_REG(R300_RB3D_ROPCNTL, rop);513OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);514OUT_CB(0);515OUT_CB(0);516OUT_CB(0);517OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);518END_CB;519520return (void*)blend;521}522523/* Bind blend state. */524static void r300_bind_blend_state(struct pipe_context* pipe,525void* state)526{527struct r300_context* r300 = r300_context(pipe);528struct r300_blend_state *blend = (struct r300_blend_state*)state;529boolean last_alpha_to_one = r300->alpha_to_one;530boolean last_alpha_to_coverage = r300->alpha_to_coverage;531532UPDATE_STATE(state, r300->blend_state);533534if (!blend)535return;536537r300->alpha_to_one = blend->state.alpha_to_one;538r300->alpha_to_coverage = blend->state.alpha_to_coverage;539540if (r300->alpha_to_one != last_alpha_to_one && r300->msaa_enable &&541r300->fs_status == FRAGMENT_SHADER_VALID) {542r300->fs_status = FRAGMENT_SHADER_MAYBE_DIRTY;543}544545if (r300->alpha_to_coverage != last_alpha_to_coverage &&546r300->msaa_enable) {547r300_mark_atom_dirty(r300, &r300->dsa_state);548}549}550551/* Free blend state. */552static void r300_delete_blend_state(struct pipe_context* pipe,553void* state)554{555FREE(state);556}557558/* Convert float to 10bit integer */559static unsigned float_to_fixed10(float f)560{561return CLAMP((unsigned)(f * 1023.9f), 0, 1023);562}563564/* Set blend color.565* Setup both R300 and R500 registers, figure out later which one to write. */566static void r300_set_blend_color(struct pipe_context* pipe,567const struct pipe_blend_color* color)568{569struct r300_context* r300 = r300_context(pipe);570struct pipe_framebuffer_state *fb = r300->fb_state.state;571struct r300_blend_color_state *state =572(struct r300_blend_color_state*)r300->blend_color_state.state;573struct pipe_blend_color c;574struct pipe_surface *cb;575float tmp;576CB_LOCALS;577578state->state = *color; /* Save it, so that we can reuse it in set_fb_state */579c = *color;580cb = fb->nr_cbufs ? r300_get_nonnull_cb(fb, 0) : NULL;581582/* The blend color is dependent on the colorbuffer format. */583if (cb) {584switch (cb->format) {585case PIPE_FORMAT_R8_UNORM:586case PIPE_FORMAT_L8_UNORM:587case PIPE_FORMAT_I8_UNORM:588c.color[1] = c.color[0];589break;590591case PIPE_FORMAT_A8_UNORM:592c.color[1] = c.color[3];593break;594595case PIPE_FORMAT_R8G8_UNORM:596c.color[2] = c.color[1];597break;598599case PIPE_FORMAT_L8A8_UNORM:600case PIPE_FORMAT_R8A8_UNORM:601c.color[2] = c.color[3];602break;603604case PIPE_FORMAT_R8G8B8A8_UNORM:605case PIPE_FORMAT_R8G8B8X8_UNORM:606tmp = c.color[0];607c.color[0] = c.color[2];608c.color[2] = tmp;609break;610611default:;612}613}614615if (r300->screen->caps.is_r500) {616BEGIN_CB(state->cb, 3);617OUT_CB_REG_SEQ(R500_RB3D_CONSTANT_COLOR_AR, 2);618619switch (cb ? cb->format : 0) {620case PIPE_FORMAT_R16G16B16A16_FLOAT:621case PIPE_FORMAT_R16G16B16X16_FLOAT:622OUT_CB(_mesa_float_to_half(c.color[2]) |623(_mesa_float_to_half(c.color[3]) << 16));624OUT_CB(_mesa_float_to_half(c.color[0]) |625(_mesa_float_to_half(c.color[1]) << 16));626break;627628default:629OUT_CB(float_to_fixed10(c.color[0]) |630(float_to_fixed10(c.color[3]) << 16));631OUT_CB(float_to_fixed10(c.color[2]) |632(float_to_fixed10(c.color[1]) << 16));633}634635END_CB;636} else {637union util_color uc;638util_pack_color(c.color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);639640BEGIN_CB(state->cb, 2);641OUT_CB_REG(R300_RB3D_BLEND_COLOR, uc.ui[0]);642END_CB;643}644645r300_mark_atom_dirty(r300, &r300->blend_color_state);646}647648static void r300_set_clip_state(struct pipe_context* pipe,649const struct pipe_clip_state* state)650{651struct r300_context* r300 = r300_context(pipe);652struct r300_clip_state *clip =653(struct r300_clip_state*)r300->clip_state.state;654CB_LOCALS;655656if (r300->screen->caps.has_tcl) {657BEGIN_CB(clip->cb, r300->clip_state.size);658OUT_CB_REG(R300_VAP_PVS_VECTOR_INDX_REG,659(r300->screen->caps.is_r500 ?660R500_PVS_UCP_START : R300_PVS_UCP_START));661OUT_CB_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 6 * 4);662OUT_CB_TABLE(state->ucp, 6 * 4);663END_CB;664665r300_mark_atom_dirty(r300, &r300->clip_state);666} else {667draw_set_clip_state(r300->draw, state);668}669}670671/* Create a new depth, stencil, and alpha state based on the CSO dsa state.672*673* This contains the depth buffer, stencil buffer, alpha test, and such.674* On the Radeon, depth and stencil buffer setup are intertwined, which is675* the reason for some of the strange-looking assignments across registers. */676static void* r300_create_dsa_state(struct pipe_context* pipe,677const struct pipe_depth_stencil_alpha_state* state)678{679boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;680struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);681CB_LOCALS;682uint32_t alpha_value_fp16 = 0;683uint32_t z_buffer_control = 0;684uint32_t z_stencil_control = 0;685uint32_t stencil_ref_mask = 0;686uint32_t stencil_ref_bf = 0;687688dsa->dsa = *state;689690/* Depth test setup. - separate write mask depth for decomp flush */691if (state->depth_writemask) {692z_buffer_control |= R300_Z_WRITE_ENABLE;693}694695if (state->depth_enabled) {696z_buffer_control |= R300_Z_ENABLE;697698z_stencil_control |=699(r300_translate_depth_stencil_function(state->depth_func) <<700R300_Z_FUNC_SHIFT);701}702703/* Stencil buffer setup. */704if (state->stencil[0].enabled) {705z_buffer_control |= R300_STENCIL_ENABLE;706z_stencil_control |=707(r300_translate_depth_stencil_function(state->stencil[0].func) <<708R300_S_FRONT_FUNC_SHIFT) |709(r300_translate_stencil_op(state->stencil[0].fail_op) <<710R300_S_FRONT_SFAIL_OP_SHIFT) |711(r300_translate_stencil_op(state->stencil[0].zpass_op) <<712R300_S_FRONT_ZPASS_OP_SHIFT) |713(r300_translate_stencil_op(state->stencil[0].zfail_op) <<714R300_S_FRONT_ZFAIL_OP_SHIFT);715716stencil_ref_mask =717(state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) |718(state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT);719720if (state->stencil[1].enabled) {721dsa->two_sided = TRUE;722723z_buffer_control |= R300_STENCIL_FRONT_BACK;724z_stencil_control |=725(r300_translate_depth_stencil_function(state->stencil[1].func) <<726R300_S_BACK_FUNC_SHIFT) |727(r300_translate_stencil_op(state->stencil[1].fail_op) <<728R300_S_BACK_SFAIL_OP_SHIFT) |729(r300_translate_stencil_op(state->stencil[1].zpass_op) <<730R300_S_BACK_ZPASS_OP_SHIFT) |731(r300_translate_stencil_op(state->stencil[1].zfail_op) <<732R300_S_BACK_ZFAIL_OP_SHIFT);733734stencil_ref_bf =735(state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) |736(state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT);737738if (is_r500) {739z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;740} else {741dsa->two_sided_stencil_ref =742(state->stencil[0].valuemask != state->stencil[1].valuemask ||743state->stencil[0].writemask != state->stencil[1].writemask);744}745}746}747748/* Alpha test setup. */749if (state->alpha_enabled) {750dsa->alpha_function =751r300_translate_alpha_function(state->alpha_func) |752R300_FG_ALPHA_FUNC_ENABLE;753754dsa->alpha_function |= float_to_ubyte(state->alpha_ref_value);755alpha_value_fp16 = _mesa_float_to_half(state->alpha_ref_value);756}757758BEGIN_CB(&dsa->cb_begin, 8);759OUT_CB_REG_SEQ(R300_ZB_CNTL, 3);760OUT_CB(z_buffer_control);761OUT_CB(z_stencil_control);762OUT_CB(stencil_ref_mask);763OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, stencil_ref_bf);764OUT_CB_REG(R500_FG_ALPHA_VALUE, alpha_value_fp16);765END_CB;766767BEGIN_CB(dsa->cb_zb_no_readwrite, 8);768OUT_CB_REG_SEQ(R300_ZB_CNTL, 3);769OUT_CB(0);770OUT_CB(0);771OUT_CB(0);772OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, 0);773OUT_CB_REG(R500_FG_ALPHA_VALUE, alpha_value_fp16);774END_CB;775776return (void*)dsa;777}778779static void r300_dsa_inject_stencilref(struct r300_context *r300)780{781struct r300_dsa_state *dsa =782(struct r300_dsa_state*)r300->dsa_state.state;783784if (!dsa)785return;786787dsa->stencil_ref_mask =788(dsa->stencil_ref_mask & ~R300_STENCILREF_MASK) |789r300->stencil_ref.ref_value[0];790dsa->stencil_ref_bf =791(dsa->stencil_ref_bf & ~R300_STENCILREF_MASK) |792r300->stencil_ref.ref_value[1];793}794795/* Bind DSA state. */796static void r300_bind_dsa_state(struct pipe_context* pipe,797void* state)798{799struct r300_context* r300 = r300_context(pipe);800801if (!state) {802return;803}804805UPDATE_STATE(state, r300->dsa_state);806807r300_mark_atom_dirty(r300, &r300->hyperz_state); /* Will be updated before the emission. */808r300_dsa_inject_stencilref(r300);809}810811/* Free DSA state. */812static void r300_delete_dsa_state(struct pipe_context* pipe,813void* state)814{815FREE(state);816}817818static void r300_set_stencil_ref(struct pipe_context* pipe,819const struct pipe_stencil_ref sr)820{821struct r300_context* r300 = r300_context(pipe);822823r300->stencil_ref = sr;824825r300_dsa_inject_stencilref(r300);826r300_mark_atom_dirty(r300, &r300->dsa_state);827}828829static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,830const char *binding)831{832struct pipe_resource *tex = surf->texture;833struct r300_resource *rtex = r300_resource(tex);834835fprintf(stderr,836"r300: %s[%i] Dim: %ix%i, Firstlayer: %i, "837"Lastlayer: %i, Level: %i, Format: %s\n"838839"r300: TEX: Macro: %s, Micro: %s, "840"Dim: %ix%ix%i, LastLevel: %i, Format: %s\n",841842binding, index, surf->width, surf->height,843surf->u.tex.first_layer, surf->u.tex.last_layer, surf->u.tex.level,844util_format_short_name(surf->format),845846rtex->tex.macrotile[0] ? "YES" : " NO",847rtex->tex.microtile ? "YES" : " NO",848tex->width0, tex->height0, tex->depth0,849tex->last_level, util_format_short_name(surf->format));850}851852void r300_mark_fb_state_dirty(struct r300_context *r300,853enum r300_fb_state_change change)854{855struct pipe_framebuffer_state *state = r300->fb_state.state;856857r300_mark_atom_dirty(r300, &r300->gpu_flush);858r300_mark_atom_dirty(r300, &r300->fb_state);859860/* What is marked as dirty depends on the enum r300_fb_state_change. */861if (change == R300_CHANGED_FB_STATE) {862r300_mark_atom_dirty(r300, &r300->aa_state);863r300_mark_atom_dirty(r300, &r300->dsa_state); /* for AlphaRef */864r300_set_blend_color(&r300->context, r300->blend_color_state.state);865}866867if (change == R300_CHANGED_FB_STATE ||868change == R300_CHANGED_HYPERZ_FLAG) {869r300_mark_atom_dirty(r300, &r300->hyperz_state);870}871872if (change == R300_CHANGED_FB_STATE ||873change == R300_CHANGED_MULTIWRITE) {874r300_mark_atom_dirty(r300, &r300->fb_state_pipelined);875}876877/* Now compute the fb_state atom size. */878r300->fb_state.size = 2 + (8 * state->nr_cbufs);879880if (r300->cbzb_clear)881r300->fb_state.size += 10;882else if (state->zsbuf) {883r300->fb_state.size += 10;884if (r300->hyperz_enabled)885r300->fb_state.size += 8;886}887888if (r300->cmask_in_use) {889r300->fb_state.size += 6;890if (r300->screen->caps.is_r500 && r300->screen->info.drm_minor >= 29) {891r300->fb_state.size += 3;892}893}894895/* The size of the rest of atoms stays the same. */896}897898static void899r300_set_framebuffer_state(struct pipe_context* pipe,900const struct pipe_framebuffer_state* state)901{902struct r300_context* r300 = r300_context(pipe);903struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;904struct pipe_framebuffer_state *current_state = r300->fb_state.state;905unsigned max_width, max_height, i;906uint32_t zbuffer_bpp = 0;907boolean unlock_zbuffer = FALSE;908909if (r300->screen->caps.is_r500) {910max_width = max_height = 4096;911} else if (r300->screen->caps.is_r400) {912max_width = max_height = 4021;913} else {914max_width = max_height = 2560;915}916917if (state->width > max_width || state->height > max_height) {918fprintf(stderr, "r300: Implementation error: Render targets are too "919"big in %s, refusing to bind framebuffer state!\n", __FUNCTION__);920return;921}922923if (current_state->zsbuf && r300->zmask_in_use && !r300->locked_zbuffer) {924/* There is a zmask in use, what are we gonna do? */925if (state->zsbuf) {926if (!pipe_surface_equal(current_state->zsbuf, state->zsbuf)) {927/* Decompress the currently bound zbuffer before we bind another one. */928r300_decompress_zmask(r300);929r300->hiz_in_use = FALSE;930}931} else {932/* We don't bind another zbuffer, so lock the current one. */933pipe_surface_reference(&r300->locked_zbuffer, current_state->zsbuf);934}935} else if (r300->locked_zbuffer) {936/* We have a locked zbuffer now, what are we gonna do? */937if (state->zsbuf) {938if (!pipe_surface_equal(r300->locked_zbuffer, state->zsbuf)) {939/* We are binding some other zbuffer, so decompress the locked one,940* it gets unlocked automatically. */941r300_decompress_zmask_locked_unsafe(r300);942r300->hiz_in_use = FALSE;943} else {944/* We are binding the locked zbuffer again, so unlock it. */945unlock_zbuffer = TRUE;946}947}948}949assert(state->zsbuf || (r300->locked_zbuffer && !unlock_zbuffer) || !r300->zmask_in_use);950951/* If zsbuf is set from NULL to non-NULL or vice versa.. */952if (!!current_state->zsbuf != !!state->zsbuf) {953r300_mark_atom_dirty(r300, &r300->dsa_state);954}955956util_copy_framebuffer_state(r300->fb_state.state, state);957958/* Remove trailing NULL colorbuffers. */959while (current_state->nr_cbufs && !current_state->cbufs[current_state->nr_cbufs-1])960current_state->nr_cbufs--;961962/* Set whether CMASK can be used. */963r300->cmask_in_use =964state->nr_cbufs == 1 && state->cbufs[0] &&965r300->screen->cmask_resource == state->cbufs[0]->texture;966967/* Need to reset clamping or colormask. */968r300_mark_atom_dirty(r300, &r300->blend_state);969970/* Re-swizzle the blend color. */971r300_set_blend_color(pipe, &((struct r300_blend_color_state*)r300->blend_color_state.state)->state);972973if (unlock_zbuffer) {974pipe_surface_reference(&r300->locked_zbuffer, NULL);975}976977r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE);978979if (state->zsbuf) {980switch (util_format_get_blocksize(state->zsbuf->format)) {981case 2:982zbuffer_bpp = 16;983break;984case 4:985zbuffer_bpp = 24;986break;987}988989/* Polygon offset depends on the zbuffer bit depth. */990if (r300->zbuffer_bpp != zbuffer_bpp) {991r300->zbuffer_bpp = zbuffer_bpp;992993if (r300->polygon_offset_enabled)994r300_mark_atom_dirty(r300, &r300->rs_state);995}996}997998r300->num_samples = util_framebuffer_get_num_samples(state);9991000/* Set up AA config. */1001if (r300->num_samples > 1) {1002switch (r300->num_samples) {1003case 2:1004aa->aa_config = R300_GB_AA_CONFIG_AA_ENABLE |1005R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2;1006break;1007case 4:1008aa->aa_config = R300_GB_AA_CONFIG_AA_ENABLE |1009R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4;1010break;1011case 6:1012aa->aa_config = R300_GB_AA_CONFIG_AA_ENABLE |1013R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6;1014break;1015}1016} else {1017aa->aa_config = 0;1018}10191020if (DBG_ON(r300, DBG_FB)) {1021fprintf(stderr, "r300: set_framebuffer_state:\n");1022for (i = 0; i < state->nr_cbufs; i++) {1023if (state->cbufs[i])1024r300_print_fb_surf_info(state->cbufs[i], i, "CB");1025}1026if (state->zsbuf) {1027r300_print_fb_surf_info(state->zsbuf, 0, "ZB");1028}1029}1030}10311032/* Create fragment shader state. */1033static void* r300_create_fs_state(struct pipe_context* pipe,1034const struct pipe_shader_state* shader)1035{1036struct r300_fragment_shader* fs = NULL;10371038fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);10391040/* Copy state directly into shader. */1041fs->state = *shader;1042fs->state.tokens = tgsi_dup_tokens(shader->tokens);10431044return (void*)fs;1045}10461047void r300_mark_fs_code_dirty(struct r300_context *r300)1048{1049struct r300_fragment_shader* fs = r300_fs(r300);10501051r300_mark_atom_dirty(r300, &r300->fs);1052r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state);1053r300_mark_atom_dirty(r300, &r300->fs_constants);1054r300->fs.size = fs->shader->cb_code_size;10551056if (r300->screen->caps.is_r500) {1057r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 7;1058r300->fs_constants.size = fs->shader->externals_count * 4 + 3;1059} else {1060r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 5;1061r300->fs_constants.size = fs->shader->externals_count * 4 + 1;1062}10631064((struct r300_constant_buffer*)r300->fs_constants.state)->remap_table =1065fs->shader->code.constants_remap_table;1066}10671068/* Bind fragment shader state. */1069static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)1070{1071struct r300_context* r300 = r300_context(pipe);1072struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;10731074if (!fs) {1075r300->fs.state = NULL;1076return;1077}10781079r300->fs.state = fs;1080r300->fs_status = FRAGMENT_SHADER_DIRTY;10811082r300_mark_atom_dirty(r300, &r300->rs_block_state); /* Will be updated before the emission. */1083}10841085/* Delete fragment shader state. */1086static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)1087{1088struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;1089struct r300_fragment_shader_code *tmp, *ptr = fs->first;10901091while (ptr) {1092tmp = ptr;1093ptr = ptr->next;1094rc_constants_destroy(&tmp->code.constants);1095FREE(tmp->cb_code);1096FREE(tmp);1097}1098FREE((void*)fs->state.tokens);1099FREE(shader);1100}11011102static void r300_set_polygon_stipple(struct pipe_context* pipe,1103const struct pipe_poly_stipple* state)1104{1105}11061107/* Create a new rasterizer state based on the CSO rasterizer state.1108*1109* This is a very large chunk of state, and covers most of the graphics1110* backend (GB), geometry assembly (GA), and setup unit (SU) blocks.1111*1112* In a not entirely unironic sidenote, this state has nearly nothing to do1113* with the actual block on the Radeon called the rasterizer (RS). */1114static void* r300_create_rs_state(struct pipe_context* pipe,1115const struct pipe_rasterizer_state* state)1116{1117struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);1118uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */1119uint32_t vap_clip_cntl; /* R300_VAP_CLIP_CNTL: 0x221C */1120uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */1121uint32_t point_minmax; /* R300_GA_POINT_MINMAX: 0x4230 */1122uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */1123uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */1124uint32_t cull_mode; /* R300_SU_CULL_MODE: 0x42b8 */1125uint32_t line_stipple_config; /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */1126uint32_t line_stipple_value; /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */1127uint32_t polygon_mode; /* R300_GA_POLY_MODE: 0x4288 */1128uint32_t clip_rule; /* R300_SC_CLIP_RULE: 0x43D0 */1129uint32_t round_mode; /* R300_GA_ROUND_MODE: 0x428c */11301131/* Point sprites texture coordinates, 0: lower left, 1: upper right */1132float point_texcoord_left = 0; /* R300_GA_POINT_S0: 0x4200 */1133float point_texcoord_bottom = 0;/* R300_GA_POINT_T0: 0x4204 */1134float point_texcoord_right = 1; /* R300_GA_POINT_S1: 0x4208 */1135float point_texcoord_top = 0; /* R300_GA_POINT_T1: 0x420c */1136boolean vclamp = !r300_context(pipe)->screen->caps.is_r500;1137CB_LOCALS;11381139/* Copy rasterizer state. */1140rs->rs = *state;1141rs->rs_draw = *state;11421143rs->rs.sprite_coord_enable = state->point_quad_rasterization *1144state->sprite_coord_enable;11451146/* Override some states for Draw. */1147rs->rs_draw.sprite_coord_enable = 0; /* We can do this in HW. */1148rs->rs_draw.offset_point = 0;1149rs->rs_draw.offset_line = 0;1150rs->rs_draw.offset_tri = 0;1151rs->rs_draw.offset_clamp = 0;11521153#if UTIL_ARCH_LITTLE_ENDIAN1154vap_control_status = R300_VC_NO_SWAP;1155#else1156vap_control_status = R300_VC_32BIT_SWAP;1157#endif11581159/* If no TCL engine is present, turn off the HW TCL. */1160if (!r300_screen(pipe->screen)->caps.has_tcl) {1161vap_control_status |= R300_VAP_TCL_BYPASS;1162}11631164/* Point size width and height. */1165point_size =1166pack_float_16_6x(state->point_size) |1167(pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT);11681169/* Point size clamping. */1170if (state->point_size_per_vertex) {1171/* Per-vertex point size.1172* Clamp to [0, max FB size] */1173float min_psiz = util_get_min_point_size(state);1174float max_psiz = pipe->screen->get_paramf(pipe->screen,1175PIPE_CAPF_MAX_POINT_WIDTH);1176point_minmax =1177(pack_float_16_6x(min_psiz) << R300_GA_POINT_MINMAX_MIN_SHIFT) |1178(pack_float_16_6x(max_psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT);1179} else {1180/* We cannot disable the point-size vertex output,1181* so clamp it. */1182float psiz = state->point_size;1183point_minmax =1184(pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MIN_SHIFT) |1185(pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT);1186}11871188/* Line control. */1189line_control = pack_float_16_6x(state->line_width) |1190R300_GA_LINE_CNTL_END_TYPE_COMP;11911192/* Enable polygon mode */1193polygon_mode = 0;1194if (state->fill_front != PIPE_POLYGON_MODE_FILL ||1195state->fill_back != PIPE_POLYGON_MODE_FILL) {1196polygon_mode = R300_GA_POLY_MODE_DUAL;1197}11981199/* Front face */1200if (state->front_ccw)1201cull_mode = R300_FRONT_FACE_CCW;1202else1203cull_mode = R300_FRONT_FACE_CW;12041205/* Polygon offset */1206polygon_offset_enable = 0;1207if (util_get_offset(state, state->fill_front)) {1208polygon_offset_enable |= R300_FRONT_ENABLE;1209}1210if (util_get_offset(state, state->fill_back)) {1211polygon_offset_enable |= R300_BACK_ENABLE;1212}12131214rs->polygon_offset_enable = polygon_offset_enable != 0;12151216/* Polygon mode */1217if (polygon_mode) {1218polygon_mode |=1219r300_translate_polygon_mode_front(state->fill_front);1220polygon_mode |=1221r300_translate_polygon_mode_back(state->fill_back);1222}12231224if (state->cull_face & PIPE_FACE_FRONT) {1225cull_mode |= R300_CULL_FRONT;1226}1227if (state->cull_face & PIPE_FACE_BACK) {1228cull_mode |= R300_CULL_BACK;1229}12301231if (state->line_stipple_enable) {1232line_stipple_config =1233R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE |1234(fui((float)state->line_stipple_factor) &1235R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK);1236/* XXX this might need to be scaled up */1237line_stipple_value = state->line_stipple_pattern;1238} else {1239line_stipple_config = 0;1240line_stipple_value = 0;1241}12421243if (state->flatshade) {1244rs->color_control = R300_SHADE_MODEL_FLAT;1245} else {1246rs->color_control = R300_SHADE_MODEL_SMOOTH;1247}12481249clip_rule = state->scissor ? 0xAAAA : 0xFFFF;12501251/* Point sprites coord mode */1252if (rs->rs.sprite_coord_enable) {1253switch (state->sprite_coord_mode) {1254case PIPE_SPRITE_COORD_UPPER_LEFT:1255point_texcoord_top = 0.0f;1256point_texcoord_bottom = 1.0f;1257break;1258case PIPE_SPRITE_COORD_LOWER_LEFT:1259point_texcoord_top = 1.0f;1260point_texcoord_bottom = 0.0f;1261break;1262}1263}12641265if (r300_screen(pipe->screen)->caps.has_tcl) {1266vap_clip_cntl = (state->clip_plane_enable & 63) |1267R300_PS_UCP_MODE_CLIP_AS_TRIFAN;1268} else {1269vap_clip_cntl = R300_CLIP_DISABLE;1270}12711272/* Vertex color clamping. FP20 means no clamping. */1273round_mode =1274R300_GA_ROUND_MODE_GEOMETRY_ROUND_NEAREST |1275(!vclamp ? (R300_GA_ROUND_MODE_RGB_CLAMP_FP20 |1276R300_GA_ROUND_MODE_ALPHA_CLAMP_FP20) : 0);12771278/* Build the main command buffer. */1279BEGIN_CB(rs->cb_main, RS_STATE_MAIN_SIZE);1280OUT_CB_REG(R300_VAP_CNTL_STATUS, vap_control_status);1281OUT_CB_REG(R300_VAP_CLIP_CNTL, vap_clip_cntl);1282OUT_CB_REG(R300_GA_POINT_SIZE, point_size);1283OUT_CB_REG_SEQ(R300_GA_POINT_MINMAX, 2);1284OUT_CB(point_minmax);1285OUT_CB(line_control);1286OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2);1287OUT_CB(polygon_offset_enable);1288rs->cull_mode_index = 11;1289OUT_CB(cull_mode);1290OUT_CB_REG(R300_GA_LINE_STIPPLE_CONFIG, line_stipple_config);1291OUT_CB_REG(R300_GA_LINE_STIPPLE_VALUE, line_stipple_value);1292OUT_CB_REG(R300_GA_POLY_MODE, polygon_mode);1293OUT_CB_REG(R300_GA_ROUND_MODE, round_mode);1294OUT_CB_REG(R300_SC_CLIP_RULE, clip_rule);1295OUT_CB_REG_SEQ(R300_GA_POINT_S0, 4);1296OUT_CB_32F(point_texcoord_left);1297OUT_CB_32F(point_texcoord_bottom);1298OUT_CB_32F(point_texcoord_right);1299OUT_CB_32F(point_texcoord_top);1300END_CB;13011302/* Build the two command buffers for polygon offset setup. */1303if (polygon_offset_enable) {1304float scale = state->offset_scale * 12;1305float offset = state->offset_units * 4;13061307BEGIN_CB(rs->cb_poly_offset_zb16, 5);1308OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4);1309OUT_CB_32F(scale);1310OUT_CB_32F(offset);1311OUT_CB_32F(scale);1312OUT_CB_32F(offset);1313END_CB;13141315offset = state->offset_units * 2;13161317BEGIN_CB(rs->cb_poly_offset_zb24, 5);1318OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4);1319OUT_CB_32F(scale);1320OUT_CB_32F(offset);1321OUT_CB_32F(scale);1322OUT_CB_32F(offset);1323END_CB;1324}13251326return (void*)rs;1327}13281329/* Bind rasterizer state. */1330static void r300_bind_rs_state(struct pipe_context* pipe, void* state)1331{1332struct r300_context* r300 = r300_context(pipe);1333struct r300_rs_state* rs = (struct r300_rs_state*)state;1334int last_sprite_coord_enable = r300->sprite_coord_enable;1335boolean last_two_sided_color = r300->two_sided_color;1336boolean last_msaa_enable = r300->msaa_enable;1337boolean last_flatshade = r300->flatshade;1338boolean last_clip_halfz = r300->clip_halfz;13391340if (r300->draw && rs) {1341draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state);1342}13431344if (rs) {1345r300->polygon_offset_enabled = rs->polygon_offset_enable;1346r300->sprite_coord_enable = rs->rs.sprite_coord_enable;1347r300->two_sided_color = rs->rs.light_twoside;1348r300->msaa_enable = rs->rs.multisample;1349r300->flatshade = rs->rs.flatshade;1350r300->clip_halfz = rs->rs.clip_halfz;1351} else {1352r300->polygon_offset_enabled = FALSE;1353r300->sprite_coord_enable = 0;1354r300->two_sided_color = FALSE;1355r300->msaa_enable = FALSE;1356r300->flatshade = FALSE;1357r300->clip_halfz = FALSE;1358}13591360UPDATE_STATE(state, r300->rs_state);1361r300->rs_state.size = RS_STATE_MAIN_SIZE + (r300->polygon_offset_enabled ? 5 : 0);13621363if (last_sprite_coord_enable != r300->sprite_coord_enable ||1364last_two_sided_color != r300->two_sided_color ||1365last_flatshade != r300->flatshade) {1366r300_mark_atom_dirty(r300, &r300->rs_block_state);1367}13681369if (last_msaa_enable != r300->msaa_enable) {1370if (r300->alpha_to_coverage) {1371r300_mark_atom_dirty(r300, &r300->dsa_state);1372}13731374if (r300->alpha_to_one &&1375r300->fs_status == FRAGMENT_SHADER_VALID) {1376r300->fs_status = FRAGMENT_SHADER_MAYBE_DIRTY;1377}1378}13791380if (r300->screen->caps.has_tcl && last_clip_halfz != r300->clip_halfz) {1381r300_mark_atom_dirty(r300, &r300->vs_state);1382}1383}13841385/* Free rasterizer state. */1386static void r300_delete_rs_state(struct pipe_context* pipe, void* state)1387{1388FREE(state);1389}13901391static void*1392r300_create_sampler_state(struct pipe_context* pipe,1393const struct pipe_sampler_state* state)1394{1395struct r300_context* r300 = r300_context(pipe);1396struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);1397boolean is_r500 = r300->screen->caps.is_r500;1398int lod_bias;13991400sampler->state = *state;14011402/* r300 doesn't handle CLAMP and MIRROR_CLAMP correctly when either MAG1403* or MIN filter is NEAREST. Since texwrap produces same results1404* for CLAMP and CLAMP_TO_EDGE, we use them instead. */1405if (sampler->state.min_img_filter == PIPE_TEX_FILTER_NEAREST ||1406sampler->state.mag_img_filter == PIPE_TEX_FILTER_NEAREST) {1407/* Wrap S. */1408if (sampler->state.wrap_s == PIPE_TEX_WRAP_CLAMP)1409sampler->state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;1410else if (sampler->state.wrap_s == PIPE_TEX_WRAP_MIRROR_CLAMP)1411sampler->state.wrap_s = PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;14121413/* Wrap T. */1414if (sampler->state.wrap_t == PIPE_TEX_WRAP_CLAMP)1415sampler->state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;1416else if (sampler->state.wrap_t == PIPE_TEX_WRAP_MIRROR_CLAMP)1417sampler->state.wrap_t = PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;14181419/* Wrap R. */1420if (sampler->state.wrap_r == PIPE_TEX_WRAP_CLAMP)1421sampler->state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;1422else if (sampler->state.wrap_r == PIPE_TEX_WRAP_MIRROR_CLAMP)1423sampler->state.wrap_r = PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;1424}14251426sampler->filter0 |=1427(r300_translate_wrap(sampler->state.wrap_s) << R300_TX_WRAP_S_SHIFT) |1428(r300_translate_wrap(sampler->state.wrap_t) << R300_TX_WRAP_T_SHIFT) |1429(r300_translate_wrap(sampler->state.wrap_r) << R300_TX_WRAP_R_SHIFT);14301431sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter,1432state->mag_img_filter,1433state->min_mip_filter,1434state->max_anisotropy > 1);14351436sampler->filter0 |= r300_anisotropy(state->max_anisotropy);14371438/* Unfortunately, r300-r500 don't support floating-point mipmap lods. */1439/* We must pass these to the merge function to clamp them properly. */1440sampler->min_lod = (unsigned)MAX2(state->min_lod, 0);1441sampler->max_lod = (unsigned)MAX2(ceilf(state->max_lod), 0);14421443lod_bias = CLAMP((int)(state->lod_bias * 32 + 1), -(1 << 9), (1 << 9) - 1);14441445sampler->filter1 |= (lod_bias << R300_LOD_BIAS_SHIFT) & R300_LOD_BIAS_MASK;14461447/* This is very high quality anisotropic filtering for R5xx.1448* It's good for benchmarking the performance of texturing but1449* in practice we don't want to slow down the driver because it's1450* a pretty good performance killer. Feel free to play with it. */1451if (DBG_ON(r300, DBG_ANISOHQ) && is_r500) {1452sampler->filter1 |= r500_anisotropy(state->max_anisotropy);1453}14541455/* R500-specific fixups and optimizations */1456if (r300->screen->caps.is_r500) {1457sampler->filter1 |= R500_BORDER_FIX;1458}14591460return (void*)sampler;1461}14621463static void r300_bind_sampler_states(struct pipe_context* pipe,1464enum pipe_shader_type shader,1465unsigned start, unsigned count,1466void** states)1467{1468struct r300_context* r300 = r300_context(pipe);1469struct r300_textures_state* state =1470(struct r300_textures_state*)r300->textures_state.state;1471unsigned tex_units = r300->screen->caps.num_tex_units;14721473assert(start == 0);14741475if (shader != PIPE_SHADER_FRAGMENT)1476return;14771478if (count > tex_units)1479return;14801481memcpy(state->sampler_states, states, sizeof(void*) * count);1482state->sampler_state_count = count;14831484r300_mark_atom_dirty(r300, &r300->textures_state);1485}14861487static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)1488{1489FREE(state);1490}14911492static uint32_t r300_assign_texture_cache_region(unsigned index, unsigned num)1493{1494/* This looks like a hack, but I believe it's suppose to work like1495* that. To illustrate how this works, let's assume you have 5 textures.1496* From docs, 5 and the successive numbers are:1497*1498* FOURTH_1 = 51499* FOURTH_2 = 61500* FOURTH_3 = 71501* EIGHTH_0 = 81502* EIGHTH_1 = 91503*1504* First 3 textures will get 3/4 of size of the cache, divided evenly1505* between them. The last 1/4 of the cache must be divided between1506* the last 2 textures, each will therefore get 1/8 of the cache.1507* Why not just to use "5 + texture_index" ?1508*1509* This simple trick works for all "num" <= 16.1510*/1511if (num <= 1)1512return R300_TX_CACHE(R300_TX_CACHE_WHOLE);1513else1514return R300_TX_CACHE(num + index);1515}15161517static void r300_set_sampler_views(struct pipe_context* pipe,1518enum pipe_shader_type shader,1519unsigned start, unsigned count,1520unsigned unbind_num_trailing_slots,1521struct pipe_sampler_view** views)1522{1523struct r300_context* r300 = r300_context(pipe);1524struct r300_textures_state* state =1525(struct r300_textures_state*)r300->textures_state.state;1526struct r300_resource *texture;1527unsigned i, real_num_views = 0, view_index = 0;1528unsigned tex_units = r300->screen->caps.num_tex_units;1529boolean dirty_tex = FALSE;15301531if (shader != PIPE_SHADER_FRAGMENT)1532return;15331534assert(start == 0); /* non-zero not handled yet */15351536if (count > tex_units) {1537return;1538}15391540/* Calculate the real number of views. */1541for (i = 0; i < count; i++) {1542if (views[i])1543real_num_views++;1544}15451546for (i = 0; i < count; i++) {1547pipe_sampler_view_reference(1548(struct pipe_sampler_view**)&state->sampler_views[i],1549views[i]);15501551if (!views[i]) {1552continue;1553}15541555/* A new sampler view (= texture)... */1556dirty_tex = TRUE;15571558/* Set the texrect factor in the fragment shader.1559* Needed for RECT and NPOT fallback. */1560texture = r300_resource(views[i]->texture);1561if (texture->tex.is_npot) {1562r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state);1563}15641565state->sampler_views[i]->texcache_region =1566r300_assign_texture_cache_region(view_index, real_num_views);1567view_index++;1568}15691570for (i = count; i < tex_units; i++) {1571if (state->sampler_views[i]) {1572pipe_sampler_view_reference(1573(struct pipe_sampler_view**)&state->sampler_views[i],1574NULL);1575}1576}15771578state->sampler_view_count = count;15791580r300_mark_atom_dirty(r300, &r300->textures_state);15811582if (dirty_tex) {1583r300_mark_atom_dirty(r300, &r300->texture_cache_inval);1584}1585}15861587struct pipe_sampler_view *1588r300_create_sampler_view_custom(struct pipe_context *pipe,1589struct pipe_resource *texture,1590const struct pipe_sampler_view *templ,1591unsigned width0_override,1592unsigned height0_override)1593{1594struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);1595struct r300_resource *tex = r300_resource(texture);1596boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;1597boolean dxtc_swizzle = r300_screen(pipe->screen)->caps.dxtc_swizzle;15981599if (view) {1600unsigned hwformat;16011602view->base = *templ;1603view->base.reference.count = 1;1604view->base.context = pipe;1605view->base.texture = NULL;1606pipe_resource_reference(&view->base.texture, texture);16071608view->width0_override = width0_override;1609view->height0_override = height0_override;1610view->swizzle[0] = templ->swizzle_r;1611view->swizzle[1] = templ->swizzle_g;1612view->swizzle[2] = templ->swizzle_b;1613view->swizzle[3] = templ->swizzle_a;16141615hwformat = r300_translate_texformat(templ->format,1616view->swizzle,1617is_r500,1618dxtc_swizzle);16191620if (hwformat == ~0) {1621fprintf(stderr, "r300: Oops. Got unsupported format %s in %s.\n",1622util_format_short_name(templ->format), __func__);1623}1624assert(hwformat != ~0);16251626r300_texture_setup_format_state(r300_screen(pipe->screen), tex,1627templ->format, 0,1628width0_override, height0_override,1629&view->format);1630view->format.format1 |= hwformat;1631if (is_r500) {1632view->format.format2 |= r500_tx_format_msb_bit(templ->format);1633}1634}16351636return (struct pipe_sampler_view*)view;1637}16381639static struct pipe_sampler_view *1640r300_create_sampler_view(struct pipe_context *pipe,1641struct pipe_resource *texture,1642const struct pipe_sampler_view *templ)1643{1644return r300_create_sampler_view_custom(pipe, texture, templ,1645r300_resource(texture)->tex.width0,1646r300_resource(texture)->tex.height0);1647}164816491650static void1651r300_sampler_view_destroy(struct pipe_context *pipe,1652struct pipe_sampler_view *view)1653{1654pipe_resource_reference(&view->texture, NULL);1655FREE(view);1656}16571658static void r300_set_sample_mask(struct pipe_context *pipe,1659unsigned mask)1660{1661struct r300_context* r300 = r300_context(pipe);16621663*((unsigned*)r300->sample_mask.state) = mask;16641665r300_mark_atom_dirty(r300, &r300->sample_mask);1666}16671668static void r300_set_scissor_states(struct pipe_context* pipe,1669unsigned start_slot,1670unsigned num_scissors,1671const struct pipe_scissor_state* state)1672{1673struct r300_context* r300 = r300_context(pipe);16741675memcpy(r300->scissor_state.state, state,1676sizeof(struct pipe_scissor_state));16771678r300_mark_atom_dirty(r300, &r300->scissor_state);1679}16801681static void r300_set_viewport_states(struct pipe_context* pipe,1682unsigned start_slot,1683unsigned num_viewports,1684const struct pipe_viewport_state* state)1685{1686struct r300_context* r300 = r300_context(pipe);1687struct r300_viewport_state* viewport =1688(struct r300_viewport_state*)r300->viewport_state.state;16891690r300->viewport = *state;16911692if (r300->draw) {1693draw_set_viewport_states(r300->draw, start_slot, num_viewports, state);1694viewport->vte_control = R300_VTX_XY_FMT | R300_VTX_Z_FMT;1695return;1696}16971698/* Do the transform in HW. */1699viewport->vte_control = R300_VTX_W0_FMT;17001701if (state->scale[0] != 1.0f) {1702viewport->xscale = state->scale[0];1703viewport->vte_control |= R300_VPORT_X_SCALE_ENA;1704}1705if (state->scale[1] != 1.0f) {1706viewport->yscale = state->scale[1];1707viewport->vte_control |= R300_VPORT_Y_SCALE_ENA;1708}1709if (state->scale[2] != 1.0f) {1710viewport->zscale = state->scale[2];1711viewport->vte_control |= R300_VPORT_Z_SCALE_ENA;1712}1713if (state->translate[0] != 0.0f) {1714viewport->xoffset = state->translate[0];1715viewport->vte_control |= R300_VPORT_X_OFFSET_ENA;1716}1717if (state->translate[1] != 0.0f) {1718viewport->yoffset = state->translate[1];1719viewport->vte_control |= R300_VPORT_Y_OFFSET_ENA;1720}1721if (state->translate[2] != 0.0f) {1722viewport->zoffset = state->translate[2];1723viewport->vte_control |= R300_VPORT_Z_OFFSET_ENA;1724}17251726r300_mark_atom_dirty(r300, &r300->viewport_state);1727if (r300->fs.state && r300_fs(r300)->shader &&1728r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) {1729r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state);1730}1731}17321733static void r300_set_vertex_buffers_hwtcl(struct pipe_context* pipe,1734unsigned start_slot, unsigned count,1735unsigned unbind_num_trailing_slots,1736bool take_ownership,1737const struct pipe_vertex_buffer* buffers)1738{1739struct r300_context* r300 = r300_context(pipe);17401741util_set_vertex_buffers_count(r300->vertex_buffer,1742&r300->nr_vertex_buffers,1743buffers, start_slot, count,1744unbind_num_trailing_slots, take_ownership);17451746/* There must be at least one vertex buffer set, otherwise it locks up. */1747if (!r300->nr_vertex_buffers) {1748util_set_vertex_buffers_count(r300->vertex_buffer,1749&r300->nr_vertex_buffers,1750&r300->dummy_vb, 0, 1, 0, false);1751}17521753r300->vertex_arrays_dirty = TRUE;1754}17551756static void r300_set_vertex_buffers_swtcl(struct pipe_context* pipe,1757unsigned start_slot, unsigned count,1758unsigned unbind_num_trailing_slots,1759bool take_ownership,1760const struct pipe_vertex_buffer* buffers)1761{1762struct r300_context* r300 = r300_context(pipe);1763unsigned i;17641765util_set_vertex_buffers_count(r300->vertex_buffer,1766&r300->nr_vertex_buffers,1767buffers, start_slot, count,1768unbind_num_trailing_slots, take_ownership);1769draw_set_vertex_buffers(r300->draw, start_slot, count,1770unbind_num_trailing_slots, buffers);17711772if (!buffers)1773return;17741775for (i = 0; i < count; i++) {1776if (buffers[i].is_user_buffer) {1777draw_set_mapped_vertex_buffer(r300->draw, start_slot + i,1778buffers[i].buffer.user, ~0);1779} else if (buffers[i].buffer.resource) {1780draw_set_mapped_vertex_buffer(r300->draw, start_slot + i,1781r300_resource(buffers[i].buffer.resource)->malloced_buffer, ~0);1782}1783}1784}17851786/* Initialize the PSC tables. */1787static void r300_vertex_psc(struct r300_vertex_element_state *velems)1788{1789struct r300_vertex_stream_state *vstream = &velems->vertex_stream;1790uint16_t type, swizzle;1791enum pipe_format format;1792unsigned i;17931794/* Vertex shaders have no semantics on their inputs,1795* so PSC should just route stuff based on the vertex elements,1796* and not on attrib information. */1797for (i = 0; i < velems->count; i++) {1798format = velems->velem[i].src_format;17991800type = r300_translate_vertex_data_type(format);1801if (type == R300_INVALID_FORMAT) {1802fprintf(stderr, "r300: Bad vertex format %s.\n",1803util_format_short_name(format));1804assert(0);1805abort();1806}18071808type |= i << R300_DST_VEC_LOC_SHIFT;1809swizzle = r300_translate_vertex_data_swizzle(format);18101811if (i & 1) {1812vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;1813vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;1814} else {1815vstream->vap_prog_stream_cntl[i >> 1] |= type;1816vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;1817}1818}18191820/* Set the last vector in the PSC. */1821if (i) {1822i -= 1;1823}1824vstream->vap_prog_stream_cntl[i >> 1] |=1825(R300_LAST_VEC << (i & 1 ? 16 : 0));18261827vstream->count = (i >> 1) + 1;1828}18291830static void* r300_create_vertex_elements_state(struct pipe_context* pipe,1831unsigned count,1832const struct pipe_vertex_element* attribs)1833{1834struct r300_vertex_element_state *velems;1835unsigned i;1836struct pipe_vertex_element dummy_attrib = {0};18371838/* R300 Programmable Stream Control (PSC) doesn't support 0 vertex elements. */1839if (!count) {1840dummy_attrib.src_format = PIPE_FORMAT_R8G8B8A8_UNORM;1841attribs = &dummy_attrib;1842count = 1;1843} else if (count > 16) {1844fprintf(stderr, "r300: More than 16 vertex elements are not supported,"1845" requested %i, using 16.\n", count);1846count = 16;1847}18481849velems = CALLOC_STRUCT(r300_vertex_element_state);1850if (!velems)1851return NULL;18521853velems->count = count;1854memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);18551856if (r300_screen(pipe->screen)->caps.has_tcl) {1857/* Setup PSC.1858* The unused components will be replaced by (..., 0, 1). */1859r300_vertex_psc(velems);18601861for (i = 0; i < count; i++) {1862velems->format_size[i] =1863align(util_format_get_blocksize(velems->velem[i].src_format), 4);1864velems->vertex_size_dwords += velems->format_size[i] / 4;1865}1866}18671868return velems;1869}18701871static void r300_bind_vertex_elements_state(struct pipe_context *pipe,1872void *state)1873{1874struct r300_context *r300 = r300_context(pipe);1875struct r300_vertex_element_state *velems = state;18761877if (!velems) {1878return;1879}18801881r300->velems = velems;18821883if (r300->draw) {1884draw_set_vertex_elements(r300->draw, velems->count, velems->velem);1885return;1886}18871888UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);1889r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2;1890r300->vertex_arrays_dirty = TRUE;1891}18921893static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)1894{1895FREE(state);1896}18971898static void* r300_create_vs_state(struct pipe_context* pipe,1899const struct pipe_shader_state* shader)1900{1901struct r300_context* r300 = r300_context(pipe);1902struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);19031904/* Copy state directly into shader. */1905vs->state = *shader;1906vs->state.tokens = tgsi_dup_tokens(shader->tokens);19071908if (r300->screen->caps.has_tcl) {1909r300_init_vs_outputs(r300, vs);1910r300_translate_vertex_shader(r300, vs);1911} else {1912r300_draw_init_vertex_shader(r300, vs);1913}19141915return vs;1916}19171918static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)1919{1920struct r300_context* r300 = r300_context(pipe);1921struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;19221923if (!vs) {1924r300->vs_state.state = NULL;1925return;1926}1927if (vs == r300->vs_state.state) {1928return;1929}1930r300->vs_state.state = vs;19311932/* The majority of the RS block bits is dependent on the vertex shader. */1933r300_mark_atom_dirty(r300, &r300->rs_block_state); /* Will be updated before the emission. */19341935if (r300->screen->caps.has_tcl) {1936unsigned fc_op_dwords = r300->screen->caps.is_r500 ? 3 : 2;1937r300_mark_atom_dirty(r300, &r300->vs_state);1938r300->vs_state.size = vs->code.length + 9 +1939(R300_VS_MAX_FC_OPS * fc_op_dwords + 4);19401941r300_mark_atom_dirty(r300, &r300->vs_constants);1942r300->vs_constants.size =19432 +1944(vs->externals_count ? vs->externals_count * 4 + 3 : 0) +1945(vs->immediates_count ? vs->immediates_count * 4 + 3 : 0);19461947((struct r300_constant_buffer*)r300->vs_constants.state)->remap_table =1948vs->code.constants_remap_table;19491950r300_mark_atom_dirty(r300, &r300->pvs_flush);1951} else {1952draw_bind_vertex_shader(r300->draw,1953(struct draw_vertex_shader*)vs->draw_vs);1954}1955}19561957static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)1958{1959struct r300_context* r300 = r300_context(pipe);1960struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;19611962if (r300->screen->caps.has_tcl) {1963rc_constants_destroy(&vs->code.constants);1964FREE(vs->code.constants_remap_table);1965} else {1966draw_delete_vertex_shader(r300->draw,1967(struct draw_vertex_shader*)vs->draw_vs);1968}19691970FREE((void*)vs->state.tokens);1971FREE(shader);1972}19731974static void r300_set_constant_buffer(struct pipe_context *pipe,1975enum pipe_shader_type shader, uint index,1976bool take_ownership,1977const struct pipe_constant_buffer *cb)1978{1979struct r300_context* r300 = r300_context(pipe);1980struct r300_constant_buffer *cbuf;1981uint32_t *mapped;19821983if (!cb || (!cb->buffer && !cb->user_buffer))1984return;19851986switch (shader) {1987case PIPE_SHADER_VERTEX:1988cbuf = (struct r300_constant_buffer*)r300->vs_constants.state;1989break;1990case PIPE_SHADER_FRAGMENT:1991cbuf = (struct r300_constant_buffer*)r300->fs_constants.state;1992break;1993default:1994return;1995}199619971998if (cb->user_buffer)1999mapped = (uint32_t*)cb->user_buffer;2000else {2001struct r300_resource *rbuf = r300_resource(cb->buffer);20022003if (rbuf && rbuf->malloced_buffer)2004mapped = (uint32_t*)rbuf->malloced_buffer;2005else2006return;2007}20082009if (shader == PIPE_SHADER_FRAGMENT ||2010(shader == PIPE_SHADER_VERTEX && r300->screen->caps.has_tcl)) {2011cbuf->ptr = mapped;2012}20132014if (shader == PIPE_SHADER_VERTEX) {2015if (r300->screen->caps.has_tcl) {2016struct r300_vertex_shader *vs =2017(struct r300_vertex_shader*)r300->vs_state.state;20182019if (!vs) {2020cbuf->buffer_base = 0;2021return;2022}20232024cbuf->buffer_base = r300->vs_const_base;2025r300->vs_const_base += vs->code.constants.Count;2026if (r300->vs_const_base > R500_MAX_PVS_CONST_VECS) {2027r300->vs_const_base = vs->code.constants.Count;2028cbuf->buffer_base = 0;2029r300_mark_atom_dirty(r300, &r300->pvs_flush);2030}2031r300_mark_atom_dirty(r300, &r300->vs_constants);2032} else if (r300->draw) {2033draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,20340, mapped, cb->buffer_size);2035}2036} else if (shader == PIPE_SHADER_FRAGMENT) {2037r300_mark_atom_dirty(r300, &r300->fs_constants);2038}2039}20402041static void r300_texture_barrier(struct pipe_context *pipe, unsigned flags)2042{2043struct r300_context *r300 = r300_context(pipe);20442045r300_mark_atom_dirty(r300, &r300->gpu_flush);2046r300_mark_atom_dirty(r300, &r300->texture_cache_inval);2047}20482049static void r300_memory_barrier(struct pipe_context *pipe, unsigned flags)2050{2051}20522053void r300_init_state_functions(struct r300_context* r300)2054{2055r300->context.create_blend_state = r300_create_blend_state;2056r300->context.bind_blend_state = r300_bind_blend_state;2057r300->context.delete_blend_state = r300_delete_blend_state;20582059r300->context.set_blend_color = r300_set_blend_color;20602061r300->context.set_clip_state = r300_set_clip_state;2062r300->context.set_sample_mask = r300_set_sample_mask;20632064r300->context.set_constant_buffer = r300_set_constant_buffer;20652066r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state;2067r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;2068r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;20692070r300->context.set_stencil_ref = r300_set_stencil_ref;20712072r300->context.set_framebuffer_state = r300_set_framebuffer_state;20732074r300->context.create_fs_state = r300_create_fs_state;2075r300->context.bind_fs_state = r300_bind_fs_state;2076r300->context.delete_fs_state = r300_delete_fs_state;20772078r300->context.set_polygon_stipple = r300_set_polygon_stipple;20792080r300->context.create_rasterizer_state = r300_create_rs_state;2081r300->context.bind_rasterizer_state = r300_bind_rs_state;2082r300->context.delete_rasterizer_state = r300_delete_rs_state;20832084r300->context.create_sampler_state = r300_create_sampler_state;2085r300->context.bind_sampler_states = r300_bind_sampler_states;2086r300->context.delete_sampler_state = r300_delete_sampler_state;20872088r300->context.set_sampler_views = r300_set_sampler_views;2089r300->context.create_sampler_view = r300_create_sampler_view;2090r300->context.sampler_view_destroy = r300_sampler_view_destroy;20912092r300->context.set_scissor_states = r300_set_scissor_states;20932094r300->context.set_viewport_states = r300_set_viewport_states;20952096if (r300->screen->caps.has_tcl) {2097r300->context.set_vertex_buffers = r300_set_vertex_buffers_hwtcl;2098} else {2099r300->context.set_vertex_buffers = r300_set_vertex_buffers_swtcl;2100}21012102r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;2103r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;2104r300->context.delete_vertex_elements_state = r300_delete_vertex_elements_state;21052106r300->context.create_vs_state = r300_create_vs_state;2107r300->context.bind_vs_state = r300_bind_vs_state;2108r300->context.delete_vs_state = r300_delete_vs_state;21092110r300->context.texture_barrier = r300_texture_barrier;2111r300->context.memory_barrier = r300_memory_barrier;2112}211321142115