14a49301eSmrg/************************************************************************** 27ec681f3Smrg * 3af69d88dSmrg * Copyright 2007 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 54a49301eSmrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 137ec681f3Smrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 177ec681f3Smrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 257ec681f3Smrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 28af69d88dSmrg/* Authors: Keith Whitwell <keithw@vmware.com> 294a49301eSmrg */ 304a49301eSmrg 317ec681f3Smrg#include "compiler/nir/nir_builder.h" 324a49301eSmrg#include "draw/draw_context.h" 337ec681f3Smrg#include "nir/nir_to_tgsi.h" 347ec681f3Smrg#include "tgsi/tgsi_parse.h" 35af69d88dSmrg#include "util/u_helpers.h" 36cdc920a0Smrg#include "util/u_inlines.h" 374a49301eSmrg#include "util/u_math.h" 384a49301eSmrg#include "util/u_memory.h" 393464ebd5Sriastradh#include "util/u_transfer.h" 407ec681f3Smrg#include "nir.h" 414a49301eSmrg 424a49301eSmrg#include "i915_context.h" 434a49301eSmrg#include "i915_fpc.h" 447ec681f3Smrg#include "i915_reg.h" 453464ebd5Sriastradh#include "i915_resource.h" 46af69d88dSmrg#include "i915_state.h" 477ec681f3Smrg#include "i915_state_inlines.h" 484a49301eSmrg 494a49301eSmrg/* The i915 (and related graphics cores) do not support GL_CLAMP. The 504a49301eSmrg * Intel drivers for "other operating systems" implement GL_CLAMP as 514a49301eSmrg * GL_CLAMP_TO_EDGE, so the same is done here. 524a49301eSmrg */ 534a49301eSmrgstatic unsigned 544a49301eSmrgtranslate_wrap_mode(unsigned wrap) 554a49301eSmrg{ 564a49301eSmrg switch (wrap) { 574a49301eSmrg case PIPE_TEX_WRAP_REPEAT: 584a49301eSmrg return TEXCOORDMODE_WRAP; 594a49301eSmrg case PIPE_TEX_WRAP_CLAMP: 607ec681f3Smrg return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ 614a49301eSmrg case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 624a49301eSmrg return TEXCOORDMODE_CLAMP_EDGE; 634a49301eSmrg case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 644a49301eSmrg return TEXCOORDMODE_CLAMP_BORDER; 653464ebd5Sriastradh case PIPE_TEX_WRAP_MIRROR_REPEAT: 664a49301eSmrg return TEXCOORDMODE_MIRROR; 674a49301eSmrg default: 684a49301eSmrg return TEXCOORDMODE_WRAP; 694a49301eSmrg } 704a49301eSmrg} 714a49301eSmrg 727ec681f3Smrgstatic unsigned 737ec681f3Smrgtranslate_img_filter(unsigned filter) 744a49301eSmrg{ 754a49301eSmrg switch (filter) { 764a49301eSmrg case PIPE_TEX_FILTER_NEAREST: 774a49301eSmrg return FILTER_NEAREST; 784a49301eSmrg case PIPE_TEX_FILTER_LINEAR: 794a49301eSmrg return FILTER_LINEAR; 804a49301eSmrg default: 814a49301eSmrg assert(0); 824a49301eSmrg return FILTER_NEAREST; 834a49301eSmrg } 844a49301eSmrg} 854a49301eSmrg 867ec681f3Smrgstatic unsigned 877ec681f3Smrgtranslate_mip_filter(unsigned filter) 884a49301eSmrg{ 894a49301eSmrg switch (filter) { 904a49301eSmrg case PIPE_TEX_MIPFILTER_NONE: 914a49301eSmrg return MIPFILTER_NONE; 924a49301eSmrg case PIPE_TEX_MIPFILTER_NEAREST: 934a49301eSmrg return MIPFILTER_NEAREST; 944a49301eSmrg case PIPE_TEX_MIPFILTER_LINEAR: 954a49301eSmrg return MIPFILTER_LINEAR; 964a49301eSmrg default: 974a49301eSmrg assert(0); 984a49301eSmrg return MIPFILTER_NONE; 994a49301eSmrg } 1004a49301eSmrg} 1014a49301eSmrg 1027ec681f3Smrgstatic uint32_t 1037ec681f3Smrgi915_remap_lis6_blend_dst_alpha(uint32_t lis6, uint32_t normal, uint32_t inv) 1047ec681f3Smrg{ 1057ec681f3Smrg uint32_t src = (lis6 >> S6_CBUF_SRC_BLEND_FACT_SHIFT) & BLENDFACT_MASK; 1067ec681f3Smrg lis6 &= ~SRC_BLND_FACT(BLENDFACT_MASK); 1077ec681f3Smrg if (src == BLENDFACT_DST_ALPHA) 1087ec681f3Smrg src = normal; 1097ec681f3Smrg else if (src == BLENDFACT_INV_DST_ALPHA) 1107ec681f3Smrg src = inv; 1117ec681f3Smrg lis6 |= SRC_BLND_FACT(src); 1127ec681f3Smrg 1137ec681f3Smrg uint32_t dst = (lis6 >> S6_CBUF_DST_BLEND_FACT_SHIFT) & BLENDFACT_MASK; 1147ec681f3Smrg lis6 &= ~DST_BLND_FACT(BLENDFACT_MASK); 1157ec681f3Smrg if (dst == BLENDFACT_DST_ALPHA) 1167ec681f3Smrg dst = normal; 1177ec681f3Smrg else if (dst == BLENDFACT_INV_DST_ALPHA) 1187ec681f3Smrg dst = inv; 1197ec681f3Smrg lis6 |= DST_BLND_FACT(dst); 1207ec681f3Smrg 1217ec681f3Smrg return lis6; 1227ec681f3Smrg} 1237ec681f3Smrg 1247ec681f3Smrgstatic uint32_t 1257ec681f3Smrgi915_remap_iab_blend_dst_alpha(uint32_t iab, uint32_t normal, uint32_t inv) 1267ec681f3Smrg{ 1277ec681f3Smrg uint32_t src = (iab >> IAB_SRC_FACTOR_SHIFT) & BLENDFACT_MASK; 1287ec681f3Smrg iab &= ~SRC_BLND_FACT(BLENDFACT_MASK); 1297ec681f3Smrg if (src == BLENDFACT_DST_ALPHA) 1307ec681f3Smrg src = normal; 1317ec681f3Smrg else if (src == BLENDFACT_INV_DST_ALPHA) 1327ec681f3Smrg src = inv; 1337ec681f3Smrg iab |= SRC_ABLND_FACT(src); 1347ec681f3Smrg 1357ec681f3Smrg uint32_t dst = (iab >> IAB_DST_FACTOR_SHIFT) & BLENDFACT_MASK; 1367ec681f3Smrg iab &= ~DST_BLND_FACT(BLENDFACT_MASK); 1377ec681f3Smrg if (dst == BLENDFACT_DST_ALPHA) 1387ec681f3Smrg dst = normal; 1397ec681f3Smrg else if (dst == BLENDFACT_INV_DST_ALPHA) 1407ec681f3Smrg dst = inv; 1417ec681f3Smrg iab |= DST_ABLND_FACT(dst); 1427ec681f3Smrg 1437ec681f3Smrg return iab; 1447ec681f3Smrg} 1457ec681f3Smrg 1464a49301eSmrg/* None of this state is actually used for anything yet. 1474a49301eSmrg */ 1484a49301eSmrgstatic void * 1494a49301eSmrgi915_create_blend_state(struct pipe_context *pipe, 1504a49301eSmrg const struct pipe_blend_state *blend) 1514a49301eSmrg{ 1527ec681f3Smrg struct i915_blend_state *cso_data = CALLOC_STRUCT(i915_blend_state); 1534a49301eSmrg 1544a49301eSmrg { 1557ec681f3Smrg unsigned eqRGB = blend->rt[0].rgb_func; 156cdc920a0Smrg unsigned srcRGB = blend->rt[0].rgb_src_factor; 157cdc920a0Smrg unsigned dstRGB = blend->rt[0].rgb_dst_factor; 1584a49301eSmrg 1597ec681f3Smrg unsigned eqA = blend->rt[0].alpha_func; 1607ec681f3Smrg unsigned srcA = blend->rt[0].alpha_src_factor; 1617ec681f3Smrg unsigned dstA = blend->rt[0].alpha_dst_factor; 1624a49301eSmrg 1634a49301eSmrg /* Special handling for MIN/MAX filter modes handled at 1647ec681f3Smrg * frontend level. 1654a49301eSmrg */ 1664a49301eSmrg 1677ec681f3Smrg if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { 1684a49301eSmrg 169af69d88dSmrg cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | 1707ec681f3Smrg IAB_MODIFY_ENABLE | IAB_ENABLE | IAB_MODIFY_FUNC | 1717ec681f3Smrg IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR | 1724a49301eSmrg SRC_ABLND_FACT(i915_translate_blend_factor(srcA)) | 1734a49301eSmrg DST_ABLND_FACT(i915_translate_blend_factor(dstA)) | 1744a49301eSmrg (i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT)); 1757ec681f3Smrg } else { 1767ec681f3Smrg cso_data->iab = 1777ec681f3Smrg (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | 0); 1784a49301eSmrg } 1794a49301eSmrg } 1804a49301eSmrg 1817ec681f3Smrg cso_data->modes4 |= 1827ec681f3Smrg (_3DSTATE_MODES_4_CMD | ENABLE_LOGIC_OP_FUNC | 1837ec681f3Smrg LOGIC_OP_FUNC(i915_translate_logic_op(blend->logicop_func))); 1844a49301eSmrg 1854a49301eSmrg if (blend->logicop_enable) 1864a49301eSmrg cso_data->LIS5 |= S5_LOGICOP_ENABLE; 1874a49301eSmrg 1884a49301eSmrg if (blend->dither) 1894a49301eSmrg cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; 1904a49301eSmrg 191af69d88dSmrg /* We potentially do some fixup at emission for non-BGRA targets */ 192cdc920a0Smrg if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) 1934a49301eSmrg cso_data->LIS5 |= S5_WRITEDISABLE_RED; 1944a49301eSmrg 195cdc920a0Smrg if ((blend->rt[0].colormask & PIPE_MASK_G) == 0) 1964a49301eSmrg cso_data->LIS5 |= S5_WRITEDISABLE_GREEN; 1974a49301eSmrg 198cdc920a0Smrg if ((blend->rt[0].colormask & PIPE_MASK_B) == 0) 1994a49301eSmrg cso_data->LIS5 |= S5_WRITEDISABLE_BLUE; 2004a49301eSmrg 201cdc920a0Smrg if ((blend->rt[0].colormask & PIPE_MASK_A) == 0) 2024a49301eSmrg cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA; 2034a49301eSmrg 204cdc920a0Smrg if (blend->rt[0].blend_enable) { 205cdc920a0Smrg unsigned funcRGB = blend->rt[0].rgb_func; 2067ec681f3Smrg unsigned srcRGB = blend->rt[0].rgb_src_factor; 2077ec681f3Smrg unsigned dstRGB = blend->rt[0].rgb_dst_factor; 2084a49301eSmrg 2097ec681f3Smrg cso_data->LIS6 |= 2107ec681f3Smrg (S6_CBUF_BLEND_ENABLE | 2117ec681f3Smrg SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) | 2127ec681f3Smrg DST_BLND_FACT(i915_translate_blend_factor(dstRGB)) | 2137ec681f3Smrg (i915_translate_blend_func(funcRGB) << S6_CBUF_BLEND_FUNC_SHIFT)); 2144a49301eSmrg } 2154a49301eSmrg 2167ec681f3Smrg cso_data->LIS6_alpha_in_g = i915_remap_lis6_blend_dst_alpha( 2177ec681f3Smrg cso_data->LIS6, BLENDFACT_DST_COLR, BLENDFACT_INV_DST_COLR); 2187ec681f3Smrg cso_data->LIS6_alpha_is_x = i915_remap_lis6_blend_dst_alpha( 2197ec681f3Smrg cso_data->LIS6, BLENDFACT_ONE, BLENDFACT_ZERO); 2207ec681f3Smrg 2217ec681f3Smrg cso_data->iab_alpha_in_g = i915_remap_iab_blend_dst_alpha( 2227ec681f3Smrg cso_data->iab, BLENDFACT_DST_COLR, BLENDFACT_INV_DST_COLR); 2237ec681f3Smrg cso_data->iab_alpha_is_x = i915_remap_iab_blend_dst_alpha( 2247ec681f3Smrg cso_data->iab, BLENDFACT_ONE, BLENDFACT_ZERO); 2257ec681f3Smrg 2264a49301eSmrg return cso_data; 2274a49301eSmrg} 2284a49301eSmrg 2297ec681f3Smrgstatic void 2307ec681f3Smrgi915_bind_blend_state(struct pipe_context *pipe, void *blend) 2314a49301eSmrg{ 2324a49301eSmrg struct i915_context *i915 = i915_context(pipe); 233af69d88dSmrg 234af69d88dSmrg if (i915->blend == blend) 235af69d88dSmrg return; 2364a49301eSmrg 2377ec681f3Smrg i915->blend = (struct i915_blend_state *)blend; 2384a49301eSmrg 2394a49301eSmrg i915->dirty |= I915_NEW_BLEND; 2404a49301eSmrg} 2414a49301eSmrg 2427ec681f3Smrgstatic void 2437ec681f3Smrgi915_delete_blend_state(struct pipe_context *pipe, void *blend) 2444a49301eSmrg{ 2454a49301eSmrg FREE(blend); 2464a49301eSmrg} 2474a49301eSmrg 2487ec681f3Smrgstatic void 2497ec681f3Smrgi915_set_blend_color(struct pipe_context *pipe, 2507ec681f3Smrg const struct pipe_blend_color *blend_color) 2514a49301eSmrg{ 2524a49301eSmrg struct i915_context *i915 = i915_context(pipe); 253af69d88dSmrg 254af69d88dSmrg if (!blend_color) 255af69d88dSmrg return; 2564a49301eSmrg 2574a49301eSmrg i915->blend_color = *blend_color; 2584a49301eSmrg 2594a49301eSmrg i915->dirty |= I915_NEW_BLEND; 2604a49301eSmrg} 2614a49301eSmrg 2627ec681f3Smrgstatic void 2637ec681f3Smrgi915_set_stencil_ref(struct pipe_context *pipe, 2647ec681f3Smrg const struct pipe_stencil_ref stencil_ref) 265cdc920a0Smrg{ 266cdc920a0Smrg struct i915_context *i915 = i915_context(pipe); 267cdc920a0Smrg 2687ec681f3Smrg i915->stencil_ref = stencil_ref; 269cdc920a0Smrg 270cdc920a0Smrg i915->dirty |= I915_NEW_DEPTH_STENCIL; 271cdc920a0Smrg} 272cdc920a0Smrg 2734a49301eSmrgstatic void * 2744a49301eSmrgi915_create_sampler_state(struct pipe_context *pipe, 2754a49301eSmrg const struct pipe_sampler_state *sampler) 2764a49301eSmrg{ 2777ec681f3Smrg struct i915_sampler_state *cso = CALLOC_STRUCT(i915_sampler_state); 2784a49301eSmrg const unsigned ws = sampler->wrap_s; 2794a49301eSmrg const unsigned wt = sampler->wrap_t; 2804a49301eSmrg const unsigned wr = sampler->wrap_r; 2814a49301eSmrg unsigned minFilt, magFilt; 2824a49301eSmrg unsigned mipFilt; 2834a49301eSmrg 284af69d88dSmrg cso->templ = *sampler; 2854a49301eSmrg 2864a49301eSmrg mipFilt = translate_mip_filter(sampler->min_mip_filter); 2877ec681f3Smrg minFilt = translate_img_filter(sampler->min_img_filter); 2887ec681f3Smrg magFilt = translate_img_filter(sampler->mag_img_filter); 289af69d88dSmrg 290cdc920a0Smrg if (sampler->max_anisotropy > 1) 291cdc920a0Smrg minFilt = magFilt = FILTER_ANISOTROPIC; 292cdc920a0Smrg 293cdc920a0Smrg if (sampler->max_anisotropy > 2) { 2944a49301eSmrg cso->state[0] |= SS2_MAX_ANISO_4; 2954a49301eSmrg } 2964a49301eSmrg 2974a49301eSmrg { 2987ec681f3Smrg int b = (int)(sampler->lod_bias * 16.0); 2994a49301eSmrg b = CLAMP(b, -256, 255); 3004a49301eSmrg cso->state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); 3014a49301eSmrg } 3024a49301eSmrg 3034a49301eSmrg /* Shadow: 3044a49301eSmrg */ 3057ec681f3Smrg if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 3067ec681f3Smrg cso->state[0] |= (SS2_SHADOW_ENABLE | i915_translate_shadow_compare_func( 3077ec681f3Smrg sampler->compare_func)); 3084a49301eSmrg 3094a49301eSmrg minFilt = FILTER_4X4_FLAT; 3104a49301eSmrg magFilt = FILTER_4X4_FLAT; 3114a49301eSmrg } 3124a49301eSmrg 3137ec681f3Smrg cso->state[0] |= 3147ec681f3Smrg ((minFilt << SS2_MIN_FILTER_SHIFT) | (mipFilt << SS2_MIP_FILTER_SHIFT) | 3157ec681f3Smrg (magFilt << SS2_MAG_FILTER_SHIFT)); 3164a49301eSmrg 3177ec681f3Smrg cso->state[1] |= ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | 3187ec681f3Smrg (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | 3197ec681f3Smrg (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); 3204a49301eSmrg 3214a49301eSmrg if (sampler->normalized_coords) 3224a49301eSmrg cso->state[1] |= SS3_NORMALIZED_COORDS; 3234a49301eSmrg 3244a49301eSmrg { 3257ec681f3Smrg int minlod = (int)(16.0 * sampler->min_lod); 3267ec681f3Smrg int maxlod = (int)(16.0 * sampler->max_lod); 3274a49301eSmrg minlod = CLAMP(minlod, 0, 16 * 11); 3284a49301eSmrg maxlod = CLAMP(maxlod, 0, 16 * 11); 3294a49301eSmrg 3304a49301eSmrg if (minlod > maxlod) 331af69d88dSmrg maxlod = minlod; 3324a49301eSmrg 3334a49301eSmrg cso->minlod = minlod; 3344a49301eSmrg cso->maxlod = maxlod; 3354a49301eSmrg } 3364a49301eSmrg 3374a49301eSmrg { 338af69d88dSmrg ubyte r = float_to_ubyte(sampler->border_color.f[0]); 339af69d88dSmrg ubyte g = float_to_ubyte(sampler->border_color.f[1]); 340af69d88dSmrg ubyte b = float_to_ubyte(sampler->border_color.f[2]); 341af69d88dSmrg ubyte a = float_to_ubyte(sampler->border_color.f[3]); 3424a49301eSmrg cso->state[2] = I915PACKCOLOR8888(r, g, b, a); 3434a49301eSmrg } 3444a49301eSmrg return cso; 3454a49301eSmrg} 3464a49301eSmrg 347af69d88dSmrgstatic void 3487ec681f3Smrgi915_bind_sampler_states(struct pipe_context *pipe, 3497ec681f3Smrg enum pipe_shader_type shader, unsigned start, 3507ec681f3Smrg unsigned num, void **samplers) 3513464ebd5Sriastradh{ 3527ec681f3Smrg if (shader != PIPE_SHADER_FRAGMENT) { 3537ec681f3Smrg assert(num == 0); 354af69d88dSmrg return; 355af69d88dSmrg } 356af69d88dSmrg 3574a49301eSmrg struct i915_context *i915 = i915_context(pipe); 3584a49301eSmrg unsigned i; 3594a49301eSmrg 3604a49301eSmrg /* Check for no-op */ 3614a49301eSmrg if (num == i915->num_samplers && 3627ec681f3Smrg !memcmp(i915->fragment_sampler + start, samplers, num * sizeof(void *))) 3634a49301eSmrg return; 3644a49301eSmrg 3654a49301eSmrg for (i = 0; i < num; ++i) 366af69d88dSmrg i915->fragment_sampler[i + start] = samplers[i]; 3674a49301eSmrg 368af69d88dSmrg /* find highest non-null samplers[] entry */ 369af69d88dSmrg { 370af69d88dSmrg unsigned j = MAX2(i915->num_samplers, start + num); 371af69d88dSmrg while (j > 0 && i915->fragment_sampler[j - 1] == NULL) 372af69d88dSmrg j--; 373af69d88dSmrg i915->num_samplers = j; 374af69d88dSmrg } 3754a49301eSmrg 3764a49301eSmrg i915->dirty |= I915_NEW_SAMPLER; 3774a49301eSmrg} 3784a49301eSmrg 379af69d88dSmrgstatic void 3807ec681f3Smrgi915_delete_sampler_state(struct pipe_context *pipe, void *sampler) 3814a49301eSmrg{ 3824a49301eSmrg FREE(sampler); 3834a49301eSmrg} 3844a49301eSmrg 3857ec681f3Smrg/** XXX move someday? Or consolidate all these simple state setters 3867ec681f3Smrg * into one file. 387af69d88dSmrg */ 388af69d88dSmrg 3897ec681f3Smrgstatic uint32_t 3907ec681f3Smrgi915_get_modes4_stencil(const struct pipe_stencil_state *stencil) 3917ec681f3Smrg{ 3927ec681f3Smrg int testmask = stencil->valuemask & 0xff; 3937ec681f3Smrg int writemask = stencil->writemask & 0xff; 394af69d88dSmrg 3957ec681f3Smrg return (_3DSTATE_MODES_4_CMD | ENABLE_STENCIL_TEST_MASK | 3967ec681f3Smrg STENCIL_TEST_MASK(testmask) | ENABLE_STENCIL_WRITE_MASK | 3977ec681f3Smrg STENCIL_WRITE_MASK(writemask)); 398af69d88dSmrg} 399af69d88dSmrg 4007ec681f3Smrgstatic uint32_t 4017ec681f3Smrgi915_get_lis5_stencil(const struct pipe_stencil_state *stencil) 402af69d88dSmrg{ 4037ec681f3Smrg int test = i915_translate_compare_func(stencil->func); 4047ec681f3Smrg int fop = i915_translate_stencil_op(stencil->fail_op); 4057ec681f3Smrg int dfop = i915_translate_stencil_op(stencil->zfail_op); 4067ec681f3Smrg int dpop = i915_translate_stencil_op(stencil->zpass_op); 4077ec681f3Smrg 4087ec681f3Smrg return (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE | 4097ec681f3Smrg (test << S5_STENCIL_TEST_FUNC_SHIFT) | 4107ec681f3Smrg (fop << S5_STENCIL_FAIL_SHIFT) | 4117ec681f3Smrg (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | 4127ec681f3Smrg (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT)); 413af69d88dSmrg} 414af69d88dSmrg 4157ec681f3Smrgstatic uint32_t 4167ec681f3Smrgi915_get_bfo(const struct pipe_stencil_state *stencil) 4177ec681f3Smrg{ 4187ec681f3Smrg int test = i915_translate_compare_func(stencil->func); 4197ec681f3Smrg int fop = i915_translate_stencil_op(stencil->fail_op); 4207ec681f3Smrg int dfop = i915_translate_stencil_op(stencil->zfail_op); 4217ec681f3Smrg int dpop = i915_translate_stencil_op(stencil->zpass_op); 4227ec681f3Smrg 4237ec681f3Smrg return (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_FUNCS | 4247ec681f3Smrg BFO_ENABLE_STENCIL_TWO_SIDE | BFO_ENABLE_STENCIL_REF | 4257ec681f3Smrg BFO_STENCIL_TWO_SIDE | (test << BFO_STENCIL_TEST_SHIFT) | 4267ec681f3Smrg (fop << BFO_STENCIL_FAIL_SHIFT) | 4277ec681f3Smrg (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) | 4287ec681f3Smrg (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT)); 4297ec681f3Smrg} 430af69d88dSmrg 4317ec681f3Smrgstatic uint32_t 4327ec681f3Smrgi915_get_bfm(const struct pipe_stencil_state *stencil) 4337ec681f3Smrg{ 4347ec681f3Smrg return (_3DSTATE_BACKFACE_STENCIL_MASKS | BFM_ENABLE_STENCIL_TEST_MASK | 4357ec681f3Smrg BFM_ENABLE_STENCIL_WRITE_MASK | 4367ec681f3Smrg ((stencil->valuemask & 0xff) << BFM_STENCIL_TEST_MASK_SHIFT) | 4377ec681f3Smrg ((stencil->writemask & 0xff) << BFM_STENCIL_WRITE_MASK_SHIFT)); 4387ec681f3Smrg} 4394a49301eSmrg 4404a49301eSmrgstatic void * 4417ec681f3Smrgi915_create_depth_stencil_state( 4427ec681f3Smrg struct pipe_context *pipe, 4437ec681f3Smrg const struct pipe_depth_stencil_alpha_state *depth_stencil) 4444a49301eSmrg{ 4457ec681f3Smrg struct i915_depth_stencil_state *cso = 4467ec681f3Smrg CALLOC_STRUCT(i915_depth_stencil_state); 4474a49301eSmrg 4487ec681f3Smrg cso->stencil_modes4_cw = i915_get_modes4_stencil(&depth_stencil->stencil[0]); 4497ec681f3Smrg cso->stencil_modes4_ccw = 4507ec681f3Smrg i915_get_modes4_stencil(&depth_stencil->stencil[1]); 4514a49301eSmrg 4524a49301eSmrg if (depth_stencil->stencil[0].enabled) { 4537ec681f3Smrg cso->stencil_LIS5_cw = i915_get_lis5_stencil(&depth_stencil->stencil[0]); 4544a49301eSmrg } 4554a49301eSmrg 4564a49301eSmrg if (depth_stencil->stencil[1].enabled) { 4577ec681f3Smrg cso->bfo_cw[0] = i915_get_bfo(&depth_stencil->stencil[1]); 4587ec681f3Smrg cso->bfo_cw[1] = i915_get_bfm(&depth_stencil->stencil[1]); 4597ec681f3Smrg 4607ec681f3Smrg /* Precompute the backface stencil settings if front winding order is 4617ec681f3Smrg * reversed -- HW doesn't have a bit to flip it for us. 4627ec681f3Smrg */ 4637ec681f3Smrg cso->stencil_LIS5_ccw = i915_get_lis5_stencil(&depth_stencil->stencil[1]); 4647ec681f3Smrg cso->bfo_ccw[0] = i915_get_bfo(&depth_stencil->stencil[0]); 4657ec681f3Smrg cso->bfo_ccw[1] = i915_get_bfm(&depth_stencil->stencil[0]); 4667ec681f3Smrg } else { 4674a49301eSmrg /* This actually disables two-side stencil: The bit set is a 4684a49301eSmrg * modify-enable bit to indicate we are changing the two-side 4694a49301eSmrg * setting. Then there is a symbolic zero to show that we are 4704a49301eSmrg * setting the flag to zero/off. 4714a49301eSmrg */ 4727ec681f3Smrg cso->bfo_cw[0] = cso->bfo_ccw[0] = 4737ec681f3Smrg (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); 4747ec681f3Smrg cso->bfo_cw[1] = cso->bfo_ccw[1] = 0; 4757ec681f3Smrg 4767ec681f3Smrg cso->stencil_LIS5_ccw = cso->stencil_LIS5_cw; 4774a49301eSmrg } 4784a49301eSmrg 4797ec681f3Smrg if (depth_stencil->depth_enabled) { 4807ec681f3Smrg int func = i915_translate_compare_func(depth_stencil->depth_func); 4814a49301eSmrg 4827ec681f3Smrg cso->depth_LIS6 |= 4837ec681f3Smrg (S6_DEPTH_TEST_ENABLE | (func << S6_DEPTH_TEST_FUNC_SHIFT)); 4844a49301eSmrg 4857ec681f3Smrg if (depth_stencil->depth_writemask) 486af69d88dSmrg cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE; 4874a49301eSmrg } 4884a49301eSmrg 4897ec681f3Smrg if (depth_stencil->alpha_enabled) { 4907ec681f3Smrg int test = i915_translate_compare_func(depth_stencil->alpha_func); 4917ec681f3Smrg ubyte refByte = float_to_ubyte(depth_stencil->alpha_ref_value); 4924a49301eSmrg 4937ec681f3Smrg cso->depth_LIS6 |= 4947ec681f3Smrg (S6_ALPHA_TEST_ENABLE | (test << S6_ALPHA_TEST_FUNC_SHIFT) | 4957ec681f3Smrg (((unsigned)refByte) << S6_ALPHA_REF_SHIFT)); 4964a49301eSmrg } 4974a49301eSmrg 4984a49301eSmrg return cso; 4994a49301eSmrg} 5004a49301eSmrg 5017ec681f3Smrgstatic void 5027ec681f3Smrgi915_bind_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil) 5034a49301eSmrg{ 5044a49301eSmrg struct i915_context *i915 = i915_context(pipe); 505af69d88dSmrg 506af69d88dSmrg if (i915->depth_stencil == depth_stencil) 507af69d88dSmrg return; 5084a49301eSmrg 5094a49301eSmrg i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil; 5104a49301eSmrg 5114a49301eSmrg i915->dirty |= I915_NEW_DEPTH_STENCIL; 5124a49301eSmrg} 5134a49301eSmrg 5147ec681f3Smrgstatic void 5157ec681f3Smrgi915_delete_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil) 5164a49301eSmrg{ 5174a49301eSmrg FREE(depth_stencil); 5184a49301eSmrg} 5194a49301eSmrg 5207ec681f3Smrgstatic void 5217ec681f3Smrgi915_set_scissor_states(struct pipe_context *pipe, unsigned start_slot, 5227ec681f3Smrg unsigned num_scissors, 5237ec681f3Smrg const struct pipe_scissor_state *scissor) 5244a49301eSmrg{ 5254a49301eSmrg struct i915_context *i915 = i915_context(pipe); 5264a49301eSmrg 5277ec681f3Smrg memcpy(&i915->scissor, scissor, sizeof(*scissor)); 5284a49301eSmrg i915->dirty |= I915_NEW_SCISSOR; 5294a49301eSmrg} 5304a49301eSmrg 5317ec681f3Smrgstatic void 5327ec681f3Smrgi915_set_polygon_stipple(struct pipe_context *pipe, 5337ec681f3Smrg const struct pipe_poly_stipple *stipple) 5344a49301eSmrg{ 5354a49301eSmrg} 5364a49301eSmrg 5374a49301eSmrgstatic void * 5384a49301eSmrgi915_create_fs_state(struct pipe_context *pipe, 5394a49301eSmrg const struct pipe_shader_state *templ) 5404a49301eSmrg{ 5414a49301eSmrg struct i915_context *i915 = i915_context(pipe); 5424a49301eSmrg struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader); 5434a49301eSmrg if (!ifs) 5444a49301eSmrg return NULL; 5454a49301eSmrg 5463464ebd5Sriastradh ifs->draw_data = draw_create_fragment_shader(i915->draw, templ); 5474a49301eSmrg 5487ec681f3Smrg if (templ->type == PIPE_SHADER_IR_NIR) { 5497ec681f3Smrg nir_shader *s = templ->ir.nir; 5507ec681f3Smrg 5517ec681f3Smrg NIR_PASS_V(s, i915_nir_lower_sincos); 5527ec681f3Smrg 5537ec681f3Smrg ifs->state.tokens = nir_to_tgsi(s, pipe->screen); 5547ec681f3Smrg } else { 5557ec681f3Smrg assert(templ->type == PIPE_SHADER_IR_TGSI); 5567ec681f3Smrg /* we need to keep a local copy of the tokens */ 5577ec681f3Smrg ifs->state.tokens = tgsi_dup_tokens(templ->tokens); 5587ec681f3Smrg } 5597ec681f3Smrg 5607ec681f3Smrg ifs->state.type = PIPE_SHADER_IR_TGSI; 5617ec681f3Smrg 5627ec681f3Smrg tgsi_scan_shader(ifs->state.tokens, &ifs->info); 5634a49301eSmrg 5644a49301eSmrg /* The shader's compiled to i915 instructions here */ 5654a49301eSmrg i915_translate_fragment_program(i915, ifs); 5664a49301eSmrg 5674a49301eSmrg return ifs; 5684a49301eSmrg} 5694a49301eSmrg 5704a49301eSmrgstatic void 5714a49301eSmrgi915_bind_fs_state(struct pipe_context *pipe, void *shader) 5724a49301eSmrg{ 5734a49301eSmrg struct i915_context *i915 = i915_context(pipe); 574af69d88dSmrg 575af69d88dSmrg if (i915->fs == shader) 576af69d88dSmrg return; 5774a49301eSmrg 5787ec681f3Smrg i915->fs = (struct i915_fragment_shader *)shader; 5797ec681f3Smrg 5807ec681f3Smrg draw_bind_fragment_shader(i915->draw, 5817ec681f3Smrg (i915->fs ? i915->fs->draw_data : NULL)); 5824a49301eSmrg 5837ec681f3Smrg /* Tell draw if we need to do point sprites so we can get PNTC. */ 5847ec681f3Smrg if (i915->fs) 5857ec681f3Smrg draw_wide_point_sprites(i915->draw, i915->fs->reads_pntc); 5863464ebd5Sriastradh 5874a49301eSmrg i915->dirty |= I915_NEW_FS; 5884a49301eSmrg} 5894a49301eSmrg 5907ec681f3Smrgstatic void 5917ec681f3Smrgi915_delete_fs_state(struct pipe_context *pipe, void *shader) 5924a49301eSmrg{ 5937ec681f3Smrg struct i915_fragment_shader *ifs = (struct i915_fragment_shader *)shader; 594af69d88dSmrg 59501e04c3fSmrg FREE(ifs->program); 59601e04c3fSmrg ifs->program = NULL; 59701e04c3fSmrg FREE((struct tgsi_token *)ifs->state.tokens); 59801e04c3fSmrg ifs->state.tokens = NULL; 5994a49301eSmrg 600af69d88dSmrg ifs->program_len = 0; 6014a49301eSmrg 6024a49301eSmrg FREE(ifs); 6034a49301eSmrg} 6044a49301eSmrg 6054a49301eSmrgstatic void * 6064a49301eSmrgi915_create_vs_state(struct pipe_context *pipe, 6074a49301eSmrg const struct pipe_shader_state *templ) 6084a49301eSmrg{ 6094a49301eSmrg struct i915_context *i915 = i915_context(pipe); 6104a49301eSmrg 6117ec681f3Smrg struct pipe_shader_state from_nir = { PIPE_SHADER_IR_TGSI }; 6127ec681f3Smrg if (templ->type == PIPE_SHADER_IR_NIR) { 6137ec681f3Smrg nir_shader *s = templ->ir.nir; 6147ec681f3Smrg 6157ec681f3Smrg NIR_PASS_V(s, nir_lower_point_size, 1.0, 255.0); 6167ec681f3Smrg 6177ec681f3Smrg /* The gallivm draw path doesn't support non-native-integers NIR shaders, 6187ec681f3Smrg * st/mesa does native-integers for the screen as a whole rather than 6197ec681f3Smrg * per-stage, and i915 FS can't do native integers. So, convert to TGSI, 6207ec681f3Smrg * where the draw path *does* support non-native-integers. 6217ec681f3Smrg */ 6227ec681f3Smrg from_nir.tokens = nir_to_tgsi(s, pipe->screen); 6237ec681f3Smrg templ = &from_nir; 6247ec681f3Smrg } 6257ec681f3Smrg 6264a49301eSmrg return draw_create_vertex_shader(i915->draw, templ); 6274a49301eSmrg} 6284a49301eSmrg 6297ec681f3Smrgstatic void 6307ec681f3Smrgi915_bind_vs_state(struct pipe_context *pipe, void *shader) 6314a49301eSmrg{ 6324a49301eSmrg struct i915_context *i915 = i915_context(pipe); 6334a49301eSmrg 634af69d88dSmrg if (i915->vs == shader) 635af69d88dSmrg return; 636af69d88dSmrg 637af69d88dSmrg i915->vs = shader; 6383464ebd5Sriastradh 6394a49301eSmrg /* just pass-through to draw module */ 6407ec681f3Smrg draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *)shader); 6414a49301eSmrg 6424a49301eSmrg i915->dirty |= I915_NEW_VS; 6434a49301eSmrg} 6444a49301eSmrg 6457ec681f3Smrgstatic void 6467ec681f3Smrgi915_delete_vs_state(struct pipe_context *pipe, void *shader) 6474a49301eSmrg{ 6484a49301eSmrg struct i915_context *i915 = i915_context(pipe); 6494a49301eSmrg 6504a49301eSmrg /* just pass-through to draw module */ 6517ec681f3Smrg draw_delete_vertex_shader(i915->draw, (struct draw_vertex_shader *)shader); 6524a49301eSmrg} 6534a49301eSmrg 6547ec681f3Smrgstatic void 6557ec681f3Smrgi915_set_constant_buffer(struct pipe_context *pipe, 6567ec681f3Smrg enum pipe_shader_type shader, uint32_t index, 6577ec681f3Smrg bool take_ownership, 6587ec681f3Smrg const struct pipe_constant_buffer *cb) 6594a49301eSmrg{ 6604a49301eSmrg struct i915_context *i915 = i915_context(pipe); 661af69d88dSmrg struct pipe_resource *buf = cb ? cb->buffer : NULL; 6623464ebd5Sriastradh unsigned new_num = 0; 6637ec681f3Smrg bool diff = true; 6644a49301eSmrg 6653464ebd5Sriastradh /* XXX don't support geom shaders now */ 6663464ebd5Sriastradh if (shader == PIPE_SHADER_GEOMETRY) 6673464ebd5Sriastradh return; 6683464ebd5Sriastradh 669af69d88dSmrg if (cb && cb->user_buffer) { 6707ec681f3Smrg buf = i915_user_buffer_create(pipe->screen, (void *)cb->user_buffer, 6717ec681f3Smrg cb->buffer_size, PIPE_BIND_CONSTANT_BUFFER); 672af69d88dSmrg } 673af69d88dSmrg 6743464ebd5Sriastradh /* if we have a new buffer compare it with the old one */ 6754a49301eSmrg if (buf) { 6763464ebd5Sriastradh struct i915_buffer *ibuf = i915_buffer(buf); 6773464ebd5Sriastradh struct pipe_resource *old_buf = i915->constants[shader]; 6783464ebd5Sriastradh struct i915_buffer *old = old_buf ? i915_buffer(old_buf) : NULL; 6793464ebd5Sriastradh unsigned old_num = i915->current.num_user_constants[shader]; 6803464ebd5Sriastradh 6817ec681f3Smrg new_num = ibuf->b.width0 / 4 * sizeof(float); 6823464ebd5Sriastradh 6833464ebd5Sriastradh if (old_num == new_num) { 6843464ebd5Sriastradh if (old_num == 0) 6857ec681f3Smrg diff = false; 6863464ebd5Sriastradh#if 0 6873464ebd5Sriastradh /* XXX no point in running this code since st/mesa only uses user buffers */ 6883464ebd5Sriastradh /* Can't compare the buffer data since they are userbuffers */ 6893464ebd5Sriastradh else if (old && old->free_on_destroy) 6907ec681f3Smrg diff = memcmp(old->data, ibuf->data, ibuf->b.width0); 6913464ebd5Sriastradh#else 6923464ebd5Sriastradh (void)old; 6933464ebd5Sriastradh#endif 6944a49301eSmrg } 6953464ebd5Sriastradh } else { 6963464ebd5Sriastradh diff = i915->current.num_user_constants[shader] != 0; 6974a49301eSmrg } 6984a49301eSmrg 6997ec681f3Smrg if (take_ownership) { 7007ec681f3Smrg pipe_resource_reference(&i915->constants[shader], NULL); 7017ec681f3Smrg i915->constants[shader] = buf; 7027ec681f3Smrg } else { 7037ec681f3Smrg pipe_resource_reference(&i915->constants[shader], buf); 7047ec681f3Smrg } 7053464ebd5Sriastradh i915->current.num_user_constants[shader] = new_num; 7063464ebd5Sriastradh 7073464ebd5Sriastradh if (diff) 7087ec681f3Smrg i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS 7097ec681f3Smrg : I915_NEW_FS_CONSTANTS; 7103464ebd5Sriastradh 711af69d88dSmrg if (cb && cb->user_buffer) { 712af69d88dSmrg pipe_resource_reference(&buf, NULL); 713af69d88dSmrg } 7143464ebd5Sriastradh} 7153464ebd5Sriastradh 7167ec681f3Smrgstatic void 7177ec681f3Smrgi915_set_sampler_views(struct pipe_context *pipe, enum pipe_shader_type shader, 7187ec681f3Smrg unsigned start, unsigned num, 7197ec681f3Smrg unsigned unbind_num_trailing_slots, 7207ec681f3Smrg bool take_ownership, 7217ec681f3Smrg struct pipe_sampler_view **views) 7224a49301eSmrg{ 7237ec681f3Smrg if (shader != PIPE_SHADER_FRAGMENT) { 7247ec681f3Smrg /* No support for VS samplers, because it would mean accessing the 7257ec681f3Smrg * write-combined maps of the textures, which is very slow. VS samplers 7267ec681f3Smrg * are not a required feature of GL2.1 or GLES2. 7277ec681f3Smrg */ 7287ec681f3Smrg assert(num == 0); 7297ec681f3Smrg return; 7307ec681f3Smrg } 7314a49301eSmrg struct i915_context *i915 = i915_context(pipe); 7327ec681f3Smrg uint32_t i; 7334a49301eSmrg 7344a49301eSmrg assert(num <= PIPE_MAX_SAMPLERS); 7354a49301eSmrg 7364a49301eSmrg /* Check for no-op */ 7377ec681f3Smrg if (views && num == i915->num_fragment_sampler_views && 7387ec681f3Smrg !memcmp(i915->fragment_sampler_views, views, 7397ec681f3Smrg num * sizeof(struct pipe_sampler_view *))) { 7407ec681f3Smrg if (take_ownership) { 7417ec681f3Smrg for (unsigned i = 0; i < num; i++) { 7427ec681f3Smrg struct pipe_sampler_view *view = views[i]; 7437ec681f3Smrg pipe_sampler_view_reference(&view, NULL); 7447ec681f3Smrg } 7457ec681f3Smrg } 7464a49301eSmrg return; 7477ec681f3Smrg } 7484a49301eSmrg 749af69d88dSmrg for (i = 0; i < num; i++) { 7507ec681f3Smrg if (take_ownership) { 7517ec681f3Smrg pipe_sampler_view_reference(&i915->fragment_sampler_views[i], NULL); 7527ec681f3Smrg i915->fragment_sampler_views[i] = views[i]; 7537ec681f3Smrg } else { 7547ec681f3Smrg pipe_sampler_view_reference(&i915->fragment_sampler_views[i], views[i]); 7557ec681f3Smrg } 756af69d88dSmrg } 7574a49301eSmrg 7583464ebd5Sriastradh for (i = num; i < i915->num_fragment_sampler_views; i++) 7599f464c52Smaya pipe_sampler_view_reference(&i915->fragment_sampler_views[i], NULL); 7604a49301eSmrg 7613464ebd5Sriastradh i915->num_fragment_sampler_views = num; 7624a49301eSmrg 7633464ebd5Sriastradh i915->dirty |= I915_NEW_SAMPLER_VIEW; 7644a49301eSmrg} 7654a49301eSmrg 766af69d88dSmrgstruct pipe_sampler_view * 767af69d88dSmrgi915_create_sampler_view_custom(struct pipe_context *pipe, 768af69d88dSmrg struct pipe_resource *texture, 769af69d88dSmrg const struct pipe_sampler_view *templ, 7707ec681f3Smrg unsigned width0, unsigned height0) 771af69d88dSmrg{ 772af69d88dSmrg struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); 773af69d88dSmrg 774af69d88dSmrg if (view) { 775af69d88dSmrg *view = *templ; 776af69d88dSmrg view->reference.count = 1; 777af69d88dSmrg view->texture = NULL; 778af69d88dSmrg pipe_resource_reference(&view->texture, texture); 779af69d88dSmrg view->context = pipe; 780af69d88dSmrg } 781af69d88dSmrg 782af69d88dSmrg return view; 783af69d88dSmrg} 7844a49301eSmrg 7853464ebd5Sriastradhstatic struct pipe_sampler_view * 7863464ebd5Sriastradhi915_create_sampler_view(struct pipe_context *pipe, 7873464ebd5Sriastradh struct pipe_resource *texture, 7883464ebd5Sriastradh const struct pipe_sampler_view *templ) 7893464ebd5Sriastradh{ 7903464ebd5Sriastradh struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); 7913464ebd5Sriastradh 7923464ebd5Sriastradh if (view) { 7933464ebd5Sriastradh *view = *templ; 7943464ebd5Sriastradh view->reference.count = 1; 7953464ebd5Sriastradh view->texture = NULL; 7963464ebd5Sriastradh pipe_resource_reference(&view->texture, texture); 7973464ebd5Sriastradh view->context = pipe; 7983464ebd5Sriastradh } 7993464ebd5Sriastradh 8003464ebd5Sriastradh return view; 8013464ebd5Sriastradh} 8023464ebd5Sriastradh 8033464ebd5Sriastradhstatic void 8043464ebd5Sriastradhi915_sampler_view_destroy(struct pipe_context *pipe, 8053464ebd5Sriastradh struct pipe_sampler_view *view) 8063464ebd5Sriastradh{ 8073464ebd5Sriastradh pipe_resource_reference(&view->texture, NULL); 8083464ebd5Sriastradh FREE(view); 8093464ebd5Sriastradh} 8103464ebd5Sriastradh 8117ec681f3Smrgstatic void 8127ec681f3Smrgi915_set_framebuffer_state(struct pipe_context *pipe, 8137ec681f3Smrg const struct pipe_framebuffer_state *fb) 8144a49301eSmrg{ 8154a49301eSmrg struct i915_context *i915 = i915_context(pipe); 8164a49301eSmrg 8174a49301eSmrg i915->framebuffer.width = fb->width; 8184a49301eSmrg i915->framebuffer.height = fb->height; 8194a49301eSmrg i915->framebuffer.nr_cbufs = fb->nr_cbufs; 8207ec681f3Smrg if (fb->nr_cbufs) { 8217ec681f3Smrg pipe_surface_reference(&i915->framebuffer.cbufs[0], fb->cbufs[0]); 8227ec681f3Smrg 8237ec681f3Smrg struct i915_surface *surf = i915_surface(i915->framebuffer.cbufs[0]); 8247ec681f3Smrg if (i915->current.fixup_swizzle != surf->oc_swizzle) { 8257ec681f3Smrg i915->current.fixup_swizzle = surf->oc_swizzle; 8267ec681f3Smrg memcpy(i915->current.color_swizzle, surf->color_swizzle, 8277ec681f3Smrg sizeof(surf->color_swizzle)); 8287ec681f3Smrg i915->dirty |= I915_NEW_COLOR_SWIZZLE; 8297ec681f3Smrg } 8307ec681f3Smrg } else { 8317ec681f3Smrg pipe_surface_reference(&i915->framebuffer.cbufs[0], NULL); 8324a49301eSmrg } 8334a49301eSmrg pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf); 8347ec681f3Smrg if (fb->zsbuf) 8357ec681f3Smrg draw_set_zs_format(i915->draw, fb->zsbuf->format); 8364a49301eSmrg 8374a49301eSmrg i915->dirty |= I915_NEW_FRAMEBUFFER; 8384a49301eSmrg} 8394a49301eSmrg 8407ec681f3Smrgstatic void 8417ec681f3Smrgi915_set_clip_state(struct pipe_context *pipe, 8427ec681f3Smrg const struct pipe_clip_state *clip) 8434a49301eSmrg{ 8444a49301eSmrg struct i915_context *i915 = i915_context(pipe); 8454a49301eSmrg 846af69d88dSmrg i915->clip = *clip; 8473464ebd5Sriastradh 8484a49301eSmrg draw_set_clip_state(i915->draw, clip); 8494a49301eSmrg 8504a49301eSmrg i915->dirty |= I915_NEW_CLIP; 8514a49301eSmrg} 8524a49301eSmrg 8537ec681f3Smrg/* Called when gallium frontends notice changes to the viewport 8544a49301eSmrg * matrix: 8554a49301eSmrg */ 8567ec681f3Smrgstatic void 8577ec681f3Smrgi915_set_viewport_states(struct pipe_context *pipe, unsigned start_slot, 8587ec681f3Smrg unsigned num_viewports, 8597ec681f3Smrg const struct pipe_viewport_state *viewport) 8604a49301eSmrg{ 8614a49301eSmrg struct i915_context *i915 = i915_context(pipe); 8624a49301eSmrg 8634a49301eSmrg i915->viewport = *viewport; /* struct copy */ 8644a49301eSmrg 8654a49301eSmrg /* pass the viewport info to the draw module */ 866af69d88dSmrg draw_set_viewport_states(i915->draw, start_slot, num_viewports, 867af69d88dSmrg &i915->viewport); 8684a49301eSmrg 8694a49301eSmrg i915->dirty |= I915_NEW_VIEWPORT; 8704a49301eSmrg} 8714a49301eSmrg 8724a49301eSmrgstatic void * 8734a49301eSmrgi915_create_rasterizer_state(struct pipe_context *pipe, 8744a49301eSmrg const struct pipe_rasterizer_state *rasterizer) 8754a49301eSmrg{ 8767ec681f3Smrg struct i915_rasterizer_state *cso = CALLOC_STRUCT(i915_rasterizer_state); 8774a49301eSmrg 8783464ebd5Sriastradh cso->templ = *rasterizer; 8794a49301eSmrg cso->light_twoside = rasterizer->light_twoside; 8804a49301eSmrg cso->ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE; 8814a49301eSmrg cso->ds[1].f = rasterizer->offset_scale; 8824a49301eSmrg if (rasterizer->poly_stipple_enable) { 8834a49301eSmrg cso->st |= ST1_ENABLE; 8844a49301eSmrg } 8854a49301eSmrg 8864a49301eSmrg if (rasterizer->scissor) 8874a49301eSmrg cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT; 8884a49301eSmrg else 8894a49301eSmrg cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT; 8904a49301eSmrg 8913464ebd5Sriastradh switch (rasterizer->cull_face) { 8923464ebd5Sriastradh case PIPE_FACE_NONE: 8934a49301eSmrg cso->LIS4 |= S4_CULLMODE_NONE; 8944a49301eSmrg break; 8953464ebd5Sriastradh case PIPE_FACE_FRONT: 8963464ebd5Sriastradh if (rasterizer->front_ccw) 8973464ebd5Sriastradh cso->LIS4 |= S4_CULLMODE_CCW; 8987ec681f3Smrg else 8993464ebd5Sriastradh cso->LIS4 |= S4_CULLMODE_CW; 9004a49301eSmrg break; 9013464ebd5Sriastradh case PIPE_FACE_BACK: 9023464ebd5Sriastradh if (rasterizer->front_ccw) 9033464ebd5Sriastradh cso->LIS4 |= S4_CULLMODE_CW; 9047ec681f3Smrg else 9053464ebd5Sriastradh cso->LIS4 |= S4_CULLMODE_CCW; 9064a49301eSmrg break; 9073464ebd5Sriastradh case PIPE_FACE_FRONT_AND_BACK: 9084a49301eSmrg cso->LIS4 |= S4_CULLMODE_BOTH; 9094a49301eSmrg break; 9104a49301eSmrg } 9114a49301eSmrg 9124a49301eSmrg { 9134a49301eSmrg int line_width = CLAMP((int)(rasterizer->line_width * 2), 1, 0xf); 9144a49301eSmrg 9154a49301eSmrg cso->LIS4 |= line_width << S4_LINE_WIDTH_SHIFT; 9164a49301eSmrg 9174a49301eSmrg if (rasterizer->line_smooth) 9187ec681f3Smrg cso->LIS4 |= S4_LINE_ANTIALIAS_ENABLE; 9194a49301eSmrg } 9204a49301eSmrg 9214a49301eSmrg { 9227ec681f3Smrg int point_size = CLAMP((int)rasterizer->point_size, 1, 0xff); 9234a49301eSmrg 9244a49301eSmrg cso->LIS4 |= point_size << S4_POINT_WIDTH_SHIFT; 9254a49301eSmrg } 9264a49301eSmrg 9274a49301eSmrg if (rasterizer->flatshade) { 9287ec681f3Smrg cso->LIS4 |= 9297ec681f3Smrg (S4_FLATSHADE_ALPHA | S4_FLATSHADE_COLOR | S4_FLATSHADE_SPECULAR); 9304a49301eSmrg } 9314a49301eSmrg 9327ec681f3Smrg if (!rasterizer->flatshade_first) 9337ec681f3Smrg cso->LIS6 |= (2 << S6_TRISTRIP_PV_SHIFT); 9344a49301eSmrg 9357ec681f3Smrg cso->LIS7 = fui(rasterizer->offset_units); 9364a49301eSmrg 9374a49301eSmrg return cso; 9384a49301eSmrg} 9394a49301eSmrg 9407ec681f3Smrgstatic void 9417ec681f3Smrgi915_bind_rasterizer_state(struct pipe_context *pipe, void *raster) 9424a49301eSmrg{ 9434a49301eSmrg struct i915_context *i915 = i915_context(pipe); 9444a49301eSmrg 945af69d88dSmrg if (i915->rasterizer == raster) 946af69d88dSmrg return; 947af69d88dSmrg 9484a49301eSmrg i915->rasterizer = (struct i915_rasterizer_state *)raster; 9494a49301eSmrg 9504a49301eSmrg /* pass-through to draw module */ 9517ec681f3Smrg draw_set_rasterizer_state( 9527ec681f3Smrg i915->draw, (i915->rasterizer ? &(i915->rasterizer->templ) : NULL), 9537ec681f3Smrg raster); 9544a49301eSmrg 9554a49301eSmrg i915->dirty |= I915_NEW_RASTERIZER; 9564a49301eSmrg} 9574a49301eSmrg 9587ec681f3Smrgstatic void 9597ec681f3Smrgi915_delete_rasterizer_state(struct pipe_context *pipe, void *raster) 9604a49301eSmrg{ 9614a49301eSmrg FREE(raster); 9624a49301eSmrg} 9634a49301eSmrg 9647ec681f3Smrgstatic void 9657ec681f3Smrgi915_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, 9667ec681f3Smrg unsigned count, unsigned unbind_num_trailing_slots, 9677ec681f3Smrg bool take_ownership, 9687ec681f3Smrg const struct pipe_vertex_buffer *buffers) 9694a49301eSmrg{ 9704a49301eSmrg struct i915_context *i915 = i915_context(pipe); 9713464ebd5Sriastradh struct draw_context *draw = i915->draw; 9724a49301eSmrg 9737ec681f3Smrg util_set_vertex_buffers_count(i915->vertex_buffers, &i915->nr_vertex_buffers, 9747ec681f3Smrg buffers, start_slot, count, 9757ec681f3Smrg unbind_num_trailing_slots, take_ownership); 9764a49301eSmrg 9774a49301eSmrg /* pass-through to draw module */ 9787ec681f3Smrg draw_set_vertex_buffers(draw, start_slot, count, unbind_num_trailing_slots, 9797ec681f3Smrg buffers); 9803464ebd5Sriastradh} 9813464ebd5Sriastradh 9823464ebd5Sriastradhstatic void * 9837ec681f3Smrgi915_create_vertex_elements_state(struct pipe_context *pipe, unsigned count, 9843464ebd5Sriastradh const struct pipe_vertex_element *attribs) 9853464ebd5Sriastradh{ 9863464ebd5Sriastradh struct i915_velems_state *velems; 9873464ebd5Sriastradh assert(count <= PIPE_MAX_ATTRIBS); 9887ec681f3Smrg velems = 9897ec681f3Smrg (struct i915_velems_state *)MALLOC(sizeof(struct i915_velems_state)); 9903464ebd5Sriastradh if (velems) { 9913464ebd5Sriastradh velems->count = count; 9923464ebd5Sriastradh memcpy(velems->velem, attribs, sizeof(*attribs) * count); 9933464ebd5Sriastradh } 9943464ebd5Sriastradh return velems; 9954a49301eSmrg} 9964a49301eSmrg 9973464ebd5Sriastradhstatic void 9987ec681f3Smrgi915_bind_vertex_elements_state(struct pipe_context *pipe, void *velems) 9994a49301eSmrg{ 10004a49301eSmrg struct i915_context *i915 = i915_context(pipe); 10017ec681f3Smrg struct i915_velems_state *i915_velems = (struct i915_velems_state *)velems; 10023464ebd5Sriastradh 1003af69d88dSmrg if (i915->velems == velems) 1004af69d88dSmrg return; 1005af69d88dSmrg 1006af69d88dSmrg i915->velems = velems; 10074a49301eSmrg 10084a49301eSmrg /* pass-through to draw module */ 10093464ebd5Sriastradh if (i915_velems) { 10107ec681f3Smrg draw_set_vertex_elements(i915->draw, i915_velems->count, 10117ec681f3Smrg i915_velems->velem); 10123464ebd5Sriastradh } 10134a49301eSmrg} 10144a49301eSmrg 10153464ebd5Sriastradhstatic void 10163464ebd5Sriastradhi915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) 10173464ebd5Sriastradh{ 10187ec681f3Smrg FREE(velems); 10193464ebd5Sriastradh} 10203464ebd5Sriastradh 10213464ebd5Sriastradhstatic void 10227ec681f3Smrgi915_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) 10233464ebd5Sriastradh{ 10243464ebd5Sriastradh} 10254a49301eSmrg 10264a49301eSmrgvoid 10277ec681f3Smrgi915_init_state_functions(struct i915_context *i915) 10284a49301eSmrg{ 10294a49301eSmrg i915->base.create_blend_state = i915_create_blend_state; 10304a49301eSmrg i915->base.bind_blend_state = i915_bind_blend_state; 10314a49301eSmrg i915->base.delete_blend_state = i915_delete_blend_state; 10324a49301eSmrg 10334a49301eSmrg i915->base.create_sampler_state = i915_create_sampler_state; 1034af69d88dSmrg i915->base.bind_sampler_states = i915_bind_sampler_states; 10354a49301eSmrg i915->base.delete_sampler_state = i915_delete_sampler_state; 10364a49301eSmrg 10377ec681f3Smrg i915->base.create_depth_stencil_alpha_state = 10387ec681f3Smrg i915_create_depth_stencil_state; 10394a49301eSmrg i915->base.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state; 10407ec681f3Smrg i915->base.delete_depth_stencil_alpha_state = 10417ec681f3Smrg i915_delete_depth_stencil_state; 10424a49301eSmrg 10434a49301eSmrg i915->base.create_rasterizer_state = i915_create_rasterizer_state; 10444a49301eSmrg i915->base.bind_rasterizer_state = i915_bind_rasterizer_state; 10454a49301eSmrg i915->base.delete_rasterizer_state = i915_delete_rasterizer_state; 10464a49301eSmrg i915->base.create_fs_state = i915_create_fs_state; 10474a49301eSmrg i915->base.bind_fs_state = i915_bind_fs_state; 10484a49301eSmrg i915->base.delete_fs_state = i915_delete_fs_state; 10494a49301eSmrg i915->base.create_vs_state = i915_create_vs_state; 10504a49301eSmrg i915->base.bind_vs_state = i915_bind_vs_state; 10514a49301eSmrg i915->base.delete_vs_state = i915_delete_vs_state; 10523464ebd5Sriastradh i915->base.create_vertex_elements_state = i915_create_vertex_elements_state; 10533464ebd5Sriastradh i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state; 10543464ebd5Sriastradh i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state; 10554a49301eSmrg 10564a49301eSmrg i915->base.set_blend_color = i915_set_blend_color; 1057cdc920a0Smrg i915->base.set_stencil_ref = i915_set_stencil_ref; 10584a49301eSmrg i915->base.set_clip_state = i915_set_clip_state; 10593464ebd5Sriastradh i915->base.set_sample_mask = i915_set_sample_mask; 10604a49301eSmrg i915->base.set_constant_buffer = i915_set_constant_buffer; 10614a49301eSmrg i915->base.set_framebuffer_state = i915_set_framebuffer_state; 10624a49301eSmrg 10634a49301eSmrg i915->base.set_polygon_stipple = i915_set_polygon_stipple; 1064af69d88dSmrg i915->base.set_scissor_states = i915_set_scissor_states; 1065af69d88dSmrg i915->base.set_sampler_views = i915_set_sampler_views; 10663464ebd5Sriastradh i915->base.create_sampler_view = i915_create_sampler_view; 10673464ebd5Sriastradh i915->base.sampler_view_destroy = i915_sampler_view_destroy; 1068af69d88dSmrg i915->base.set_viewport_states = i915_set_viewport_states; 10694a49301eSmrg i915->base.set_vertex_buffers = i915_set_vertex_buffers; 10704a49301eSmrg} 1071