Minor r200 vertex program cleanups. Remove disabled leftovers from r300 vertex progra...
[mesa.git] / src / mesa / drivers / dri / i965 / intel_blit.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include <stdio.h>
30 #include <errno.h>
31
32 #include "mtypes.h"
33 #include "context.h"
34 #include "enums.h"
35 #include "vblank.h"
36
37 #include "intel_reg.h"
38 #include "intel_batchbuffer.h"
39 #include "intel_context.h"
40 #include "intel_blit.h"
41 #include "intel_regions.h"
42
43 #include "bufmgr.h"
44
45
46
47
48 /*
49 * Copy the back buffer to the front buffer.
50 */
51 void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
52 const drm_clip_rect_t *rect )
53 {
54 struct intel_context *intel;
55 GLboolean missed_target;
56 int64_t ust;
57
58 DBG("%s\n", __FUNCTION__);
59
60 assert(dPriv);
61 assert(dPriv->driContextPriv);
62 assert(dPriv->driContextPriv->driverPrivate);
63
64 intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
65 intelFlush( &intel->ctx );
66
67
68 bmFinishFence(intel, intel->last_swap_fence);
69
70 /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
71 * should work regardless.
72 */
73 LOCK_HARDWARE( intel );
74
75 if (!rect)
76 {
77 /* This is a really crappy way to do wait-for-vblank. I guess
78 * it sortof works in the single-application case.
79 */
80 UNLOCK_HARDWARE( intel );
81 driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
82 LOCK_HARDWARE( intel );
83 }
84
85 {
86 intelScreenPrivate *intelScreen = intel->intelScreen;
87 __DRIdrawablePrivate *dPriv = intel->driDrawable;
88 int nbox = dPriv->numClipRects;
89 drm_clip_rect_t *pbox = dPriv->pClipRects;
90 int cpp = intelScreen->cpp;
91 struct intel_region *src, *dst;
92 int BR13, CMD;
93 int i;
94 int src_pitch, dst_pitch;
95
96 if (intel->sarea->pf_current_page == 0) {
97 dst = intel->front_region;
98 src = intel->back_region;
99 }
100 else {
101 assert(0);
102 src = intel->front_region;
103 dst = intel->back_region;
104 }
105
106 src_pitch = src->pitch * src->cpp;
107 dst_pitch = dst->pitch * dst->cpp;
108
109 if (cpp == 2) {
110 BR13 = (0xCC << 16) | (1<<24);
111 CMD = XY_SRC_COPY_BLT_CMD;
112 }
113 else {
114 BR13 = (0xCC << 16) | (1<<24) | (1<<25);
115 CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
116 XY_SRC_COPY_BLT_WRITE_RGB);
117 }
118
119 if (src->tiled) {
120 CMD |= XY_SRC_TILED;
121 src_pitch /= 4;
122 }
123
124 if (dst->tiled) {
125 CMD |= XY_DST_TILED;
126 dst_pitch /= 4;
127 }
128
129 for (i = 0 ; i < nbox; i++, pbox++)
130 {
131 drm_clip_rect_t tmp = *pbox;
132
133 if (rect) {
134 if (!intel_intersect_cliprects(&tmp, &tmp, rect))
135 continue;
136 }
137
138
139 if (tmp.x1 > tmp.x2 ||
140 tmp.y1 > tmp.y2 ||
141 tmp.x2 > intelScreen->width ||
142 tmp.y2 > intelScreen->height)
143 continue;
144
145 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
146 OUT_BATCH( CMD );
147 OUT_BATCH( dst_pitch | BR13 );
148 OUT_BATCH( (tmp.y1 << 16) | tmp.x1 );
149 OUT_BATCH( (tmp.y2 << 16) | tmp.x2 );
150 OUT_BATCH( bmBufferOffset(intel, dst->buffer) );
151 OUT_BATCH( (tmp.y1 << 16) | tmp.x1 );
152 OUT_BATCH( src_pitch );
153 OUT_BATCH( bmBufferOffset(intel, src->buffer) );
154 ADVANCE_BATCH();
155 }
156 }
157
158 intel_batchbuffer_flush( intel->batch );
159 intel->second_last_swap_fence = intel->last_swap_fence;
160 intel->last_swap_fence = bmSetFence( intel );
161 UNLOCK_HARDWARE( intel );
162
163 if (!rect)
164 {
165 intel->swap_count++;
166 (*dri_interface->getUST)(&ust);
167 if (missed_target) {
168 intel->swap_missed_count++;
169 intel->swap_missed_ust = ust - intel->swap_ust;
170 }
171
172 intel->swap_ust = ust;
173 }
174
175 }
176
177
178
179
180 void intelEmitFillBlit( struct intel_context *intel,
181 GLuint cpp,
182 GLshort dst_pitch,
183 struct buffer *dst_buffer,
184 GLuint dst_offset,
185 GLboolean dst_tiled,
186 GLshort x, GLshort y,
187 GLshort w, GLshort h,
188 GLuint color )
189 {
190 GLuint BR13, CMD;
191 BATCH_LOCALS;
192
193 dst_pitch *= cpp;
194
195 switch(cpp) {
196 case 1:
197 case 2:
198 case 3:
199 BR13 = (0xF0 << 16) | (1<<24);
200 CMD = XY_COLOR_BLT_CMD;
201 break;
202 case 4:
203 BR13 = (0xF0 << 16) | (1<<24) | (1<<25);
204 CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
205 XY_COLOR_BLT_WRITE_RGB);
206 break;
207 default:
208 return;
209 }
210
211 if (dst_tiled) {
212 CMD |= XY_DST_TILED;
213 dst_pitch /= 4;
214 }
215
216 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
217 OUT_BATCH( CMD );
218 OUT_BATCH( dst_pitch | BR13 );
219 OUT_BATCH( (y << 16) | x );
220 OUT_BATCH( ((y+h) << 16) | (x+w) );
221 OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset );
222 OUT_BATCH( color );
223 ADVANCE_BATCH();
224 }
225
226
227 /* Copy BitBlt
228 */
229 void intelEmitCopyBlit( struct intel_context *intel,
230 GLuint cpp,
231 GLshort src_pitch,
232 struct buffer *src_buffer,
233 GLuint src_offset,
234 GLboolean src_tiled,
235 GLshort dst_pitch,
236 struct buffer *dst_buffer,
237 GLuint dst_offset,
238 GLboolean dst_tiled,
239 GLshort src_x, GLshort src_y,
240 GLshort dst_x, GLshort dst_y,
241 GLshort w, GLshort h )
242 {
243 GLuint CMD, BR13;
244 int dst_y2 = dst_y + h;
245 int dst_x2 = dst_x + w;
246 BATCH_LOCALS;
247
248
249 DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d\n",
250 __FUNCTION__,
251 src_buffer, src_pitch, src_x, src_y,
252 dst_buffer, dst_pitch, dst_x, dst_y,
253 w,h);
254
255 src_pitch *= cpp;
256 dst_pitch *= cpp;
257
258 switch(cpp) {
259 case 1:
260 case 2:
261 case 3:
262 BR13 = (0xCC << 16) | (1<<24);
263 CMD = XY_SRC_COPY_BLT_CMD;
264 break;
265 case 4:
266 BR13 = (0xCC << 16) | (1<<24) | (1<<25);
267 CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
268 XY_SRC_COPY_BLT_WRITE_RGB);
269 break;
270 default:
271 return;
272 }
273
274 if (src_tiled) {
275 CMD |= XY_SRC_TILED;
276 src_pitch /= 4;
277 }
278
279 if (dst_tiled) {
280 CMD |= XY_DST_TILED;
281 dst_pitch /= 4;
282 }
283
284 if (dst_y2 < dst_y ||
285 dst_x2 < dst_x) {
286 return;
287 }
288
289 dst_pitch &= 0xffff;
290 src_pitch &= 0xffff;
291
292 /* Initial y values don't seem to work with negative pitches. If
293 * we adjust the offsets manually (below), it seems to work fine.
294 */
295 if (0) {
296 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
297 OUT_BATCH( CMD );
298 OUT_BATCH( dst_pitch | BR13 );
299 OUT_BATCH( (dst_y << 16) | dst_x );
300 OUT_BATCH( (dst_y2 << 16) | dst_x2 );
301 OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset );
302 OUT_BATCH( (src_y << 16) | src_x );
303 OUT_BATCH( src_pitch );
304 OUT_BATCH( bmBufferOffset(intel, src_buffer) + src_offset );
305 ADVANCE_BATCH();
306 }
307 else {
308 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
309 OUT_BATCH( CMD );
310 OUT_BATCH( (dst_pitch & 0xffff) | BR13 );
311 OUT_BATCH( (0 << 16) | dst_x );
312 OUT_BATCH( (h << 16) | dst_x2 );
313 OUT_BATCH( bmBufferOffset(intel, dst_buffer) + dst_offset + dst_y * dst_pitch );
314 OUT_BATCH( (0 << 16) | src_x );
315 OUT_BATCH( (src_pitch & 0xffff) );
316 OUT_BATCH( bmBufferOffset(intel, src_buffer) + src_offset + src_y * src_pitch );
317 ADVANCE_BATCH();
318 }
319 }
320
321
322
323 void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
324 GLint cx1, GLint cy1, GLint cw, GLint ch)
325 {
326 struct intel_context *intel = intel_context( ctx );
327 intelScreenPrivate *intelScreen = intel->intelScreen;
328 GLuint clear_depth, clear_color;
329 GLint cx, cy;
330 GLint cpp = intelScreen->cpp;
331 GLint i;
332 struct intel_region *front = intel->front_region;
333 struct intel_region *back = intel->back_region;
334 struct intel_region *depth = intel->depth_region;
335 GLuint BR13, FRONT_CMD, BACK_CMD, DEPTH_CMD;
336 GLuint front_pitch;
337 GLuint back_pitch;
338 GLuint depth_pitch;
339 BATCH_LOCALS;
340
341
342 clear_color = intel->ClearColor;
343 clear_depth = 0;
344
345 if (flags & BUFFER_BIT_DEPTH) {
346 clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
347 }
348
349 if (flags & BUFFER_BIT_STENCIL) {
350 clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
351 }
352
353 switch(cpp) {
354 case 2:
355 BR13 = (0xF0 << 16) | (1<<24);
356 BACK_CMD = FRONT_CMD = XY_COLOR_BLT_CMD;
357 DEPTH_CMD = XY_COLOR_BLT_CMD;
358 break;
359 case 4:
360 BR13 = (0xF0 << 16) | (1<<24) | (1<<25);
361 BACK_CMD = FRONT_CMD = (XY_COLOR_BLT_CMD |
362 XY_COLOR_BLT_WRITE_ALPHA |
363 XY_COLOR_BLT_WRITE_RGB);
364 DEPTH_CMD = XY_COLOR_BLT_CMD;
365 if (flags & BUFFER_BIT_DEPTH) DEPTH_CMD |= XY_COLOR_BLT_WRITE_RGB;
366 if (flags & BUFFER_BIT_STENCIL) DEPTH_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
367 break;
368 default:
369 return;
370 }
371
372
373
374 intelFlush( &intel->ctx );
375 LOCK_HARDWARE( intel );
376 {
377 /* Refresh the cx/y/w/h values as they may have been invalidated
378 * by a new window position or size picked up when we did
379 * LOCK_HARDWARE above. The values passed by mesa are not
380 * reliable.
381 */
382 {
383 cx = ctx->DrawBuffer->_Xmin;
384 cy = ctx->DrawBuffer->_Ymin;
385 ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
386 cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
387 }
388
389 /* flip top to bottom */
390 cy = intel->driDrawable->h-cy1-ch;
391 cx = cx1 + intel->drawX;
392 cy += intel->drawY;
393
394 /* adjust for page flipping */
395 if ( intel->sarea->pf_current_page == 0 ) {
396 front = intel->front_region;
397 back = intel->back_region;
398 }
399 else {
400 back = intel->front_region;
401 front = intel->back_region;
402 }
403
404 front_pitch = front->pitch * front->cpp;
405 back_pitch = back->pitch * back->cpp;
406 depth_pitch = depth->pitch * depth->cpp;
407
408 if (front->tiled) {
409 FRONT_CMD |= XY_DST_TILED;
410 front_pitch /= 4;
411 }
412
413 if (back->tiled) {
414 BACK_CMD |= XY_DST_TILED;
415 back_pitch /= 4;
416 }
417
418 if (depth->tiled) {
419 DEPTH_CMD |= XY_DST_TILED;
420 depth_pitch /= 4;
421 }
422
423 for (i = 0 ; i < intel->numClipRects ; i++)
424 {
425 drm_clip_rect_t *box = &intel->pClipRects[i];
426 drm_clip_rect_t b;
427
428 if (!all) {
429 GLint x = box->x1;
430 GLint y = box->y1;
431 GLint w = box->x2 - x;
432 GLint h = box->y2 - y;
433
434 if (x < cx) w -= cx - x, x = cx;
435 if (y < cy) h -= cy - y, y = cy;
436 if (x + w > cx + cw) w = cx + cw - x;
437 if (y + h > cy + ch) h = cy + ch - y;
438 if (w <= 0) continue;
439 if (h <= 0) continue;
440
441 b.x1 = x;
442 b.y1 = y;
443 b.x2 = x + w;
444 b.y2 = y + h;
445 } else {
446 b = *box;
447 }
448
449
450 if (b.x1 > b.x2 ||
451 b.y1 > b.y2 ||
452 b.x2 > intelScreen->width ||
453 b.y2 > intelScreen->height)
454 continue;
455
456 if ( flags & BUFFER_BIT_FRONT_LEFT ) {
457 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
458 OUT_BATCH( FRONT_CMD );
459 OUT_BATCH( front_pitch | BR13 );
460 OUT_BATCH( (b.y1 << 16) | b.x1 );
461 OUT_BATCH( (b.y2 << 16) | b.x2 );
462 OUT_BATCH( bmBufferOffset(intel, front->buffer) );
463 OUT_BATCH( clear_color );
464 ADVANCE_BATCH();
465 }
466
467 if ( flags & BUFFER_BIT_BACK_LEFT ) {
468 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
469 OUT_BATCH( BACK_CMD );
470 OUT_BATCH( back_pitch | BR13 );
471 OUT_BATCH( (b.y1 << 16) | b.x1 );
472 OUT_BATCH( (b.y2 << 16) | b.x2 );
473 OUT_BATCH( bmBufferOffset(intel, back->buffer) );
474 OUT_BATCH( clear_color );
475 ADVANCE_BATCH();
476 }
477
478 if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
479 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
480 OUT_BATCH( DEPTH_CMD );
481 OUT_BATCH( depth_pitch | BR13 );
482 OUT_BATCH( (b.y1 << 16) | b.x1 );
483 OUT_BATCH( (b.y2 << 16) | b.x2 );
484 OUT_BATCH( bmBufferOffset(intel, depth->buffer) );
485 OUT_BATCH( clear_depth );
486 ADVANCE_BATCH();
487 }
488 }
489 }
490 intel_batchbuffer_flush( intel->batch );
491 UNLOCK_HARDWARE( intel );
492 }
493
494