1a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/*
2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Permission is hereby granted, free of charge, to any person obtaining a
5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * copy of this software and associated documentation files (the "Software"),
6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * to deal in the Software without restriction, including without limitation
7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * on the rights to use, copy, modify, merge, publish, distribute, sub
8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * license, and/or sell copies of the Software, and to permit persons to whom
9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * the Software is furnished to do so, subject to the following conditions:
10a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
11a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * The above copyright notice and this permission notice (including the next
12a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * paragraph) shall be included in all copies or substantial portions of the
13a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Software.
14a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
15a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * USE OR OTHER DEALINGS IN THE SOFTWARE.
22a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */
23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_surface.h"
24a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_blitter.h"
25a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_format.h"
26a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "radeonsi_pipe.h"
277e011d92c9746ba4050890442db6e504fa42c4adChristian König#include "si_state.h"
28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardenum r600_blitter_op /* bitmask */
30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	R600_SAVE_TEXTURES      = 1,
32a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	R600_SAVE_FRAMEBUFFER   = 2,
33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	R600_DISABLE_RENDER_COND = 4,
34a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
35a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	R600_CLEAR         = 0,
36a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	R600_CLEAR_SURFACE = R600_SAVE_FRAMEBUFFER,
38a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
39a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	R600_COPY          = R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES |
40a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			     R600_DISABLE_RENDER_COND,
41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	R600_DECOMPRESS    = R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND,
43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard};
44a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op)
46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
47a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context *)ctx;
48a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_context_queries_suspend(rctx);
50a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
5163636ae52aefc275115d1f3daac4e75285583485Christian König	util_blitter_save_blend(rctx->blitter, rctx->queued.named.blend);
52b41b3eb9893b9bac8df363fef4d10c68798616e2Christian König	util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->queued.named.dsa);
53e6937211da019223ca3b8fd0be6ed5a5fe35c706Christian König	util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref);
54f67fae0e43fa0909b57b8a07858d37caecd5cbb1Christian König	util_blitter_save_rasterizer(rctx->blitter, rctx->queued.named.rasterizer);
55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader);
56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
57a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements);
587e011d92c9746ba4050890442db6e504fa42c4adChristian König	if (rctx->queued.named.viewport) {
597e011d92c9746ba4050890442db6e504fa42c4adChristian König		util_blitter_save_viewport(rctx->blitter, &rctx->queued.named.viewport->viewport);
60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	util_blitter_save_vertex_buffers(rctx->blitter,
622a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák					 rctx->nr_vertex_buffers,
632a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák					 rctx->vertex_buffer);
64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets,
65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     (struct pipe_stream_output_target**)rctx->so_targets);
66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (op & R600_SAVE_FRAMEBUFFER)
68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer);
69a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (op & R600_SAVE_TEXTURES) {
71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		util_blitter_save_fragment_sampler_states(
72a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			rctx->blitter, rctx->ps_samplers.n_samplers,
73a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			(void**)rctx->ps_samplers.samplers);
74a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
75a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		util_blitter_save_fragment_sampler_views(
76a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			rctx->blitter, rctx->ps_samplers.n_views,
77a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			(struct pipe_sampler_view**)rctx->ps_samplers.views);
78a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
79a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if ((op & R600_DISABLE_RENDER_COND) && rctx->current_render_cond) {
81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rctx->saved_render_cond = rctx->current_render_cond;
82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rctx->saved_render_cond_mode = rctx->current_render_cond_mode;
83a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rctx->context.render_condition(&rctx->context, NULL, 0);
84a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_blitter_end(struct pipe_context *ctx)
89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context *)ctx;
91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rctx->saved_render_cond) {
92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rctx->context.render_condition(&rctx->context,
93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					       rctx->saved_render_cond,
94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					       rctx->saved_render_cond_mode);
95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		rctx->saved_render_cond = NULL;
96a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_context_queries_resume(rctx);
98a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
99a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
100a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic unsigned u_num_layers(struct pipe_resource *r, unsigned level)
101a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
102a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	switch (r->target) {
103a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_TEXTURE_CUBE:
104a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return 6;
105a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_TEXTURE_3D:
106a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return u_minify(r->depth0, level);
107a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_TEXTURE_1D_ARRAY:
108a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return r->array_size;
109a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case PIPE_TEXTURE_2D_ARRAY:
110a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return r->array_size;
111a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
112a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return 1;
113a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
114a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
115a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1161b11395a36a44a902cfb3e1783758544662df73fMichel Dänzervoid si_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture)
117a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
118a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context *)ctx;
119a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned layer, level;
120a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	float depth = 1.0f;
121a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
122a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!texture->dirty_db)
123a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return;
124a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1252a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	for (level = 0; level <= texture->resource.b.b.last_level; level++) {
1262a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák		unsigned num_layers = u_num_layers(&texture->resource.b.b, level);
127a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
128a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		for (layer = 0; layer < num_layers; layer++) {
129a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			struct pipe_surface *zsurf, *cbsurf, surf_tmpl;
130a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
131a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			surf_tmpl.format = texture->real_format;
132a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			surf_tmpl.u.tex.level = level;
133a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			surf_tmpl.u.tex.first_layer = layer;
134a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			surf_tmpl.u.tex.last_layer = layer;
135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			surf_tmpl.usage = PIPE_BIND_DEPTH_STENCIL;
136a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1372a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák			zsurf = ctx->create_surface(ctx, &texture->resource.b.b, &surf_tmpl);
138a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
139a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			surf_tmpl.format = texture->flushed_depth_texture->real_format;
140a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
141a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			cbsurf = ctx->create_surface(ctx,
142a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					(struct pipe_resource*)texture->flushed_depth_texture, &surf_tmpl);
143a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
144a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			r600_blitter_begin(ctx, R600_DECOMPRESS);
14597b4b97b2f9b0e4532c8ba9cedfff9f013a76fc2Marek Olšák			util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, ~0, rctx->custom_dsa_flush, depth);
146a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			r600_blitter_end(ctx);
147a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
148a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			pipe_surface_reference(&zsurf, NULL);
149a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			pipe_surface_reference(&cbsurf, NULL);
150a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
151a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
152a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	texture->dirty_db = FALSE;
154a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1561b11395a36a44a902cfb3e1783758544662df73fMichel Dänzervoid si_flush_depth_textures(struct r600_context *rctx)
157a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
158a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned int i;
159a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
160a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* FIXME: This handles fragment shader textures only. */
161a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
162a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	for (i = 0; i < rctx->ps_samplers.n_views; ++i) {
163a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		struct si_pipe_sampler_view *view;
164a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		struct r600_resource_texture *tex;
165a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
166a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		view = rctx->ps_samplers.views[i];
167a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (!view) continue;
168a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
169a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		tex = (struct r600_resource_texture *)view->base.texture;
170a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (!tex->depth)
171a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			continue;
172a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
173a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (tex->is_flushing_texture)
174a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			continue;
175a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1761b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		si_blit_uncompress_depth(&rctx->context, tex);
177a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* also check CB here */
180a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	for (i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		struct r600_resource_texture *tex;
182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		tex = (struct r600_resource_texture *)rctx->framebuffer.cbufs[i]->texture;
183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (!tex->depth)
185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			continue;
186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
187a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (tex->is_flushing_texture)
188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			continue;
189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1901b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer		si_blit_uncompress_depth(&rctx->context, tex);
191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
194a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_clear(struct pipe_context *ctx, unsigned buffers,
195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		       const union pipe_color_union *color,
196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		       double depth, unsigned stencil)
197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context *)ctx;
199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_framebuffer_state *fb = &rctx->framebuffer;
20088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blitter_begin(ctx, R600_CLEAR);
202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	util_blitter_clear(rctx->blitter, fb->width, fb->height,
203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   fb->nr_cbufs, buffers, fb->nr_cbufs ? fb->cbufs[0]->format : PIPE_FORMAT_NONE,
204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			   color, depth, stencil);
205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blitter_end(ctx);
206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_clear_render_target(struct pipe_context *ctx,
209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     struct pipe_surface *dst,
210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     const union pipe_color_union *color,
211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     unsigned dstx, unsigned dsty,
212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     unsigned width, unsigned height)
213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
214a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context *)ctx;
215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blitter_begin(ctx, R600_CLEAR_SURFACE);
217a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	util_blitter_clear_render_target(rctx->blitter, dst, color,
218a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					 dstx, dsty, width, height);
219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blitter_end(ctx);
220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
221a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
222a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_clear_depth_stencil(struct pipe_context *ctx,
223a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     struct pipe_surface *dst,
224a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     unsigned clear_flags,
225a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     double depth,
226a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     unsigned stencil,
227a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     unsigned dstx, unsigned dsty,
228a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				     unsigned width, unsigned height)
229a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
230a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context *)ctx;
231a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
232a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blitter_begin(ctx, R600_CLEAR_SURFACE);
233a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil,
234a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					 dstx, dsty, width, height);
235a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blitter_end(ctx);
236a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
237a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
238a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
239a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
240a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* Copy a block of pixels from one surface to another using HW. */
241a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_hw_copy_region(struct pipe_context *ctx,
242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				struct pipe_resource *dst,
243a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				unsigned dst_level,
244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				unsigned dstx, unsigned dsty, unsigned dstz,
245a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				struct pipe_resource *src,
246a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				unsigned src_level,
247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				const struct pipe_box *src_box)
248a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_context *rctx = (struct r600_context *)ctx;
250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
251a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blitter_begin(ctx, R600_COPY);
25297b4b97b2f9b0e4532c8ba9cedfff9f013a76fc2Marek Olšák	util_blitter_copy_texture(rctx->blitter, dst, dst_level, ~0, dstx, dsty, dstz,
25397b4b97b2f9b0e4532c8ba9cedfff9f013a76fc2Marek Olšák				  src, src_level, 0, src_box);
254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_blitter_end(ctx);
255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
257a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct texture_orig_info {
258a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned format;
259a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned width0;
260a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned height0;
26188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	unsigned npix_x;
26288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	unsigned npix_y;
26388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	unsigned npix0_x;
26488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	unsigned npix0_y;
265a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard};
266a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
267a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_compressed_to_blittable(struct pipe_resource *tex,
268a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				   unsigned level,
269a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				   struct texture_orig_info *orig)
270a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
271a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex;
27288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	struct r600_screen *rscreen = (struct r600_screen *)tex->screen;
273a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned pixsize = util_format_get_blocksize(rtex->real_format);
274a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	int new_format;
275a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	int new_height, new_width;
276a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
277a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	orig->format = tex->format;
278a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	orig->width0 = tex->width0;
279a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	orig->height0 = tex->height0;
28088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	orig->npix0_x = rtex->surface.level[0].npix_x;
28188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	orig->npix0_y = rtex->surface.level[0].npix_y;
28288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	orig->npix_x = rtex->surface.level[level].npix_x;
28388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	orig->npix_y = rtex->surface.level[level].npix_y;
284a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
285a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (pixsize == 8)
286a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		new_format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */
287a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	else
288a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		new_format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */
289a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
290a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	new_width = util_format_get_nblocksx(tex->format, orig->width0);
291a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	new_height = util_format_get_nblocksy(tex->format, orig->height0);
292a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
293a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	tex->width0 = new_width;
294a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	tex->height0 = new_height;
295a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	tex->format = new_format;
29688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface.level[0].npix_x = util_format_get_nblocksx(orig->format, orig->npix0_x);
29788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface.level[0].npix_y = util_format_get_nblocksy(orig->format, orig->npix0_y);
29888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface.level[level].npix_x = util_format_get_nblocksx(orig->format, orig->npix_x);
29988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface.level[level].npix_y = util_format_get_nblocksy(orig->format, orig->npix_y);
300a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
301a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
302a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_reset_blittable_to_compressed(struct pipe_resource *tex,
30388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer					       unsigned level,
304a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					       struct texture_orig_info *orig)
305a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
30688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex;
30788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	struct r600_screen *rscreen = (struct r600_screen *)tex->screen;
30888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer
309a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	tex->format = orig->format;
310a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	tex->width0 = orig->width0;
311a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	tex->height0 = orig->height0;
31288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface.level[0].npix_x = orig->npix0_x;
31388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface.level[0].npix_y = orig->npix0_y;
31488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface.level[level].npix_x = orig->npix_x;
31588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer	rtex->surface.level[level].npix_y = orig->npix_y;
316a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
317a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
318a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void r600_resource_copy_region(struct pipe_context *ctx,
319a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				      struct pipe_resource *dst,
320a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				      unsigned dst_level,
321a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				      unsigned dstx, unsigned dsty, unsigned dstz,
322a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				      struct pipe_resource *src,
323a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				      unsigned src_level,
324a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				      const struct pipe_box *src_box)
325a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
326a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src;
327a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct texture_orig_info orig_info[2];
328a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_box sbox;
329a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct pipe_box *psbox;
330a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	boolean restore_orig[2];
331a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
332a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	memset(orig_info, 0, sizeof(orig_info));
333a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
334a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Fallback for buffers. */
335a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
336a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
337a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                                          src, src_level, src_box);
338a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return;
339a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
340a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
341a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (rsrc->depth && !rsrc->is_flushing_texture)
342a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		r600_texture_depth_flush(ctx, src, FALSE);
343a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
344a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	restore_orig[0] = restore_orig[1] = FALSE;
345a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
346a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_compressed(src->format)) {
347a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		r600_compressed_to_blittable(src, src_level, &orig_info[0]);
348a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		restore_orig[0] = TRUE;
349a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x);
350a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y);
351a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		sbox.z = src_box->z;
352a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width);
353a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height);
354a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		sbox.depth = src_box->depth;
355a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		psbox=&sbox;
356a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else
357a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		psbox=src_box;
358a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
359a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (util_format_is_compressed(dst->format)) {
360a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		r600_compressed_to_blittable(dst, dst_level, &orig_info[1]);
361a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		restore_orig[1] = TRUE;
362a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		/* translate the dst box as well */
363a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		dstx = util_format_get_nblocksx(orig_info[1].format, dstx);
364a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		dsty = util_format_get_nblocksy(orig_info[1].format, dsty);
365a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
366a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
367a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
368a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			    src, src_level, psbox);
369a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
370a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (restore_orig[0])
37188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]);
372a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
373a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (restore_orig[1])
37488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer		r600_reset_blittable_to_compressed(dst, dst_level, &orig_info[1]);
375a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
376a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
3771b11395a36a44a902cfb3e1783758544662df73fMichel Dänzervoid si_init_blit_functions(struct r600_context *rctx)
378a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
379a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rctx->context.clear = r600_clear;
380a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rctx->context.clear_render_target = r600_clear_render_target;
381a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rctx->context.clear_depth_stencil = r600_clear_depth_stencil;
382a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	rctx->context.resource_copy_region = r600_resource_copy_region;
383a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
384a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
385a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture *texture)
386a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
387a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct pipe_box sbox;
388a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
389a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	sbox.x = sbox.y = sbox.z = 0;
3902a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	sbox.width = texture->resource.b.b.width0;
3912a311b18fce9ea6538b0997ad23d86a061fb273cMarek Olšák	sbox.height = texture->resource.b.b.height0;
392a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX that might be wrong */
393a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	sbox.depth = 1;
394a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
395a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	r600_hw_copy_region(ctx, (struct pipe_resource *)texture, 0,
396a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			    0, 0, 0,
397a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			    (struct pipe_resource *)texture->flushed_depth_texture, 0,
398a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			    &sbox);
399a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
400