Merge commit 'origin/openvg-1.0'
[mesa.git] / src / gallium / drivers / r300 / r300_surface.c
1 /*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 * Joakim Sindholt <opensource@zhasha.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23
24 #include "r300_surface.h"
25
26 static void r300_surface_setup(struct r300_context* r300,
27 struct r300_texture* dest,
28 unsigned x, unsigned y,
29 unsigned w, unsigned h)
30 {
31 struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
32 unsigned pixpitch = dest->stride / dest->tex.block.size;
33 CS_LOCALS(r300);
34
35 r300_emit_blend_state(r300, &blend_clear_state);
36 r300_emit_blend_color_state(r300, &blend_color_clear_state);
37 r300_emit_dsa_state(r300, &dsa_clear_state);
38 r300_emit_rs_state(r300, &rs_clear_state);
39
40 BEGIN_CS(24);
41
42 /* Viewport setup */
43 OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
44 OUT_CS_32F((float)w);
45 OUT_CS_32F((float)x);
46 OUT_CS_32F((float)h);
47 OUT_CS_32F((float)y);
48 OUT_CS_32F(1.0);
49 OUT_CS_32F(0.0);
50
51 OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VPORT_X_SCALE_ENA |
52 R300_VPORT_X_OFFSET_ENA |
53 R300_VPORT_Y_SCALE_ENA |
54 R300_VPORT_Y_OFFSET_ENA |
55 R300_VTX_XY_FMT | R300_VTX_Z_FMT);
56
57 /* Pixel scissors. */
58 OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
59 if (caps->is_r500) {
60 OUT_CS((x << R300_SCISSORS_X_SHIFT) | (y << R300_SCISSORS_Y_SHIFT));
61 OUT_CS((w << R300_SCISSORS_X_SHIFT) | (h << R300_SCISSORS_Y_SHIFT));
62 } else {
63 /* Non-R500 chipsets have an offset of 1440 in their scissors. */
64 OUT_CS(((x + 1440) << R300_SCISSORS_X_SHIFT) |
65 ((y + 1440) << R300_SCISSORS_Y_SHIFT));
66 OUT_CS(((w + 1440) << R300_SCISSORS_X_SHIFT) |
67 ((h + 1440) << R300_SCISSORS_Y_SHIFT));
68 }
69
70 /* Flush colorbuffer and blend caches. */
71 OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
72 R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D |
73 R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL);
74 OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
75 R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
76 R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
77
78 /* Setup colorbuffer. */
79 OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1);
80 OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
81 OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch |
82 r300_translate_colorformat(dest->tex.format));
83 OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf);
84
85 END_CS;
86 }
87
88 /* Provides pipe_context's "surface_fill". Commonly used for clearing
89 * buffers. */
90 static void r300_surface_fill(struct pipe_context* pipe,
91 struct pipe_surface* dest,
92 unsigned x, unsigned y,
93 unsigned w, unsigned h,
94 unsigned color)
95 {
96 int i;
97 float r, g, b, a, depth;
98 struct r300_context* r300 = r300_context(pipe);
99 struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
100 struct r300_texture* tex = (struct r300_texture*)dest->texture;
101 unsigned pixpitch = tex->stride / tex->tex.block.size;
102 boolean invalid = FALSE;
103 CS_LOCALS(r300);
104
105 a = (float)((color >> 24) & 0xff) / 255.0f;
106 r = (float)((color >> 16) & 0xff) / 255.0f;
107 g = (float)((color >> 8) & 0xff) / 255.0f;
108 b = (float)((color >> 0) & 0xff) / 255.0f;
109 debug_printf("r300: Filling surface %p at (%d,%d),"
110 " dimensions %dx%d (pixel pitch %d), color 0x%x\n",
111 dest, x, y, w, h, pixpitch, color);
112
113 /* Fallback? */
114 if (FALSE) {
115 fallback:
116 debug_printf("r300: Falling back on surface clear...");
117 util_surface_fill(pipe, dest, x, y, w, h, color);
118 return;
119 }
120
121 /* Make sure our target BO is okay. */
122 validate:
123 if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
124 0, RADEON_GEM_DOMAIN_VRAM)) {
125 r300->context.flush(&r300->context, 0, NULL);
126 goto validate;
127 }
128 if (r300->winsys->validate(r300->winsys)) {
129 r300->context.flush(&r300->context, 0, NULL);
130 if (invalid) {
131 goto fallback;
132 }
133 invalid = TRUE;
134 goto validate;
135 }
136
137 r300_surface_setup(r300, tex, x, y, w, h);
138
139 /* Vertex shader setup */
140 if (caps->has_tcl) {
141 r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
142 } else {
143 BEGIN_CS(4);
144 OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
145 OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |
146 R300_PVS_NUM_CNTLRS(5) |
147 R300_PVS_NUM_FPUS(caps->num_vert_fpus) |
148 R300_PVS_VF_MAX_VTX_NUM(12));
149 END_CS;
150 }
151
152 /* Fragment shader setup */
153 if (caps->is_r500) {
154 r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader);
155 r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);
156 } else {
157 r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader);
158 r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);
159 }
160
161 BEGIN_CS(26);
162
163 /* VAP stream control, mapping from input memory to PVS/RS memory */
164 if (caps->has_tcl) {
165 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
166 (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) |
167 ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) |
168 R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT));
169 } else {
170 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
171 (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) |
172 ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) |
173 R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT));
174 }
175 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
176 (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) |
177 (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT));
178
179 /* VAP format controls */
180 OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0,
181 R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
182 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT);
183 OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x0);
184
185 /* Disable textures */
186 OUT_CS_REG(R300_TX_ENABLE, 0x0);
187
188 /* The size of the point we're about to draw, in sixths of pixels */
189 OUT_CS_REG(R300_GA_POINT_SIZE,
190 ((h * 6) & R300_POINTSIZE_Y_MASK) |
191 ((w * 6) << R300_POINTSIZE_X_SHIFT));
192
193 /* Vertex size. */
194 OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);
195
196 /* Packet3 with our point vertex */
197 OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8);
198 OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
199 (1 << R300_PRIM_NUM_VERTICES_SHIFT));
200 /* Position */
201 OUT_CS_32F(0.5);
202 OUT_CS_32F(0.5);
203 OUT_CS_32F(1.0);
204 OUT_CS_32F(1.0);
205 /* Color */
206 OUT_CS_32F(r);
207 OUT_CS_32F(g);
208 OUT_CS_32F(b);
209 OUT_CS_32F(a);
210
211 OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
212
213 END_CS;
214
215 r300->dirty_hw++;
216 }
217
218 static void r300_surface_copy(struct pipe_context* pipe,
219 struct pipe_surface* dest,
220 unsigned destx, unsigned desty,
221 struct pipe_surface* src,
222 unsigned srcx, unsigned srcy,
223 unsigned w, unsigned h)
224 {
225 struct r300_context* r300 = r300_context(pipe);
226 struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
227 struct r300_texture* srctex = (struct r300_texture*)src->texture;
228 struct r300_texture* desttex = (struct r300_texture*)dest->texture;
229 unsigned pixpitch = srctex->stride / srctex->tex.block.size;
230 boolean invalid = FALSE;
231 float fsrcx = srcx, fsrcy = srcy, fdestx = destx, fdesty = desty;
232 CS_LOCALS(r300);
233
234 debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d),"
235 " dimensions %dx%d (pixel pitch %d)\n",
236 src, srcx, srcy, dest, destx, desty, w, h, pixpitch);
237
238 if ((srctex->buffer == desttex->buffer) &&
239 ((destx < srcx + w) || (srcx < destx + w)) &&
240 ((desty < srcy + h) || (srcy < desty + h))) {
241 fallback:
242 debug_printf("r300: Falling back on surface_copy\n");
243 util_surface_copy(pipe, FALSE, dest, destx, desty, src,
244 srcx, srcy, w, h);
245 }
246
247 /* Add our target BOs to the list. */
248 validate:
249 if (!r300->winsys->add_buffer(r300->winsys, srctex->buffer,
250 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
251 r300->context.flush(&r300->context, 0, NULL);
252 goto validate;
253 }
254 if (!r300->winsys->add_buffer(r300->winsys, desttex->buffer,
255 0, RADEON_GEM_DOMAIN_VRAM)) {
256 r300->context.flush(&r300->context, 0, NULL);
257 goto validate;
258 }
259 if (r300->winsys->validate(r300->winsys)) {
260 r300->context.flush(&r300->context, 0, NULL);
261 if (invalid) {
262 goto fallback;
263 }
264 invalid = TRUE;
265 goto validate;
266 }
267
268 r300_surface_setup(r300, desttex, destx, desty, w, h);
269
270 /* Setup the texture. */
271 r300_emit_sampler(r300, &r300_sampler_copy_state, 0);
272 r300_emit_texture(r300, srctex, 0);
273
274 /* Flush and enable. */
275 BEGIN_CS(4);
276 OUT_CS_REG(R300_TX_INVALTAGS, 0);
277 OUT_CS_REG(R300_TX_ENABLE, 0x1);
278 END_CS;
279
280 /* Vertex shader setup */
281 if (caps->has_tcl) {
282 r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
283 } else {
284 BEGIN_CS(4);
285 OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
286 OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |
287 R300_PVS_NUM_CNTLRS(5) |
288 R300_PVS_NUM_FPUS(caps->num_vert_fpus) |
289 R300_PVS_VF_MAX_VTX_NUM(12));
290 END_CS;
291 }
292
293 /* Fragment shader setup */
294 if (caps->is_r500) {
295 r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader);
296 r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);
297 } else {
298 r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader);
299 r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);
300 }
301
302 BEGIN_CS(30);
303 /* VAP stream control, mapping from input memory to PVS/RS memory */
304 if (caps->has_tcl) {
305 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
306 (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
307 ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) |
308 R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT));
309 } else {
310 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
311 (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
312 ((R300_LAST_VEC | (6 << R300_DST_VEC_LOC_SHIFT) |
313 R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT));
314 }
315 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
316 (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) |
317 (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT));
318
319 /* VAP format controls */
320 OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0,
321 R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT);
322 /* Two components of texture 0 */
323 OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2);
324
325 /* Vertex size. */
326 OUT_CS_REG(R300_VAP_VTX_SIZE, 0x4);
327
328 /* Packet3 with our texcoords */
329 OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 16);
330 OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING |
331 (4 << R300_PRIM_NUM_VERTICES_SHIFT));
332 /* (x , y ) */
333 OUT_CS_32F(fdestx / dest->width);
334 OUT_CS_32F(fdesty / dest->height);
335 OUT_CS_32F(fsrcx / src->width);
336 OUT_CS_32F(fsrcy / src->height);
337 /* (x , y + h) */
338 OUT_CS_32F(fdestx / dest->width);
339 OUT_CS_32F((fdesty + h) / dest->height);
340 OUT_CS_32F(fsrcx / src->width);
341 OUT_CS_32F((fsrcy + h) / src->height);
342 /* (x + w, y + h) */
343 OUT_CS_32F((fdestx + w) / dest->width);
344 OUT_CS_32F((fdesty + h) / dest->height);
345 OUT_CS_32F((fsrcx + w) / src->width);
346 OUT_CS_32F((fsrcy + h) / src->height);
347 /* (x + w, y ) */
348 OUT_CS_32F((fdestx + w) / dest->width);
349 OUT_CS_32F(fdesty / dest->height);
350 OUT_CS_32F((fsrcx + w) / src->width);
351 OUT_CS_32F(fsrcy / src->height);
352
353 OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
354
355 END_CS;
356
357 r300->dirty_hw++;
358 }
359
360 void r300_init_surface_functions(struct r300_context* r300)
361 {
362 r300->context.surface_fill = r300_surface_fill;
363 r300->context.surface_copy = r300_surface_copy;
364 }