r600_blit.c revision 7c1fcc41be15b6d648f84c8c1870a3a00575a48f
1/*
2 * Copyright 2009 Marek Olšák <maraeo@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 *      Jerome Glisse
25 *      Marek Olšák
26 */
27#include <errno.h>
28#include <pipe/p_screen.h>
29#include <util/u_blitter.h>
30#include <util/u_inlines.h>
31#include <util/u_memory.h>
32#include "util/u_surface.h"
33#include "r600_screen.h"
34#include "r600_context.h"
35#include "r600d.h"
36
37static void r600_blitter_save_states(struct pipe_context *ctx)
38{
39	struct r600_context *rctx = r600_context(ctx);
40
41	util_blitter_save_blend(rctx->blitter, rctx->blend);
42	util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa);
43	if (rctx->stencil_ref) {
44		util_blitter_save_stencil_ref(rctx->blitter,
45					&rctx->stencil_ref->state.stencil_ref);
46	}
47	util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer);
48	util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader);
49	util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
50	util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements);
51	if (rctx->viewport) {
52		util_blitter_save_viewport(rctx->blitter, &rctx->viewport->state.viewport);
53	}
54	if (rctx->clip) {
55		util_blitter_save_clip(rctx->blitter, &rctx->clip->state.clip);
56	}
57	util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffer,
58					rctx->vertex_buffer);
59
60	/* remove ptr so they don't get deleted */
61	rctx->blend = NULL;
62	rctx->clip = NULL;
63	rctx->vs_shader = NULL;
64	rctx->ps_shader = NULL;
65	rctx->rasterizer = NULL;
66	rctx->dsa = NULL;
67	rctx->vertex_elements = NULL;
68
69	/* suspend queries */
70	r600_queries_suspend(ctx);
71}
72
73static void r600_clear(struct pipe_context *ctx, unsigned buffers,
74			const float *rgba, double depth, unsigned stencil)
75{
76	struct r600_context *rctx = r600_context(ctx);
77	struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
78
79	r600_blitter_save_states(ctx);
80	util_blitter_clear(rctx->blitter, fb->width, fb->height,
81				fb->nr_cbufs, buffers, rgba, depth,
82				stencil);
83	/* resume queries */
84	r600_queries_resume(ctx);
85}
86
87static void r600_clear_render_target(struct pipe_context *ctx,
88				     struct pipe_surface *dst,
89				     const float *rgba,
90				     unsigned dstx, unsigned dsty,
91				     unsigned width, unsigned height)
92{
93	struct r600_context *rctx = r600_context(ctx);
94	struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
95
96	r600_blitter_save_states(ctx);
97	util_blitter_save_framebuffer(rctx->blitter, fb);
98
99	util_blitter_clear_render_target(rctx->blitter, dst, rgba,
100					 dstx, dsty, width, height);
101	/* resume queries */
102	r600_queries_resume(ctx);
103}
104
105static void r600_clear_depth_stencil(struct pipe_context *ctx,
106				     struct pipe_surface *dst,
107				     unsigned clear_flags,
108				     double depth,
109				     unsigned stencil,
110				     unsigned dstx, unsigned dsty,
111				     unsigned width, unsigned height)
112{
113	struct r600_context *rctx = r600_context(ctx);
114	struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
115
116	r600_blitter_save_states(ctx);
117	util_blitter_save_framebuffer(rctx->blitter, fb);
118
119	util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil,
120					 dstx, dsty, width, height);
121	/* resume queries */
122	r600_queries_resume(ctx);
123}
124
125
126static void r600_resource_copy_region(struct pipe_context *ctx,
127				      struct pipe_resource *dst,
128				      struct pipe_subresource subdst,
129				      unsigned dstx, unsigned dsty, unsigned dstz,
130				      struct pipe_resource *src,
131				      struct pipe_subresource subsrc,
132				      unsigned srcx, unsigned srcy, unsigned srcz,
133				      unsigned width, unsigned height)
134{
135	util_resource_copy_region(ctx, dst, subdst, dstx, dsty, dstz,
136				  src, subsrc, srcx, srcy, srcz, width, height);
137}
138
139void r600_init_blit_functions(struct r600_context *rctx)
140{
141	rctx->context.clear = r600_clear;
142	rctx->context.clear_render_target = r600_clear_render_target;
143	rctx->context.clear_depth_stencil = r600_clear_depth_stencil;
144	rctx->context.resource_copy_region = r600_resource_copy_region;
145}
146
147
148struct r600_blit_states {
149	struct radeon_state	rasterizer;
150	struct radeon_state	dsa;
151	struct radeon_state	blend;
152	struct radeon_state	cb_cntl;
153	struct radeon_state	vgt;
154	struct radeon_state	draw;
155	struct radeon_state	vs_constant0;
156	struct radeon_state	vs_constant1;
157	struct radeon_state	vs_constant2;
158	struct radeon_state	vs_constant3;
159	struct radeon_state	ps_shader;
160	struct radeon_state	vs_shader;
161	struct radeon_state	vs_resource0;
162	struct radeon_state	vs_resource1;
163};
164
165static int r600_blit_state_vs_resources(struct r600_screen *rscreen, struct r600_blit_states *bstates)
166{
167	struct radeon_state *rstate;
168	struct radeon_ws_bo *bo;
169	void *data;
170	u32 vbo[] = {
171		0xBF800000, 0xBF800000, 0x3F800000, 0x3F800000,
172		0x3F000000, 0x3F000000, 0x3F000000, 0x00000000,
173		0x3F800000, 0xBF800000, 0x3F800000, 0x3F800000,
174		0x3F000000, 0x3F000000, 0x3F000000, 0x00000000,
175		0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000,
176		0x3F000000, 0x3F000000, 0x3F000000, 0x00000000,
177		0xBF800000, 0x3F800000, 0x3F800000, 0x3F800000,
178		0x3F000000, 0x3F000000, 0x3F000000, 0x00000000
179	};
180
181	/* simple shader */
182	bo = radeon_ws_bo(rscreen->rw, 128, 4096, 0);
183	if (bo == NULL) {
184		return -ENOMEM;
185	}
186	data = radeon_ws_bo_map(rscreen->rw, bo, 0, NULL);
187	if (!data) {
188		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
189		return -ENOMEM;
190	}
191	memcpy(data, vbo, 128);
192	radeon_ws_bo_unmap(rscreen->rw, bo);
193
194	rstate = &bstates->vs_resource0;
195	radeon_state_init(rstate, rscreen->rw, R600_STATE_RESOURCE, 0, R600_SHADER_VS);
196
197	/* set states (most default value are 0 and struct already
198	 * initialized to 0, thus avoid resetting them)
199	 */
200	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD0] = 0x00000000;
201	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD1] = 0x00000080;
202	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD2] = 0x02302000;
203	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD3] = 0x00000000;
204	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD4] = 0x00000000;
205	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD5] = 0x00000000;
206	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD6] = 0xC0000000;
207	rstate->bo[0] = bo;
208	rstate->nbo = 1;
209	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
210	if (radeon_state_pm4(rstate)) {
211		radeon_state_fini(rstate);
212		return -ENOMEM;
213	}
214
215	rstate = &bstates->vs_resource1;
216	radeon_state_init(rstate, rscreen->rw, R600_STATE_RESOURCE, 1, R600_SHADER_VS);
217	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD0] = 0x00000010;
218	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD1] = 0x00000070;
219	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD2] = 0x02302000;
220	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD3] = 0x00000000;
221	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD4] = 0x00000000;
222	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD5] = 0x00000000;
223	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD6] = 0xC0000000;
224	radeon_ws_bo_reference(rscreen->rw, &rstate->bo[0], bo);
225	rstate->nbo = 1;
226	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
227	if (radeon_state_pm4(rstate)) {
228		radeon_state_fini(rstate);
229		return -ENOMEM;
230	}
231
232	return 0;
233}
234
235static void r600_blit_state_vs_shader(struct r600_screen *rscreen, struct radeon_state *rstate)
236{
237	struct radeon_ws_bo *bo;
238	void *data;
239	u32 shader_bc_r600[] = {
240		0x00000004, 0x81000400,
241		0x00000008, 0xA01C0000,
242		0xC001A03C, 0x94000688,
243		0xC0024000, 0x94200688,
244		0x7C000000, 0x002D1001,
245		0x00080000, 0x00000000,
246		0x7C000100, 0x002D1002,
247		0x00080000, 0x00000000,
248		0x00000001, 0x00601910,
249		0x00000401, 0x20601910,
250		0x00000801, 0x40601910,
251		0x80000C01, 0x60601910,
252		0x00000002, 0x00801910,
253		0x00000402, 0x20801910,
254		0x00000802, 0x40801910,
255		0x80000C02, 0x60801910
256	};
257	u32 shader_bc_r700[] = {
258		0x00000004, 0x81000400,
259		0x00000008, 0xA01C0000,
260		0xC001A03C, 0x94000688,
261		0xC0024000, 0x94200688,
262		0x7C000000, 0x002D1001,
263		0x00080000, 0x00000000,
264		0x7C000100, 0x002D1002,
265		0x00080000, 0x00000000,
266		0x00000001, 0x00600C90,
267		0x00000401, 0x20600C90,
268		0x00000801, 0x40600C90,
269		0x80000C01, 0x60600C90,
270		0x00000002, 0x00800C90,
271		0x00000402, 0x20800C90,
272		0x00000802, 0x40800C90,
273		0x80000C02, 0x60800C90
274	};
275
276	/* simple shader */
277	bo = radeon_ws_bo(rscreen->rw, 128, 4096, 0);
278	if (bo == NULL) {
279		return;
280	}
281	data = radeon_ws_bo_map(rscreen->rw, bo, 0, NULL);
282	if (!data) {
283		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
284		return;
285	}
286	switch (rscreen->chip_class) {
287	case R600:
288		memcpy(data, shader_bc_r600, 128);
289		break;
290	case R700:
291		memcpy(data, shader_bc_r700, 128);
292		break;
293	default:
294		R600_ERR("unsupported chip family\n");
295		radeon_ws_bo_unmap(rscreen->rw, bo);
296		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
297		return;
298	}
299	radeon_ws_bo_unmap(rscreen->rw, bo);
300
301	radeon_state_init(rstate, rscreen->rw, R600_STATE_SHADER, 0, R600_SHADER_VS);
302
303	/* set states (most default value are 0 and struct already
304	 * initialized to 0, thus avoid resetting them)
305	 */
306	rstate->states[R600_VS_SHADER__SPI_VS_OUT_ID_0] = 0x03020100;
307	rstate->states[R600_VS_SHADER__SPI_VS_OUT_ID_1] = 0x07060504;
308	rstate->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = 0x00000005;
309
310	rstate->bo[0] = bo;
311	radeon_ws_bo_reference(rscreen->rw, &rstate->bo[1], bo);
312	rstate->nbo = 2;
313	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
314	rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
315
316	radeon_state_pm4(rstate);
317}
318
319static void r600_blit_state_ps_shader(struct r600_screen *rscreen, struct radeon_state *rstate)
320{
321	struct radeon_ws_bo *bo;
322	void *data;
323	u32 shader_bc_r600[] = {
324		0x00000002, 0xA00C0000,
325		0xC0008000, 0x94200688,
326		0x00000000, 0x00201910,
327		0x00000400, 0x20201910,
328		0x00000800, 0x40201910,
329		0x80000C00, 0x60201910
330	};
331	u32 shader_bc_r700[] = {
332		0x00000002, 0xA00C0000,
333		0xC0008000, 0x94200688,
334		0x00000000, 0x00200C90,
335		0x00000400, 0x20200C90,
336		0x00000800, 0x40200C90,
337		0x80000C00, 0x60200C90
338	};
339
340	/* simple shader */
341	bo = radeon_ws_bo(rscreen->rw, 128, 4096, 0);
342	if (bo == NULL) {
343		return;
344	}
345	data = radeon_ws_bo_map(rscreen->rw, bo, 0, NULL);
346	if (!data) {
347		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
348		return;
349	}
350	switch (rscreen->chip_class) {
351	case R600:
352		memcpy(data, shader_bc_r600, 48);
353		break;
354	case R700:
355		memcpy(data, shader_bc_r700, 48);
356		break;
357	default:
358		R600_ERR("unsupported chip family\n");
359		radeon_ws_bo_unmap(rscreen->rw, bo);
360		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
361		return;
362	}
363	radeon_ws_bo_unmap(rscreen->rw, bo);
364
365	radeon_state_init(rstate, rscreen->rw, R600_STATE_SHADER, 0, R600_SHADER_PS);
366
367	/* set states (most default value are 0 and struct already
368	 * initialized to 0, thus avoid resetting them)
369	 */
370	rstate->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0] = 0x00000C00;
371	rstate->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = 0x10000001;
372	rstate->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
373	rstate->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = 0x00000002;
374
375	rstate->bo[0] = bo;
376	rstate->nbo = 1;
377	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
378
379	radeon_state_pm4(rstate);
380}
381
382static void r600_blit_state_vgt(struct r600_screen *rscreen, struct radeon_state *rstate)
383{
384	radeon_state_init(rstate, rscreen->rw, R600_STATE_VGT, 0, 0);
385
386	/* set states (most default value are 0 and struct already
387	 * initialized to 0, thus avoid resetting them)
388	 */
389	rstate->states[R600_VGT__VGT_DMA_NUM_INSTANCES] = 0x00000001;
390	rstate->states[R600_VGT__VGT_MAX_VTX_INDX] = 0x00FFFFFF;
391	rstate->states[R600_VGT__VGT_PRIMITIVE_TYPE] = 0x00000005;
392
393	radeon_state_pm4(rstate);
394}
395
396static void r600_blit_state_draw(struct r600_screen *rscreen, struct radeon_state *rstate)
397{
398	radeon_state_init(rstate, rscreen->rw, R600_STATE_DRAW, 0, 0);
399
400	/* set states (most default value are 0 and struct already
401	 * initialized to 0, thus avoid resetting them)
402	 */
403	rstate->states[R600_DRAW__VGT_DRAW_INITIATOR] = 0x00000002;
404	rstate->states[R600_DRAW__VGT_NUM_INDICES] = 0x00000004;
405
406	radeon_state_pm4(rstate);
407}
408
409static void r600_blit_state_vs_constant(struct r600_screen *rscreen, struct radeon_state *rstate,
410					unsigned id, float c0, float c1, float c2, float c3)
411{
412	radeon_state_init(rstate, rscreen->rw, R600_STATE_CONSTANT, id, R600_SHADER_VS);
413
414	/* set states (most default value are 0 and struct already
415	 * initialized to 0, thus avoid resetting them)
416	 */
417	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT0_256] = fui(c0);
418	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT1_256] = fui(c1);
419	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT2_256] = fui(c2);
420	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT3_256] = fui(c3);
421
422	radeon_state_pm4(rstate);
423}
424
425static void r600_blit_state_rasterizer(struct r600_screen *rscreen, struct radeon_state *rstate)
426{
427	radeon_state_init(rstate, rscreen->rw, R600_STATE_RASTERIZER, 0, 0);
428
429	/* set states (most default value are 0 and struct already
430	 * initialized to 0, thus avoid resetting them)
431	 */
432	rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ] = 0x3F800000;
433	rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000;
434	rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_CLIP_ADJ] = 0x3F800000;
435	rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000;
436	rstate->states[R600_RASTERIZER__PA_SC_LINE_CNTL] = 0x00000400;
437	rstate->states[R600_RASTERIZER__PA_SC_LINE_STIPPLE] = 0x00000005;
438	rstate->states[R600_RASTERIZER__PA_SU_LINE_CNTL] = 0x00000008;
439	rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x80000000;
440	rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080004;
441	rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001;
442
443	radeon_state_pm4(rstate);
444}
445
446static void r600_blit_state_dsa(struct r600_screen *rscreen, struct radeon_state *rstate)
447{
448	radeon_state_init(rstate, rscreen->rw, R600_STATE_DSA, 0, 0);
449
450	/* set states (most default value are 0 and struct already
451	 * initialized to 0, thus avoid resetting them)
452	 */
453	rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00;
454	rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
455	rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060;
456	rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A;
457	rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210;
458
459	radeon_state_pm4(rstate);
460}
461
462static void r600_blit_state_blend(struct r600_screen *rscreen, struct radeon_state *rstate)
463{
464	radeon_state_init(rstate, rscreen->rw, R600_STATE_BLEND, 0, 0);
465	radeon_state_pm4(rstate);
466}
467
468static void r600_blit_state_cb_cntl(struct r600_screen *rscreen, struct radeon_state *rstate)
469{
470	radeon_state_init(rstate, rscreen->rw, R600_STATE_CB_CNTL, 0, 0);
471	rstate->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000;
472	rstate->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;
473	rstate->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;
474	rstate->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0080;
475	rstate->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F;
476	rstate->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F;
477	rstate->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
478	radeon_state_pm4(rstate);
479}
480
481static int r600_blit_states_init(struct pipe_context *ctx, struct r600_blit_states *bstates)
482{
483	struct r600_screen *rscreen = r600_screen(ctx->screen);
484
485	r600_blit_state_ps_shader(rscreen, &bstates->ps_shader);
486	r600_blit_state_vs_shader(rscreen, &bstates->vs_shader);
487	r600_blit_state_vgt(rscreen, &bstates->vgt);
488	r600_blit_state_draw(rscreen, &bstates->draw);
489	r600_blit_state_vs_constant(rscreen, &bstates->vs_constant0, 0, 1.0, 0.0, 0.0, 0.0);
490	r600_blit_state_vs_constant(rscreen, &bstates->vs_constant1, 1, 0.0, 1.0, 0.0, 0.0);
491	r600_blit_state_vs_constant(rscreen, &bstates->vs_constant2, 2, 0.0, 0.0, -0.00199900055, 0.0);
492	r600_blit_state_vs_constant(rscreen, &bstates->vs_constant3, 3, 0.0, 0.0, -0.99900049, 1.0);
493	r600_blit_state_rasterizer(rscreen, &bstates->rasterizer);
494	r600_blit_state_dsa(rscreen, &bstates->dsa);
495	r600_blit_state_blend(rscreen, &bstates->blend);
496	r600_blit_state_cb_cntl(rscreen, &bstates->cb_cntl);
497	r600_blit_state_vs_resources(rscreen, bstates);
498	return 0;
499}
500
501static void r600_blit_states_destroy(struct pipe_context *ctx, struct r600_blit_states *bstates)
502{
503	radeon_state_fini(&bstates->ps_shader);
504	radeon_state_fini(&bstates->vs_shader);
505	radeon_state_fini(&bstates->vs_resource0);
506	radeon_state_fini(&bstates->vs_resource1);
507}
508
509int r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
510{
511	struct r600_screen *rscreen = r600_screen(ctx->screen);
512	struct r600_context *rctx = r600_context(ctx);
513	struct radeon_draw draw;
514	struct r600_blit_states bstates;
515	int r;
516
517	r = r600_texture_scissor(ctx, rtexture, level);
518	if (r) {
519		return r;
520	}
521	r = r600_texture_cb(ctx, rtexture, 0, level);
522	if (r) {
523		return r;
524	}
525	r = r600_texture_db(ctx, rtexture, level);
526	if (r) {
527		return r;
528	}
529	r = r600_texture_viewport(ctx, rtexture, level);
530	if (r) {
531		return r;
532	}
533
534	r = r600_blit_states_init(ctx, &bstates);
535	if (r) {
536		return r;
537	}
538	bstates.dsa.states[R600_DSA__DB_RENDER_CONTROL] = 0x0000008C;
539	bstates.cb_cntl.states[R600_CB_CNTL__CB_TARGET_MASK] = 0x00000001;
540	/* force rebuild */
541	bstates.dsa.cpm4 = bstates.cb_cntl.cpm4 = 0;
542	if (radeon_state_pm4(&bstates.dsa)) {
543		goto out;
544	}
545	if (radeon_state_pm4(&bstates.cb_cntl)) {
546		goto out;
547	}
548
549	r = radeon_draw_init(&draw, rscreen->rw);
550	if (r) {
551		R600_ERR("failed creating draw for uncompressing textures\n");
552		goto out;
553	}
554
555	radeon_draw_bind(&draw, &bstates.vs_shader);
556	radeon_draw_bind(&draw, &bstates.ps_shader);
557	radeon_draw_bind(&draw, &bstates.rasterizer);
558	radeon_draw_bind(&draw, &bstates.dsa);
559	radeon_draw_bind(&draw, &bstates.blend);
560	radeon_draw_bind(&draw, &bstates.cb_cntl);
561	radeon_draw_bind(&draw, &rctx->config);
562	radeon_draw_bind(&draw, &bstates.vgt);
563	radeon_draw_bind(&draw, &bstates.draw);
564	radeon_draw_bind(&draw, &bstates.vs_resource0);
565	radeon_draw_bind(&draw, &bstates.vs_resource1);
566	radeon_draw_bind(&draw, &bstates.vs_constant0);
567	radeon_draw_bind(&draw, &bstates.vs_constant1);
568	radeon_draw_bind(&draw, &bstates.vs_constant2);
569	radeon_draw_bind(&draw, &bstates.vs_constant3);
570	radeon_draw_bind(&draw, &rtexture->viewport[level]);
571	radeon_draw_bind(&draw, &rtexture->scissor[level]);
572	radeon_draw_bind(&draw, &rtexture->cb[0][level]);
573	radeon_draw_bind(&draw, &rtexture->db[level]);
574
575	/* suspend queries */
576	r600_queries_suspend(ctx);
577
578	/* schedule draw*/
579	r = radeon_ctx_set_draw(rctx->ctx, &draw);
580	if (r == -EBUSY) {
581		r600_flush(ctx, 0, NULL);
582		r = radeon_ctx_set_draw(rctx->ctx, &draw);
583	}
584	if (r) {
585		goto out;
586	}
587
588	/* resume queries */
589	r600_queries_resume(ctx);
590
591out:
592	r600_blit_states_destroy(ctx, &bstates);
593	return r;
594}
595