1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright © 2006,2008 Intel Corporation
3428d7b3dSmrg * Copyright © 2007 Red Hat, Inc.
4428d7b3dSmrg *
5428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
6428d7b3dSmrg * copy of this software and associated documentation files (the "Software"),
7428d7b3dSmrg * to deal in the Software without restriction, including without limitation
8428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the
10428d7b3dSmrg * Software is furnished to do so, subject to the following conditions:
11428d7b3dSmrg *
12428d7b3dSmrg * The above copyright notice and this permission notice (including the next
13428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the
14428d7b3dSmrg * Software.
15428d7b3dSmrg *
16428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21428d7b3dSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22428d7b3dSmrg * SOFTWARE.
23428d7b3dSmrg *
24428d7b3dSmrg * Authors:
25428d7b3dSmrg *    Wang Zhenyu <zhenyu.z.wang@intel.com>
26428d7b3dSmrg *    Eric Anholt <eric@anholt.net>
27428d7b3dSmrg *    Carl Worth <cworth@redhat.com>
28428d7b3dSmrg *    Keith Packard <keithp@keithp.com>
29428d7b3dSmrg *
30428d7b3dSmrg */
31428d7b3dSmrg
32428d7b3dSmrg#ifdef HAVE_CONFIG_H
33428d7b3dSmrg#include "config.h"
34428d7b3dSmrg#endif
35428d7b3dSmrg
36428d7b3dSmrg#include <assert.h>
37428d7b3dSmrg#include "xorg-server.h"
38428d7b3dSmrg#include "xf86.h"
39428d7b3dSmrg#include "intel.h"
40428d7b3dSmrg#include "intel_uxa.h"
41428d7b3dSmrg#include "i830_reg.h"
42428d7b3dSmrg#include "i965_reg.h"
43428d7b3dSmrg
44428d7b3dSmrg/* bring in brw structs */
45428d7b3dSmrg#include "brw_defines.h"
46428d7b3dSmrg#include "brw_structs.h"
47428d7b3dSmrg
48428d7b3dSmrg// refer vol2, 3d rasterization 3.8.1
49428d7b3dSmrg
50428d7b3dSmrg/* defined in brw_defines.h */
51428d7b3dSmrgstatic const struct blendinfo {
52428d7b3dSmrg	Bool dst_alpha;
53428d7b3dSmrg	Bool src_alpha;
54428d7b3dSmrg	uint32_t src_blend;
55428d7b3dSmrg	uint32_t dst_blend;
56428d7b3dSmrg} i965_blend_op[] = {
57428d7b3dSmrg	/* Clear */
58428d7b3dSmrg	{0, 0, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_ZERO},
59428d7b3dSmrg	/* Src */
60428d7b3dSmrg	{0, 0, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_ZERO},
61428d7b3dSmrg	/* Dst */
62428d7b3dSmrg	{0, 0, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_ONE},
63428d7b3dSmrg	/* Over */
64428d7b3dSmrg	{0, 1, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_INV_SRC_ALPHA},
65428d7b3dSmrg	/* OverReverse */
66428d7b3dSmrg	{1, 0, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_ONE},
67428d7b3dSmrg	/* In */
68428d7b3dSmrg	{1, 0, BRW_BLENDFACTOR_DST_ALPHA, BRW_BLENDFACTOR_ZERO},
69428d7b3dSmrg	/* InReverse */
70428d7b3dSmrg	{0, 1, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_SRC_ALPHA},
71428d7b3dSmrg	/* Out */
72428d7b3dSmrg	{1, 0, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_ZERO},
73428d7b3dSmrg	/* OutReverse */
74428d7b3dSmrg	{0, 1, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_INV_SRC_ALPHA},
75428d7b3dSmrg	/* Atop */
76428d7b3dSmrg	{1, 1, BRW_BLENDFACTOR_DST_ALPHA, BRW_BLENDFACTOR_INV_SRC_ALPHA},
77428d7b3dSmrg	/* AtopReverse */
78428d7b3dSmrg	{1, 1, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_SRC_ALPHA},
79428d7b3dSmrg	/* Xor */
80428d7b3dSmrg	{1, 1, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_INV_SRC_ALPHA},
81428d7b3dSmrg	/* Add */
82428d7b3dSmrg	{0, 0, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_ONE},
83428d7b3dSmrg};
84428d7b3dSmrg
85428d7b3dSmrg/**
86428d7b3dSmrg * Highest-valued BLENDFACTOR used in i965_blend_op.
87428d7b3dSmrg *
88428d7b3dSmrg * This leaves out BRW_BLENDFACTOR_INV_DST_COLOR,
89428d7b3dSmrg * BRW_BLENDFACTOR_INV_CONST_{COLOR,ALPHA},
90428d7b3dSmrg * BRW_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA}
91428d7b3dSmrg */
92428d7b3dSmrg#define BRW_BLENDFACTOR_COUNT (BRW_BLENDFACTOR_INV_DST_ALPHA + 1)
93428d7b3dSmrg
94428d7b3dSmrg/* FIXME: surface format defined in brw_defines.h, shared Sampling engine
95428d7b3dSmrg * 1.7.2
96428d7b3dSmrg */
97428d7b3dSmrgstatic const struct formatinfo {
98428d7b3dSmrg	int fmt;
99428d7b3dSmrg	uint32_t card_fmt;
100428d7b3dSmrg} i965_tex_formats[] = {
101428d7b3dSmrg	{PICT_a8, BRW_SURFACEFORMAT_A8_UNORM},
102428d7b3dSmrg	{PICT_a8r8g8b8, BRW_SURFACEFORMAT_B8G8R8A8_UNORM},
103428d7b3dSmrg	{PICT_x8r8g8b8, BRW_SURFACEFORMAT_B8G8R8X8_UNORM},
104428d7b3dSmrg	{PICT_a8b8g8r8, BRW_SURFACEFORMAT_R8G8B8A8_UNORM},
105428d7b3dSmrg	{PICT_x8b8g8r8, BRW_SURFACEFORMAT_R8G8B8X8_UNORM},
106428d7b3dSmrg	{PICT_r8g8b8, BRW_SURFACEFORMAT_R8G8B8_UNORM},
107428d7b3dSmrg	{PICT_r5g6b5, BRW_SURFACEFORMAT_B5G6R5_UNORM},
108428d7b3dSmrg	{PICT_a1r5g5b5, BRW_SURFACEFORMAT_B5G5R5A1_UNORM},
109428d7b3dSmrg#if XORG_VERSION_CURRENT >= 10699900
110428d7b3dSmrg	{PICT_a2r10g10b10, BRW_SURFACEFORMAT_B10G10R10A2_UNORM},
111428d7b3dSmrg	{PICT_x2r10g10b10, BRW_SURFACEFORMAT_B10G10R10X2_UNORM},
112428d7b3dSmrg	{PICT_a2b10g10r10, BRW_SURFACEFORMAT_R10G10B10A2_UNORM},
113428d7b3dSmrg	{PICT_x2r10g10b10, BRW_SURFACEFORMAT_B10G10R10X2_UNORM},
114428d7b3dSmrg#endif
115428d7b3dSmrg	{PICT_a4r4g4b4, BRW_SURFACEFORMAT_B4G4R4A4_UNORM},
116428d7b3dSmrg};
117428d7b3dSmrg
118428d7b3dSmrgstatic void i965_get_blend_cntl(int op, PicturePtr mask, uint32_t dst_format,
119428d7b3dSmrg				uint32_t * sblend, uint32_t * dblend)
120428d7b3dSmrg{
121428d7b3dSmrg
122428d7b3dSmrg	*sblend = i965_blend_op[op].src_blend;
123428d7b3dSmrg	*dblend = i965_blend_op[op].dst_blend;
124428d7b3dSmrg
125428d7b3dSmrg	/* If there's no dst alpha channel, adjust the blend op so that we'll treat
126428d7b3dSmrg	 * it as always 1.
127428d7b3dSmrg	 */
128428d7b3dSmrg	if (PICT_FORMAT_A(dst_format) == 0 && i965_blend_op[op].dst_alpha) {
129428d7b3dSmrg		if (*sblend == BRW_BLENDFACTOR_DST_ALPHA)
130428d7b3dSmrg			*sblend = BRW_BLENDFACTOR_ONE;
131428d7b3dSmrg		else if (*sblend == BRW_BLENDFACTOR_INV_DST_ALPHA)
132428d7b3dSmrg			*sblend = BRW_BLENDFACTOR_ZERO;
133428d7b3dSmrg	}
134428d7b3dSmrg
135428d7b3dSmrg	/* If the source alpha is being used, then we should only be in a case where
136428d7b3dSmrg	 * the source blend factor is 0, and the source blend value is the mask
137428d7b3dSmrg	 * channels multiplied by the source picture's alpha.
138428d7b3dSmrg	 */
139428d7b3dSmrg	if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format)
140428d7b3dSmrg	    && i965_blend_op[op].src_alpha) {
141428d7b3dSmrg		if (*dblend == BRW_BLENDFACTOR_SRC_ALPHA) {
142428d7b3dSmrg			*dblend = BRW_BLENDFACTOR_SRC_COLOR;
143428d7b3dSmrg		} else if (*dblend == BRW_BLENDFACTOR_INV_SRC_ALPHA) {
144428d7b3dSmrg			*dblend = BRW_BLENDFACTOR_INV_SRC_COLOR;
145428d7b3dSmrg		}
146428d7b3dSmrg	}
147428d7b3dSmrg
148428d7b3dSmrg}
149428d7b3dSmrg
150428d7b3dSmrgstatic uint32_t i965_get_dest_format(PicturePtr dest_picture)
151428d7b3dSmrg{
152428d7b3dSmrg	switch (dest_picture->format) {
153428d7b3dSmrg	case PICT_a8r8g8b8:
154428d7b3dSmrg	case PICT_x8r8g8b8:
155428d7b3dSmrg		return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
156428d7b3dSmrg	case PICT_a8b8g8r8:
157428d7b3dSmrg	case PICT_x8b8g8r8:
158428d7b3dSmrg		return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
159428d7b3dSmrg#if XORG_VERSION_CURRENT >= 10699900
160428d7b3dSmrg	case PICT_a2r10g10b10:
161428d7b3dSmrg	case PICT_x2r10g10b10:
162428d7b3dSmrg		return BRW_SURFACEFORMAT_B10G10R10A2_UNORM;
163428d7b3dSmrg#endif
164428d7b3dSmrg	case PICT_r5g6b5:
165428d7b3dSmrg		return BRW_SURFACEFORMAT_B5G6R5_UNORM;
166428d7b3dSmrg	case PICT_x1r5g5b5:
167428d7b3dSmrg	case PICT_a1r5g5b5:
168428d7b3dSmrg		return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
169428d7b3dSmrg	case PICT_a8:
170428d7b3dSmrg		return BRW_SURFACEFORMAT_A8_UNORM;
171428d7b3dSmrg	case PICT_a4r4g4b4:
172428d7b3dSmrg	case PICT_x4r4g4b4:
173428d7b3dSmrg		return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
174428d7b3dSmrg	default:
175428d7b3dSmrg		return -1;
176428d7b3dSmrg	}
177428d7b3dSmrg}
178428d7b3dSmrg
179428d7b3dSmrgBool
180428d7b3dSmrgi965_check_composite(int op,
181428d7b3dSmrg		     PicturePtr source_picture,
182428d7b3dSmrg		     PicturePtr mask_picture,
183428d7b3dSmrg		     PicturePtr dest_picture,
184428d7b3dSmrg		     int width, int height)
185428d7b3dSmrg{
186428d7b3dSmrg	ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen);
187428d7b3dSmrg
188428d7b3dSmrg	/* Check for unsupported compositing operations. */
189428d7b3dSmrg	if (op >= sizeof(i965_blend_op) / sizeof(i965_blend_op[0])) {
190428d7b3dSmrg		intel_uxa_debug_fallback(scrn,
191428d7b3dSmrg				     "Unsupported Composite op 0x%x\n", op);
192428d7b3dSmrg		return FALSE;
193428d7b3dSmrg	}
194428d7b3dSmrg
195428d7b3dSmrg	if (mask_picture && mask_picture->componentAlpha &&
196428d7b3dSmrg	    PICT_FORMAT_RGB(mask_picture->format)) {
197428d7b3dSmrg		/* Check if it's component alpha that relies on a source alpha and on
198428d7b3dSmrg		 * the source value.  We can only get one of those into the single
199428d7b3dSmrg		 * source value that we get to blend with.
200428d7b3dSmrg		 */
201428d7b3dSmrg		if (i965_blend_op[op].src_alpha &&
202428d7b3dSmrg		    (i965_blend_op[op].src_blend != BRW_BLENDFACTOR_ZERO)) {
203428d7b3dSmrg			intel_uxa_debug_fallback(scrn,
204428d7b3dSmrg					     "Component alpha not supported "
205428d7b3dSmrg					     "with source alpha and source "
206428d7b3dSmrg					     "value blending.\n");
207428d7b3dSmrg			return FALSE;
208428d7b3dSmrg		}
209428d7b3dSmrg	}
210428d7b3dSmrg
211428d7b3dSmrg	if (i965_get_dest_format(dest_picture) == -1) {
212428d7b3dSmrg		intel_uxa_debug_fallback(scrn, "Usupported Color buffer format 0x%x\n",
213428d7b3dSmrg				     (int)dest_picture->format);
214428d7b3dSmrg		return FALSE;
215428d7b3dSmrg	}
216428d7b3dSmrg
217428d7b3dSmrg	return TRUE;
218428d7b3dSmrg}
219428d7b3dSmrg
220428d7b3dSmrgBool
221428d7b3dSmrgi965_check_composite_texture(ScreenPtr screen, PicturePtr picture)
222428d7b3dSmrg{
223428d7b3dSmrg	if (picture->repeatType > RepeatReflect) {
224428d7b3dSmrg		ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
225428d7b3dSmrg		intel_uxa_debug_fallback(scrn,
226428d7b3dSmrg				     "extended repeat (%d) not supported\n",
227428d7b3dSmrg				     picture->repeatType);
228428d7b3dSmrg		return FALSE;
229428d7b3dSmrg	}
230428d7b3dSmrg
231428d7b3dSmrg	if (picture->filter != PictFilterNearest &&
232428d7b3dSmrg	    picture->filter != PictFilterBilinear) {
233428d7b3dSmrg		ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
234428d7b3dSmrg		intel_uxa_debug_fallback(scrn, "Unsupported filter 0x%x\n",
235428d7b3dSmrg				     picture->filter);
236428d7b3dSmrg		return FALSE;
237428d7b3dSmrg	}
238428d7b3dSmrg
239428d7b3dSmrg	if (picture->pDrawable) {
240428d7b3dSmrg		int w, h, i;
241428d7b3dSmrg
242428d7b3dSmrg		w = picture->pDrawable->width;
243428d7b3dSmrg		h = picture->pDrawable->height;
244428d7b3dSmrg		if ((w > 8192) || (h > 8192)) {
245428d7b3dSmrg			ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
246428d7b3dSmrg			intel_uxa_debug_fallback(scrn,
247428d7b3dSmrg					     "Picture w/h too large (%dx%d)\n",
248428d7b3dSmrg					     w, h);
249428d7b3dSmrg			return FALSE;
250428d7b3dSmrg		}
251428d7b3dSmrg
252428d7b3dSmrg		for (i = 0;
253428d7b3dSmrg		     i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
254428d7b3dSmrg		     i++) {
255428d7b3dSmrg			if (i965_tex_formats[i].fmt == picture->format)
256428d7b3dSmrg				break;
257428d7b3dSmrg		}
258428d7b3dSmrg		if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]))
259428d7b3dSmrg		{
260428d7b3dSmrg			ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
261428d7b3dSmrg			intel_uxa_debug_fallback(scrn,
262428d7b3dSmrg					     "Unsupported picture format "
263428d7b3dSmrg					     "0x%x\n",
264428d7b3dSmrg					     (int)picture->format);
265428d7b3dSmrg			return FALSE;
266428d7b3dSmrg		}
267428d7b3dSmrg
268428d7b3dSmrg		return TRUE;
269428d7b3dSmrg	}
270428d7b3dSmrg
271428d7b3dSmrg	return FALSE;
272428d7b3dSmrg}
273428d7b3dSmrg
274428d7b3dSmrg
275428d7b3dSmrg#define BRW_GRF_BLOCKS(nreg)    ((nreg + 15) / 16 - 1)
276428d7b3dSmrg
277428d7b3dSmrg/* Set up a default static partitioning of the URB, which is supposed to
278428d7b3dSmrg * allow anything we would want to do, at potentially lower performance.
279428d7b3dSmrg */
280428d7b3dSmrg#define URB_CS_ENTRY_SIZE     0
281428d7b3dSmrg#define URB_CS_ENTRIES	      0
282428d7b3dSmrg
283428d7b3dSmrg#define URB_VS_ENTRY_SIZE     1	// each 512-bit row
284428d7b3dSmrg#define URB_VS_ENTRIES	      8	// we needs at least 8 entries
285428d7b3dSmrg
286428d7b3dSmrg#define URB_GS_ENTRY_SIZE     0
287428d7b3dSmrg#define URB_GS_ENTRIES	      0
288428d7b3dSmrg
289428d7b3dSmrg#define URB_CLIP_ENTRY_SIZE   0
290428d7b3dSmrg#define URB_CLIP_ENTRIES      0
291428d7b3dSmrg
292428d7b3dSmrg#define URB_SF_ENTRY_SIZE     2
293428d7b3dSmrg#define URB_SF_ENTRIES	      1
294428d7b3dSmrg
295428d7b3dSmrg/*
296428d7b3dSmrg * this program computes dA/dx and dA/dy for the texture coordinates along
297428d7b3dSmrg * with the base texture coordinate. It was extracted from the Mesa driver
298428d7b3dSmrg */
299428d7b3dSmrg
300428d7b3dSmrg#define SF_KERNEL_NUM_GRF  16
301428d7b3dSmrg#define SF_MAX_THREADS	   2
302428d7b3dSmrg
303428d7b3dSmrgstatic const uint32_t sf_kernel_static[][4] = {
304428d7b3dSmrg#include "exa_sf.g4b"
305428d7b3dSmrg};
306428d7b3dSmrg
307428d7b3dSmrgstatic const uint32_t sf_kernel_mask_static[][4] = {
308428d7b3dSmrg#include "exa_sf_mask.g4b"
309428d7b3dSmrg};
310428d7b3dSmrg
311428d7b3dSmrg/* ps kernels */
312428d7b3dSmrg#define PS_KERNEL_NUM_GRF   32
313428d7b3dSmrg#define PS_MAX_THREADS	    48
314428d7b3dSmrg
315428d7b3dSmrgstatic const uint32_t ps_kernel_nomask_affine_static[][4] = {
316428d7b3dSmrg#include "exa_wm_xy.g4b"
317428d7b3dSmrg#include "exa_wm_src_affine.g4b"
318428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b"
319428d7b3dSmrg#include "exa_wm_write.g4b"
320428d7b3dSmrg};
321428d7b3dSmrg
322428d7b3dSmrgstatic const uint32_t ps_kernel_nomask_projective_static[][4] = {
323428d7b3dSmrg#include "exa_wm_xy.g4b"
324428d7b3dSmrg#include "exa_wm_src_projective.g4b"
325428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b"
326428d7b3dSmrg#include "exa_wm_write.g4b"
327428d7b3dSmrg};
328428d7b3dSmrg
329428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_affine_static[][4] = {
330428d7b3dSmrg#include "exa_wm_xy.g4b"
331428d7b3dSmrg#include "exa_wm_src_affine.g4b"
332428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b"
333428d7b3dSmrg#include "exa_wm_mask_affine.g4b"
334428d7b3dSmrg#include "exa_wm_mask_sample_argb.g4b"
335428d7b3dSmrg#include "exa_wm_ca.g4b"
336428d7b3dSmrg#include "exa_wm_write.g4b"
337428d7b3dSmrg};
338428d7b3dSmrg
339428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_projective_static[][4] = {
340428d7b3dSmrg#include "exa_wm_xy.g4b"
341428d7b3dSmrg#include "exa_wm_src_projective.g4b"
342428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b"
343428d7b3dSmrg#include "exa_wm_mask_projective.g4b"
344428d7b3dSmrg#include "exa_wm_mask_sample_argb.g4b"
345428d7b3dSmrg#include "exa_wm_ca.g4b"
346428d7b3dSmrg#include "exa_wm_write.g4b"
347428d7b3dSmrg};
348428d7b3dSmrg
349428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_srcalpha_affine_static[][4] = {
350428d7b3dSmrg#include "exa_wm_xy.g4b"
351428d7b3dSmrg#include "exa_wm_src_affine.g4b"
352428d7b3dSmrg#include "exa_wm_src_sample_a.g4b"
353428d7b3dSmrg#include "exa_wm_mask_affine.g4b"
354428d7b3dSmrg#include "exa_wm_mask_sample_argb.g4b"
355428d7b3dSmrg#include "exa_wm_ca_srcalpha.g4b"
356428d7b3dSmrg#include "exa_wm_write.g4b"
357428d7b3dSmrg};
358428d7b3dSmrg
359428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_srcalpha_projective_static[][4] = {
360428d7b3dSmrg#include "exa_wm_xy.g4b"
361428d7b3dSmrg#include "exa_wm_src_projective.g4b"
362428d7b3dSmrg#include "exa_wm_src_sample_a.g4b"
363428d7b3dSmrg#include "exa_wm_mask_projective.g4b"
364428d7b3dSmrg#include "exa_wm_mask_sample_argb.g4b"
365428d7b3dSmrg#include "exa_wm_ca_srcalpha.g4b"
366428d7b3dSmrg#include "exa_wm_write.g4b"
367428d7b3dSmrg};
368428d7b3dSmrg
369428d7b3dSmrgstatic const uint32_t ps_kernel_masknoca_affine_static[][4] = {
370428d7b3dSmrg#include "exa_wm_xy.g4b"
371428d7b3dSmrg#include "exa_wm_src_affine.g4b"
372428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b"
373428d7b3dSmrg#include "exa_wm_mask_affine.g4b"
374428d7b3dSmrg#include "exa_wm_mask_sample_a.g4b"
375428d7b3dSmrg#include "exa_wm_noca.g4b"
376428d7b3dSmrg#include "exa_wm_write.g4b"
377428d7b3dSmrg};
378428d7b3dSmrg
379428d7b3dSmrgstatic const uint32_t ps_kernel_masknoca_projective_static[][4] = {
380428d7b3dSmrg#include "exa_wm_xy.g4b"
381428d7b3dSmrg#include "exa_wm_src_projective.g4b"
382428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b"
383428d7b3dSmrg#include "exa_wm_mask_projective.g4b"
384428d7b3dSmrg#include "exa_wm_mask_sample_a.g4b"
385428d7b3dSmrg#include "exa_wm_noca.g4b"
386428d7b3dSmrg#include "exa_wm_write.g4b"
387428d7b3dSmrg};
388428d7b3dSmrg
389428d7b3dSmrg/* new programs for Ironlake */
390428d7b3dSmrgstatic const uint32_t sf_kernel_static_gen5[][4] = {
391428d7b3dSmrg#include "exa_sf.g4b.gen5"
392428d7b3dSmrg};
393428d7b3dSmrg
394428d7b3dSmrgstatic const uint32_t sf_kernel_mask_static_gen5[][4] = {
395428d7b3dSmrg#include "exa_sf_mask.g4b.gen5"
396428d7b3dSmrg};
397428d7b3dSmrg
398428d7b3dSmrgstatic const uint32_t ps_kernel_nomask_affine_static_gen5[][4] = {
399428d7b3dSmrg#include "exa_wm_xy.g4b.gen5"
400428d7b3dSmrg#include "exa_wm_src_affine.g4b.gen5"
401428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b.gen5"
402428d7b3dSmrg#include "exa_wm_write.g4b.gen5"
403428d7b3dSmrg};
404428d7b3dSmrg
405428d7b3dSmrgstatic const uint32_t ps_kernel_nomask_projective_static_gen5[][4] = {
406428d7b3dSmrg#include "exa_wm_xy.g4b.gen5"
407428d7b3dSmrg#include "exa_wm_src_projective.g4b.gen5"
408428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b.gen5"
409428d7b3dSmrg#include "exa_wm_write.g4b.gen5"
410428d7b3dSmrg};
411428d7b3dSmrg
412428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_affine_static_gen5[][4] = {
413428d7b3dSmrg#include "exa_wm_xy.g4b.gen5"
414428d7b3dSmrg#include "exa_wm_src_affine.g4b.gen5"
415428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b.gen5"
416428d7b3dSmrg#include "exa_wm_mask_affine.g4b.gen5"
417428d7b3dSmrg#include "exa_wm_mask_sample_argb.g4b.gen5"
418428d7b3dSmrg#include "exa_wm_ca.g4b.gen5"
419428d7b3dSmrg#include "exa_wm_write.g4b.gen5"
420428d7b3dSmrg};
421428d7b3dSmrg
422428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_projective_static_gen5[][4] = {
423428d7b3dSmrg#include "exa_wm_xy.g4b.gen5"
424428d7b3dSmrg#include "exa_wm_src_projective.g4b.gen5"
425428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b.gen5"
426428d7b3dSmrg#include "exa_wm_mask_projective.g4b.gen5"
427428d7b3dSmrg#include "exa_wm_mask_sample_argb.g4b.gen5"
428428d7b3dSmrg#include "exa_wm_ca.g4b.gen5"
429428d7b3dSmrg#include "exa_wm_write.g4b.gen5"
430428d7b3dSmrg};
431428d7b3dSmrg
432428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_srcalpha_affine_static_gen5[][4] = {
433428d7b3dSmrg#include "exa_wm_xy.g4b.gen5"
434428d7b3dSmrg#include "exa_wm_src_affine.g4b.gen5"
435428d7b3dSmrg#include "exa_wm_src_sample_a.g4b.gen5"
436428d7b3dSmrg#include "exa_wm_mask_affine.g4b.gen5"
437428d7b3dSmrg#include "exa_wm_mask_sample_argb.g4b.gen5"
438428d7b3dSmrg#include "exa_wm_ca_srcalpha.g4b.gen5"
439428d7b3dSmrg#include "exa_wm_write.g4b.gen5"
440428d7b3dSmrg};
441428d7b3dSmrg
442428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_srcalpha_projective_static_gen5[][4] = {
443428d7b3dSmrg#include "exa_wm_xy.g4b.gen5"
444428d7b3dSmrg#include "exa_wm_src_projective.g4b.gen5"
445428d7b3dSmrg#include "exa_wm_src_sample_a.g4b.gen5"
446428d7b3dSmrg#include "exa_wm_mask_projective.g4b.gen5"
447428d7b3dSmrg#include "exa_wm_mask_sample_argb.g4b.gen5"
448428d7b3dSmrg#include "exa_wm_ca_srcalpha.g4b.gen5"
449428d7b3dSmrg#include "exa_wm_write.g4b.gen5"
450428d7b3dSmrg};
451428d7b3dSmrg
452428d7b3dSmrgstatic const uint32_t ps_kernel_masknoca_affine_static_gen5[][4] = {
453428d7b3dSmrg#include "exa_wm_xy.g4b.gen5"
454428d7b3dSmrg#include "exa_wm_src_affine.g4b.gen5"
455428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b.gen5"
456428d7b3dSmrg#include "exa_wm_mask_affine.g4b.gen5"
457428d7b3dSmrg#include "exa_wm_mask_sample_a.g4b.gen5"
458428d7b3dSmrg#include "exa_wm_noca.g4b.gen5"
459428d7b3dSmrg#include "exa_wm_write.g4b.gen5"
460428d7b3dSmrg};
461428d7b3dSmrg
462428d7b3dSmrgstatic const uint32_t ps_kernel_masknoca_projective_static_gen5[][4] = {
463428d7b3dSmrg#include "exa_wm_xy.g4b.gen5"
464428d7b3dSmrg#include "exa_wm_src_projective.g4b.gen5"
465428d7b3dSmrg#include "exa_wm_src_sample_argb.g4b.gen5"
466428d7b3dSmrg#include "exa_wm_mask_projective.g4b.gen5"
467428d7b3dSmrg#include "exa_wm_mask_sample_a.g4b.gen5"
468428d7b3dSmrg#include "exa_wm_noca.g4b.gen5"
469428d7b3dSmrg#include "exa_wm_write.g4b.gen5"
470428d7b3dSmrg};
471428d7b3dSmrg
472428d7b3dSmrg/* programs for GEN6 */
473428d7b3dSmrgstatic const uint32_t ps_kernel_nomask_affine_static_gen6[][4] = {
474428d7b3dSmrg#include "exa_wm_src_affine.g6b"
475428d7b3dSmrg#include "exa_wm_src_sample_argb.g6b"
476428d7b3dSmrg#include "exa_wm_write.g6b"
477428d7b3dSmrg};
478428d7b3dSmrg
479428d7b3dSmrgstatic const uint32_t ps_kernel_nomask_projective_static_gen6[][4] = {
480428d7b3dSmrg#include "exa_wm_src_projective.g6b"
481428d7b3dSmrg#include "exa_wm_src_sample_argb.g6b"
482428d7b3dSmrg#include "exa_wm_write.g6b"
483428d7b3dSmrg};
484428d7b3dSmrg
485428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_affine_static_gen6[][4] = {
486428d7b3dSmrg#include "exa_wm_src_affine.g6b"
487428d7b3dSmrg#include "exa_wm_src_sample_argb.g6b"
488428d7b3dSmrg#include "exa_wm_mask_affine.g6b"
489428d7b3dSmrg#include "exa_wm_mask_sample_argb.g6b"
490428d7b3dSmrg#include "exa_wm_ca.g6b"
491428d7b3dSmrg#include "exa_wm_write.g6b"
492428d7b3dSmrg};
493428d7b3dSmrg
494428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_projective_static_gen6[][4] = {
495428d7b3dSmrg#include "exa_wm_src_projective.g6b"
496428d7b3dSmrg#include "exa_wm_src_sample_argb.g6b"
497428d7b3dSmrg#include "exa_wm_mask_projective.g6b"
498428d7b3dSmrg#include "exa_wm_mask_sample_argb.g6b"
499428d7b3dSmrg#include "exa_wm_ca.g4b.gen5"
500428d7b3dSmrg#include "exa_wm_write.g6b"
501428d7b3dSmrg};
502428d7b3dSmrg
503428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_srcalpha_affine_static_gen6[][4] = {
504428d7b3dSmrg#include "exa_wm_src_affine.g6b"
505428d7b3dSmrg#include "exa_wm_src_sample_a.g6b"
506428d7b3dSmrg#include "exa_wm_mask_affine.g6b"
507428d7b3dSmrg#include "exa_wm_mask_sample_argb.g6b"
508428d7b3dSmrg#include "exa_wm_ca_srcalpha.g6b"
509428d7b3dSmrg#include "exa_wm_write.g6b"
510428d7b3dSmrg};
511428d7b3dSmrg
512428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_srcalpha_projective_static_gen6[][4] = {
513428d7b3dSmrg#include "exa_wm_src_projective.g6b"
514428d7b3dSmrg#include "exa_wm_src_sample_a.g6b"
515428d7b3dSmrg#include "exa_wm_mask_projective.g6b"
516428d7b3dSmrg#include "exa_wm_mask_sample_argb.g6b"
517428d7b3dSmrg#include "exa_wm_ca_srcalpha.g6b"
518428d7b3dSmrg#include "exa_wm_write.g6b"
519428d7b3dSmrg};
520428d7b3dSmrg
521428d7b3dSmrgstatic const uint32_t ps_kernel_masknoca_affine_static_gen6[][4] = {
522428d7b3dSmrg#include "exa_wm_src_affine.g6b"
523428d7b3dSmrg#include "exa_wm_src_sample_argb.g6b"
524428d7b3dSmrg#include "exa_wm_mask_affine.g6b"
525428d7b3dSmrg#include "exa_wm_mask_sample_a.g6b"
526428d7b3dSmrg#include "exa_wm_noca.g6b"
527428d7b3dSmrg#include "exa_wm_write.g6b"
528428d7b3dSmrg};
529428d7b3dSmrg
530428d7b3dSmrgstatic const uint32_t ps_kernel_masknoca_projective_static_gen6[][4] = {
531428d7b3dSmrg#include "exa_wm_src_projective.g6b"
532428d7b3dSmrg#include "exa_wm_src_sample_argb.g6b"
533428d7b3dSmrg#include "exa_wm_mask_projective.g6b"
534428d7b3dSmrg#include "exa_wm_mask_sample_a.g6b"
535428d7b3dSmrg#include "exa_wm_noca.g6b"
536428d7b3dSmrg#include "exa_wm_write.g6b"
537428d7b3dSmrg};
538428d7b3dSmrg
539428d7b3dSmrg/* programs for GEN7 */
540428d7b3dSmrgstatic const uint32_t ps_kernel_nomask_affine_static_gen7[][4] = {
541428d7b3dSmrg#include "exa_wm_src_affine.g7b"
542428d7b3dSmrg#include "exa_wm_src_sample_argb.g7b"
543428d7b3dSmrg#include "exa_wm_write.g7b"
544428d7b3dSmrg};
545428d7b3dSmrg
546428d7b3dSmrgstatic const uint32_t ps_kernel_nomask_projective_static_gen7[][4] = {
547428d7b3dSmrg#include "exa_wm_src_projective.g7b"
548428d7b3dSmrg#include "exa_wm_src_sample_argb.g7b"
549428d7b3dSmrg#include "exa_wm_write.g7b"
550428d7b3dSmrg};
551428d7b3dSmrg
552428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_affine_static_gen7[][4] = {
553428d7b3dSmrg#include "exa_wm_src_affine.g7b"
554428d7b3dSmrg#include "exa_wm_src_sample_argb.g7b"
555428d7b3dSmrg#include "exa_wm_mask_affine.g7b"
556428d7b3dSmrg#include "exa_wm_mask_sample_argb.g7b"
557428d7b3dSmrg#include "exa_wm_ca.g6b"
558428d7b3dSmrg#include "exa_wm_write.g7b"
559428d7b3dSmrg};
560428d7b3dSmrg
561428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_projective_static_gen7[][4] = {
562428d7b3dSmrg#include "exa_wm_src_projective.g7b"
563428d7b3dSmrg#include "exa_wm_src_sample_argb.g7b"
564428d7b3dSmrg#include "exa_wm_mask_projective.g7b"
565428d7b3dSmrg#include "exa_wm_mask_sample_argb.g7b"
566428d7b3dSmrg#include "exa_wm_ca.g4b.gen5"
567428d7b3dSmrg#include "exa_wm_write.g7b"
568428d7b3dSmrg};
569428d7b3dSmrg
570428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_srcalpha_affine_static_gen7[][4] = {
571428d7b3dSmrg#include "exa_wm_src_affine.g7b"
572428d7b3dSmrg#include "exa_wm_src_sample_a.g7b"
573428d7b3dSmrg#include "exa_wm_mask_affine.g7b"
574428d7b3dSmrg#include "exa_wm_mask_sample_argb.g7b"
575428d7b3dSmrg#include "exa_wm_ca_srcalpha.g6b"
576428d7b3dSmrg#include "exa_wm_write.g7b"
577428d7b3dSmrg};
578428d7b3dSmrg
579428d7b3dSmrgstatic const uint32_t ps_kernel_maskca_srcalpha_projective_static_gen7[][4] = {
580428d7b3dSmrg#include "exa_wm_src_projective.g7b"
581428d7b3dSmrg#include "exa_wm_src_sample_a.g7b"
582428d7b3dSmrg#include "exa_wm_mask_projective.g7b"
583428d7b3dSmrg#include "exa_wm_mask_sample_argb.g7b"
584428d7b3dSmrg#include "exa_wm_ca_srcalpha.g6b"
585428d7b3dSmrg#include "exa_wm_write.g7b"
586428d7b3dSmrg};
587428d7b3dSmrg
588428d7b3dSmrgstatic const uint32_t ps_kernel_masknoca_affine_static_gen7[][4] = {
589428d7b3dSmrg#include "exa_wm_src_affine.g7b"
590428d7b3dSmrg#include "exa_wm_src_sample_argb.g7b"
591428d7b3dSmrg#include "exa_wm_mask_affine.g7b"
592428d7b3dSmrg#include "exa_wm_mask_sample_a.g7b"
593428d7b3dSmrg#include "exa_wm_noca.g6b"
594428d7b3dSmrg#include "exa_wm_write.g7b"
595428d7b3dSmrg};
596428d7b3dSmrg
597428d7b3dSmrgstatic const uint32_t ps_kernel_masknoca_projective_static_gen7[][4] = {
598428d7b3dSmrg#include "exa_wm_src_projective.g7b"
599428d7b3dSmrg#include "exa_wm_src_sample_argb.g7b"
600428d7b3dSmrg#include "exa_wm_mask_projective.g7b"
601428d7b3dSmrg#include "exa_wm_mask_sample_a.g7b"
602428d7b3dSmrg#include "exa_wm_noca.g6b"
603428d7b3dSmrg#include "exa_wm_write.g7b"
604428d7b3dSmrg};
605428d7b3dSmrg
606428d7b3dSmrg
607428d7b3dSmrgtypedef enum {
608428d7b3dSmrg	SS_INVALID_FILTER = -1,
609428d7b3dSmrg	SS_FILTER_NEAREST,
610428d7b3dSmrg	SS_FILTER_BILINEAR,
611428d7b3dSmrg	FILTER_COUNT,
612428d7b3dSmrg} sampler_state_filter_t;
613428d7b3dSmrg
614428d7b3dSmrgtypedef enum {
615428d7b3dSmrg	SS_INVALID_EXTEND = -1,
616428d7b3dSmrg	SS_EXTEND_NONE,
617428d7b3dSmrg	SS_EXTEND_REPEAT,
618428d7b3dSmrg	SS_EXTEND_PAD,
619428d7b3dSmrg	SS_EXTEND_REFLECT,
620428d7b3dSmrg	EXTEND_COUNT,
621428d7b3dSmrg} sampler_state_extend_t;
622428d7b3dSmrg
623428d7b3dSmrgtypedef enum {
624428d7b3dSmrg	WM_KERNEL_NOMASK_AFFINE,
625428d7b3dSmrg	WM_KERNEL_NOMASK_PROJECTIVE,
626428d7b3dSmrg	WM_KERNEL_MASKCA_AFFINE,
627428d7b3dSmrg	WM_KERNEL_MASKCA_PROJECTIVE,
628428d7b3dSmrg	WM_KERNEL_MASKCA_SRCALPHA_AFFINE,
629428d7b3dSmrg	WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE,
630428d7b3dSmrg	WM_KERNEL_MASKNOCA_AFFINE,
631428d7b3dSmrg	WM_KERNEL_MASKNOCA_PROJECTIVE,
632428d7b3dSmrg	KERNEL_COUNT
633428d7b3dSmrg} wm_kernel_t;
634428d7b3dSmrg
635428d7b3dSmrg#define KERNEL(kernel_enum, kernel, masked) \
636428d7b3dSmrg    [kernel_enum] = {&kernel, sizeof(kernel), masked}
637428d7b3dSmrgstruct wm_kernel_info {
638428d7b3dSmrg	const void *data;
639428d7b3dSmrg	unsigned int size;
640428d7b3dSmrg	Bool has_mask;
641428d7b3dSmrg};
642428d7b3dSmrg
643428d7b3dSmrgstatic const struct wm_kernel_info wm_kernels_gen4[] = {
644428d7b3dSmrg	KERNEL(WM_KERNEL_NOMASK_AFFINE,
645428d7b3dSmrg	       ps_kernel_nomask_affine_static, FALSE),
646428d7b3dSmrg	KERNEL(WM_KERNEL_NOMASK_PROJECTIVE,
647428d7b3dSmrg	       ps_kernel_nomask_projective_static, FALSE),
648428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_AFFINE,
649428d7b3dSmrg	       ps_kernel_maskca_affine_static, TRUE),
650428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_PROJECTIVE,
651428d7b3dSmrg	       ps_kernel_maskca_projective_static, TRUE),
652428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_SRCALPHA_AFFINE,
653428d7b3dSmrg	       ps_kernel_maskca_srcalpha_affine_static, TRUE),
654428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE,
655428d7b3dSmrg	       ps_kernel_maskca_srcalpha_projective_static, TRUE),
656428d7b3dSmrg	KERNEL(WM_KERNEL_MASKNOCA_AFFINE,
657428d7b3dSmrg	       ps_kernel_masknoca_affine_static, TRUE),
658428d7b3dSmrg	KERNEL(WM_KERNEL_MASKNOCA_PROJECTIVE,
659428d7b3dSmrg	       ps_kernel_masknoca_projective_static, TRUE),
660428d7b3dSmrg};
661428d7b3dSmrg
662428d7b3dSmrgstatic const struct wm_kernel_info wm_kernels_gen5[] = {
663428d7b3dSmrg	KERNEL(WM_KERNEL_NOMASK_AFFINE,
664428d7b3dSmrg	       ps_kernel_nomask_affine_static_gen5, FALSE),
665428d7b3dSmrg	KERNEL(WM_KERNEL_NOMASK_PROJECTIVE,
666428d7b3dSmrg	       ps_kernel_nomask_projective_static_gen5, FALSE),
667428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_AFFINE,
668428d7b3dSmrg	       ps_kernel_maskca_affine_static_gen5, TRUE),
669428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_PROJECTIVE,
670428d7b3dSmrg	       ps_kernel_maskca_projective_static_gen5, TRUE),
671428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_SRCALPHA_AFFINE,
672428d7b3dSmrg	       ps_kernel_maskca_srcalpha_affine_static_gen5, TRUE),
673428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE,
674428d7b3dSmrg	       ps_kernel_maskca_srcalpha_projective_static_gen5, TRUE),
675428d7b3dSmrg	KERNEL(WM_KERNEL_MASKNOCA_AFFINE,
676428d7b3dSmrg	       ps_kernel_masknoca_affine_static_gen5, TRUE),
677428d7b3dSmrg	KERNEL(WM_KERNEL_MASKNOCA_PROJECTIVE,
678428d7b3dSmrg	       ps_kernel_masknoca_projective_static_gen5, TRUE),
679428d7b3dSmrg};
680428d7b3dSmrg
681428d7b3dSmrgstatic const struct wm_kernel_info wm_kernels_gen6[] = {
682428d7b3dSmrg	KERNEL(WM_KERNEL_NOMASK_AFFINE,
683428d7b3dSmrg	       ps_kernel_nomask_affine_static_gen6, FALSE),
684428d7b3dSmrg	KERNEL(WM_KERNEL_NOMASK_PROJECTIVE,
685428d7b3dSmrg	       ps_kernel_nomask_projective_static_gen6, FALSE),
686428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_AFFINE,
687428d7b3dSmrg	       ps_kernel_maskca_affine_static_gen6, TRUE),
688428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_PROJECTIVE,
689428d7b3dSmrg	       ps_kernel_maskca_projective_static_gen6, TRUE),
690428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_SRCALPHA_AFFINE,
691428d7b3dSmrg	       ps_kernel_maskca_srcalpha_affine_static_gen6, TRUE),
692428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE,
693428d7b3dSmrg	       ps_kernel_maskca_srcalpha_projective_static_gen6, TRUE),
694428d7b3dSmrg	KERNEL(WM_KERNEL_MASKNOCA_AFFINE,
695428d7b3dSmrg	       ps_kernel_masknoca_affine_static_gen6, TRUE),
696428d7b3dSmrg	KERNEL(WM_KERNEL_MASKNOCA_PROJECTIVE,
697428d7b3dSmrg	       ps_kernel_masknoca_projective_static_gen6, TRUE),
698428d7b3dSmrg};
699428d7b3dSmrg
700428d7b3dSmrgstatic const struct wm_kernel_info wm_kernels_gen7[] = {
701428d7b3dSmrg	KERNEL(WM_KERNEL_NOMASK_AFFINE,
702428d7b3dSmrg	       ps_kernel_nomask_affine_static_gen7, FALSE),
703428d7b3dSmrg	KERNEL(WM_KERNEL_NOMASK_PROJECTIVE,
704428d7b3dSmrg	       ps_kernel_nomask_projective_static_gen7, FALSE),
705428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_AFFINE,
706428d7b3dSmrg	       ps_kernel_maskca_affine_static_gen7, TRUE),
707428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_PROJECTIVE,
708428d7b3dSmrg	       ps_kernel_maskca_projective_static_gen7, TRUE),
709428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_SRCALPHA_AFFINE,
710428d7b3dSmrg	       ps_kernel_maskca_srcalpha_affine_static_gen7, TRUE),
711428d7b3dSmrg	KERNEL(WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE,
712428d7b3dSmrg	       ps_kernel_maskca_srcalpha_projective_static_gen7, TRUE),
713428d7b3dSmrg	KERNEL(WM_KERNEL_MASKNOCA_AFFINE,
714428d7b3dSmrg	       ps_kernel_masknoca_affine_static_gen7, TRUE),
715428d7b3dSmrg	KERNEL(WM_KERNEL_MASKNOCA_PROJECTIVE,
716428d7b3dSmrg	       ps_kernel_masknoca_projective_static_gen7, TRUE),
717428d7b3dSmrg};
718428d7b3dSmrg
719428d7b3dSmrg#undef KERNEL
720428d7b3dSmrg
721428d7b3dSmrgtypedef struct _brw_cc_unit_state_padded {
722428d7b3dSmrg	struct brw_cc_unit_state state;
723428d7b3dSmrg	char pad[64 - sizeof(struct brw_cc_unit_state)];
724428d7b3dSmrg} brw_cc_unit_state_padded;
725428d7b3dSmrg
726428d7b3dSmrg#ifndef MAX
727428d7b3dSmrg#define MAX(a, b) ((a) > (b) ? (a) : (b))
728428d7b3dSmrg#endif
729428d7b3dSmrg#define SURFACE_STATE_PADDED_SIZE ALIGN(MAX(sizeof(struct brw_surface_state), sizeof(struct gen7_surface_state)), 32)
730428d7b3dSmrg
731428d7b3dSmrgstruct gen4_cc_unit_state {
732428d7b3dSmrg	/* Index by [src_blend][dst_blend] */
733428d7b3dSmrg	brw_cc_unit_state_padded cc_state[BRW_BLENDFACTOR_COUNT][BRW_BLENDFACTOR_COUNT];
734428d7b3dSmrg};
735428d7b3dSmrg
736428d7b3dSmrgtypedef struct gen4_composite_op {
737428d7b3dSmrg	int op;
738428d7b3dSmrg	sampler_state_filter_t src_filter;
739428d7b3dSmrg	sampler_state_filter_t mask_filter;
740428d7b3dSmrg	sampler_state_extend_t src_extend;
741428d7b3dSmrg	sampler_state_extend_t mask_extend;
742428d7b3dSmrg	Bool is_affine;
743428d7b3dSmrg	wm_kernel_t wm_kernel;
744428d7b3dSmrg	int vertex_id;
745428d7b3dSmrg} gen4_composite_op;
746428d7b3dSmrg
747428d7b3dSmrg/** Private data for gen4 render accel implementation. */
748428d7b3dSmrgstruct gen4_render_state {
749428d7b3dSmrg	drm_intel_bo *vs_state_bo;
750428d7b3dSmrg	drm_intel_bo *sf_state_bo;
751428d7b3dSmrg	drm_intel_bo *sf_mask_state_bo;
752428d7b3dSmrg	drm_intel_bo *cc_state_bo;
753428d7b3dSmrg	drm_intel_bo *wm_state_bo[KERNEL_COUNT]
754428d7b3dSmrg	    [FILTER_COUNT] [EXTEND_COUNT]
755428d7b3dSmrg	    [FILTER_COUNT] [EXTEND_COUNT];
756428d7b3dSmrg	drm_intel_bo *wm_kernel_bo[KERNEL_COUNT];
757428d7b3dSmrg
758428d7b3dSmrg	drm_intel_bo *cc_vp_bo;
759428d7b3dSmrg	drm_intel_bo *gen6_blend_bo;
760428d7b3dSmrg	drm_intel_bo *gen6_depth_stencil_bo;
761428d7b3dSmrg	drm_intel_bo *ps_sampler_state_bo[FILTER_COUNT]
762428d7b3dSmrg	    [EXTEND_COUNT]
763428d7b3dSmrg	    [FILTER_COUNT]
764428d7b3dSmrg	    [EXTEND_COUNT];
765428d7b3dSmrg	gen4_composite_op composite_op;
766428d7b3dSmrg};
767428d7b3dSmrg
768428d7b3dSmrgstatic void gen6_emit_composite_state(struct intel_screen_private *intel);
769428d7b3dSmrgstatic void gen6_render_state_init(ScrnInfoPtr scrn);
770428d7b3dSmrg
771428d7b3dSmrg/**
772428d7b3dSmrg * Sets up the SF state pointing at an SF kernel.
773428d7b3dSmrg *
774428d7b3dSmrg * The SF kernel does coord interp: for each attribute,
775428d7b3dSmrg * calculate dA/dx and dA/dy.  Hand these interpolation coefficients
776428d7b3dSmrg * back to SF which then hands pixels off to WM.
777428d7b3dSmrg */
778428d7b3dSmrgstatic drm_intel_bo *gen4_create_sf_state(intel_screen_private *intel,
779428d7b3dSmrg					  drm_intel_bo * kernel_bo)
780428d7b3dSmrg{
781428d7b3dSmrg	struct brw_sf_unit_state *sf_state;
782428d7b3dSmrg	drm_intel_bo *sf_state_bo;
783428d7b3dSmrg	int ret;
784428d7b3dSmrg
785428d7b3dSmrg	sf_state_bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 SF state",
786428d7b3dSmrg					 sizeof(*sf_state), 4096);
787428d7b3dSmrg	assert(sf_state_bo);
788428d7b3dSmrg
789428d7b3dSmrg	ret = drm_intel_bo_map(sf_state_bo, TRUE);
790428d7b3dSmrg	assert(ret == 0);
791428d7b3dSmrg
792428d7b3dSmrg	sf_state = memset(sf_state_bo->virtual, 0, sizeof(*sf_state));
793428d7b3dSmrg	sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
794428d7b3dSmrg	sf_state->thread0.kernel_start_pointer =
795428d7b3dSmrg	    intel_uxa_emit_reloc(sf_state_bo,
796428d7b3dSmrg			     offsetof(struct brw_sf_unit_state, thread0),
797428d7b3dSmrg			     kernel_bo, sf_state->thread0.grf_reg_count << 1,
798428d7b3dSmrg			     I915_GEM_DOMAIN_INSTRUCTION, 0) >> 6;
799428d7b3dSmrg	sf_state->sf1.single_program_flow = 1;
800428d7b3dSmrg	sf_state->sf1.binding_table_entry_count = 0;
801428d7b3dSmrg	sf_state->sf1.thread_priority = 0;
802428d7b3dSmrg	sf_state->sf1.floating_point_mode = 0;	/* Mesa does this */
803428d7b3dSmrg	sf_state->sf1.illegal_op_exception_enable = 1;
804428d7b3dSmrg	sf_state->sf1.mask_stack_exception_enable = 1;
805428d7b3dSmrg	sf_state->sf1.sw_exception_enable = 1;
806428d7b3dSmrg	sf_state->thread2.per_thread_scratch_space = 0;
807428d7b3dSmrg	/* scratch space is not used in our kernel */
808428d7b3dSmrg	sf_state->thread2.scratch_space_base_pointer = 0;
809428d7b3dSmrg	sf_state->thread3.const_urb_entry_read_length = 0;	/* no const URBs */
810428d7b3dSmrg	sf_state->thread3.const_urb_entry_read_offset = 0;	/* no const URBs */
811428d7b3dSmrg	sf_state->thread3.urb_entry_read_length = 1;	/* 1 URB per vertex */
812428d7b3dSmrg	/* don't smash vertex header, read start from dw8 */
813428d7b3dSmrg	sf_state->thread3.urb_entry_read_offset = 1;
814428d7b3dSmrg	sf_state->thread3.dispatch_grf_start_reg = 3;
815428d7b3dSmrg	sf_state->thread4.max_threads = SF_MAX_THREADS - 1;
816428d7b3dSmrg	sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
817428d7b3dSmrg	sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
818428d7b3dSmrg	sf_state->sf5.viewport_transform = FALSE;	/* skip viewport */
819428d7b3dSmrg	sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
820428d7b3dSmrg	sf_state->sf6.scissor = 0;
821428d7b3dSmrg	sf_state->sf7.trifan_pv = 2;
822428d7b3dSmrg	sf_state->sf6.dest_org_vbias = 0x8;
823428d7b3dSmrg	sf_state->sf6.dest_org_hbias = 0x8;
824428d7b3dSmrg
825428d7b3dSmrg	drm_intel_bo_unmap(sf_state_bo);
826428d7b3dSmrg
827428d7b3dSmrg	return sf_state_bo;
828428d7b3dSmrg	(void)ret;
829428d7b3dSmrg}
830428d7b3dSmrg
831428d7b3dSmrgstatic drm_intel_bo *sampler_border_color_create(intel_screen_private *intel)
832428d7b3dSmrg{
833428d7b3dSmrg	struct brw_sampler_legacy_border_color sampler_border_color;
834428d7b3dSmrg
835428d7b3dSmrg	/* Set up the sampler border color (always transparent black) */
836428d7b3dSmrg	memset(&sampler_border_color, 0, sizeof(sampler_border_color));
837428d7b3dSmrg	sampler_border_color.color[0] = 0;	/* R */
838428d7b3dSmrg	sampler_border_color.color[1] = 0;	/* G */
839428d7b3dSmrg	sampler_border_color.color[2] = 0;	/* B */
840428d7b3dSmrg	sampler_border_color.color[3] = 0;	/* A */
841428d7b3dSmrg
842428d7b3dSmrg	return intel_uxa_bo_alloc_for_data(intel,
843428d7b3dSmrg				       &sampler_border_color,
844428d7b3dSmrg				       sizeof(sampler_border_color),
845428d7b3dSmrg				       "gen4 render sampler border color");
846428d7b3dSmrg}
847428d7b3dSmrg
848428d7b3dSmrgstatic void
849428d7b3dSmrggen4_sampler_state_init(drm_intel_bo * sampler_state_bo,
850428d7b3dSmrg		   struct brw_sampler_state *sampler_state,
851428d7b3dSmrg		   sampler_state_filter_t filter,
852428d7b3dSmrg		   sampler_state_extend_t extend,
853428d7b3dSmrg		   drm_intel_bo * border_color_bo)
854428d7b3dSmrg{
855428d7b3dSmrg	uint32_t sampler_state_offset;
856428d7b3dSmrg
857428d7b3dSmrg	sampler_state_offset = (char *)sampler_state -
858428d7b3dSmrg	    (char *)sampler_state_bo->virtual;
859428d7b3dSmrg
860428d7b3dSmrg	/* PS kernel use this sampler */
861428d7b3dSmrg	memset(sampler_state, 0, sizeof(*sampler_state));
862428d7b3dSmrg
863428d7b3dSmrg	sampler_state->ss0.lod_preclamp = 1;	/* GL mode */
864428d7b3dSmrg
865428d7b3dSmrg	/* We use the legacy mode to get the semantics specified by
866428d7b3dSmrg	 * the Render extension. */
867428d7b3dSmrg	sampler_state->ss0.border_color_mode = BRW_BORDER_COLOR_MODE_LEGACY;
868428d7b3dSmrg
869428d7b3dSmrg	switch (filter) {
870428d7b3dSmrg	default:
871428d7b3dSmrg	case SS_FILTER_NEAREST:
872428d7b3dSmrg		sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST;
873428d7b3dSmrg		sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
874428d7b3dSmrg		break;
875428d7b3dSmrg	case SS_FILTER_BILINEAR:
876428d7b3dSmrg		sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
877428d7b3dSmrg		sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
878428d7b3dSmrg		break;
879428d7b3dSmrg	}
880428d7b3dSmrg
881428d7b3dSmrg	switch (extend) {
882428d7b3dSmrg	default:
883428d7b3dSmrg	case SS_EXTEND_NONE:
884428d7b3dSmrg		sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
885428d7b3dSmrg		sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
886428d7b3dSmrg		sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
887428d7b3dSmrg		break;
888428d7b3dSmrg	case SS_EXTEND_REPEAT:
889428d7b3dSmrg		sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP;
890428d7b3dSmrg		sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
891428d7b3dSmrg		sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
892428d7b3dSmrg		break;
893428d7b3dSmrg	case SS_EXTEND_PAD:
894428d7b3dSmrg		sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
895428d7b3dSmrg		sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
896428d7b3dSmrg		sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
897428d7b3dSmrg		break;
898428d7b3dSmrg	case SS_EXTEND_REFLECT:
899428d7b3dSmrg		sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_MIRROR;
900428d7b3dSmrg		sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_MIRROR;
901428d7b3dSmrg		sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_MIRROR;
902428d7b3dSmrg		break;
903428d7b3dSmrg	}
904428d7b3dSmrg
905428d7b3dSmrg	sampler_state->ss2.border_color_pointer =
906428d7b3dSmrg	    intel_uxa_emit_reloc(sampler_state_bo, sampler_state_offset +
907428d7b3dSmrg			     offsetof(struct brw_sampler_state, ss2),
908428d7b3dSmrg			     border_color_bo, 0,
909428d7b3dSmrg			     I915_GEM_DOMAIN_SAMPLER, 0) >> 5;
910428d7b3dSmrg
911428d7b3dSmrg	sampler_state->ss3.chroma_key_enable = 0;	/* disable chromakey */
912428d7b3dSmrg}
913428d7b3dSmrg
914428d7b3dSmrgstatic void
915428d7b3dSmrggen7_sampler_state_init(drm_intel_bo * sampler_state_bo,
916428d7b3dSmrg		   struct gen7_sampler_state *sampler_state,
917428d7b3dSmrg		   sampler_state_filter_t filter,
918428d7b3dSmrg		   sampler_state_extend_t extend,
919428d7b3dSmrg		   drm_intel_bo * border_color_bo)
920428d7b3dSmrg{
921428d7b3dSmrg	uint32_t sampler_state_offset;
922428d7b3dSmrg
923428d7b3dSmrg	sampler_state_offset = (char *)sampler_state -
924428d7b3dSmrg	    (char *)sampler_state_bo->virtual;
925428d7b3dSmrg
926428d7b3dSmrg	/* PS kernel use this sampler */
927428d7b3dSmrg	memset(sampler_state, 0, sizeof(*sampler_state));
928428d7b3dSmrg
929428d7b3dSmrg	sampler_state->ss0.lod_preclamp = 1;	/* GL mode */
930428d7b3dSmrg
931428d7b3dSmrg	/* We use the legacy mode to get the semantics specified by
932428d7b3dSmrg	 * the Render extension. */
933428d7b3dSmrg	sampler_state->ss0.default_color_mode = BRW_BORDER_COLOR_MODE_LEGACY;
934428d7b3dSmrg
935428d7b3dSmrg	switch (filter) {
936428d7b3dSmrg	default:
937428d7b3dSmrg	case SS_FILTER_NEAREST:
938428d7b3dSmrg		sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST;
939428d7b3dSmrg		sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
940428d7b3dSmrg		break;
941428d7b3dSmrg	case SS_FILTER_BILINEAR:
942428d7b3dSmrg		sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
943428d7b3dSmrg		sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
944428d7b3dSmrg		break;
945428d7b3dSmrg	}
946428d7b3dSmrg
947428d7b3dSmrg	switch (extend) {
948428d7b3dSmrg	default:
949428d7b3dSmrg	case SS_EXTEND_NONE:
950428d7b3dSmrg		sampler_state->ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
951428d7b3dSmrg		sampler_state->ss3.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
952428d7b3dSmrg		sampler_state->ss3.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
953428d7b3dSmrg		break;
954428d7b3dSmrg	case SS_EXTEND_REPEAT:
955428d7b3dSmrg		sampler_state->ss3.r_wrap_mode = BRW_TEXCOORDMODE_WRAP;
956428d7b3dSmrg		sampler_state->ss3.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
957428d7b3dSmrg		sampler_state->ss3.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
958428d7b3dSmrg		break;
959428d7b3dSmrg	case SS_EXTEND_PAD:
960428d7b3dSmrg		sampler_state->ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
961428d7b3dSmrg		sampler_state->ss3.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
962428d7b3dSmrg		sampler_state->ss3.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
963428d7b3dSmrg		break;
964428d7b3dSmrg	case SS_EXTEND_REFLECT:
965428d7b3dSmrg		sampler_state->ss3.r_wrap_mode = BRW_TEXCOORDMODE_MIRROR;
966428d7b3dSmrg		sampler_state->ss3.s_wrap_mode = BRW_TEXCOORDMODE_MIRROR;
967428d7b3dSmrg		sampler_state->ss3.t_wrap_mode = BRW_TEXCOORDMODE_MIRROR;
968428d7b3dSmrg		break;
969428d7b3dSmrg	}
970428d7b3dSmrg
971428d7b3dSmrg	sampler_state->ss2.default_color_pointer =
972428d7b3dSmrg	    intel_uxa_emit_reloc(sampler_state_bo, sampler_state_offset +
973428d7b3dSmrg			     offsetof(struct gen7_sampler_state, ss2),
974428d7b3dSmrg			     border_color_bo, 0,
975428d7b3dSmrg			     I915_GEM_DOMAIN_SAMPLER, 0) >> 5;
976428d7b3dSmrg
977428d7b3dSmrg	sampler_state->ss3.chroma_key_enable = 0;	/* disable chromakey */
978428d7b3dSmrg}
979428d7b3dSmrg
980428d7b3dSmrg
981428d7b3dSmrg
982428d7b3dSmrgstatic drm_intel_bo *gen4_create_sampler_state(intel_screen_private *intel,
983428d7b3dSmrg					       sampler_state_filter_t src_filter,
984428d7b3dSmrg					       sampler_state_extend_t src_extend,
985428d7b3dSmrg					       sampler_state_filter_t mask_filter,
986428d7b3dSmrg					       sampler_state_extend_t mask_extend,
987428d7b3dSmrg					       drm_intel_bo * border_color_bo)
988428d7b3dSmrg{
989428d7b3dSmrg	drm_intel_bo *sampler_state_bo;
990428d7b3dSmrg	struct brw_sampler_state *sampler_state;
991428d7b3dSmrg	int ret;
992428d7b3dSmrg
993428d7b3dSmrg	sampler_state_bo =
994428d7b3dSmrg	    drm_intel_bo_alloc(intel->bufmgr, "gen4 sampler state",
995428d7b3dSmrg			       sizeof(struct brw_sampler_state) * 2, 4096);
996428d7b3dSmrg	assert(sampler_state_bo);
997428d7b3dSmrg
998428d7b3dSmrg	ret = drm_intel_bo_map(sampler_state_bo, TRUE);
999428d7b3dSmrg	assert(ret == 0);
1000428d7b3dSmrg
1001428d7b3dSmrg	sampler_state = sampler_state_bo->virtual;
1002428d7b3dSmrg
1003428d7b3dSmrg	gen4_sampler_state_init(sampler_state_bo,
1004428d7b3dSmrg				&sampler_state[0],
1005428d7b3dSmrg				src_filter, src_extend, border_color_bo);
1006428d7b3dSmrg	gen4_sampler_state_init(sampler_state_bo,
1007428d7b3dSmrg				&sampler_state[1],
1008428d7b3dSmrg				mask_filter, mask_extend, border_color_bo);
1009428d7b3dSmrg
1010428d7b3dSmrg	drm_intel_bo_unmap(sampler_state_bo);
1011428d7b3dSmrg
1012428d7b3dSmrg	return sampler_state_bo;
1013428d7b3dSmrg	(void)ret;
1014428d7b3dSmrg}
1015428d7b3dSmrg
1016428d7b3dSmrgstatic drm_intel_bo *
1017428d7b3dSmrggen7_create_sampler_state(intel_screen_private *intel,
1018428d7b3dSmrg			  sampler_state_filter_t src_filter,
1019428d7b3dSmrg			  sampler_state_extend_t src_extend,
1020428d7b3dSmrg			  sampler_state_filter_t mask_filter,
1021428d7b3dSmrg			  sampler_state_extend_t mask_extend,
1022428d7b3dSmrg			  drm_intel_bo * border_color_bo)
1023428d7b3dSmrg{
1024428d7b3dSmrg	drm_intel_bo *sampler_state_bo;
1025428d7b3dSmrg	struct gen7_sampler_state *sampler_state;
1026428d7b3dSmrg	int ret;
1027428d7b3dSmrg
1028428d7b3dSmrg	sampler_state_bo =
1029428d7b3dSmrg	    drm_intel_bo_alloc(intel->bufmgr, "gen7 sampler state",
1030428d7b3dSmrg			       sizeof(struct gen7_sampler_state) * 2, 4096);
1031428d7b3dSmrg	assert(sampler_state_bo);
1032428d7b3dSmrg
1033428d7b3dSmrg	ret = drm_intel_bo_map(sampler_state_bo, TRUE);
1034428d7b3dSmrg	assert(ret == 0);
1035428d7b3dSmrg
1036428d7b3dSmrg	sampler_state = sampler_state_bo->virtual;
1037428d7b3dSmrg
1038428d7b3dSmrg	gen7_sampler_state_init(sampler_state_bo,
1039428d7b3dSmrg				&sampler_state[0],
1040428d7b3dSmrg				src_filter, src_extend, border_color_bo);
1041428d7b3dSmrg	gen7_sampler_state_init(sampler_state_bo,
1042428d7b3dSmrg				&sampler_state[1],
1043428d7b3dSmrg				mask_filter, mask_extend, border_color_bo);
1044428d7b3dSmrg
1045428d7b3dSmrg	drm_intel_bo_unmap(sampler_state_bo);
1046428d7b3dSmrg
1047428d7b3dSmrg	return sampler_state_bo;
1048428d7b3dSmrg	(void)ret;
1049428d7b3dSmrg}
1050428d7b3dSmrg
1051428d7b3dSmrgstatic inline drm_intel_bo *
1052428d7b3dSmrgi965_create_sampler_state(intel_screen_private *intel,
1053428d7b3dSmrg			  sampler_state_filter_t src_filter,
1054428d7b3dSmrg			  sampler_state_extend_t src_extend,
1055428d7b3dSmrg			  sampler_state_filter_t mask_filter,
1056428d7b3dSmrg			  sampler_state_extend_t mask_extend,
1057428d7b3dSmrg			  drm_intel_bo * border_color_bo)
1058428d7b3dSmrg{
1059428d7b3dSmrg	if (INTEL_INFO(intel)->gen < 070)
1060428d7b3dSmrg		return gen4_create_sampler_state(intel, src_filter, src_extend,
1061428d7b3dSmrg						 mask_filter, mask_extend,
1062428d7b3dSmrg						 border_color_bo);
1063428d7b3dSmrg	return gen7_create_sampler_state(intel, src_filter, src_extend,
1064428d7b3dSmrg					 mask_filter, mask_extend,
1065428d7b3dSmrg					 border_color_bo);
1066428d7b3dSmrg}
1067428d7b3dSmrg
1068428d7b3dSmrg
1069428d7b3dSmrgstatic void
1070428d7b3dSmrgcc_state_init(drm_intel_bo * cc_state_bo,
1071428d7b3dSmrg	      uint32_t cc_state_offset,
1072428d7b3dSmrg	      int src_blend, int dst_blend, drm_intel_bo * cc_vp_bo)
1073428d7b3dSmrg{
1074428d7b3dSmrg	struct brw_cc_unit_state *cc_state;
1075428d7b3dSmrg
1076428d7b3dSmrg	cc_state = (struct brw_cc_unit_state *)((char *)cc_state_bo->virtual +
1077428d7b3dSmrg						cc_state_offset);
1078428d7b3dSmrg
1079428d7b3dSmrg	memset(cc_state, 0, sizeof(*cc_state));
1080428d7b3dSmrg	cc_state->cc0.stencil_enable = 0;	/* disable stencil */
1081428d7b3dSmrg	cc_state->cc2.depth_test = 0;	/* disable depth test */
1082428d7b3dSmrg	cc_state->cc2.logicop_enable = 0;	/* disable logic op */
1083428d7b3dSmrg	cc_state->cc3.ia_blend_enable = 0;	/* blend alpha same as colors */
1084428d7b3dSmrg	cc_state->cc3.blend_enable = 1;	/* enable color blend */
1085428d7b3dSmrg	cc_state->cc3.alpha_test = 0;	/* disable alpha test */
1086428d7b3dSmrg
1087428d7b3dSmrg	cc_state->cc4.cc_viewport_state_offset =
1088428d7b3dSmrg	    intel_uxa_emit_reloc(cc_state_bo, cc_state_offset +
1089428d7b3dSmrg			     offsetof(struct brw_cc_unit_state, cc4),
1090428d7b3dSmrg			     cc_vp_bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 5;
1091428d7b3dSmrg
1092428d7b3dSmrg	cc_state->cc5.dither_enable = 0;	/* disable dither */
1093428d7b3dSmrg	cc_state->cc5.logicop_func = 0xc;	/* COPY */
1094428d7b3dSmrg	cc_state->cc5.statistics_enable = 1;
1095428d7b3dSmrg	cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
1096428d7b3dSmrg
1097428d7b3dSmrg	/* Fill in alpha blend factors same as color, for the future. */
1098428d7b3dSmrg	cc_state->cc5.ia_src_blend_factor = src_blend;
1099428d7b3dSmrg	cc_state->cc5.ia_dest_blend_factor = dst_blend;
1100428d7b3dSmrg
1101428d7b3dSmrg	cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD;
1102428d7b3dSmrg	cc_state->cc6.clamp_post_alpha_blend = 1;
1103428d7b3dSmrg	cc_state->cc6.clamp_pre_alpha_blend = 1;
1104428d7b3dSmrg	cc_state->cc6.clamp_range = 0;	/* clamp range [0,1] */
1105428d7b3dSmrg
1106428d7b3dSmrg	cc_state->cc6.src_blend_factor = src_blend;
1107428d7b3dSmrg	cc_state->cc6.dest_blend_factor = dst_blend;
1108428d7b3dSmrg}
1109428d7b3dSmrg
1110428d7b3dSmrgstatic drm_intel_bo *gen4_create_wm_state(intel_screen_private *intel,
1111428d7b3dSmrg					  Bool has_mask,
1112428d7b3dSmrg					  drm_intel_bo * kernel_bo,
1113428d7b3dSmrg					  drm_intel_bo * sampler_bo)
1114428d7b3dSmrg{
1115428d7b3dSmrg	struct brw_wm_unit_state *state;
1116428d7b3dSmrg	drm_intel_bo *wm_state_bo;
1117428d7b3dSmrg	int ret;
1118428d7b3dSmrg
1119428d7b3dSmrg	wm_state_bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 WM state",
1120428d7b3dSmrg					 sizeof(*state), 4096);
1121428d7b3dSmrg	assert(wm_state_bo);
1122428d7b3dSmrg
1123428d7b3dSmrg	ret = drm_intel_bo_map(wm_state_bo, TRUE);
1124428d7b3dSmrg	assert(ret == 0);
1125428d7b3dSmrg
1126428d7b3dSmrg	state = memset(wm_state_bo->virtual, 0, sizeof(*state));
1127428d7b3dSmrg	state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
1128428d7b3dSmrg	state->thread0.kernel_start_pointer =
1129428d7b3dSmrg	    intel_uxa_emit_reloc(wm_state_bo,
1130428d7b3dSmrg			     offsetof(struct brw_wm_unit_state, thread0),
1131428d7b3dSmrg			     kernel_bo, state->thread0.grf_reg_count << 1,
1132428d7b3dSmrg			     I915_GEM_DOMAIN_INSTRUCTION, 0) >> 6;
1133428d7b3dSmrg
1134428d7b3dSmrg	state->thread1.single_program_flow = 0;
1135428d7b3dSmrg
1136428d7b3dSmrg	/* scratch space is not used in our kernel */
1137428d7b3dSmrg	state->thread2.scratch_space_base_pointer = 0;
1138428d7b3dSmrg	state->thread2.per_thread_scratch_space = 0;
1139428d7b3dSmrg
1140428d7b3dSmrg	state->thread3.const_urb_entry_read_length = 0;
1141428d7b3dSmrg	state->thread3.const_urb_entry_read_offset = 0;
1142428d7b3dSmrg
1143428d7b3dSmrg	state->thread3.urb_entry_read_offset = 0;
1144428d7b3dSmrg	/* wm kernel use urb from 3, see wm_program in compiler module */
1145428d7b3dSmrg	state->thread3.dispatch_grf_start_reg = 3;	/* must match kernel */
1146428d7b3dSmrg
1147428d7b3dSmrg	if (IS_GEN5(intel))
1148428d7b3dSmrg		state->wm4.sampler_count = 0;	/* hardware requirement */
1149428d7b3dSmrg	else
1150428d7b3dSmrg		state->wm4.sampler_count = 1;	/* 1-4 samplers used */
1151428d7b3dSmrg
1152428d7b3dSmrg	state->wm4.sampler_state_pointer =
1153428d7b3dSmrg	    intel_uxa_emit_reloc(wm_state_bo,
1154428d7b3dSmrg			     offsetof(struct brw_wm_unit_state, wm4),
1155428d7b3dSmrg			     sampler_bo,
1156428d7b3dSmrg			     state->wm4.sampler_count << 2,
1157428d7b3dSmrg			     I915_GEM_DOMAIN_INSTRUCTION, 0) >> 5;
1158428d7b3dSmrg	state->wm5.max_threads = PS_MAX_THREADS - 1;
1159428d7b3dSmrg	state->wm5.transposed_urb_read = 0;
1160428d7b3dSmrg	state->wm5.thread_dispatch_enable = 1;
1161428d7b3dSmrg	/* just use 16-pixel dispatch (4 subspans), don't need to change kernel
1162428d7b3dSmrg	 * start point
1163428d7b3dSmrg	 */
1164428d7b3dSmrg	state->wm5.enable_16_pix = 1;
1165428d7b3dSmrg	state->wm5.enable_8_pix = 0;
1166428d7b3dSmrg	state->wm5.early_depth_test = 1;
1167428d7b3dSmrg
1168428d7b3dSmrg	/* Each pair of attributes (src/mask coords) is two URB entries */
1169428d7b3dSmrg	if (has_mask) {
1170428d7b3dSmrg		state->thread1.binding_table_entry_count = 3;	/* 2 tex and fb */
1171428d7b3dSmrg		state->thread3.urb_entry_read_length = 4;
1172428d7b3dSmrg	} else {
1173428d7b3dSmrg		state->thread1.binding_table_entry_count = 2;	/* 1 tex and fb */
1174428d7b3dSmrg		state->thread3.urb_entry_read_length = 2;
1175428d7b3dSmrg	}
1176428d7b3dSmrg
1177428d7b3dSmrg	/* binding table entry count is only used for prefetching, and it has to
1178428d7b3dSmrg	 * be set 0 for Ironlake
1179428d7b3dSmrg	 */
1180428d7b3dSmrg	if (IS_GEN5(intel))
1181428d7b3dSmrg		state->thread1.binding_table_entry_count = 0;
1182428d7b3dSmrg
1183428d7b3dSmrg	drm_intel_bo_unmap(wm_state_bo);
1184428d7b3dSmrg
1185428d7b3dSmrg	return wm_state_bo;
1186428d7b3dSmrg	(void)ret;
1187428d7b3dSmrg}
1188428d7b3dSmrg
1189428d7b3dSmrgstatic drm_intel_bo *gen4_create_cc_viewport(intel_screen_private *intel)
1190428d7b3dSmrg{
1191428d7b3dSmrg	drm_intel_bo *bo;
1192428d7b3dSmrg	struct brw_cc_viewport vp;
1193428d7b3dSmrg	int ret;
1194428d7b3dSmrg
1195428d7b3dSmrg	vp.min_depth = -1.e35;
1196428d7b3dSmrg	vp.max_depth = 1.e35;
1197428d7b3dSmrg
1198428d7b3dSmrg	bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 render unit state",
1199428d7b3dSmrg				sizeof(vp), 4096);
1200428d7b3dSmrg	assert(bo);
1201428d7b3dSmrg
1202428d7b3dSmrg	ret = drm_intel_bo_subdata(bo, 0, sizeof(vp), &vp);
1203428d7b3dSmrg	assert(ret == 0);
1204428d7b3dSmrg
1205428d7b3dSmrg	return bo;
1206428d7b3dSmrg	(void)ret;
1207428d7b3dSmrg}
1208428d7b3dSmrg
1209428d7b3dSmrgstatic drm_intel_bo *gen4_create_vs_unit_state(intel_screen_private *intel)
1210428d7b3dSmrg{
1211428d7b3dSmrg	struct brw_vs_unit_state vs_state;
1212428d7b3dSmrg	memset(&vs_state, 0, sizeof(vs_state));
1213428d7b3dSmrg
1214428d7b3dSmrg	/* Set up the vertex shader to be disabled (passthrough) */
1215428d7b3dSmrg	if (IS_GEN5(intel))
1216428d7b3dSmrg		vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES >> 2;	/* hardware requirement */
1217428d7b3dSmrg	else
1218428d7b3dSmrg		vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES;
1219428d7b3dSmrg	vs_state.thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
1220428d7b3dSmrg	vs_state.vs6.vs_enable = 0;
1221428d7b3dSmrg	vs_state.vs6.vert_cache_disable = 1;
1222428d7b3dSmrg
1223428d7b3dSmrg	return intel_uxa_bo_alloc_for_data(intel, &vs_state, sizeof(vs_state),
1224428d7b3dSmrg				       "gen4 render VS state");
1225428d7b3dSmrg}
1226428d7b3dSmrg
1227428d7b3dSmrg/**
1228428d7b3dSmrg * Set up all combinations of cc state: each blendfactor for source and
1229428d7b3dSmrg * dest.
1230428d7b3dSmrg */
1231428d7b3dSmrgstatic drm_intel_bo *gen4_create_cc_unit_state(intel_screen_private *intel)
1232428d7b3dSmrg{
1233428d7b3dSmrg	drm_intel_bo *cc_state_bo, *cc_vp_bo;
1234428d7b3dSmrg	int i, j, ret;
1235428d7b3dSmrg
1236428d7b3dSmrg	cc_vp_bo = gen4_create_cc_viewport(intel);
1237428d7b3dSmrg
1238428d7b3dSmrg	cc_state_bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 CC state",
1239428d7b3dSmrg					 sizeof(struct gen4_cc_unit_state),
1240428d7b3dSmrg					 4096);
1241428d7b3dSmrg	assert(cc_state_bo);
1242428d7b3dSmrg
1243428d7b3dSmrg	ret = drm_intel_bo_map(cc_state_bo, TRUE);
1244428d7b3dSmrg	assert(ret == 0);
1245428d7b3dSmrg
1246428d7b3dSmrg	for (i = 0; i < BRW_BLENDFACTOR_COUNT; i++) {
1247428d7b3dSmrg		for (j = 0; j < BRW_BLENDFACTOR_COUNT; j++) {
1248428d7b3dSmrg			cc_state_init(cc_state_bo,
1249428d7b3dSmrg				      offsetof(struct gen4_cc_unit_state,
1250428d7b3dSmrg					       cc_state[i][j].state),
1251428d7b3dSmrg				      i, j, cc_vp_bo);
1252428d7b3dSmrg		}
1253428d7b3dSmrg	}
1254428d7b3dSmrg	drm_intel_bo_unmap(cc_state_bo);
1255428d7b3dSmrg
1256428d7b3dSmrg	drm_intel_bo_unreference(cc_vp_bo);
1257428d7b3dSmrg
1258428d7b3dSmrg	return cc_state_bo;
1259428d7b3dSmrg	(void)ret;
1260428d7b3dSmrg}
1261428d7b3dSmrg
1262428d7b3dSmrgstatic uint32_t i965_get_card_format(PicturePtr picture)
1263428d7b3dSmrg{
1264428d7b3dSmrg	unsigned i;
1265428d7b3dSmrg
1266428d7b3dSmrg	for (i = 0; i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
1267428d7b3dSmrg	     i++)
1268428d7b3dSmrg		if (i965_tex_formats[i].fmt == picture->format)
1269428d7b3dSmrg			return i965_tex_formats[i].card_fmt;
1270428d7b3dSmrg
1271428d7b3dSmrg	assert(i != sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]));
1272428d7b3dSmrg
1273428d7b3dSmrg	return 0;
1274428d7b3dSmrg}
1275428d7b3dSmrg
1276428d7b3dSmrgstatic sampler_state_filter_t sampler_state_filter_from_picture(int filter)
1277428d7b3dSmrg{
1278428d7b3dSmrg	switch (filter) {
1279428d7b3dSmrg	case PictFilterNearest:
1280428d7b3dSmrg		return SS_FILTER_NEAREST;
1281428d7b3dSmrg	case PictFilterBilinear:
1282428d7b3dSmrg		return SS_FILTER_BILINEAR;
1283428d7b3dSmrg	default:
1284428d7b3dSmrg		return SS_INVALID_FILTER;
1285428d7b3dSmrg	}
1286428d7b3dSmrg}
1287428d7b3dSmrg
1288428d7b3dSmrgstatic sampler_state_extend_t sampler_state_extend_from_picture(int repeat_type)
1289428d7b3dSmrg{
1290428d7b3dSmrg	switch (repeat_type) {
1291428d7b3dSmrg	case RepeatNone:
1292428d7b3dSmrg		return SS_EXTEND_NONE;
1293428d7b3dSmrg	case RepeatNormal:
1294428d7b3dSmrg		return SS_EXTEND_REPEAT;
1295428d7b3dSmrg	case RepeatPad:
1296428d7b3dSmrg		return SS_EXTEND_PAD;
1297428d7b3dSmrg	case RepeatReflect:
1298428d7b3dSmrg		return SS_EXTEND_REFLECT;
1299428d7b3dSmrg	default:
1300428d7b3dSmrg		return SS_INVALID_EXTEND;
1301428d7b3dSmrg	}
1302428d7b3dSmrg}
1303428d7b3dSmrg
1304428d7b3dSmrg/**
1305428d7b3dSmrg * Sets up the common fields for a surface state buffer for the given
1306428d7b3dSmrg * picture in the given surface state buffer.
1307428d7b3dSmrg */
1308428d7b3dSmrgstatic int
1309428d7b3dSmrggen4_set_picture_surface_state(intel_screen_private *intel,
1310428d7b3dSmrg			       PicturePtr picture, PixmapPtr pixmap,
1311428d7b3dSmrg			       Bool is_dst)
1312428d7b3dSmrg{
1313428d7b3dSmrg	struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap);
1314428d7b3dSmrg	struct brw_surface_state *ss;
1315428d7b3dSmrg	uint32_t write_domain, read_domains;
1316428d7b3dSmrg	int offset;
1317428d7b3dSmrg
1318428d7b3dSmrg	if (is_dst) {
1319428d7b3dSmrg		write_domain = I915_GEM_DOMAIN_RENDER;
1320428d7b3dSmrg		read_domains = I915_GEM_DOMAIN_RENDER;
1321428d7b3dSmrg	} else {
1322428d7b3dSmrg		write_domain = 0;
1323428d7b3dSmrg		read_domains = I915_GEM_DOMAIN_SAMPLER;
1324428d7b3dSmrg	}
1325428d7b3dSmrg	intel_batch_mark_pixmap_domains(intel, priv,
1326428d7b3dSmrg					read_domains, write_domain);
1327428d7b3dSmrg	ss = (struct brw_surface_state *)
1328428d7b3dSmrg		(intel->surface_data + intel->surface_used);
1329428d7b3dSmrg
1330428d7b3dSmrg	memset(ss, 0, sizeof(*ss));
1331428d7b3dSmrg	ss->ss0.surface_type = BRW_SURFACE_2D;
1332428d7b3dSmrg	if (is_dst)
1333428d7b3dSmrg		ss->ss0.surface_format = i965_get_dest_format(picture);
1334428d7b3dSmrg	else
1335428d7b3dSmrg		ss->ss0.surface_format = i965_get_card_format(picture);
1336428d7b3dSmrg
1337428d7b3dSmrg	ss->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
1338428d7b3dSmrg	ss->ss0.color_blend = 1;
1339428d7b3dSmrg	ss->ss1.base_addr = priv->bo->offset;
1340428d7b3dSmrg
1341428d7b3dSmrg	ss->ss2.height = pixmap->drawable.height - 1;
1342428d7b3dSmrg	ss->ss2.width = pixmap->drawable.width - 1;
1343428d7b3dSmrg	ss->ss3.pitch = intel_pixmap_pitch(pixmap) - 1;
1344428d7b3dSmrg	ss->ss3.tile_walk = 0;	/* Tiled X */
1345428d7b3dSmrg	ss->ss3.tiled_surface = intel_uxa_pixmap_tiled(pixmap) ? 1 : 0;
1346428d7b3dSmrg
1347428d7b3dSmrg	dri_bo_emit_reloc(intel->surface_bo,
1348428d7b3dSmrg			  read_domains, write_domain,
1349428d7b3dSmrg			  0,
1350428d7b3dSmrg			  intel->surface_used +
1351428d7b3dSmrg			  offsetof(struct brw_surface_state, ss1),
1352428d7b3dSmrg			  priv->bo);
1353428d7b3dSmrg
1354428d7b3dSmrg	offset = intel->surface_used;
1355428d7b3dSmrg	intel->surface_used += SURFACE_STATE_PADDED_SIZE;
1356428d7b3dSmrg
1357428d7b3dSmrg	return offset;
1358428d7b3dSmrg}
1359428d7b3dSmrg
1360428d7b3dSmrgstatic int
1361428d7b3dSmrggen7_set_picture_surface_state(intel_screen_private *intel,
1362428d7b3dSmrg			       PicturePtr picture, PixmapPtr pixmap,
1363428d7b3dSmrg			       Bool is_dst)
1364428d7b3dSmrg{
1365428d7b3dSmrg	struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap);
1366428d7b3dSmrg	struct gen7_surface_state *ss;
1367428d7b3dSmrg	uint32_t write_domain, read_domains;
1368428d7b3dSmrg	int offset;
1369428d7b3dSmrg
1370428d7b3dSmrg	if (is_dst) {
1371428d7b3dSmrg		write_domain = I915_GEM_DOMAIN_RENDER;
1372428d7b3dSmrg		read_domains = I915_GEM_DOMAIN_RENDER;
1373428d7b3dSmrg	} else {
1374428d7b3dSmrg		write_domain = 0;
1375428d7b3dSmrg		read_domains = I915_GEM_DOMAIN_SAMPLER;
1376428d7b3dSmrg	}
1377428d7b3dSmrg	intel_batch_mark_pixmap_domains(intel, priv,
1378428d7b3dSmrg					read_domains, write_domain);
1379428d7b3dSmrg	ss = (struct gen7_surface_state *)
1380428d7b3dSmrg		(intel->surface_data + intel->surface_used);
1381428d7b3dSmrg
1382428d7b3dSmrg	memset(ss, 0, sizeof(*ss));
1383428d7b3dSmrg	ss->ss0.surface_type = BRW_SURFACE_2D;
1384428d7b3dSmrg	if (is_dst)
1385428d7b3dSmrg		ss->ss0.surface_format = i965_get_dest_format(picture);
1386428d7b3dSmrg	else
1387428d7b3dSmrg		ss->ss0.surface_format = i965_get_card_format(picture);
1388428d7b3dSmrg
1389428d7b3dSmrg	ss->ss0.tile_walk = 0;	/* Tiled X */
1390428d7b3dSmrg	ss->ss0.tiled_surface = intel_uxa_pixmap_tiled(pixmap) ? 1 : 0;
1391428d7b3dSmrg	ss->ss1.base_addr = priv->bo->offset;
1392428d7b3dSmrg
1393428d7b3dSmrg	ss->ss2.height = pixmap->drawable.height - 1;
1394428d7b3dSmrg	ss->ss2.width = pixmap->drawable.width - 1;
1395428d7b3dSmrg	ss->ss3.pitch = intel_pixmap_pitch(pixmap) - 1;
1396428d7b3dSmrg
1397428d7b3dSmrg	if (IS_HSW(intel)) {
1398428d7b3dSmrg		ss->ss7.shader_chanel_select_r = HSW_SCS_RED;
1399428d7b3dSmrg		ss->ss7.shader_chanel_select_g = HSW_SCS_GREEN;
1400428d7b3dSmrg		ss->ss7.shader_chanel_select_b = HSW_SCS_BLUE;
1401428d7b3dSmrg		ss->ss7.shader_chanel_select_a = HSW_SCS_ALPHA;
1402428d7b3dSmrg	}
1403428d7b3dSmrg
1404428d7b3dSmrg	dri_bo_emit_reloc(intel->surface_bo,
1405428d7b3dSmrg			  read_domains, write_domain,
1406428d7b3dSmrg			  0,
1407428d7b3dSmrg			  intel->surface_used +
1408428d7b3dSmrg			  offsetof(struct gen7_surface_state, ss1),
1409428d7b3dSmrg			  priv->bo);
1410428d7b3dSmrg
1411428d7b3dSmrg	offset = intel->surface_used;
1412428d7b3dSmrg	intel->surface_used += SURFACE_STATE_PADDED_SIZE;
1413428d7b3dSmrg
1414428d7b3dSmrg	return offset;
1415428d7b3dSmrg}
1416428d7b3dSmrg
1417428d7b3dSmrgstatic inline int
1418428d7b3dSmrgi965_set_picture_surface_state(intel_screen_private *intel,
1419428d7b3dSmrg			       PicturePtr picture, PixmapPtr pixmap,
1420428d7b3dSmrg			       Bool is_dst)
1421428d7b3dSmrg{
1422428d7b3dSmrg    if (INTEL_INFO(intel)->gen < 070)
1423428d7b3dSmrg        return gen4_set_picture_surface_state(intel, picture, pixmap, is_dst);
1424428d7b3dSmrg    return gen7_set_picture_surface_state(intel, picture, pixmap, is_dst);
1425428d7b3dSmrg}
1426428d7b3dSmrg
1427428d7b3dSmrgstatic void gen4_composite_vertex_elements(struct intel_screen_private *intel)
1428428d7b3dSmrg{
1429428d7b3dSmrg	struct gen4_render_state *render_state = intel->gen4_render_state;
1430428d7b3dSmrg	gen4_composite_op *composite_op = &render_state->composite_op;
1431428d7b3dSmrg	Bool has_mask = intel->render_mask != NULL;
1432428d7b3dSmrg	Bool is_affine = composite_op->is_affine;
1433428d7b3dSmrg	/*
1434428d7b3dSmrg	 * number of extra parameters per vertex
1435428d7b3dSmrg	 */
1436428d7b3dSmrg	int nelem = has_mask ? 2 : 1;
1437428d7b3dSmrg	/*
1438428d7b3dSmrg	 * size of extra parameters:
1439428d7b3dSmrg	 *  3 for homogenous (xyzw)
1440428d7b3dSmrg	 *  2 for cartesian (xy)
1441428d7b3dSmrg	 */
1442428d7b3dSmrg	int selem = is_affine ? 2 : 3;
1443428d7b3dSmrg	uint32_t w_component;
1444428d7b3dSmrg	uint32_t src_format;
1445428d7b3dSmrg	int id;
1446428d7b3dSmrg
1447428d7b3dSmrg	id = has_mask << 1 | is_affine;
1448428d7b3dSmrg
1449428d7b3dSmrg	if (composite_op->vertex_id == id)
1450428d7b3dSmrg		return;
1451428d7b3dSmrg
1452428d7b3dSmrg	composite_op->vertex_id = id;
1453428d7b3dSmrg
1454428d7b3dSmrg	if (is_affine) {
1455428d7b3dSmrg		src_format = BRW_SURFACEFORMAT_R32G32_FLOAT;
1456428d7b3dSmrg		w_component = BRW_VFCOMPONENT_STORE_1_FLT;
1457428d7b3dSmrg	} else {
1458428d7b3dSmrg		src_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT;
1459428d7b3dSmrg		w_component = BRW_VFCOMPONENT_STORE_SRC;
1460428d7b3dSmrg	}
1461428d7b3dSmrg
1462428d7b3dSmrg	if (IS_GEN5(intel)) {
1463428d7b3dSmrg		/*
1464428d7b3dSmrg		 * The reason to add this extra vertex element in the header is that
1465428d7b3dSmrg		 * Ironlake has different vertex header definition and origin method to
1466428d7b3dSmrg		 * set destination element offset doesn't exist anymore, which means
1467428d7b3dSmrg		 * hardware requires a predefined vertex element layout.
1468428d7b3dSmrg		 *
1469428d7b3dSmrg		 * haihao proposed this approach to fill the first vertex element, so
1470428d7b3dSmrg		 * origin layout for Gen4 doesn't need to change, and origin shader
1471428d7b3dSmrg		 * programs behavior is also kept.
1472428d7b3dSmrg		 *
1473428d7b3dSmrg		 * I think this is not bad. - zhenyu
1474428d7b3dSmrg		 */
1475428d7b3dSmrg
1476428d7b3dSmrg		OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS |
1477428d7b3dSmrg			  ((2 * (2 + nelem)) - 1));
1478428d7b3dSmrg		OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
1479428d7b3dSmrg			  (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
1480428d7b3dSmrg			  (0 << VE0_OFFSET_SHIFT));
1481428d7b3dSmrg
1482428d7b3dSmrg		OUT_BATCH((BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) |
1483428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) |
1484428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
1485428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT));
1486428d7b3dSmrg	} else {
1487428d7b3dSmrg		/* Set up our vertex elements, sourced from the single vertex buffer.
1488428d7b3dSmrg		 * that will be set up later.
1489428d7b3dSmrg		 */
1490428d7b3dSmrg		OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS |
1491428d7b3dSmrg			  ((2 * (1 + nelem)) - 1));
1492428d7b3dSmrg	}
1493428d7b3dSmrg
1494428d7b3dSmrg	/* x,y */
1495428d7b3dSmrg	OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
1496428d7b3dSmrg		  (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
1497428d7b3dSmrg		  (0 << VE0_OFFSET_SHIFT));
1498428d7b3dSmrg
1499428d7b3dSmrg	if (IS_GEN5(intel))
1500428d7b3dSmrg		OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1501428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1502428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
1503428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
1504428d7b3dSmrg	else
1505428d7b3dSmrg		OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1506428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1507428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
1508428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
1509428d7b3dSmrg			  (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
1510428d7b3dSmrg	/* u0, v0, w0 */
1511428d7b3dSmrg	OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
1512428d7b3dSmrg		  (src_format << VE0_FORMAT_SHIFT) |
1513428d7b3dSmrg		  ((2 * 4) << VE0_OFFSET_SHIFT));	/* offset vb in bytes */
1514428d7b3dSmrg
1515428d7b3dSmrg	if (IS_GEN5(intel))
1516428d7b3dSmrg		OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1517428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1518428d7b3dSmrg			  (w_component << VE1_VFCOMPONENT_2_SHIFT) |
1519428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
1520428d7b3dSmrg	else
1521428d7b3dSmrg		OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1522428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1523428d7b3dSmrg			  (w_component << VE1_VFCOMPONENT_2_SHIFT) |
1524428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
1525428d7b3dSmrg			  ((4 + 4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));	/* VUE offset in dwords */
1526428d7b3dSmrg	/* u1, v1, w1 */
1527428d7b3dSmrg	if (has_mask) {
1528428d7b3dSmrg		OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID |
1529428d7b3dSmrg			  (src_format << VE0_FORMAT_SHIFT) |
1530428d7b3dSmrg			  (((2 + selem) * 4) << VE0_OFFSET_SHIFT));	/* vb offset in bytes */
1531428d7b3dSmrg
1532428d7b3dSmrg		if (IS_GEN5(intel))
1533428d7b3dSmrg			OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1534428d7b3dSmrg				  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1535428d7b3dSmrg				  (w_component << VE1_VFCOMPONENT_2_SHIFT) |
1536428d7b3dSmrg				  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
1537428d7b3dSmrg		else
1538428d7b3dSmrg			OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1539428d7b3dSmrg				  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1540428d7b3dSmrg				  (w_component << VE1_VFCOMPONENT_2_SHIFT) |
1541428d7b3dSmrg				  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
1542428d7b3dSmrg				  ((4 + 4 + 4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));	/* VUE offset in dwords */
1543428d7b3dSmrg	}
1544428d7b3dSmrg}
1545428d7b3dSmrg
1546428d7b3dSmrgstatic void i965_emit_composite_state(struct intel_screen_private *intel)
1547428d7b3dSmrg{
1548428d7b3dSmrg	struct gen4_render_state *render_state = intel->gen4_render_state;
1549428d7b3dSmrg	gen4_composite_op *composite_op = &render_state->composite_op;
1550428d7b3dSmrg	int op = composite_op->op;
1551428d7b3dSmrg	PicturePtr mask_picture = intel->render_mask_picture;
1552428d7b3dSmrg	PicturePtr dest_picture = intel->render_dest_picture;
1553428d7b3dSmrg	PixmapPtr mask = intel->render_mask;
1554428d7b3dSmrg	PixmapPtr dest = intel->render_dest;
1555428d7b3dSmrg	sampler_state_filter_t src_filter = composite_op->src_filter;
1556428d7b3dSmrg	sampler_state_filter_t mask_filter = composite_op->mask_filter;
1557428d7b3dSmrg	sampler_state_extend_t src_extend = composite_op->src_extend;
1558428d7b3dSmrg	sampler_state_extend_t mask_extend = composite_op->mask_extend;
1559428d7b3dSmrg	uint32_t src_blend, dst_blend;
1560428d7b3dSmrg
1561428d7b3dSmrg	intel->needs_render_state_emit = FALSE;
1562428d7b3dSmrg
1563428d7b3dSmrg	/* Begin the long sequence of commands needed to set up the 3D
1564428d7b3dSmrg	 * rendering pipe
1565428d7b3dSmrg	 */
1566428d7b3dSmrg
1567428d7b3dSmrg	if (intel->needs_3d_invariant) {
1568428d7b3dSmrg		if (IS_GEN5(intel)) {
1569428d7b3dSmrg			/* Ironlake errata workaround: Before disabling the clipper,
1570428d7b3dSmrg			 * you have to MI_FLUSH to get the pipeline idle.
1571428d7b3dSmrg			 */
1572428d7b3dSmrg			OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH);
1573428d7b3dSmrg		}
1574428d7b3dSmrg
1575428d7b3dSmrg		/* Match Mesa driver setup */
1576428d7b3dSmrg		if (INTEL_INFO(intel)->gen >= 045)
1577428d7b3dSmrg			OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
1578428d7b3dSmrg		else
1579428d7b3dSmrg			OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
1580428d7b3dSmrg
1581428d7b3dSmrg		/* Set system instruction pointer */
1582428d7b3dSmrg		OUT_BATCH(BRW_STATE_SIP | 0);
1583428d7b3dSmrg		OUT_BATCH(0);
1584428d7b3dSmrg
1585428d7b3dSmrg		intel->needs_3d_invariant = FALSE;
1586428d7b3dSmrg	}
1587428d7b3dSmrg
1588428d7b3dSmrg	if (intel->surface_reloc == 0) {
1589428d7b3dSmrg		/* Zero out the two base address registers so all offsets are
1590428d7b3dSmrg		 * absolute.
1591428d7b3dSmrg		 */
1592428d7b3dSmrg		if (IS_GEN5(intel)) {
1593428d7b3dSmrg			OUT_BATCH(BRW_STATE_BASE_ADDRESS | 6);
1594428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);	/* Generate state base address */
1595428d7b3dSmrg			intel->surface_reloc = intel->batch_used;
1596428d7b3dSmrg			intel_batch_emit_dword(intel,
1597428d7b3dSmrg					       intel->surface_bo->offset | BASE_ADDRESS_MODIFY);
1598428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);	/* media base addr, don't care */
1599428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);	/* Instruction base address */
1600428d7b3dSmrg			/* general state max addr, disabled */
1601428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
1602428d7b3dSmrg			/* media object state max addr, disabled */
1603428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
1604428d7b3dSmrg			/* Instruction max addr, disabled */
1605428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
1606428d7b3dSmrg		} else {
1607428d7b3dSmrg			OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4);
1608428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);	/* Generate state base address */
1609428d7b3dSmrg			intel->surface_reloc = intel->batch_used;
1610428d7b3dSmrg			intel_batch_emit_dword(intel,
1611428d7b3dSmrg					       intel->surface_bo->offset | BASE_ADDRESS_MODIFY);
1612428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);	/* media base addr, don't care */
1613428d7b3dSmrg			/* general state max addr, disabled */
1614428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
1615428d7b3dSmrg			/* media object state max addr, disabled */
1616428d7b3dSmrg			OUT_BATCH(0 | BASE_ADDRESS_MODIFY);
1617428d7b3dSmrg		}
1618428d7b3dSmrg	}
1619428d7b3dSmrg
1620428d7b3dSmrg	i965_get_blend_cntl(op, mask_picture, dest_picture->format,
1621428d7b3dSmrg			    &src_blend, &dst_blend);
1622428d7b3dSmrg
1623428d7b3dSmrg	/* Binding table pointers */
1624428d7b3dSmrg	OUT_BATCH(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
1625428d7b3dSmrg	OUT_BATCH(0);	/* vs */
1626428d7b3dSmrg	OUT_BATCH(0);	/* gs */
1627428d7b3dSmrg	OUT_BATCH(0);	/* clip */
1628428d7b3dSmrg	OUT_BATCH(0);	/* sf */
1629428d7b3dSmrg	/* Only the PS uses the binding table */
1630428d7b3dSmrg	OUT_BATCH(intel->surface_table);
1631428d7b3dSmrg
1632428d7b3dSmrg	/* The drawing rectangle clipping is always on.  Set it to values that
1633428d7b3dSmrg	 * shouldn't do any clipping.
1634428d7b3dSmrg	 */
1635428d7b3dSmrg	OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | 2);
1636428d7b3dSmrg	OUT_BATCH(0x00000000);	/* ymin, xmin */
1637428d7b3dSmrg	OUT_BATCH(DRAW_YMAX(dest->drawable.height - 1) |
1638428d7b3dSmrg		  DRAW_XMAX(dest->drawable.width - 1));	/* ymax, xmax */
1639428d7b3dSmrg	OUT_BATCH(0x00000000);	/* yorigin, xorigin */
1640428d7b3dSmrg
1641428d7b3dSmrg	/* skip the depth buffer */
1642428d7b3dSmrg	/* skip the polygon stipple */
1643428d7b3dSmrg	/* skip the polygon stipple offset */
1644428d7b3dSmrg	/* skip the line stipple */
1645428d7b3dSmrg
1646428d7b3dSmrg	/* Set the pointers to the 3d pipeline state */
1647428d7b3dSmrg	OUT_BATCH(BRW_3DSTATE_PIPELINED_POINTERS | 5);
1648428d7b3dSmrg	OUT_RELOC(render_state->vs_state_bo,
1649428d7b3dSmrg		  I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1650428d7b3dSmrg	OUT_BATCH(BRW_GS_DISABLE);	/* disable GS, resulting in passthrough */
1651428d7b3dSmrg	OUT_BATCH(BRW_CLIP_DISABLE);	/* disable CLIP, resulting in passthrough */
1652428d7b3dSmrg	if (mask) {
1653428d7b3dSmrg		OUT_RELOC(render_state->sf_mask_state_bo,
1654428d7b3dSmrg			  I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1655428d7b3dSmrg	} else {
1656428d7b3dSmrg		OUT_RELOC(render_state->sf_state_bo,
1657428d7b3dSmrg			  I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1658428d7b3dSmrg	}
1659428d7b3dSmrg
1660428d7b3dSmrg	OUT_RELOC(render_state->wm_state_bo[composite_op->wm_kernel]
1661428d7b3dSmrg		  [src_filter][src_extend]
1662428d7b3dSmrg		  [mask_filter][mask_extend],
1663428d7b3dSmrg		  I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
1664428d7b3dSmrg
1665428d7b3dSmrg	OUT_RELOC(render_state->cc_state_bo,
1666428d7b3dSmrg		  I915_GEM_DOMAIN_INSTRUCTION, 0,
1667428d7b3dSmrg		  offsetof(struct gen4_cc_unit_state,
1668428d7b3dSmrg			   cc_state[src_blend][dst_blend]));
1669428d7b3dSmrg
1670428d7b3dSmrg	{
1671428d7b3dSmrg		int urb_vs_start, urb_vs_size;
1672428d7b3dSmrg		int urb_gs_start, urb_gs_size;
1673428d7b3dSmrg		int urb_clip_start, urb_clip_size;
1674428d7b3dSmrg		int urb_sf_start, urb_sf_size;
1675428d7b3dSmrg		int urb_cs_start, urb_cs_size;
1676428d7b3dSmrg
1677428d7b3dSmrg		urb_vs_start = 0;
1678428d7b3dSmrg		urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
1679428d7b3dSmrg		urb_gs_start = urb_vs_start + urb_vs_size;
1680428d7b3dSmrg		urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
1681428d7b3dSmrg		urb_clip_start = urb_gs_start + urb_gs_size;
1682428d7b3dSmrg		urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
1683428d7b3dSmrg		urb_sf_start = urb_clip_start + urb_clip_size;
1684428d7b3dSmrg		urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
1685428d7b3dSmrg		urb_cs_start = urb_sf_start + urb_sf_size;
1686428d7b3dSmrg		urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
1687428d7b3dSmrg
1688428d7b3dSmrg		/* Erratum (Vol 1a, p32):
1689428d7b3dSmrg		 *   URB_FENCE must not cross a cache-line (64 bytes).
1690428d7b3dSmrg		 */
1691428d7b3dSmrg		if ((intel->batch_used & 15) > (16 - 3)) {
1692428d7b3dSmrg			int cnt = 16 - (intel->batch_used & 15);
1693428d7b3dSmrg			while (cnt--)
1694428d7b3dSmrg				OUT_BATCH(MI_NOOP);
1695428d7b3dSmrg		}
1696428d7b3dSmrg
1697428d7b3dSmrg		OUT_BATCH(BRW_URB_FENCE |
1698428d7b3dSmrg			  UF0_CS_REALLOC |
1699428d7b3dSmrg			  UF0_SF_REALLOC |
1700428d7b3dSmrg			  UF0_CLIP_REALLOC |
1701428d7b3dSmrg			  UF0_GS_REALLOC |
1702428d7b3dSmrg			  UF0_VS_REALLOC |
1703428d7b3dSmrg			  1);
1704428d7b3dSmrg		OUT_BATCH(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
1705428d7b3dSmrg			  ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
1706428d7b3dSmrg			  ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
1707428d7b3dSmrg		OUT_BATCH(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
1708428d7b3dSmrg			  ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
1709428d7b3dSmrg
1710428d7b3dSmrg		/* Constant buffer state */
1711428d7b3dSmrg		OUT_BATCH(BRW_CS_URB_STATE | 0);
1712428d7b3dSmrg		OUT_BATCH(((URB_CS_ENTRY_SIZE - 1) << 4) |
1713428d7b3dSmrg			  (URB_CS_ENTRIES << 0));
1714428d7b3dSmrg	}
1715428d7b3dSmrg
1716428d7b3dSmrg	gen4_composite_vertex_elements(intel);
1717428d7b3dSmrg}
1718428d7b3dSmrg
1719428d7b3dSmrg/**
1720428d7b3dSmrg * Returns whether the current set of composite state plus vertex buffer is
1721428d7b3dSmrg * expected to fit in the aperture.
1722428d7b3dSmrg */
1723428d7b3dSmrgstatic Bool i965_composite_check_aperture(intel_screen_private *intel)
1724428d7b3dSmrg{
1725428d7b3dSmrg	struct gen4_render_state *render_state = intel->gen4_render_state;
1726428d7b3dSmrg	gen4_composite_op *composite_op = &render_state->composite_op;
1727428d7b3dSmrg	drm_intel_bo *bo_table[] = {
1728428d7b3dSmrg		intel->batch_bo,
1729428d7b3dSmrg		intel->vertex_bo,
1730428d7b3dSmrg		intel->surface_bo,
1731428d7b3dSmrg		render_state->vs_state_bo,
1732428d7b3dSmrg		render_state->sf_state_bo,
1733428d7b3dSmrg		render_state->sf_mask_state_bo,
1734428d7b3dSmrg		render_state->wm_state_bo[composite_op->wm_kernel]
1735428d7b3dSmrg		    [composite_op->src_filter]
1736428d7b3dSmrg		    [composite_op->src_extend]
1737428d7b3dSmrg		    [composite_op->mask_filter]
1738428d7b3dSmrg		    [composite_op->mask_extend],
1739428d7b3dSmrg		render_state->cc_state_bo,
1740428d7b3dSmrg	};
1741428d7b3dSmrg	drm_intel_bo *gen6_bo_table[] = {
1742428d7b3dSmrg		intel->batch_bo,
1743428d7b3dSmrg		intel->vertex_bo,
1744428d7b3dSmrg		intel->surface_bo,
1745428d7b3dSmrg		render_state->wm_kernel_bo[composite_op->wm_kernel],
1746428d7b3dSmrg		render_state->ps_sampler_state_bo[composite_op->src_filter]
1747428d7b3dSmrg		    [composite_op->src_extend]
1748428d7b3dSmrg		    [composite_op->mask_filter]
1749428d7b3dSmrg		    [composite_op->mask_extend],
1750428d7b3dSmrg		render_state->cc_vp_bo,
1751428d7b3dSmrg		render_state->cc_state_bo,
1752428d7b3dSmrg		render_state->gen6_blend_bo,
1753428d7b3dSmrg		render_state->gen6_depth_stencil_bo,
1754428d7b3dSmrg	};
1755428d7b3dSmrg
1756428d7b3dSmrg	if (INTEL_INFO(intel)->gen >= 060)
1757428d7b3dSmrg		return drm_intel_bufmgr_check_aperture_space(gen6_bo_table,
1758428d7b3dSmrg							ARRAY_SIZE(gen6_bo_table)) == 0;
1759428d7b3dSmrg	else
1760428d7b3dSmrg		return drm_intel_bufmgr_check_aperture_space(bo_table,
1761428d7b3dSmrg							ARRAY_SIZE(bo_table)) == 0;
1762428d7b3dSmrg}
1763428d7b3dSmrg
1764428d7b3dSmrgstatic void i965_surface_flush(struct intel_screen_private *intel)
1765428d7b3dSmrg{
1766428d7b3dSmrg	int ret;
1767428d7b3dSmrg
1768428d7b3dSmrg	ret = drm_intel_bo_subdata(intel->surface_bo,
1769428d7b3dSmrg				   0, intel->surface_used,
1770428d7b3dSmrg				   intel->surface_data);
1771428d7b3dSmrg	assert(ret == 0);
1772428d7b3dSmrg	intel->surface_used = 0;
1773428d7b3dSmrg
1774428d7b3dSmrg	assert (intel->surface_reloc != 0);
1775428d7b3dSmrg	drm_intel_bo_emit_reloc(intel->batch_bo,
1776428d7b3dSmrg				intel->surface_reloc * 4,
1777428d7b3dSmrg				intel->surface_bo, BASE_ADDRESS_MODIFY,
1778428d7b3dSmrg				I915_GEM_DOMAIN_INSTRUCTION, 0);
1779428d7b3dSmrg	intel->surface_reloc = 0;
1780428d7b3dSmrg
1781428d7b3dSmrg	drm_intel_bo_unreference(intel->surface_bo);
1782428d7b3dSmrg	intel->surface_bo =
1783428d7b3dSmrg		drm_intel_bo_alloc(intel->bufmgr, "surface data",
1784428d7b3dSmrg				   sizeof(intel->surface_data), 4096);
1785428d7b3dSmrg	assert(intel->surface_bo);
1786428d7b3dSmrg
1787428d7b3dSmrg	return;
1788428d7b3dSmrg	(void)ret;
1789428d7b3dSmrg}
1790428d7b3dSmrg
1791428d7b3dSmrgstatic void
1792428d7b3dSmrgi965_emit_composite_primitive_identity_source(intel_screen_private *intel,
1793428d7b3dSmrg					      int srcX, int srcY,
1794428d7b3dSmrg					      int maskX, int maskY,
1795428d7b3dSmrg					      int dstX, int dstY,
1796428d7b3dSmrg					      int w, int h)
1797428d7b3dSmrg{
1798428d7b3dSmrg	OUT_VERTEX(dstX + w);
1799428d7b3dSmrg	OUT_VERTEX(dstY + h);
1800428d7b3dSmrg	OUT_VERTEX((srcX + w) * intel->scale_units[0][0]);
1801428d7b3dSmrg	OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
1802428d7b3dSmrg
1803428d7b3dSmrg	OUT_VERTEX(dstX);
1804428d7b3dSmrg	OUT_VERTEX(dstY + h);
1805428d7b3dSmrg	OUT_VERTEX(srcX * intel->scale_units[0][0]);
1806428d7b3dSmrg	OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
1807428d7b3dSmrg
1808428d7b3dSmrg	OUT_VERTEX(dstX);
1809428d7b3dSmrg	OUT_VERTEX(dstY);
1810428d7b3dSmrg	OUT_VERTEX(srcX * intel->scale_units[0][0]);
1811428d7b3dSmrg	OUT_VERTEX(srcY * intel->scale_units[0][1]);
1812428d7b3dSmrg}
1813428d7b3dSmrg
1814428d7b3dSmrgstatic void
1815428d7b3dSmrgi965_emit_composite_primitive_affine_source(intel_screen_private *intel,
1816428d7b3dSmrg					    int srcX, int srcY,
1817428d7b3dSmrg					    int maskX, int maskY,
1818428d7b3dSmrg					    int dstX, int dstY,
1819428d7b3dSmrg					    int w, int h)
1820428d7b3dSmrg{
1821428d7b3dSmrg	float src_x[3], src_y[3];
1822428d7b3dSmrg
1823428d7b3dSmrg	if (!intel_uxa_get_transformed_coordinates(srcX, srcY,
1824428d7b3dSmrg					      intel->transform[0],
1825428d7b3dSmrg					      &src_x[0],
1826428d7b3dSmrg					      &src_y[0]))
1827428d7b3dSmrg		return;
1828428d7b3dSmrg
1829428d7b3dSmrg	if (!intel_uxa_get_transformed_coordinates(srcX, srcY + h,
1830428d7b3dSmrg					      intel->transform[0],
1831428d7b3dSmrg					      &src_x[1],
1832428d7b3dSmrg					      &src_y[1]))
1833428d7b3dSmrg		return;
1834428d7b3dSmrg
1835428d7b3dSmrg	if (!intel_uxa_get_transformed_coordinates(srcX + w, srcY + h,
1836428d7b3dSmrg					      intel->transform[0],
1837428d7b3dSmrg					      &src_x[2],
1838428d7b3dSmrg					      &src_y[2]))
1839428d7b3dSmrg		return;
1840428d7b3dSmrg
1841428d7b3dSmrg	OUT_VERTEX(dstX + w);
1842428d7b3dSmrg	OUT_VERTEX(dstY + h);
1843428d7b3dSmrg	OUT_VERTEX(src_x[2] * intel->scale_units[0][0]);
1844428d7b3dSmrg	OUT_VERTEX(src_y[2] * intel->scale_units[0][1]);
1845428d7b3dSmrg
1846428d7b3dSmrg	OUT_VERTEX(dstX);
1847428d7b3dSmrg	OUT_VERTEX(dstY + h);
1848428d7b3dSmrg	OUT_VERTEX(src_x[1] * intel->scale_units[0][0]);
1849428d7b3dSmrg	OUT_VERTEX(src_y[1] * intel->scale_units[0][1]);
1850428d7b3dSmrg
1851428d7b3dSmrg	OUT_VERTEX(dstX);
1852428d7b3dSmrg	OUT_VERTEX(dstY);
1853428d7b3dSmrg	OUT_VERTEX(src_x[0] * intel->scale_units[0][0]);
1854428d7b3dSmrg	OUT_VERTEX(src_y[0] * intel->scale_units[0][1]);
1855428d7b3dSmrg}
1856428d7b3dSmrg
1857428d7b3dSmrgstatic void
1858428d7b3dSmrgi965_emit_composite_primitive_identity_source_mask(intel_screen_private *intel,
1859428d7b3dSmrg						   int srcX, int srcY,
1860428d7b3dSmrg						   int maskX, int maskY,
1861428d7b3dSmrg						   int dstX, int dstY,
1862428d7b3dSmrg						   int w, int h)
1863428d7b3dSmrg{
1864428d7b3dSmrg	OUT_VERTEX(dstX + w);
1865428d7b3dSmrg	OUT_VERTEX(dstY + h);
1866428d7b3dSmrg	OUT_VERTEX((srcX + w) * intel->scale_units[0][0]);
1867428d7b3dSmrg	OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
1868428d7b3dSmrg	OUT_VERTEX((maskX + w) * intel->scale_units[1][0]);
1869428d7b3dSmrg	OUT_VERTEX((maskY + h) * intel->scale_units[1][1]);
1870428d7b3dSmrg
1871428d7b3dSmrg	OUT_VERTEX(dstX);
1872428d7b3dSmrg	OUT_VERTEX(dstY + h);
1873428d7b3dSmrg	OUT_VERTEX(srcX * intel->scale_units[0][0]);
1874428d7b3dSmrg	OUT_VERTEX((srcY + h) * intel->scale_units[0][1]);
1875428d7b3dSmrg	OUT_VERTEX(maskX * intel->scale_units[1][0]);
1876428d7b3dSmrg	OUT_VERTEX((maskY + h) * intel->scale_units[1][1]);
1877428d7b3dSmrg
1878428d7b3dSmrg	OUT_VERTEX(dstX);
1879428d7b3dSmrg	OUT_VERTEX(dstY);
1880428d7b3dSmrg	OUT_VERTEX(srcX * intel->scale_units[0][0]);
1881428d7b3dSmrg	OUT_VERTEX(srcY * intel->scale_units[0][1]);
1882428d7b3dSmrg	OUT_VERTEX(maskX * intel->scale_units[1][0]);
1883428d7b3dSmrg	OUT_VERTEX(maskY * intel->scale_units[1][1]);
1884428d7b3dSmrg}
1885428d7b3dSmrg
1886428d7b3dSmrgstatic void
1887428d7b3dSmrgi965_emit_composite_primitive(intel_screen_private *intel,
1888428d7b3dSmrg			      int srcX, int srcY,
1889428d7b3dSmrg			      int maskX, int maskY,
1890428d7b3dSmrg			      int dstX, int dstY,
1891428d7b3dSmrg			      int w, int h)
1892428d7b3dSmrg{
1893428d7b3dSmrg	float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
1894428d7b3dSmrg	Bool is_affine = intel->gen4_render_state->composite_op.is_affine;
1895428d7b3dSmrg
1896428d7b3dSmrg	if (is_affine) {
1897428d7b3dSmrg		if (!intel_uxa_get_transformed_coordinates(srcX, srcY,
1898428d7b3dSmrg						       intel->transform[0],
1899428d7b3dSmrg						       &src_x[0],
1900428d7b3dSmrg						       &src_y[0]))
1901428d7b3dSmrg			return;
1902428d7b3dSmrg
1903428d7b3dSmrg		if (!intel_uxa_get_transformed_coordinates(srcX, srcY + h,
1904428d7b3dSmrg						       intel->transform[0],
1905428d7b3dSmrg						       &src_x[1],
1906428d7b3dSmrg						       &src_y[1]))
1907428d7b3dSmrg			return;
1908428d7b3dSmrg
1909428d7b3dSmrg		if (!intel_uxa_get_transformed_coordinates(srcX + w, srcY + h,
1910428d7b3dSmrg						       intel->transform[0],
1911428d7b3dSmrg						       &src_x[2],
1912428d7b3dSmrg						       &src_y[2]))
1913428d7b3dSmrg			return;
1914428d7b3dSmrg	} else {
1915428d7b3dSmrg		if (!intel_uxa_get_transformed_coordinates_3d(srcX, srcY,
1916428d7b3dSmrg							  intel->transform[0],
1917428d7b3dSmrg							  &src_x[0],
1918428d7b3dSmrg							  &src_y[0],
1919428d7b3dSmrg							  &src_w[0]))
1920428d7b3dSmrg			return;
1921428d7b3dSmrg
1922428d7b3dSmrg		if (!intel_uxa_get_transformed_coordinates_3d(srcX, srcY + h,
1923428d7b3dSmrg							  intel->transform[0],
1924428d7b3dSmrg							  &src_x[1],
1925428d7b3dSmrg							  &src_y[1],
1926428d7b3dSmrg							  &src_w[1]))
1927428d7b3dSmrg			return;
1928428d7b3dSmrg
1929428d7b3dSmrg		if (!intel_uxa_get_transformed_coordinates_3d(srcX + w, srcY + h,
1930428d7b3dSmrg							  intel->transform[0],
1931428d7b3dSmrg							  &src_x[2],
1932428d7b3dSmrg							  &src_y[2],
1933428d7b3dSmrg							  &src_w[2]))
1934428d7b3dSmrg			return;
1935428d7b3dSmrg	}
1936428d7b3dSmrg
1937428d7b3dSmrg	if (intel->render_mask) {
1938428d7b3dSmrg		if (is_affine) {
1939428d7b3dSmrg			if (!intel_uxa_get_transformed_coordinates(maskX, maskY,
1940428d7b3dSmrg							      intel->transform[1],
1941428d7b3dSmrg							      &mask_x[0],
1942428d7b3dSmrg							      &mask_y[0]))
1943428d7b3dSmrg				return;
1944428d7b3dSmrg
1945428d7b3dSmrg			if (!intel_uxa_get_transformed_coordinates(maskX, maskY + h,
1946428d7b3dSmrg							      intel->transform[1],
1947428d7b3dSmrg							      &mask_x[1],
1948428d7b3dSmrg							      &mask_y[1]))
1949428d7b3dSmrg				return;
1950428d7b3dSmrg
1951428d7b3dSmrg			if (!intel_uxa_get_transformed_coordinates(maskX + w, maskY + h,
1952428d7b3dSmrg							      intel->transform[1],
1953428d7b3dSmrg							      &mask_x[2],
1954428d7b3dSmrg							      &mask_y[2]))
1955428d7b3dSmrg				return;
1956428d7b3dSmrg		} else {
1957428d7b3dSmrg			if (!intel_uxa_get_transformed_coordinates_3d(maskX, maskY,
1958428d7b3dSmrg								 intel->transform[1],
1959428d7b3dSmrg								 &mask_x[0],
1960428d7b3dSmrg								 &mask_y[0],
1961428d7b3dSmrg								 &mask_w[0]))
1962428d7b3dSmrg				return;
1963428d7b3dSmrg
1964428d7b3dSmrg			if (!intel_uxa_get_transformed_coordinates_3d(maskX, maskY + h,
1965428d7b3dSmrg								 intel->transform[1],
1966428d7b3dSmrg								 &mask_x[1],
1967428d7b3dSmrg								 &mask_y[1],
1968428d7b3dSmrg								 &mask_w[1]))
1969428d7b3dSmrg				return;
1970428d7b3dSmrg
1971428d7b3dSmrg			if (!intel_uxa_get_transformed_coordinates_3d(maskX + w, maskY + h,
1972428d7b3dSmrg								 intel->transform[1],
1973428d7b3dSmrg								 &mask_x[2],
1974428d7b3dSmrg								 &mask_y[2],
1975428d7b3dSmrg								 &mask_w[2]))
1976428d7b3dSmrg				return;
1977428d7b3dSmrg		}
1978428d7b3dSmrg	}
1979428d7b3dSmrg
1980428d7b3dSmrg	OUT_VERTEX(dstX + w);
1981428d7b3dSmrg	OUT_VERTEX(dstY + h);
1982428d7b3dSmrg	OUT_VERTEX(src_x[2] * intel->scale_units[0][0]);
1983428d7b3dSmrg	OUT_VERTEX(src_y[2] * intel->scale_units[0][1]);
1984428d7b3dSmrg	if (!is_affine)
1985428d7b3dSmrg		OUT_VERTEX(src_w[2]);
1986428d7b3dSmrg	if (intel->render_mask) {
1987428d7b3dSmrg		OUT_VERTEX(mask_x[2] * intel->scale_units[1][0]);
1988428d7b3dSmrg		OUT_VERTEX(mask_y[2] * intel->scale_units[1][1]);
1989428d7b3dSmrg		if (!is_affine)
1990428d7b3dSmrg			OUT_VERTEX(mask_w[2]);
1991428d7b3dSmrg	}
1992428d7b3dSmrg
1993428d7b3dSmrg	OUT_VERTEX(dstX);
1994428d7b3dSmrg	OUT_VERTEX(dstY + h);
1995428d7b3dSmrg	OUT_VERTEX(src_x[1] * intel->scale_units[0][0]);
1996428d7b3dSmrg	OUT_VERTEX(src_y[1] * intel->scale_units[0][1]);
1997428d7b3dSmrg	if (!is_affine)
1998428d7b3dSmrg		OUT_VERTEX(src_w[1]);
1999428d7b3dSmrg	if (intel->render_mask) {
2000428d7b3dSmrg		OUT_VERTEX(mask_x[1] * intel->scale_units[1][0]);
2001428d7b3dSmrg		OUT_VERTEX(mask_y[1] * intel->scale_units[1][1]);
2002428d7b3dSmrg		if (!is_affine)
2003428d7b3dSmrg			OUT_VERTEX(mask_w[1]);
2004428d7b3dSmrg	}
2005428d7b3dSmrg
2006428d7b3dSmrg	OUT_VERTEX(dstX);
2007428d7b3dSmrg	OUT_VERTEX(dstY);
2008428d7b3dSmrg	OUT_VERTEX(src_x[0] * intel->scale_units[0][0]);
2009428d7b3dSmrg	OUT_VERTEX(src_y[0] * intel->scale_units[0][1]);
2010428d7b3dSmrg	if (!is_affine)
2011428d7b3dSmrg		OUT_VERTEX(src_w[0]);
2012428d7b3dSmrg	if (intel->render_mask) {
2013428d7b3dSmrg		OUT_VERTEX(mask_x[0] * intel->scale_units[1][0]);
2014428d7b3dSmrg		OUT_VERTEX(mask_y[0] * intel->scale_units[1][1]);
2015428d7b3dSmrg		if (!is_affine)
2016428d7b3dSmrg			OUT_VERTEX(mask_w[0]);
2017428d7b3dSmrg	}
2018428d7b3dSmrg}
2019428d7b3dSmrg
2020428d7b3dSmrgBool
2021428d7b3dSmrgi965_prepare_composite(int op, PicturePtr source_picture,
2022428d7b3dSmrg		       PicturePtr mask_picture, PicturePtr dest_picture,
2023428d7b3dSmrg		       PixmapPtr source, PixmapPtr mask, PixmapPtr dest)
2024428d7b3dSmrg{
2025428d7b3dSmrg	ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen);
2026428d7b3dSmrg	intel_screen_private *intel = intel_get_screen_private(scrn);
2027428d7b3dSmrg	struct gen4_render_state *render_state = intel->gen4_render_state;
2028428d7b3dSmrg	gen4_composite_op *composite_op = &render_state->composite_op;
2029428d7b3dSmrg
2030428d7b3dSmrg	composite_op->src_filter =
2031428d7b3dSmrg	    sampler_state_filter_from_picture(source_picture->filter);
2032428d7b3dSmrg	if (composite_op->src_filter == SS_INVALID_FILTER) {
2033428d7b3dSmrg		intel_uxa_debug_fallback(scrn, "Bad src filter 0x%x\n",
2034428d7b3dSmrg				     source_picture->filter);
2035428d7b3dSmrg		return FALSE;
2036428d7b3dSmrg	}
2037428d7b3dSmrg	composite_op->src_extend =
2038428d7b3dSmrg	    sampler_state_extend_from_picture(source_picture->repeatType);
2039428d7b3dSmrg	if (composite_op->src_extend == SS_INVALID_EXTEND) {
2040428d7b3dSmrg		intel_uxa_debug_fallback(scrn, "Bad src repeat 0x%x\n",
2041428d7b3dSmrg				     source_picture->repeatType);
2042428d7b3dSmrg		return FALSE;
2043428d7b3dSmrg	}
2044428d7b3dSmrg
2045428d7b3dSmrg	if (mask_picture) {
2046428d7b3dSmrg		if (mask_picture->componentAlpha &&
2047428d7b3dSmrg		    PICT_FORMAT_RGB(mask_picture->format)) {
2048428d7b3dSmrg			/* Check if it's component alpha that relies on a source alpha and on
2049428d7b3dSmrg			 * the source value.  We can only get one of those into the single
2050428d7b3dSmrg			 * source value that we get to blend with.
2051428d7b3dSmrg			 */
2052428d7b3dSmrg			if (i965_blend_op[op].src_alpha &&
2053428d7b3dSmrg			    (i965_blend_op[op].src_blend != BRW_BLENDFACTOR_ZERO)) {
2054428d7b3dSmrg				intel_uxa_debug_fallback(scrn,
2055428d7b3dSmrg						     "Component alpha not supported "
2056428d7b3dSmrg						     "with source alpha and source "
2057428d7b3dSmrg						     "value blending.\n");
2058428d7b3dSmrg				return FALSE;
2059428d7b3dSmrg			}
2060428d7b3dSmrg		}
2061428d7b3dSmrg
2062428d7b3dSmrg		composite_op->mask_filter =
2063428d7b3dSmrg		    sampler_state_filter_from_picture(mask_picture->filter);
2064428d7b3dSmrg		if (composite_op->mask_filter == SS_INVALID_FILTER) {
2065428d7b3dSmrg			intel_uxa_debug_fallback(scrn, "Bad mask filter 0x%x\n",
2066428d7b3dSmrg					     mask_picture->filter);
2067428d7b3dSmrg			return FALSE;
2068428d7b3dSmrg		}
2069428d7b3dSmrg		composite_op->mask_extend =
2070428d7b3dSmrg		    sampler_state_extend_from_picture(mask_picture->repeatType);
2071428d7b3dSmrg		if (composite_op->mask_extend == SS_INVALID_EXTEND) {
2072428d7b3dSmrg			intel_uxa_debug_fallback(scrn, "Bad mask repeat 0x%x\n",
2073428d7b3dSmrg					     mask_picture->repeatType);
2074428d7b3dSmrg			return FALSE;
2075428d7b3dSmrg		}
2076428d7b3dSmrg	} else {
2077428d7b3dSmrg		composite_op->mask_filter = SS_FILTER_NEAREST;
2078428d7b3dSmrg		composite_op->mask_extend = SS_EXTEND_NONE;
2079428d7b3dSmrg	}
2080428d7b3dSmrg
2081428d7b3dSmrg	/* Flush any pending writes prior to relocating the textures. */
2082428d7b3dSmrg	if (intel_uxa_pixmap_is_dirty(source) || intel_uxa_pixmap_is_dirty(mask))
2083428d7b3dSmrg		intel_batch_emit_flush(scrn);
2084428d7b3dSmrg
2085428d7b3dSmrg	composite_op->op = op;
2086428d7b3dSmrg	intel->render_source_picture = source_picture;
2087428d7b3dSmrg	intel->render_mask_picture = mask_picture;
2088428d7b3dSmrg	intel->render_dest_picture = dest_picture;
2089428d7b3dSmrg	intel->render_source = source;
2090428d7b3dSmrg	intel->render_mask = mask;
2091428d7b3dSmrg	intel->render_dest = dest;
2092428d7b3dSmrg
2093428d7b3dSmrg	intel->scale_units[0][0] = 1. / source->drawable.width;
2094428d7b3dSmrg	intel->scale_units[0][1] = 1. / source->drawable.height;
2095428d7b3dSmrg
2096428d7b3dSmrg	intel->transform[0] = source_picture->transform;
2097428d7b3dSmrg	composite_op->is_affine = intel_uxa_transform_is_affine(intel->transform[0]);
2098428d7b3dSmrg
2099428d7b3dSmrg	if (mask_picture == NULL) {
2100428d7b3dSmrg		intel->transform[1] = NULL;
2101428d7b3dSmrg		intel->scale_units[1][0] = -1;
2102428d7b3dSmrg		intel->scale_units[1][1] = -1;
2103428d7b3dSmrg	} else {
2104428d7b3dSmrg		assert(mask != NULL);
2105428d7b3dSmrg		intel->transform[1] = mask_picture->transform;
2106428d7b3dSmrg		intel->scale_units[1][0] = 1. / mask->drawable.width;
2107428d7b3dSmrg		intel->scale_units[1][1] = 1. / mask->drawable.height;
2108428d7b3dSmrg		composite_op->is_affine &=
2109428d7b3dSmrg		    intel_uxa_transform_is_affine(intel->transform[1]);
2110428d7b3dSmrg	}
2111428d7b3dSmrg
2112428d7b3dSmrg	if (mask) {
2113428d7b3dSmrg		assert(mask_picture != NULL);
2114428d7b3dSmrg		if (mask_picture->componentAlpha &&
2115428d7b3dSmrg		    PICT_FORMAT_RGB(mask_picture->format)) {
2116428d7b3dSmrg			if (i965_blend_op[op].src_alpha) {
2117428d7b3dSmrg				if (composite_op->is_affine)
2118428d7b3dSmrg					composite_op->wm_kernel =
2119428d7b3dSmrg					    WM_KERNEL_MASKCA_SRCALPHA_AFFINE;
2120428d7b3dSmrg				else
2121428d7b3dSmrg					composite_op->wm_kernel =
2122428d7b3dSmrg					    WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE;
2123428d7b3dSmrg			} else {
2124428d7b3dSmrg				if (composite_op->is_affine)
2125428d7b3dSmrg					composite_op->wm_kernel =
2126428d7b3dSmrg					    WM_KERNEL_MASKCA_AFFINE;
2127428d7b3dSmrg				else
2128428d7b3dSmrg					composite_op->wm_kernel =
2129428d7b3dSmrg					    WM_KERNEL_MASKCA_PROJECTIVE;
2130428d7b3dSmrg			}
2131428d7b3dSmrg		} else {
2132428d7b3dSmrg			if (composite_op->is_affine)
2133428d7b3dSmrg				composite_op->wm_kernel =
2134428d7b3dSmrg				    WM_KERNEL_MASKNOCA_AFFINE;
2135428d7b3dSmrg			else
2136428d7b3dSmrg				composite_op->wm_kernel =
2137428d7b3dSmrg				    WM_KERNEL_MASKNOCA_PROJECTIVE;
2138428d7b3dSmrg		}
2139428d7b3dSmrg	} else {
2140428d7b3dSmrg		if (composite_op->is_affine)
2141428d7b3dSmrg			composite_op->wm_kernel = WM_KERNEL_NOMASK_AFFINE;
2142428d7b3dSmrg		else
2143428d7b3dSmrg			composite_op->wm_kernel = WM_KERNEL_NOMASK_PROJECTIVE;
2144428d7b3dSmrg	}
2145428d7b3dSmrg
2146428d7b3dSmrg	intel->prim_emit = i965_emit_composite_primitive;
2147428d7b3dSmrg	if (!mask) {
2148428d7b3dSmrg		if (intel->transform[0] == NULL)
2149428d7b3dSmrg			intel->prim_emit = i965_emit_composite_primitive_identity_source;
2150428d7b3dSmrg		else if (composite_op->is_affine)
2151428d7b3dSmrg			intel->prim_emit = i965_emit_composite_primitive_affine_source;
2152428d7b3dSmrg	} else {
2153428d7b3dSmrg		if (intel->transform[0] == NULL && intel->transform[1] == NULL)
2154428d7b3dSmrg			intel->prim_emit = i965_emit_composite_primitive_identity_source_mask;
2155428d7b3dSmrg	}
2156428d7b3dSmrg
2157428d7b3dSmrg	intel->floats_per_vertex =
2158428d7b3dSmrg		2 + (mask ? 2 : 1) * (composite_op->is_affine ? 2: 3);
2159428d7b3dSmrg
2160428d7b3dSmrg	if (!i965_composite_check_aperture(intel)) {
2161428d7b3dSmrg		intel_batch_submit(scrn);
2162428d7b3dSmrg		if (!i965_composite_check_aperture(intel)) {
2163428d7b3dSmrg			intel_uxa_debug_fallback(scrn,
2164428d7b3dSmrg					     "Couldn't fit render operation "
2165428d7b3dSmrg					     "in aperture\n");
2166428d7b3dSmrg			return FALSE;
2167428d7b3dSmrg		}
2168428d7b3dSmrg	}
2169428d7b3dSmrg
2170428d7b3dSmrg	if (sizeof(intel->surface_data) - intel->surface_used <
2171428d7b3dSmrg	    4 * SURFACE_STATE_PADDED_SIZE)
2172428d7b3dSmrg		i965_surface_flush(intel);
2173428d7b3dSmrg
2174428d7b3dSmrg	intel->needs_render_state_emit = TRUE;
2175428d7b3dSmrg
2176428d7b3dSmrg	return TRUE;
2177428d7b3dSmrg}
2178428d7b3dSmrg
2179428d7b3dSmrgstatic void i965_select_vertex_buffer(struct intel_screen_private *intel)
2180428d7b3dSmrg{
2181428d7b3dSmrg	int id = intel->gen4_render_state->composite_op.vertex_id;
2182428d7b3dSmrg	int modifyenable = 0;
2183428d7b3dSmrg
2184428d7b3dSmrg	if (intel->vertex_id & (1 << id))
2185428d7b3dSmrg		return;
2186428d7b3dSmrg
2187428d7b3dSmrg	if (INTEL_INFO(intel)->gen >= 070)
2188428d7b3dSmrg		modifyenable = GEN7_VB0_ADDRESS_MODIFYENABLE;
2189428d7b3dSmrg
2190428d7b3dSmrg	/* Set up the pointer to our (single) vertex buffer */
2191428d7b3dSmrg	OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3);
2192428d7b3dSmrg
2193428d7b3dSmrg	/* XXX could use multiple vbo to reduce relocations if
2194428d7b3dSmrg	 * frequently switching between vertex sizes, like rgb10text.
2195428d7b3dSmrg	 */
2196428d7b3dSmrg	if (INTEL_INFO(intel)->gen >= 060) {
2197428d7b3dSmrg		OUT_BATCH((id << GEN6_VB0_BUFFER_INDEX_SHIFT) |
2198428d7b3dSmrg			  GEN6_VB0_VERTEXDATA |
2199428d7b3dSmrg			  modifyenable |
2200428d7b3dSmrg			  (4*intel->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT));
2201428d7b3dSmrg	} else {
2202428d7b3dSmrg		OUT_BATCH((id << VB0_BUFFER_INDEX_SHIFT) |
2203428d7b3dSmrg			  VB0_VERTEXDATA |
2204428d7b3dSmrg			  (4*intel->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT));
2205428d7b3dSmrg	}
2206428d7b3dSmrg	OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0);
2207428d7b3dSmrg	if (INTEL_INFO(intel)->gen >= 050)
2208428d7b3dSmrg		OUT_RELOC(intel->vertex_bo,
2209428d7b3dSmrg			  I915_GEM_DOMAIN_VERTEX, 0,
2210428d7b3dSmrg			  sizeof(intel->vertex_ptr) - 1);
2211428d7b3dSmrg	else
2212428d7b3dSmrg		OUT_BATCH(0);
2213428d7b3dSmrg	OUT_BATCH(0);		// ignore for VERTEXDATA, but still there
2214428d7b3dSmrg
2215428d7b3dSmrg	intel->vertex_id |= 1 << id;
2216428d7b3dSmrg}
2217428d7b3dSmrg
2218428d7b3dSmrgstatic void i965_bind_surfaces(struct intel_screen_private *intel)
2219428d7b3dSmrg{
2220428d7b3dSmrg	uint32_t *binding_table;
2221428d7b3dSmrg
2222428d7b3dSmrg	assert(intel->surface_used + 4 * SURFACE_STATE_PADDED_SIZE <= sizeof(intel->surface_data));
2223428d7b3dSmrg
2224428d7b3dSmrg	binding_table = (uint32_t*) (intel->surface_data + intel->surface_used);
2225428d7b3dSmrg	intel->surface_table = intel->surface_used;
2226428d7b3dSmrg	intel->surface_used += SURFACE_STATE_PADDED_SIZE;
2227428d7b3dSmrg
2228428d7b3dSmrg	binding_table[0] =
2229428d7b3dSmrg		i965_set_picture_surface_state(intel,
2230428d7b3dSmrg					       intel->render_dest_picture,
2231428d7b3dSmrg					       intel->render_dest,
2232428d7b3dSmrg					       TRUE);
2233428d7b3dSmrg	binding_table[1] =
2234428d7b3dSmrg		i965_set_picture_surface_state(intel,
2235428d7b3dSmrg					       intel->render_source_picture,
2236428d7b3dSmrg					       intel->render_source,
2237428d7b3dSmrg					       FALSE);
2238428d7b3dSmrg	if (intel->render_mask) {
2239428d7b3dSmrg		binding_table[2] =
2240428d7b3dSmrg			i965_set_picture_surface_state(intel,
2241428d7b3dSmrg						       intel->render_mask_picture,
2242428d7b3dSmrg						       intel->render_mask,
2243428d7b3dSmrg						       FALSE);
2244428d7b3dSmrg	}
2245428d7b3dSmrg}
2246428d7b3dSmrg
2247428d7b3dSmrgvoid
2248428d7b3dSmrgi965_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
2249428d7b3dSmrg	       int dstX, int dstY, int w, int h)
2250428d7b3dSmrg{
2251428d7b3dSmrg	ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen);
2252428d7b3dSmrg	intel_screen_private *intel = intel_get_screen_private(scrn);
2253428d7b3dSmrg
2254428d7b3dSmrg	intel_batch_start_atomic(scrn, 200);
2255428d7b3dSmrg	if (intel->needs_render_state_emit) {
2256428d7b3dSmrg		i965_bind_surfaces(intel);
2257428d7b3dSmrg
2258428d7b3dSmrg		if (INTEL_INFO(intel)->gen >= 060)
2259428d7b3dSmrg			gen6_emit_composite_state(intel);
2260428d7b3dSmrg		else
2261428d7b3dSmrg			i965_emit_composite_state(intel);
2262428d7b3dSmrg	}
2263428d7b3dSmrg
2264428d7b3dSmrg	if (intel->floats_per_vertex != intel->last_floats_per_vertex) {
2265428d7b3dSmrg		intel->vertex_index = (intel->vertex_used + intel->floats_per_vertex - 1) / intel->floats_per_vertex;
2266428d7b3dSmrg		intel->vertex_used = intel->vertex_index * intel->floats_per_vertex;
2267428d7b3dSmrg		intel->last_floats_per_vertex = intel->floats_per_vertex;
2268428d7b3dSmrg	}
2269428d7b3dSmrg	if (intel_vertex_space(intel) < 3*4*intel->floats_per_vertex) {
2270428d7b3dSmrg		i965_vertex_flush(intel);
2271428d7b3dSmrg		intel_next_vertex(intel);
2272428d7b3dSmrg		intel->vertex_index = 0;
2273428d7b3dSmrg	}
2274428d7b3dSmrg	i965_select_vertex_buffer(intel);
2275428d7b3dSmrg
2276428d7b3dSmrg	if (intel->vertex_offset == 0) {
2277428d7b3dSmrg		if (INTEL_INFO(intel)->gen >= 070) {
2278428d7b3dSmrg			OUT_BATCH(BRW_3DPRIMITIVE | (7 - 2));
2279428d7b3dSmrg			OUT_BATCH(BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
2280428d7b3dSmrg				  _3DPRIM_RECTLIST);
2281428d7b3dSmrg		} else {
2282428d7b3dSmrg			OUT_BATCH(BRW_3DPRIMITIVE |
2283428d7b3dSmrg				  BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
2284428d7b3dSmrg				  (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
2285428d7b3dSmrg				  (0 << 9) |
2286428d7b3dSmrg				  4);
2287428d7b3dSmrg		}
2288428d7b3dSmrg		intel->vertex_offset = intel->batch_used;
2289428d7b3dSmrg		OUT_BATCH(0);	/* vertex count, to be filled in later */
2290428d7b3dSmrg		OUT_BATCH(intel->vertex_index);
2291428d7b3dSmrg		OUT_BATCH(1);	/* single instance */
2292428d7b3dSmrg		OUT_BATCH(0);	/* start instance location */
2293428d7b3dSmrg		OUT_BATCH(0);	/* index buffer offset, ignored */
2294428d7b3dSmrg		intel->vertex_count = intel->vertex_index;
2295428d7b3dSmrg	}
2296428d7b3dSmrg
2297428d7b3dSmrg	intel->prim_emit(intel,
2298428d7b3dSmrg			 srcX, srcY,
2299428d7b3dSmrg			 maskX, maskY,
2300428d7b3dSmrg			 dstX, dstY,
2301428d7b3dSmrg			 w, h);
2302428d7b3dSmrg	intel->vertex_index += 3;
2303428d7b3dSmrg
2304428d7b3dSmrg	if (INTEL_INFO(intel)->gen < 050) {
2305428d7b3dSmrg	    /* XXX OMG! */
2306428d7b3dSmrg	    i965_vertex_flush(intel);
2307428d7b3dSmrg	    OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH);
2308428d7b3dSmrg	}
2309428d7b3dSmrg
2310428d7b3dSmrg	intel_batch_end_atomic(scrn);
2311428d7b3dSmrg}
2312428d7b3dSmrg
2313428d7b3dSmrgvoid i965_batch_commit_notify(intel_screen_private *intel)
2314428d7b3dSmrg{
2315428d7b3dSmrg	intel->needs_render_state_emit = TRUE;
2316428d7b3dSmrg	intel->needs_3d_invariant = TRUE;
2317428d7b3dSmrg	intel->last_floats_per_vertex = 0;
2318428d7b3dSmrg	intel->vertex_index = 0;
2319428d7b3dSmrg
2320428d7b3dSmrg	intel->gen4_render_state->composite_op.vertex_id = -1;
2321428d7b3dSmrg
2322428d7b3dSmrg	intel->gen6_render_state.num_sf_outputs = 0;
2323428d7b3dSmrg	intel->gen6_render_state.samplers = NULL;
2324428d7b3dSmrg	intel->gen6_render_state.blend = -1;
2325428d7b3dSmrg	intel->gen6_render_state.kernel = NULL;
2326428d7b3dSmrg	intel->gen6_render_state.drawrect = -1;
2327428d7b3dSmrg
2328428d7b3dSmrg	assert(intel->surface_reloc == 0);
2329428d7b3dSmrg}
2330428d7b3dSmrg
2331428d7b3dSmrg/**
2332428d7b3dSmrg * Called at EnterVT so we can set up our offsets into the state buffer.
2333428d7b3dSmrg */
2334428d7b3dSmrgvoid gen4_render_state_init(ScrnInfoPtr scrn)
2335428d7b3dSmrg{
2336428d7b3dSmrg	intel_screen_private *intel = intel_get_screen_private(scrn);
2337428d7b3dSmrg	struct gen4_render_state *render;
2338428d7b3dSmrg	const struct wm_kernel_info *wm_kernels;
2339428d7b3dSmrg	sampler_state_filter_t src_filter;
2340428d7b3dSmrg	sampler_state_extend_t src_extend;
2341428d7b3dSmrg	sampler_state_filter_t mask_filter;
2342428d7b3dSmrg	sampler_state_extend_t mask_extend;
2343428d7b3dSmrg	drm_intel_bo *sf_kernel_bo, *sf_kernel_mask_bo;
2344428d7b3dSmrg	drm_intel_bo *border_color_bo;
2345428d7b3dSmrg	int m;
2346428d7b3dSmrg
2347428d7b3dSmrg	intel->needs_3d_invariant = TRUE;
2348428d7b3dSmrg
2349428d7b3dSmrg	intel->surface_bo =
2350428d7b3dSmrg		drm_intel_bo_alloc(intel->bufmgr, "surface data",
2351428d7b3dSmrg				   sizeof(intel->surface_data), 4096);
2352428d7b3dSmrg	assert(intel->surface_bo);
2353428d7b3dSmrg
2354428d7b3dSmrg	intel->surface_used = 0;
2355428d7b3dSmrg
2356428d7b3dSmrg	if (intel->gen4_render_state == NULL) {
2357428d7b3dSmrg		intel->gen4_render_state = calloc(1, sizeof(*render));
2358428d7b3dSmrg		assert(intel->gen4_render_state != NULL);
2359428d7b3dSmrg	}
2360428d7b3dSmrg
2361428d7b3dSmrg	if (INTEL_INFO(intel)->gen >= 060)
2362428d7b3dSmrg		return gen6_render_state_init(scrn);
2363428d7b3dSmrg
2364428d7b3dSmrg	render = intel->gen4_render_state;
2365428d7b3dSmrg	render->composite_op.vertex_id = -1;
2366428d7b3dSmrg
2367428d7b3dSmrg	render->vs_state_bo = gen4_create_vs_unit_state(intel);
2368428d7b3dSmrg
2369428d7b3dSmrg	/* Set up the two SF states (one for blending with a mask, one without) */
2370428d7b3dSmrg	if (IS_GEN5(intel)) {
2371428d7b3dSmrg		sf_kernel_bo = intel_uxa_bo_alloc_for_data(intel,
2372428d7b3dSmrg						       sf_kernel_static_gen5,
2373428d7b3dSmrg						       sizeof
2374428d7b3dSmrg						       (sf_kernel_static_gen5),
2375428d7b3dSmrg						       "sf kernel gen5");
2376428d7b3dSmrg		sf_kernel_mask_bo =
2377428d7b3dSmrg		    intel_uxa_bo_alloc_for_data(intel, sf_kernel_mask_static_gen5,
2378428d7b3dSmrg					    sizeof(sf_kernel_mask_static_gen5),
2379428d7b3dSmrg					    "sf mask kernel");
2380428d7b3dSmrg	} else {
2381428d7b3dSmrg		sf_kernel_bo = intel_uxa_bo_alloc_for_data(intel,
2382428d7b3dSmrg						       sf_kernel_static,
2383428d7b3dSmrg						       sizeof(sf_kernel_static),
2384428d7b3dSmrg						       "sf kernel");
2385428d7b3dSmrg		sf_kernel_mask_bo = intel_uxa_bo_alloc_for_data(intel,
2386428d7b3dSmrg							    sf_kernel_mask_static,
2387428d7b3dSmrg							    sizeof
2388428d7b3dSmrg							    (sf_kernel_mask_static),
2389428d7b3dSmrg							    "sf mask kernel");
2390428d7b3dSmrg	}
2391428d7b3dSmrg	render->sf_state_bo = gen4_create_sf_state(intel, sf_kernel_bo);
2392428d7b3dSmrg	render->sf_mask_state_bo = gen4_create_sf_state(intel, sf_kernel_mask_bo);
2393428d7b3dSmrg	drm_intel_bo_unreference(sf_kernel_bo);
2394428d7b3dSmrg	drm_intel_bo_unreference(sf_kernel_mask_bo);
2395428d7b3dSmrg
2396428d7b3dSmrg	wm_kernels = IS_GEN5(intel) ? wm_kernels_gen5 : wm_kernels_gen4;
2397428d7b3dSmrg	for (m = 0; m < KERNEL_COUNT; m++) {
2398428d7b3dSmrg		render->wm_kernel_bo[m] =
2399428d7b3dSmrg			intel_uxa_bo_alloc_for_data(intel,
2400428d7b3dSmrg					wm_kernels[m].data,
2401428d7b3dSmrg					wm_kernels[m].size,
2402428d7b3dSmrg					"WM kernel");
2403428d7b3dSmrg	}
2404428d7b3dSmrg
2405428d7b3dSmrg	/* Set up the WM states: each filter/extend type for source and mask, per
2406428d7b3dSmrg	 * kernel.
2407428d7b3dSmrg	 */
2408428d7b3dSmrg	border_color_bo = sampler_border_color_create(intel);
2409428d7b3dSmrg	for (src_filter = 0; src_filter < FILTER_COUNT; src_filter++) {
2410428d7b3dSmrg		for (src_extend = 0; src_extend < EXTEND_COUNT; src_extend++) {
2411428d7b3dSmrg			for (mask_filter = 0; mask_filter < FILTER_COUNT; mask_filter++) {
2412428d7b3dSmrg				for (mask_extend = 0; mask_extend < EXTEND_COUNT; mask_extend++) {
2413428d7b3dSmrg					drm_intel_bo *sampler_state_bo;
2414428d7b3dSmrg
2415428d7b3dSmrg					sampler_state_bo =
2416428d7b3dSmrg					    i965_create_sampler_state(intel,
2417428d7b3dSmrg								      src_filter, src_extend,
2418428d7b3dSmrg								      mask_filter, mask_extend,
2419428d7b3dSmrg								      border_color_bo);
2420428d7b3dSmrg
2421428d7b3dSmrg					for (m = 0; m < KERNEL_COUNT; m++) {
2422428d7b3dSmrg						render->wm_state_bo[m][src_filter][src_extend][mask_filter][mask_extend] =
2423428d7b3dSmrg							gen4_create_wm_state
2424428d7b3dSmrg							(intel,
2425428d7b3dSmrg							 wm_kernels[m]. has_mask,
2426428d7b3dSmrg							 render->wm_kernel_bo[m],
2427428d7b3dSmrg							 sampler_state_bo);
2428428d7b3dSmrg					}
2429428d7b3dSmrg					drm_intel_bo_unreference(sampler_state_bo);
2430428d7b3dSmrg				}
2431428d7b3dSmrg			}
2432428d7b3dSmrg		}
2433428d7b3dSmrg	}
2434428d7b3dSmrg	drm_intel_bo_unreference(border_color_bo);
2435428d7b3dSmrg
2436428d7b3dSmrg	render->cc_state_bo = gen4_create_cc_unit_state(intel);
2437428d7b3dSmrg}
2438428d7b3dSmrg
2439428d7b3dSmrg/**
2440428d7b3dSmrg * Called at LeaveVT.
2441428d7b3dSmrg */
2442428d7b3dSmrgvoid gen4_render_state_cleanup(ScrnInfoPtr scrn)
2443428d7b3dSmrg{
2444428d7b3dSmrg	intel_screen_private *intel = intel_get_screen_private(scrn);
2445428d7b3dSmrg	struct gen4_render_state *render_state = intel->gen4_render_state;
2446428d7b3dSmrg	int i, j, k, l, m;
2447428d7b3dSmrg
2448428d7b3dSmrg	drm_intel_bo_unreference(intel->surface_bo);
2449428d7b3dSmrg	drm_intel_bo_unreference(render_state->vs_state_bo);
2450428d7b3dSmrg	drm_intel_bo_unreference(render_state->sf_state_bo);
2451428d7b3dSmrg	drm_intel_bo_unreference(render_state->sf_mask_state_bo);
2452428d7b3dSmrg
2453428d7b3dSmrg	for (i = 0; i < KERNEL_COUNT; i++)
2454428d7b3dSmrg		drm_intel_bo_unreference(render_state->wm_kernel_bo[i]);
2455428d7b3dSmrg
2456428d7b3dSmrg	for (i = 0; i < FILTER_COUNT; i++)
2457428d7b3dSmrg		for (j = 0; j < EXTEND_COUNT; j++)
2458428d7b3dSmrg			for (k = 0; k < FILTER_COUNT; k++)
2459428d7b3dSmrg				for (l = 0; l < EXTEND_COUNT; l++)
2460428d7b3dSmrg					for (m = 0; m < KERNEL_COUNT; m++)
2461428d7b3dSmrg						drm_intel_bo_unreference
2462428d7b3dSmrg						    (render_state->
2463428d7b3dSmrg						     wm_state_bo[m][i][j][k]
2464428d7b3dSmrg						     [l]);
2465428d7b3dSmrg
2466428d7b3dSmrg	for (i = 0; i < FILTER_COUNT; i++)
2467428d7b3dSmrg		for (j = 0; j < EXTEND_COUNT; j++)
2468428d7b3dSmrg			for (k = 0; k < FILTER_COUNT; k++)
2469428d7b3dSmrg				for (l = 0; l < EXTEND_COUNT; l++)
2470428d7b3dSmrg					drm_intel_bo_unreference(render_state->ps_sampler_state_bo[i][j][k][l]);
2471428d7b3dSmrg
2472428d7b3dSmrg	drm_intel_bo_unreference(render_state->cc_state_bo);
2473428d7b3dSmrg
2474428d7b3dSmrg	drm_intel_bo_unreference(render_state->cc_vp_bo);
2475428d7b3dSmrg	drm_intel_bo_unreference(render_state->gen6_blend_bo);
2476428d7b3dSmrg	drm_intel_bo_unreference(render_state->gen6_depth_stencil_bo);
2477428d7b3dSmrg
2478428d7b3dSmrg	free(intel->gen4_render_state);
2479428d7b3dSmrg	intel->gen4_render_state = NULL;
2480428d7b3dSmrg}
2481428d7b3dSmrg
2482428d7b3dSmrg/*
2483428d7b3dSmrg * for GEN6+
2484428d7b3dSmrg */
2485428d7b3dSmrg#define GEN6_BLEND_STATE_PADDED_SIZE	ALIGN(sizeof(struct gen6_blend_state), 64)
2486428d7b3dSmrg
2487428d7b3dSmrgstatic drm_intel_bo *
2488428d7b3dSmrggen6_composite_create_cc_state(intel_screen_private *intel)
2489428d7b3dSmrg{
2490428d7b3dSmrg	struct gen6_color_calc_state *state;
2491428d7b3dSmrg	drm_intel_bo *cc_bo;
2492428d7b3dSmrg	int ret;
2493428d7b3dSmrg
2494428d7b3dSmrg	cc_bo = drm_intel_bo_alloc(intel->bufmgr,
2495428d7b3dSmrg				"gen6 CC state",
2496428d7b3dSmrg				sizeof(*state),
2497428d7b3dSmrg				4096);
2498428d7b3dSmrg	assert(cc_bo);
2499428d7b3dSmrg
2500428d7b3dSmrg	ret = drm_intel_bo_map(cc_bo, TRUE);
2501428d7b3dSmrg	assert(ret == 0);
2502428d7b3dSmrg
2503428d7b3dSmrg	state = memset(cc_bo->virtual, 0, sizeof(*state));
2504428d7b3dSmrg	state->constant_r = 1.0;
2505428d7b3dSmrg	state->constant_g = 0.0;
2506428d7b3dSmrg	state->constant_b = 1.0;
2507428d7b3dSmrg	state->constant_a = 1.0;
2508428d7b3dSmrg	drm_intel_bo_unmap(cc_bo);
2509428d7b3dSmrg
2510428d7b3dSmrg	return cc_bo;
2511428d7b3dSmrg	(void)ret;
2512428d7b3dSmrg}
2513428d7b3dSmrg
2514428d7b3dSmrgstatic drm_intel_bo *
2515428d7b3dSmrggen6_composite_create_blend_state(intel_screen_private *intel)
2516428d7b3dSmrg{
2517428d7b3dSmrg	drm_intel_bo *blend_bo;
2518428d7b3dSmrg	int src, dst, ret;
2519428d7b3dSmrg
2520428d7b3dSmrg	blend_bo = drm_intel_bo_alloc(intel->bufmgr,
2521428d7b3dSmrg				"gen6 BLEND state",
2522428d7b3dSmrg				BRW_BLENDFACTOR_COUNT * BRW_BLENDFACTOR_COUNT * GEN6_BLEND_STATE_PADDED_SIZE,
2523428d7b3dSmrg				4096);
2524428d7b3dSmrg	assert(blend_bo);
2525428d7b3dSmrg
2526428d7b3dSmrg	ret = drm_intel_bo_map(blend_bo, TRUE);
2527428d7b3dSmrg	assert(ret == 0);
2528428d7b3dSmrg
2529428d7b3dSmrg	memset(blend_bo->virtual, 0, blend_bo->size);
2530428d7b3dSmrg	for (src = 0; src < BRW_BLENDFACTOR_COUNT; src++) {
2531428d7b3dSmrg		for (dst = 0; dst < BRW_BLENDFACTOR_COUNT; dst++) {
2532428d7b3dSmrg			uint32_t blend_state_offset = (src * BRW_BLENDFACTOR_COUNT + dst) * GEN6_BLEND_STATE_PADDED_SIZE;
2533428d7b3dSmrg			struct gen6_blend_state *blend;
2534428d7b3dSmrg
2535428d7b3dSmrg			blend = (struct gen6_blend_state *)((char *)blend_bo->virtual + blend_state_offset);
2536428d7b3dSmrg			blend->blend0.dest_blend_factor = dst;
2537428d7b3dSmrg			blend->blend0.source_blend_factor = src;
2538428d7b3dSmrg			blend->blend0.blend_func = BRW_BLENDFUNCTION_ADD;
2539428d7b3dSmrg			blend->blend0.blend_enable = 1;
2540428d7b3dSmrg
2541428d7b3dSmrg			blend->blend1.post_blend_clamp_enable = 1;
2542428d7b3dSmrg			blend->blend1.pre_blend_clamp_enable = 1;
2543428d7b3dSmrg		}
2544428d7b3dSmrg	}
2545428d7b3dSmrg
2546428d7b3dSmrg	drm_intel_bo_unmap(blend_bo);
2547428d7b3dSmrg	return blend_bo;
2548428d7b3dSmrg	(void)ret;
2549428d7b3dSmrg}
2550428d7b3dSmrg
2551428d7b3dSmrgstatic drm_intel_bo *
2552428d7b3dSmrggen6_composite_create_depth_stencil_state(intel_screen_private *intel)
2553428d7b3dSmrg{
2554428d7b3dSmrg	drm_intel_bo *depth_stencil_bo;
2555428d7b3dSmrg	int ret;
2556428d7b3dSmrg
2557428d7b3dSmrg	depth_stencil_bo =
2558428d7b3dSmrg		drm_intel_bo_alloc(intel->bufmgr,
2559428d7b3dSmrg				   "gen6 DEPTH_STENCIL state",
2560428d7b3dSmrg				   sizeof(struct gen6_depth_stencil_state),
2561428d7b3dSmrg				   4096);
2562428d7b3dSmrg	assert(depth_stencil_bo);
2563428d7b3dSmrg
2564428d7b3dSmrg	ret = drm_intel_bo_map(depth_stencil_bo, TRUE);
2565428d7b3dSmrg	assert(ret == 0);
2566428d7b3dSmrg
2567428d7b3dSmrg	memset(depth_stencil_bo->virtual, 0,
2568428d7b3dSmrg	       sizeof(struct gen6_depth_stencil_state));
2569428d7b3dSmrg	drm_intel_bo_unmap(depth_stencil_bo);
2570428d7b3dSmrg
2571428d7b3dSmrg	return depth_stencil_bo;
2572428d7b3dSmrg	(void)ret;
2573428d7b3dSmrg}
2574428d7b3dSmrg
2575428d7b3dSmrgstatic void
2576428d7b3dSmrggen6_composite_state_base_address(intel_screen_private *intel)
2577428d7b3dSmrg{
2578428d7b3dSmrg	OUT_BATCH(BRW_STATE_BASE_ADDRESS | (10 - 2));
2579428d7b3dSmrg	OUT_BATCH(BASE_ADDRESS_MODIFY); /* General state base address */
2580428d7b3dSmrg	intel->surface_reloc = intel->batch_used;
2581428d7b3dSmrg	intel_batch_emit_dword(intel,
2582428d7b3dSmrg			       intel->surface_bo->offset | BASE_ADDRESS_MODIFY);
2583428d7b3dSmrg	OUT_BATCH(BASE_ADDRESS_MODIFY); /* Dynamic state base address */
2584428d7b3dSmrg	OUT_BATCH(BASE_ADDRESS_MODIFY); /* Indirect object base address */
2585428d7b3dSmrg	OUT_BATCH(BASE_ADDRESS_MODIFY); /* Instruction base address */
2586428d7b3dSmrg	OUT_BATCH(BASE_ADDRESS_MODIFY); /* General state upper bound */
2587428d7b3dSmrg	OUT_BATCH(BASE_ADDRESS_MODIFY); /* Dynamic state upper bound */
2588428d7b3dSmrg	OUT_BATCH(BASE_ADDRESS_MODIFY); /* Indirect object upper bound */
2589428d7b3dSmrg	OUT_BATCH(BASE_ADDRESS_MODIFY); /* Instruction access upper bound */
2590428d7b3dSmrg}
2591428d7b3dSmrg
2592428d7b3dSmrgstatic void
2593428d7b3dSmrggen6_composite_cc_state_pointers(intel_screen_private *intel,
2594428d7b3dSmrg				 uint32_t blend_offset)
2595428d7b3dSmrg{
2596428d7b3dSmrg	struct gen4_render_state *render_state = intel->gen4_render_state;
2597428d7b3dSmrg	drm_intel_bo *cc_bo = NULL;
2598428d7b3dSmrg	drm_intel_bo *depth_stencil_bo = NULL;
2599428d7b3dSmrg
2600428d7b3dSmrg	if (intel->gen6_render_state.blend == blend_offset)
2601428d7b3dSmrg		return;
2602428d7b3dSmrg
2603428d7b3dSmrg	if (intel->gen6_render_state.blend == -1) {
2604428d7b3dSmrg		cc_bo = render_state->cc_state_bo;
2605428d7b3dSmrg		depth_stencil_bo = render_state->gen6_depth_stencil_bo;
2606428d7b3dSmrg	}
2607428d7b3dSmrg	if (INTEL_INFO(intel)->gen >= 070) {
2608428d7b3dSmrg		gen7_upload_cc_state_pointers(intel, render_state->gen6_blend_bo, cc_bo, depth_stencil_bo, blend_offset);
2609428d7b3dSmrg	} else {
2610428d7b3dSmrg		gen6_upload_cc_state_pointers(intel, render_state->gen6_blend_bo, cc_bo, depth_stencil_bo, blend_offset);
2611428d7b3dSmrg	}
2612428d7b3dSmrg
2613428d7b3dSmrg	intel->gen6_render_state.blend = blend_offset;
2614428d7b3dSmrg}
2615428d7b3dSmrg
2616428d7b3dSmrgstatic void
2617428d7b3dSmrggen6_composite_sampler_state_pointers(intel_screen_private *intel,
2618428d7b3dSmrg				      drm_intel_bo *bo)
2619428d7b3dSmrg{
2620428d7b3dSmrg	if (intel->gen6_render_state.samplers == bo)
2621428d7b3dSmrg		return;
2622428d7b3dSmrg
2623428d7b3dSmrg	intel->gen6_render_state.samplers = bo;
2624428d7b3dSmrg
2625428d7b3dSmrg	if (INTEL_INFO(intel)->gen >= 070)
2626428d7b3dSmrg		gen7_upload_sampler_state_pointers(intel, bo);
2627428d7b3dSmrg	else
2628428d7b3dSmrg		gen6_upload_sampler_state_pointers(intel, bo);
2629428d7b3dSmrg}
2630428d7b3dSmrg
2631428d7b3dSmrgstatic void
2632428d7b3dSmrggen6_composite_wm_constants(intel_screen_private *intel)
2633428d7b3dSmrg{
2634428d7b3dSmrg	Bool ivb = INTEL_INFO(intel)->gen >= 070;
2635428d7b3dSmrg	/* disable WM constant buffer */
2636428d7b3dSmrg	OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | ((ivb ? 7 : 5) - 2));
2637428d7b3dSmrg	OUT_BATCH(0);
2638428d7b3dSmrg	OUT_BATCH(0);
2639428d7b3dSmrg	OUT_BATCH(0);
2640428d7b3dSmrg	OUT_BATCH(0);
2641428d7b3dSmrg	if (ivb) {
2642428d7b3dSmrg		OUT_BATCH(0);
2643428d7b3dSmrg		OUT_BATCH(0);
2644428d7b3dSmrg	}
2645428d7b3dSmrg}
2646428d7b3dSmrg
2647428d7b3dSmrgstatic void
2648428d7b3dSmrggen6_composite_sf_state(intel_screen_private *intel,
2649428d7b3dSmrg			Bool has_mask)
2650428d7b3dSmrg{
2651428d7b3dSmrg	int num_sf_outputs = has_mask ? 2 : 1;
2652428d7b3dSmrg
2653428d7b3dSmrg	if (intel->gen6_render_state.num_sf_outputs == num_sf_outputs)
2654428d7b3dSmrg		return;
2655428d7b3dSmrg
2656428d7b3dSmrg	intel->gen6_render_state.num_sf_outputs = num_sf_outputs;
2657428d7b3dSmrg
2658428d7b3dSmrg	if (INTEL_INFO(intel)->gen >= 070)
2659428d7b3dSmrg		gen7_upload_sf_state(intel, num_sf_outputs, 1);
2660428d7b3dSmrg	else
2661428d7b3dSmrg		gen6_upload_sf_state(intel, num_sf_outputs, 1);
2662428d7b3dSmrg}
2663428d7b3dSmrg
2664428d7b3dSmrgstatic void
2665428d7b3dSmrggen6_composite_wm_state(intel_screen_private *intel,
2666428d7b3dSmrg			Bool has_mask,
2667428d7b3dSmrg			drm_intel_bo *bo)
2668428d7b3dSmrg{
2669428d7b3dSmrg	int num_surfaces = has_mask ? 3 : 2;
2670428d7b3dSmrg	int num_sf_outputs = has_mask ? 2 : 1;
2671428d7b3dSmrg
2672428d7b3dSmrg	if (intel->gen6_render_state.kernel == bo)
2673428d7b3dSmrg		return;
2674428d7b3dSmrg
2675428d7b3dSmrg	intel->gen6_render_state.kernel = bo;
2676428d7b3dSmrg
2677428d7b3dSmrg	OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2));
2678428d7b3dSmrg	OUT_RELOC(bo,
2679428d7b3dSmrg		I915_GEM_DOMAIN_INSTRUCTION, 0,
2680428d7b3dSmrg		0);
2681428d7b3dSmrg	OUT_BATCH((1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF) |
2682428d7b3dSmrg		  (num_surfaces << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT));
2683428d7b3dSmrg	OUT_BATCH(0);
2684428d7b3dSmrg	OUT_BATCH((6 << GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT)); /* DW4 */
2685428d7b3dSmrg	OUT_BATCH(((40 - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT) |
2686428d7b3dSmrg		  GEN6_3DSTATE_WM_DISPATCH_ENABLE |
2687428d7b3dSmrg		  GEN6_3DSTATE_WM_16_DISPATCH_ENABLE);
2688428d7b3dSmrg	OUT_BATCH((num_sf_outputs << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT) |
2689428d7b3dSmrg		  GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
2690428d7b3dSmrg	OUT_BATCH(0);
2691428d7b3dSmrg	OUT_BATCH(0);
2692428d7b3dSmrg}
2693428d7b3dSmrg
2694428d7b3dSmrgstatic void
2695428d7b3dSmrggen7_composite_wm_state(intel_screen_private *intel,
2696428d7b3dSmrg			Bool has_mask,
2697428d7b3dSmrg			drm_intel_bo *bo)
2698428d7b3dSmrg{
2699428d7b3dSmrg	int num_surfaces = has_mask ? 3 : 2;
2700428d7b3dSmrg	unsigned int max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_IVB;
2701428d7b3dSmrg	unsigned int num_samples = 0;
2702428d7b3dSmrg
2703428d7b3dSmrg	if (IS_HSW(intel)) {
2704428d7b3dSmrg		max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_HSW;
2705428d7b3dSmrg		num_samples = 1 << GEN7_PS_SAMPLE_MASK_SHIFT_HSW;
2706428d7b3dSmrg	}
2707428d7b3dSmrg
2708428d7b3dSmrg	if (intel->gen6_render_state.kernel == bo)
2709428d7b3dSmrg		return;
2710428d7b3dSmrg
2711428d7b3dSmrg	intel->gen6_render_state.kernel = bo;
2712428d7b3dSmrg
2713428d7b3dSmrg	OUT_BATCH(GEN6_3DSTATE_WM | (3 - 2));
2714428d7b3dSmrg	OUT_BATCH(GEN7_WM_DISPATCH_ENABLE |
2715428d7b3dSmrg		  GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
2716428d7b3dSmrg	OUT_BATCH(0);
2717428d7b3dSmrg
2718428d7b3dSmrg	OUT_BATCH(GEN7_3DSTATE_PS | (8 - 2));
2719428d7b3dSmrg	OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
2720428d7b3dSmrg	OUT_BATCH((1 << GEN7_PS_SAMPLER_COUNT_SHIFT) |
2721428d7b3dSmrg		  (num_surfaces << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
2722428d7b3dSmrg	OUT_BATCH(0); /* scratch space base offset */
2723428d7b3dSmrg	OUT_BATCH(((48 - 1) << max_threads_shift) | num_samples |
2724428d7b3dSmrg		  GEN7_PS_ATTRIBUTE_ENABLE |
2725428d7b3dSmrg		  GEN7_PS_16_DISPATCH_ENABLE);
2726428d7b3dSmrg	OUT_BATCH((6 << GEN7_PS_DISPATCH_START_GRF_SHIFT_0));
2727428d7b3dSmrg	OUT_BATCH(0); /* kernel 1 pointer */
2728428d7b3dSmrg	OUT_BATCH(0); /* kernel 2 pointer */
2729428d7b3dSmrg}
2730428d7b3dSmrg
2731428d7b3dSmrg
2732428d7b3dSmrgstatic void
2733428d7b3dSmrggen6_composite_drawing_rectangle(intel_screen_private *intel,
2734428d7b3dSmrg				 PixmapPtr dest)
2735428d7b3dSmrg{
2736428d7b3dSmrg	uint32_t dw =
2737428d7b3dSmrg		DRAW_YMAX(dest->drawable.height - 1) |
2738428d7b3dSmrg		DRAW_XMAX(dest->drawable.width - 1);
2739428d7b3dSmrg
2740428d7b3dSmrg	/* XXX cacomposite depends upon the implicit non-pipelined flush */
2741428d7b3dSmrg	if (0 && intel->gen6_render_state.drawrect == dw)
2742428d7b3dSmrg		return;
2743428d7b3dSmrg	intel->gen6_render_state.drawrect = dw;
2744428d7b3dSmrg
2745428d7b3dSmrg	OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
2746428d7b3dSmrg	OUT_BATCH(0x00000000);	/* ymin, xmin */
2747428d7b3dSmrg	OUT_BATCH(dw);	/* ymax, xmax */
2748428d7b3dSmrg	OUT_BATCH(0x00000000);	/* yorigin, xorigin */
2749428d7b3dSmrg}
2750428d7b3dSmrg
2751428d7b3dSmrgstatic void
2752428d7b3dSmrggen6_composite_vertex_element_state(intel_screen_private *intel,
2753428d7b3dSmrg				    Bool has_mask,
2754428d7b3dSmrg				    Bool is_affine)
2755428d7b3dSmrg{
2756428d7b3dSmrg	/*
2757428d7b3dSmrg	 * vertex data in vertex buffer
2758428d7b3dSmrg	 *    position: (x, y)
2759428d7b3dSmrg	 *    texture coordinate 0: (u0, v0) if (is_affine is TRUE) else (u0, v0, w0)
2760428d7b3dSmrg	 *    texture coordinate 1 if (has_mask is TRUE): same as above
2761428d7b3dSmrg	 */
2762428d7b3dSmrg	gen4_composite_op *composite_op = &intel->gen4_render_state->composite_op;
2763428d7b3dSmrg	int nelem = has_mask ? 2 : 1;
2764428d7b3dSmrg	int selem = is_affine ? 2 : 3;
2765428d7b3dSmrg	uint32_t w_component;
2766428d7b3dSmrg	uint32_t src_format;
2767428d7b3dSmrg	int id;
2768428d7b3dSmrg
2769428d7b3dSmrg	id = has_mask << 1 | is_affine;
2770428d7b3dSmrg
2771428d7b3dSmrg	if (composite_op->vertex_id == id)
2772428d7b3dSmrg		return;
2773428d7b3dSmrg
2774428d7b3dSmrg	composite_op->vertex_id = id;
2775428d7b3dSmrg
2776428d7b3dSmrg	if (is_affine) {
2777428d7b3dSmrg		src_format = BRW_SURFACEFORMAT_R32G32_FLOAT;
2778428d7b3dSmrg		w_component = BRW_VFCOMPONENT_STORE_1_FLT;
2779428d7b3dSmrg	} else {
2780428d7b3dSmrg		src_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT;
2781428d7b3dSmrg		w_component = BRW_VFCOMPONENT_STORE_SRC;
2782428d7b3dSmrg	}
2783428d7b3dSmrg
2784428d7b3dSmrg	/* The VUE layout
2785428d7b3dSmrg	 *    dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
2786428d7b3dSmrg	 *    dword 4-7: position (x, y, 1.0, 1.0),
2787428d7b3dSmrg	 *    dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0)
2788428d7b3dSmrg	 *    dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0)
2789428d7b3dSmrg	 *
2790428d7b3dSmrg	 * dword 4-15 are fetched from vertex buffer
2791428d7b3dSmrg	 */
2792428d7b3dSmrg	OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS |
2793428d7b3dSmrg		((2 * (2 + nelem)) + 1 - 2));
2794428d7b3dSmrg
2795428d7b3dSmrg	OUT_BATCH((id << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID |
2796428d7b3dSmrg		  (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
2797428d7b3dSmrg		  (0 << VE0_OFFSET_SHIFT));
2798428d7b3dSmrg	OUT_BATCH((BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) |
2799428d7b3dSmrg		  (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) |
2800428d7b3dSmrg		  (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) |
2801428d7b3dSmrg		  (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT));
2802428d7b3dSmrg
2803428d7b3dSmrg	/* x,y */
2804428d7b3dSmrg	OUT_BATCH((id << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID |
2805428d7b3dSmrg		  (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
2806428d7b3dSmrg		  (0 << VE0_OFFSET_SHIFT)); /* offsets vb in bytes */
2807428d7b3dSmrg	OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
2808428d7b3dSmrg		  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
2809428d7b3dSmrg		  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
2810428d7b3dSmrg		  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
2811428d7b3dSmrg
2812428d7b3dSmrg	/* u0, v0, w0 */
2813428d7b3dSmrg	OUT_BATCH((id << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID |
2814428d7b3dSmrg		  (src_format << VE0_FORMAT_SHIFT) |
2815428d7b3dSmrg		  ((2 * 4) << VE0_OFFSET_SHIFT));	/* offset vb in bytes */
2816428d7b3dSmrg	OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
2817428d7b3dSmrg		  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
2818428d7b3dSmrg		  (w_component << VE1_VFCOMPONENT_2_SHIFT) |
2819428d7b3dSmrg		  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
2820428d7b3dSmrg
2821428d7b3dSmrg	/* u1, v1, w1 */
2822428d7b3dSmrg	if (has_mask) {
2823428d7b3dSmrg		OUT_BATCH((id << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) |
2824428d7b3dSmrg			  GEN6_VE0_VALID |
2825428d7b3dSmrg			  (src_format << VE0_FORMAT_SHIFT) |
2826428d7b3dSmrg			  (((2 + selem) * 4) << VE0_OFFSET_SHIFT)); /* vb offset in bytes */
2827428d7b3dSmrg		OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
2828428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
2829428d7b3dSmrg			  (w_component << VE1_VFCOMPONENT_2_SHIFT) |
2830428d7b3dSmrg			  (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
2831428d7b3dSmrg	}
2832428d7b3dSmrg}
2833428d7b3dSmrg
2834428d7b3dSmrgstatic void
2835428d7b3dSmrggen6_emit_composite_state(struct intel_screen_private *intel)
2836428d7b3dSmrg{
2837428d7b3dSmrg	struct gen4_render_state *render = intel->gen4_render_state;
2838428d7b3dSmrg	gen4_composite_op *composite_op = &render->composite_op;
2839428d7b3dSmrg	sampler_state_filter_t src_filter = composite_op->src_filter;
2840428d7b3dSmrg	sampler_state_filter_t mask_filter = composite_op->mask_filter;
2841428d7b3dSmrg	sampler_state_extend_t src_extend = composite_op->src_extend;
2842428d7b3dSmrg	sampler_state_extend_t mask_extend = composite_op->mask_extend;
2843428d7b3dSmrg	Bool is_affine = composite_op->is_affine;
2844428d7b3dSmrg	Bool has_mask = intel->render_mask != NULL;
2845428d7b3dSmrg	Bool ivb = INTEL_INFO(intel)->gen >= 070;
2846428d7b3dSmrg	uint32_t src, dst;
2847428d7b3dSmrg	drm_intel_bo *ps_sampler_state_bo = render->ps_sampler_state_bo[src_filter][src_extend][mask_filter][mask_extend];
2848428d7b3dSmrg
2849428d7b3dSmrg	intel->needs_render_state_emit = FALSE;
2850428d7b3dSmrg	if (intel->needs_3d_invariant) {
2851428d7b3dSmrg		gen6_upload_invariant_states(intel);
2852428d7b3dSmrg
2853428d7b3dSmrg		if (ivb) {
2854428d7b3dSmrg			gen7_upload_viewport_state_pointers(intel, render->cc_vp_bo);
2855428d7b3dSmrg			gen7_upload_urb(intel);
2856428d7b3dSmrg			gen7_upload_bypass_states(intel);
2857428d7b3dSmrg			gen7_upload_depth_buffer_state(intel);
2858428d7b3dSmrg		} else {
2859428d7b3dSmrg			gen6_upload_invariant_states(intel);
2860428d7b3dSmrg			gen6_upload_viewport_state_pointers(intel, render->cc_vp_bo);
2861428d7b3dSmrg			gen6_upload_urb(intel);
2862428d7b3dSmrg
2863428d7b3dSmrg			gen6_upload_gs_state(intel);
2864428d7b3dSmrg			gen6_upload_depth_buffer_state(intel);
2865428d7b3dSmrg		}
2866428d7b3dSmrg		gen6_composite_wm_constants(intel);
2867428d7b3dSmrg		gen6_upload_vs_state(intel);
2868428d7b3dSmrg		gen6_upload_clip_state(intel);
2869428d7b3dSmrg
2870428d7b3dSmrg		intel->needs_3d_invariant = FALSE;
2871428d7b3dSmrg	}
2872428d7b3dSmrg
2873428d7b3dSmrg	i965_get_blend_cntl(composite_op->op,
2874428d7b3dSmrg			    intel->render_mask_picture,
2875428d7b3dSmrg			    intel->render_dest_picture->format,
2876428d7b3dSmrg			    &src, &dst);
2877428d7b3dSmrg
2878428d7b3dSmrg	if (intel->surface_reloc == 0)
2879428d7b3dSmrg		gen6_composite_state_base_address(intel);
2880428d7b3dSmrg
2881428d7b3dSmrg	gen6_composite_cc_state_pointers(intel,
2882428d7b3dSmrg					(src * BRW_BLENDFACTOR_COUNT + dst) * GEN6_BLEND_STATE_PADDED_SIZE);
2883428d7b3dSmrg	gen6_composite_sampler_state_pointers(intel, ps_sampler_state_bo);
2884428d7b3dSmrg	gen6_composite_sf_state(intel, has_mask);
2885428d7b3dSmrg	if (ivb) {
2886428d7b3dSmrg		gen7_composite_wm_state(intel, has_mask,
2887428d7b3dSmrg					render->wm_kernel_bo[composite_op->wm_kernel]);
2888428d7b3dSmrg		gen7_upload_binding_table(intel, intel->surface_table);
2889428d7b3dSmrg	} else {
2890428d7b3dSmrg		gen6_composite_wm_state(intel, has_mask,
2891428d7b3dSmrg					render->wm_kernel_bo[composite_op->wm_kernel]);
2892428d7b3dSmrg		gen6_upload_binding_table(intel, intel->surface_table);
2893428d7b3dSmrg	}
2894428d7b3dSmrg	gen6_composite_drawing_rectangle(intel, intel->render_dest);
2895428d7b3dSmrg	gen6_composite_vertex_element_state(intel, has_mask, is_affine);
2896428d7b3dSmrg}
2897428d7b3dSmrg
2898428d7b3dSmrgstatic void
2899428d7b3dSmrggen6_render_state_init(ScrnInfoPtr scrn)
2900428d7b3dSmrg{
2901428d7b3dSmrg	intel_screen_private *intel = intel_get_screen_private(scrn);
2902428d7b3dSmrg	struct gen4_render_state *render;
2903428d7b3dSmrg	sampler_state_filter_t src_filter;
2904428d7b3dSmrg	sampler_state_filter_t mask_filter;
2905428d7b3dSmrg	sampler_state_extend_t src_extend;
2906428d7b3dSmrg	sampler_state_extend_t mask_extend;
2907428d7b3dSmrg	int m;
2908428d7b3dSmrg	drm_intel_bo *border_color_bo;
2909428d7b3dSmrg	const struct wm_kernel_info *wm_kernels;
2910428d7b3dSmrg
2911428d7b3dSmrg	render= intel->gen4_render_state;
2912428d7b3dSmrg	render->composite_op.vertex_id = -1;
2913428d7b3dSmrg
2914428d7b3dSmrg	intel->gen6_render_state.num_sf_outputs = 0;
2915428d7b3dSmrg	intel->gen6_render_state.samplers = NULL;
2916428d7b3dSmrg	intel->gen6_render_state.blend = -1;
2917428d7b3dSmrg	intel->gen6_render_state.kernel = NULL;
2918428d7b3dSmrg	intel->gen6_render_state.drawrect = -1;
2919428d7b3dSmrg
2920428d7b3dSmrg	wm_kernels = IS_GEN7(intel) ? wm_kernels_gen7 : wm_kernels_gen6;
2921428d7b3dSmrg	for (m = 0; m < KERNEL_COUNT; m++) {
2922428d7b3dSmrg		render->wm_kernel_bo[m] =
2923428d7b3dSmrg			intel_uxa_bo_alloc_for_data(intel,
2924428d7b3dSmrg					wm_kernels[m].data,
2925428d7b3dSmrg					wm_kernels[m].size,
2926428d7b3dSmrg					"WM kernel gen6/7");
2927428d7b3dSmrg	}
2928428d7b3dSmrg
2929428d7b3dSmrg	border_color_bo = sampler_border_color_create(intel);
2930428d7b3dSmrg
2931428d7b3dSmrg	for (src_filter = 0; src_filter < FILTER_COUNT; src_filter++) {
2932428d7b3dSmrg		for (src_extend = 0; src_extend < EXTEND_COUNT; src_extend++) {
2933428d7b3dSmrg			for (mask_filter = 0; mask_filter < FILTER_COUNT; mask_filter++) {
2934428d7b3dSmrg				for (mask_extend = 0; mask_extend < EXTEND_COUNT; mask_extend++) {
2935428d7b3dSmrg					render->ps_sampler_state_bo[src_filter][src_extend][mask_filter][mask_extend] =
2936428d7b3dSmrg						i965_create_sampler_state(intel,
2937428d7b3dSmrg									  src_filter, src_extend,
2938428d7b3dSmrg									  mask_filter, mask_extend,
2939428d7b3dSmrg								border_color_bo);
2940428d7b3dSmrg				}
2941428d7b3dSmrg			}
2942428d7b3dSmrg		}
2943428d7b3dSmrg	}
2944428d7b3dSmrg
2945428d7b3dSmrg	drm_intel_bo_unreference(border_color_bo);
2946428d7b3dSmrg	render->cc_vp_bo = gen4_create_cc_viewport(intel);
2947428d7b3dSmrg	render->cc_state_bo = gen6_composite_create_cc_state(intel);
2948428d7b3dSmrg	render->gen6_blend_bo = gen6_composite_create_blend_state(intel);
2949428d7b3dSmrg	render->gen6_depth_stencil_bo = gen6_composite_create_depth_stencil_state(intel);
2950428d7b3dSmrg}
2951428d7b3dSmrg
2952428d7b3dSmrgvoid i965_vertex_flush(struct intel_screen_private *intel)
2953428d7b3dSmrg{
2954428d7b3dSmrg	if (intel->vertex_offset) {
2955428d7b3dSmrg		intel->batch_ptr[intel->vertex_offset] =
2956428d7b3dSmrg			intel->vertex_index - intel->vertex_count;
2957428d7b3dSmrg		intel->vertex_offset = 0;
2958428d7b3dSmrg	}
2959428d7b3dSmrg}
2960428d7b3dSmrg
2961428d7b3dSmrgvoid i965_batch_flush(struct intel_screen_private *intel)
2962428d7b3dSmrg{
2963428d7b3dSmrg	if (intel->surface_used)
2964428d7b3dSmrg		i965_surface_flush(intel);
2965428d7b3dSmrg}
2966