r600_blit.c revision 8078e58795052b8eb7c35fd73db06f26bec078e2
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	struct radeon_state     cb_flush;
164	struct radeon_state     db_flush;
165};
166
167static int r600_blit_state_vs_resources(struct r600_screen *rscreen, struct r600_blit_states *bstates)
168{
169	struct radeon_state *rstate;
170	struct radeon_ws_bo *bo;
171	void *data;
172	float *vbo;
173	enum radeon_family family;
174	float vbo_r600[] = {
175	  -1.0, -1.0, 1.0, 1.0,
176	   0.5,  0.5, 0.0, 0.0,
177	   1.0, -1.0, 1.0, 1.0,
178	   0.5,  0.5, 0.0, 0.0,
179	   1.0,  1.0, 1.0, 1.0,
180	   0.5,  0.5, 0.0, 0.0,
181	  -1.0,  1.0, 1.0, 1.0,
182	   0.5,  0.5, 0.0, 0.0 };
183
184	float vbo_rv6xx[] = {
185	  -1.0, -1.0, 0.0, 1.0,
186	   0.5,  0.5, 0.0, 0.0,
187	   1.0, -1.0, 0.0, 1.0,
188	   0.5,  0.5, 0.0, 0.0,
189	   1.0,  1.0, 0.0, 1.0,
190	   0.5,  0.5, 0.0, 0.0,
191	  -1.0,  1.0, 0.0, 1.0,
192	   0.5,  0.5, 0.0, 0.0};
193
194
195	family = radeon_get_family(rscreen->rw);
196	/* simple shader */
197	bo = radeon_ws_bo(rscreen->rw, 128, 4096, 0);
198	if (bo == NULL) {
199		return -ENOMEM;
200	}
201	data = radeon_ws_bo_map(rscreen->rw, bo, 0, NULL);
202	if (!data) {
203		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
204		return -ENOMEM;
205	}
206	if (family == CHIP_RV610 || family == CHIP_RV630 || family == CHIP_RV620 ||
207	    family == CHIP_RV635)
208		vbo = vbo_rv6xx;
209	else
210		vbo = vbo_r600;
211
212	memcpy(data, vbo, 128);
213	radeon_ws_bo_unmap(rscreen->rw, bo);
214
215	rstate = &bstates->vs_resource0;
216	radeon_state_init(rstate, rscreen->rw, R600_STATE_RESOURCE, 0, R600_SHADER_VS);
217
218	/* set states (most default value are 0 and struct already
219	 * initialized to 0, thus avoid resetting them)
220	 */
221	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD0] = 0x00000000;
222	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD1] = 0x00000080;
223	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD2] = 0x02302000;
224	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD3] = 0x00000000;
225	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD4] = 0x00000000;
226	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD5] = 0x00000000;
227	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD6] = 0xC0000000;
228	rstate->bo[0] = bo;
229	rstate->nbo = 1;
230	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
231	if (radeon_state_pm4(rstate)) {
232		radeon_state_fini(rstate);
233		return -ENOMEM;
234	}
235
236	rstate = &bstates->vs_resource1;
237	radeon_state_init(rstate, rscreen->rw, R600_STATE_RESOURCE, 1, R600_SHADER_VS);
238	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD0] = 0x00000010;
239	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD1] = 0x00000070;
240	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD2] = 0x02302000;
241	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD3] = 0x00000000;
242	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD4] = 0x00000000;
243	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD5] = 0x00000000;
244	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD6] = 0xC0000000;
245	radeon_ws_bo_reference(rscreen->rw, &rstate->bo[0], bo);
246	rstate->nbo = 1;
247	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
248	if (radeon_state_pm4(rstate)) {
249		radeon_state_fini(rstate);
250		return -ENOMEM;
251	}
252
253	return 0;
254}
255
256static void r600_blit_state_vs_shader(struct r600_screen *rscreen, struct radeon_state *rstate)
257{
258	struct radeon_ws_bo *bo;
259	void *data;
260	u32 shader_bc_r600[] = {
261		0x00000004, 0x81000400,
262		0x00000008, 0xA01C0000,
263		0xC001A03C, 0x94000688,
264		0xC0024000, 0x94200688,
265		0x7C000000, 0x002D1001,
266		0x00080000, 0x00000000,
267		0x7C000100, 0x002D1002,
268		0x00080000, 0x00000000,
269		0x00000001, 0x00601910,
270		0x00000401, 0x20601910,
271		0x00000801, 0x40601910,
272		0x80000C01, 0x60601910,
273		0x00000002, 0x00801910,
274		0x00000402, 0x20801910,
275		0x00000802, 0x40801910,
276		0x80000C02, 0x60801910
277	};
278	u32 shader_bc_r700[] = {
279		0x00000004, 0x81000400,
280		0x00000008, 0xA01C0000,
281		0xC001A03C, 0x94000688,
282		0xC0024000, 0x94200688,
283		0x7C000000, 0x002D1001,
284		0x00080000, 0x00000000,
285		0x7C000100, 0x002D1002,
286		0x00080000, 0x00000000,
287		0x00000001, 0x00600C90,
288		0x00000401, 0x20600C90,
289		0x00000801, 0x40600C90,
290		0x80000C01, 0x60600C90,
291		0x00000002, 0x00800C90,
292		0x00000402, 0x20800C90,
293		0x00000802, 0x40800C90,
294		0x80000C02, 0x60800C90
295	};
296
297	/* simple shader */
298	bo = radeon_ws_bo(rscreen->rw, 128, 4096, 0);
299	if (bo == NULL) {
300		return;
301	}
302	data = radeon_ws_bo_map(rscreen->rw, bo, 0, NULL);
303	if (!data) {
304		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
305		return;
306	}
307	switch (radeon_get_family_class(rscreen->rw)) {
308	case R600:
309		memcpy(data, shader_bc_r600, 128);
310		break;
311	case R700:
312		memcpy(data, shader_bc_r700, 128);
313		break;
314	default:
315		R600_ERR("unsupported chip family\n");
316		radeon_ws_bo_unmap(rscreen->rw, bo);
317		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
318		return;
319	}
320	radeon_ws_bo_unmap(rscreen->rw, bo);
321
322	radeon_state_init(rstate, rscreen->rw, R600_STATE_SHADER, 0, R600_SHADER_VS);
323
324	/* set states (most default value are 0 and struct already
325	 * initialized to 0, thus avoid resetting them)
326	 */
327	rstate->states[R600_VS_SHADER__SPI_VS_OUT_ID_0] = 0x03020100;
328	rstate->states[R600_VS_SHADER__SPI_VS_OUT_ID_1] = 0x07060504;
329	rstate->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = 0x00000005;
330
331	rstate->bo[0] = bo;
332	radeon_ws_bo_reference(rscreen->rw, &rstate->bo[1], bo);
333	rstate->nbo = 2;
334	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
335	rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
336
337	radeon_state_pm4(rstate);
338}
339
340static void r600_blit_state_ps_shader(struct r600_screen *rscreen, struct radeon_state *rstate)
341{
342	struct radeon_ws_bo *bo;
343	void *data;
344	u32 shader_bc_r600[] = {
345		0x00000002, 0xA00C0000,
346		0xC0008000, 0x94200688,
347		0x00000000, 0x00201910,
348		0x00000400, 0x20201910,
349		0x00000800, 0x40201910,
350		0x80000C00, 0x60201910
351	};
352	u32 shader_bc_r700[] = {
353		0x00000002, 0xA00C0000,
354		0xC0008000, 0x94200688,
355		0x00000000, 0x00200C90,
356		0x00000400, 0x20200C90,
357		0x00000800, 0x40200C90,
358		0x80000C00, 0x60200C90
359	};
360
361	/* simple shader */
362	bo = radeon_ws_bo(rscreen->rw, 128, 4096, 0);
363	if (bo == NULL) {
364		return;
365	}
366	data = radeon_ws_bo_map(rscreen->rw, bo, 0, NULL);
367	if (!data) {
368		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
369		return;
370	}
371	switch (radeon_get_family_class(rscreen->rw)) {
372	case R600:
373		memcpy(data, shader_bc_r600, 48);
374		break;
375	case R700:
376		memcpy(data, shader_bc_r700, 48);
377		break;
378	default:
379		R600_ERR("unsupported chip family\n");
380		radeon_ws_bo_unmap(rscreen->rw, bo);
381		radeon_ws_bo_reference(rscreen->rw, &bo, NULL);
382		return;
383	}
384	radeon_ws_bo_unmap(rscreen->rw, bo);
385
386	radeon_state_init(rstate, rscreen->rw, R600_STATE_SHADER, 0, R600_SHADER_PS);
387
388	/* set states (most default value are 0 and struct already
389	 * initialized to 0, thus avoid resetting them)
390	 */
391	rstate->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0] = 0x00000C00;
392	rstate->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = 0x10000001;
393	rstate->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
394	rstate->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = 0x00000002;
395
396	rstate->bo[0] = bo;
397	rstate->nbo = 1;
398	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
399
400	radeon_state_pm4(rstate);
401}
402
403static void r600_blit_state_vgt(struct r600_screen *rscreen, struct radeon_state *rstate)
404{
405	radeon_state_init(rstate, rscreen->rw, R600_STATE_VGT, 0, 0);
406
407	/* set states (most default value are 0 and struct already
408	 * initialized to 0, thus avoid resetting them)
409	 */
410	rstate->states[R600_VGT__VGT_DMA_NUM_INSTANCES] = 0x00000001;
411	rstate->states[R600_VGT__VGT_MAX_VTX_INDX] = 0x00FFFFFF;
412	rstate->states[R600_VGT__VGT_PRIMITIVE_TYPE] = 0x00000005;
413
414	radeon_state_pm4(rstate);
415}
416
417static void r600_blit_state_draw(struct r600_screen *rscreen, struct radeon_state *rstate)
418{
419	radeon_state_init(rstate, rscreen->rw, R600_STATE_DRAW, 0, 0);
420
421	/* set states (most default value are 0 and struct already
422	 * initialized to 0, thus avoid resetting them)
423	 */
424	rstate->states[R600_DRAW__VGT_DRAW_INITIATOR] = 0x00000002;
425	rstate->states[R600_DRAW__VGT_NUM_INDICES] = 0x00000004;
426
427	radeon_state_pm4(rstate);
428}
429
430static void r600_blit_state_vs_constant(struct r600_screen *rscreen, struct radeon_state *rstate,
431					unsigned id, float c0, float c1, float c2, float c3)
432{
433	radeon_state_init(rstate, rscreen->rw, R600_STATE_CONSTANT, id, R600_SHADER_VS);
434
435	/* set states (most default value are 0 and struct already
436	 * initialized to 0, thus avoid resetting them)
437	 */
438	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT0_256] = fui(c0);
439	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT1_256] = fui(c1);
440	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT2_256] = fui(c2);
441	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT3_256] = fui(c3);
442
443	radeon_state_pm4(rstate);
444}
445
446static void r600_blit_state_rasterizer(struct r600_screen *rscreen, struct radeon_state *rstate)
447{
448	radeon_state_init(rstate, rscreen->rw, R600_STATE_RASTERIZER, 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_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ] = 0x3F800000;
454	rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000;
455	rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_CLIP_ADJ] = 0x3F800000;
456	rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000;
457	rstate->states[R600_RASTERIZER__PA_SC_LINE_CNTL] = 0x00000400;
458	rstate->states[R600_RASTERIZER__PA_SC_LINE_STIPPLE] = 0x00000005;
459	rstate->states[R600_RASTERIZER__PA_SU_LINE_CNTL] = 0x00000008;
460	rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x80000000;
461	rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080004;
462	rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001;
463
464	radeon_state_pm4(rstate);
465}
466
467static void r600_blit_state_dsa(struct r600_screen *rscreen, struct radeon_state *rstate)
468{
469	uint32_t db_render_override, db_shader_control;
470	radeon_state_init(rstate, rscreen->rw, R600_STATE_DSA, 0, 0);
471
472	/* set states (most default value are 0 and struct already
473	 * initialized to 0, thus avoid resetting them)
474	 */
475	rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00;
476	rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
477	rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060;
478
479	db_render_override = S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE) |
480		S_028D10_FORCE_HIS_ENABLE0(V_028D10_FORCE_DISABLE) |
481		S_028D10_FORCE_HIS_ENABLE1(V_028D10_FORCE_DISABLE);
482
483	db_shader_control = S_02880C_DUAL_EXPORT_ENABLE(0) |
484		S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
485
486	rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = db_render_override;
487	rstate->states[R600_DSA__DB_SHADER_CONTROL] = db_shader_control;
488
489	radeon_state_pm4(rstate);
490}
491
492static void r600_blit_state_blend(struct r600_screen *rscreen, struct radeon_state *rstate)
493{
494	radeon_state_init(rstate, rscreen->rw, R600_STATE_BLEND, 0, 0);
495	radeon_state_pm4(rstate);
496}
497
498static void r600_blit_state_cb_cntl(struct r600_screen *rscreen, struct radeon_state *rstate)
499{
500	radeon_state_init(rstate, rscreen->rw, R600_STATE_CB_CNTL, 0, 0);
501	rstate->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000;
502	rstate->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;
503	rstate->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;
504	rstate->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0080;
505	rstate->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F;
506	rstate->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F;
507	rstate->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
508	rstate->states[R600_CB_CNTL__CB_SHADER_CONTROL] = 0x1;
509	radeon_state_pm4(rstate);
510}
511
512static void r600_blit_state_cb_flush(struct r600_screen *rscreen, struct radeon_state *rstate, struct r600_resource_texture *rtexture, unsigned cb, unsigned level)
513{
514	radeon_state_init(rstate, rscreen->rw, R600_STATE_CB_FLUSH, 0, 0);
515
516	radeon_ws_bo_reference(rscreen->rw, &rstate->bo[0], rtexture->uncompressed);
517	rstate->nbo = 1;
518	radeon_state_pm4(rstate);
519}
520
521static void r600_blit_state_db_flush(struct r600_screen *rscreen, struct radeon_state *rstate, struct r600_resource_texture *rtexture, unsigned cb, unsigned level)
522{
523	radeon_state_init(rstate, rscreen->rw, R600_STATE_DB_FLUSH, 0, 0);
524
525	radeon_ws_bo_reference(rscreen->rw, &rstate->bo[0], rtexture->resource.bo);
526	rstate->nbo = 1;
527	radeon_state_pm4(rstate);
528}
529
530static int r600_blit_states_init(struct pipe_context *ctx, struct r600_blit_states *bstates)
531{
532	struct r600_screen *rscreen = r600_screen(ctx->screen);
533
534	r600_blit_state_ps_shader(rscreen, &bstates->ps_shader);
535	r600_blit_state_vs_shader(rscreen, &bstates->vs_shader);
536	r600_blit_state_vgt(rscreen, &bstates->vgt);
537	r600_blit_state_draw(rscreen, &bstates->draw);
538	r600_blit_state_vs_constant(rscreen, &bstates->vs_constant0, 0, 1.0, 0.0, 0.0, 0.0);
539	r600_blit_state_vs_constant(rscreen, &bstates->vs_constant1, 1, 0.0, 1.0, 0.0, 0.0);
540	r600_blit_state_vs_constant(rscreen, &bstates->vs_constant2, 2, 0.0, 0.0, -0.00199900055, 0.0);
541	r600_blit_state_vs_constant(rscreen, &bstates->vs_constant3, 3, 0.0, 0.0, -0.99900049, 1.0);
542	r600_blit_state_rasterizer(rscreen, &bstates->rasterizer);
543	r600_blit_state_dsa(rscreen, &bstates->dsa);
544	r600_blit_state_blend(rscreen, &bstates->blend);
545	r600_blit_state_cb_cntl(rscreen, &bstates->cb_cntl);
546	r600_blit_state_vs_resources(rscreen, bstates);
547	return 0;
548}
549
550static void r600_blit_states_destroy(struct pipe_context *ctx, struct r600_blit_states *bstates)
551{
552	radeon_state_fini(&bstates->ps_shader);
553	radeon_state_fini(&bstates->vs_shader);
554	radeon_state_fini(&bstates->vs_resource0);
555	radeon_state_fini(&bstates->vs_resource1);
556}
557
558int r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
559{
560	struct r600_screen *rscreen = r600_screen(ctx->screen);
561	struct r600_context *rctx = r600_context(ctx);
562	struct radeon_draw draw;
563	struct r600_blit_states bstates;
564	enum radeon_family family;
565	int r;
566
567	r = r600_texture_scissor(ctx, rtexture, level);
568	if (r) {
569		return r;
570	}
571	r = r600_texture_cb(ctx, rtexture, 0, level);
572	if (r) {
573		return r;
574	}
575	r = r600_texture_db(ctx, rtexture, level);
576	if (r) {
577		return r;
578	}
579	r = r600_texture_viewport(ctx, rtexture, level);
580	if (r) {
581		return r;
582	}
583
584	r = r600_blit_states_init(ctx, &bstates);
585	if (r) {
586		return r;
587	}
588
589	/* for some gpus we need special cases */
590	family = radeon_get_family(rscreen->rw);
591	/* according to R6xx_R7xx_3D.pdf section 6.3.1, these GPUs needs special handling */
592	if (family == CHIP_RV610 || family == CHIP_RV630 || family == CHIP_RV620 ||
593	    family == CHIP_RV635) {
594		bstates.dsa.states[R600_DSA__DB_DEPTH_CONTROL] = S_028800_Z_ENABLE(1) |
595			S_028800_STENCIL_ENABLE(1) | S_028800_ZFUNC(V_028800_STENCILFUNC_LEQUAL) |
596			S_028800_STENCILFUNC(V_028800_STENCILFUNC_ALWAYS) |
597			S_028800_STENCILZPASS(V_028800_STENCIL_KEEP) |
598			S_028800_STENCILZFAIL(V_028800_STENCIL_INCR);
599
600		bstates.dsa.states[R600_DSA__DB_STENCILREFMASK] = S_028430_STENCILWRITEMASK(0xff);
601	}
602	bstates.dsa.states[R600_DSA__DB_RENDER_CONTROL] = S_028D0C_DEPTH_COPY_ENABLE(1) |
603			S_028D0C_STENCIL_COPY_ENABLE(1) |
604			S_028D0C_COPY_CENTROID(1);
605
606	bstates.cb_cntl.states[R600_CB_CNTL__CB_TARGET_MASK] = 0x00000003;
607	r600_blit_state_cb_flush(rscreen, &bstates.cb_flush, rtexture, 0, 0);
608	r600_blit_state_db_flush(rscreen, &bstates.db_flush, rtexture, 0, 0);
609
610	/* force rebuild */
611	bstates.dsa.cpm4 = bstates.cb_cntl.cpm4 = 0;
612	if (radeon_state_pm4(&bstates.dsa)) {
613		goto out;
614	}
615	if (radeon_state_pm4(&bstates.cb_cntl)) {
616		goto out;
617	}
618
619	r = radeon_draw_init(&draw, rscreen->rw);
620	if (r) {
621		R600_ERR("failed creating draw for uncompressing textures\n");
622		goto out;
623	}
624
625	radeon_draw_bind(&draw, &bstates.vs_shader);
626	radeon_draw_bind(&draw, &bstates.ps_shader);
627	radeon_draw_bind(&draw, &bstates.rasterizer);
628	radeon_draw_bind(&draw, &bstates.dsa);
629	radeon_draw_bind(&draw, &bstates.blend);
630	radeon_draw_bind(&draw, &bstates.cb_cntl);
631	radeon_draw_bind(&draw, &rctx->config);
632	radeon_draw_bind(&draw, &bstates.vgt);
633	radeon_draw_bind(&draw, &bstates.draw);
634	radeon_draw_bind(&draw, &bstates.cb_flush);
635	radeon_draw_bind(&draw, &bstates.db_flush);
636	radeon_draw_bind(&draw, &bstates.vs_resource0);
637	radeon_draw_bind(&draw, &bstates.vs_resource1);
638	radeon_draw_bind(&draw, &bstates.vs_constant0);
639	radeon_draw_bind(&draw, &bstates.vs_constant1);
640	radeon_draw_bind(&draw, &bstates.vs_constant2);
641	radeon_draw_bind(&draw, &bstates.vs_constant3);
642	radeon_draw_bind(&draw, &rtexture->viewport[level]);
643	radeon_draw_bind(&draw, &rtexture->scissor[level]);
644	radeon_draw_bind(&draw, &rtexture->cb[0][level]);
645	radeon_draw_bind(&draw, &rtexture->db[level]);
646
647	/* suspend queries */
648	r600_queries_suspend(ctx);
649
650	/* schedule draw*/
651	r = radeon_ctx_set_draw(rctx->ctx, &draw);
652	if (r == -EBUSY) {
653		r600_flush(ctx, 0, NULL);
654		r = radeon_ctx_set_draw(rctx->ctx, &draw);
655	}
656	if (r) {
657		goto out;
658	}
659
660	/* resume queries */
661	r600_queries_resume(ctx);
662
663out:
664	r600_blit_states_destroy(ctx, &bstates);
665	return r;
666}
667