1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
34 #include "intel_screen.h"
35 #include "intel_batchbuffer.h"
36 #include "intel_ioctl.h"
37 #include "intel_rotate.h"
39 #include "i915_context.h"
42 /* A large amount of state doesn't need to be uploaded.
44 #define ACTIVE (I915_UPLOAD_PROGRAM | \
45 I915_UPLOAD_STIPPLE | \
47 I915_UPLOAD_BUFFERS | \
50 #define SET_STATE( i915, STATE ) \
52 i915->current->emitted &= ~ACTIVE; \
53 i915->current = &i915->STATE; \
54 i915->current->emitted &= ~ACTIVE; \
57 /* Operations where the 3D engine is decoupled temporarily from the
58 * current GL state and used for other purposes than simply rendering
61 static void set_initial_state( i915ContextPtr i915
)
63 memcpy(&i915
->meta
, &i915
->initial
, sizeof(i915
->meta
) );
64 i915
->meta
.active
= ACTIVE
;
65 i915
->meta
.emitted
= 0;
69 static void set_no_depth_stencil_write( i915ContextPtr i915
)
71 /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
73 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] &= ~(S5_STENCIL_TEST_ENABLE
|
74 S5_STENCIL_WRITE_ENABLE
);
76 /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
78 i915
->meta
.Ctx
[I915_CTXREG_LIS6
] &= ~(S6_DEPTH_TEST_ENABLE
|
79 S6_DEPTH_WRITE_ENABLE
);
81 i915
->meta
.emitted
&= ~I915_UPLOAD_CTX
;
84 /* Set stencil unit to replace always with the reference value.
86 static void set_stencil_replace( i915ContextPtr i915
,
90 GLuint op
= STENCILOP_REPLACE
;
91 GLuint func
= COMPAREFUNC_ALWAYS
;
93 /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE )
95 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] |= (S5_STENCIL_TEST_ENABLE
|
96 S5_STENCIL_WRITE_ENABLE
);
99 /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
101 i915
->meta
.Ctx
[I915_CTXREG_LIS6
] &= ~(S6_DEPTH_TEST_ENABLE
|
102 S6_DEPTH_WRITE_ENABLE
);
105 /* ctx->Driver.StencilMask( ctx, s_mask )
107 i915
->meta
.Ctx
[I915_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
109 i915
->meta
.Ctx
[I915_CTXREG_STATE4
] |= (ENABLE_STENCIL_WRITE_MASK
|
110 STENCIL_WRITE_MASK(s_mask
));
113 /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE )
115 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] &= ~(S5_STENCIL_FAIL_MASK
|
116 S5_STENCIL_PASS_Z_FAIL_MASK
|
117 S5_STENCIL_PASS_Z_PASS_MASK
);
119 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] |= ((op
<< S5_STENCIL_FAIL_SHIFT
) |
120 (op
<< S5_STENCIL_PASS_Z_FAIL_SHIFT
) |
121 (op
<< S5_STENCIL_PASS_Z_PASS_SHIFT
));
124 /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 )
126 i915
->meta
.Ctx
[I915_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_TEST_MASK
;
127 i915
->meta
.Ctx
[I915_CTXREG_STATE4
] |= (ENABLE_STENCIL_TEST_MASK
|
128 STENCIL_TEST_MASK(0xff));
130 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] &= ~(S5_STENCIL_REF_MASK
|
131 S5_STENCIL_TEST_FUNC_MASK
);
133 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] |= ((s_clear
<< S5_STENCIL_REF_SHIFT
) |
134 (func
<< S5_STENCIL_TEST_FUNC_SHIFT
));
137 i915
->meta
.emitted
&= ~I915_UPLOAD_CTX
;
141 static void set_color_mask( i915ContextPtr i915
, GLboolean state
)
143 const GLuint mask
= (S5_WRITEDISABLE_RED
|
144 S5_WRITEDISABLE_GREEN
|
145 S5_WRITEDISABLE_BLUE
|
146 S5_WRITEDISABLE_ALPHA
);
148 /* Copy colormask state from "regular" hw context.
151 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] &= ~mask
;
152 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] |=
153 (i915
->state
.Ctx
[I915_CTXREG_LIS5
] & mask
);
156 i915
->meta
.Ctx
[I915_CTXREG_LIS5
] |= mask
;
158 i915
->meta
.emitted
&= ~I915_UPLOAD_CTX
;
164 #define REG( type, nr ) (((type)<<5)|(nr))
166 #define REG_R(x) REG(REG_TYPE_R, x)
167 #define REG_T(x) REG(REG_TYPE_T, x)
168 #define REG_CONST(x) REG(REG_TYPE_CONST, x)
169 #define REG_S(x) REG(REG_TYPE_S, x)
170 #define REG_OC REG(REG_TYPE_OC, 0)
171 #define REG_OD REG(REG_TYPE_OD, 0)
172 #define REG_U(x) REG(REG_TYPE_U, x)
174 #define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE)
175 #define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR)
176 #define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W)
177 #define REG_T_TEX(x) REG(REG_TYPE_T, x)
180 #define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT )
181 #define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT )
182 #define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT )
183 #define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT )
184 #define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT )
185 #define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT )
186 #define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT )
188 #define T0_SAMPLER( unit ) ((unit)<<T0_SAMPLER_NR_SHIFT)
190 #define T1_ADDRESS_REG( type, nr ) (((type)<<T1_ADDRESS_REG_TYPE_SHIFT)| \
191 ((nr)<<T1_ADDRESS_REG_NR_SHIFT))
194 #define A1_SRC0_XYZW ((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | \
195 (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) | \
196 (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | \
197 (SRC_W << A1_SRC0_CHANNEL_W_SHIFT))
199 #define A1_SRC1_XY ((SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | \
200 (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT))
202 #define A2_SRC1_ZW ((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | \
203 (SRC_W << A2_SRC1_CHANNEL_W_SHIFT))
205 #define A2_SRC2_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \
206 (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \
207 (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \
208 (SRC_W << A2_SRC2_CHANNEL_W_SHIFT))
214 static void set_no_texture( i915ContextPtr i915
)
216 static const GLuint prog
[] = {
217 _3DSTATE_PIXEL_SHADER_PROGRAM
,
219 /* Declare incoming diffuse color:
222 D0_DECL_REG( REG_T_DIFFUSE
) |
227 /* output-color = mov(t_diffuse)
230 A0_DEST_REG( REG_OC
) |
231 A0_DEST_CHANNEL_ALL
|
232 A0_SRC0_REG( REG_T_DIFFUSE
)),
238 memcpy( i915
->meta
.Program
, prog
, sizeof(prog
) );
239 i915
->meta
.ProgramSize
= sizeof(prog
) / sizeof(*prog
);
240 i915
->meta
.Program
[0] |= i915
->meta
.ProgramSize
- 2;
241 i915
->meta
.emitted
&= ~I915_UPLOAD_PROGRAM
;
245 static void enable_texture_blend_replace( i915ContextPtr i915
)
247 static const GLuint prog
[] = {
248 _3DSTATE_PIXEL_SHADER_PROGRAM
,
250 /* Declare the sampler:
253 D0_DECL_REG( REG_S(0) ) |
259 /* Declare the interpolated texture coordinate:
262 D0_DECL_REG( REG_T_TEX(0) ) |
267 /* output-color = texld(sample0, texcoord0)
270 T0_DEST_REG( REG_OC
) |
272 T1_ADDRESS_REG(REG_TYPE_T
, 0),
276 memcpy( i915
->meta
.Program
, prog
, sizeof(prog
) );
277 i915
->meta
.ProgramSize
= sizeof(prog
) / sizeof(*prog
);
278 i915
->meta
.Program
[0] |= i915
->meta
.ProgramSize
- 2;
279 i915
->meta
.emitted
&= ~I915_UPLOAD_PROGRAM
;
286 /* Set up an arbitary piece of memory as a rectangular texture
287 * (including the front or back buffer).
289 static void set_tex_rect_source( i915ContextPtr i915
,
293 GLuint pitch
, /* in bytes! */
294 GLuint textureFormat
)
298 GLuint
*state
= i915
->meta
.Tex
[0];
301 printf("TexRect source offset 0x%x pitch %d\n", offset
, pitch
);
304 /* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
305 /* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
307 state
[I915_TEXREG_MS2
] = offset
;
308 state
[I915_TEXREG_MS3
] = (((height
- 1) << MS3_HEIGHT_SHIFT
) |
309 ((width
- 1) << MS3_WIDTH_SHIFT
) |
313 state
[I915_TEXREG_MS4
] = ((((pitch
/ 4) - 1) << MS4_PITCH_SHIFT
) |
314 ((((numLevels
-1) * 4)) << MS4_MAX_LOD_SHIFT
));
316 state
[I915_TEXREG_SS2
] = ((FILTER_NEAREST
<< SS2_MIN_FILTER_SHIFT
) |
317 (MIPFILTER_NONE
<< SS2_MIP_FILTER_SHIFT
) |
318 (FILTER_NEAREST
<< SS2_MAG_FILTER_SHIFT
));
319 state
[I915_TEXREG_SS3
] = ((TEXCOORDMODE_WRAP
<< SS3_TCX_ADDR_MODE_SHIFT
) |
320 (TEXCOORDMODE_WRAP
<< SS3_TCY_ADDR_MODE_SHIFT
) |
321 (TEXCOORDMODE_WRAP
<< SS3_TCZ_ADDR_MODE_SHIFT
) |
322 (unit
<<SS3_TEXTUREMAP_INDEX_SHIFT
));
324 state
[I915_TEXREG_SS4
] = 0;
326 i915
->meta
.emitted
&= ~I915_UPLOAD_TEX(0);
330 /* Select between front and back draw buffers.
332 static void set_draw_region( i915ContextPtr i915
, const intelRegion
*region
)
335 printf("Rotate into region: offset 0x%x pitch %d\n",
336 region
->offset
, region
->pitch
);
338 i915
->meta
.Buffer
[I915_DESTREG_CBUFADDR1
] =
339 (BUF_3D_ID_COLOR_BACK
| BUF_3D_PITCH(region
->pitch
) | BUF_3D_USE_FENCE
);
340 i915
->meta
.Buffer
[I915_DESTREG_CBUFADDR2
] = region
->offset
;
341 i915
->meta
.emitted
&= ~I915_UPLOAD_BUFFERS
;
346 /* Setup an arbitary draw format, useful for targeting texture or agp
349 static void set_draw_format( i915ContextPtr i915
,
353 i915
->meta
.Buffer
[I915_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
354 DSTORG_VERT_BIAS(0x8) | /* .5 */
357 TEX_DEFAULT_COLOR_OGL
|
360 i915
->meta
.emitted
&= ~I915_UPLOAD_BUFFERS
;
361 /* fprintf(stderr, "%s: DV1: %x\n", */
362 /* __FUNCTION__, i915->meta.Buffer[I915_DESTREG_DV1]); */
366 static void set_vertex_format( i915ContextPtr i915
)
368 i915
->meta
.Ctx
[I915_CTXREG_LIS2
] =
369 (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D
) |
370 S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT
) |
371 S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT
) |
372 S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT
) |
373 S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT
) |
374 S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT
) |
375 S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT
) |
376 S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT
));
378 i915
->meta
.Ctx
[I915_CTXREG_LIS4
] &= ~S4_VFMT_MASK
;
380 i915
->meta
.Ctx
[I915_CTXREG_LIS4
] |=
385 i915
->meta
.emitted
&= ~I915_UPLOAD_CTX
;
390 static void draw_quad(i915ContextPtr i915
,
391 GLfloat x0
, GLfloat x1
,
392 GLfloat y0
, GLfloat y1
,
393 GLubyte red
, GLubyte green
,
394 GLubyte blue
, GLubyte alpha
,
395 GLfloat s0
, GLfloat s1
,
396 GLfloat t0
, GLfloat t1
)
398 GLuint vertex_size
= 8;
399 GLuint
*vb
= intelEmitInlinePrimitiveLocked( &i915
->intel
,
407 fprintf(stderr
, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n",
409 x0
,y0
,x1
,y1
,red
,green
,blue
,alpha
,s0
,t0
,s1
,t1
);
412 /* initial vertex, left bottom */
417 tmp
.v
.color
.red
= red
;
418 tmp
.v
.color
.green
= green
;
419 tmp
.v
.color
.blue
= blue
;
420 tmp
.v
.color
.alpha
= alpha
;
421 tmp
.v
.specular
.red
= 0;
422 tmp
.v
.specular
.green
= 0;
423 tmp
.v
.specular
.blue
= 0;
424 tmp
.v
.specular
.alpha
= 0;
428 for (i
= 0 ; i
< vertex_size
; i
++)
435 for (i
= 0 ; i
< vertex_size
; i
++)
442 for (i
= 0 ; i
< vertex_size
; i
++)
449 for (i
= 0 ; i
< vertex_size
; i
++)
454 static void draw_poly(i915ContextPtr i915
,
455 GLubyte red
, GLubyte green
, GLubyte blue
, GLubyte alpha
,
457 /*const*/ GLfloat verts
[][2],
458 /*const*/ GLfloat texcoords
[][2])
460 GLuint vertex_size
= 8;
461 GLuint
*vb
= intelEmitInlinePrimitiveLocked( &i915
->intel
,
463 numVerts
* vertex_size
,
468 /* initial constant vertex fields */
471 tmp
.v
.color
.red
= red
;
472 tmp
.v
.color
.green
= green
;
473 tmp
.v
.color
.blue
= blue
;
474 tmp
.v
.color
.alpha
= alpha
;
475 tmp
.v
.specular
.red
= 0;
476 tmp
.v
.specular
.green
= 0;
477 tmp
.v
.specular
.blue
= 0;
478 tmp
.v
.specular
.alpha
= 0;
480 for (k
= 0; k
< numVerts
; k
++) {
481 tmp
.v
.x
= verts
[k
][0];
482 tmp
.v
.y
= verts
[k
][1];
483 tmp
.v
.u0
= texcoords
[k
][0];
484 tmp
.v
.v0
= texcoords
[k
][1];
486 for (i
= 0 ; i
< vertex_size
; i
++)
495 i915ClearWithTris(intelContextPtr intel
, GLbitfield mask
,
497 GLint cx
, GLint cy
, GLint cw
, GLint ch
)
499 i915ContextPtr i915
= I915_CONTEXT( intel
);
500 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
501 intelScreenPrivate
*screen
= intel
->intelScreen
;
504 SET_STATE( i915
, meta
);
505 set_initial_state( i915
);
506 set_no_texture( i915
);
507 set_vertex_format( i915
);
509 LOCK_HARDWARE(intel
);
523 /* Don't do any clipping to screen - these are window coordinates.
524 * The active cliprects will be applied as for any other geometry.
527 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
528 set_no_depth_stencil_write( i915
);
529 set_color_mask( i915
, GL_TRUE
);
530 set_draw_region( i915
, &screen
->front
);
532 draw_quad(i915
, x0
, x1
, y0
, y1
,
533 intel
->clear_red
, intel
->clear_green
,
534 intel
->clear_blue
, intel
->clear_alpha
,
538 if (mask
& BUFFER_BIT_BACK_LEFT
) {
539 set_no_depth_stencil_write( i915
);
540 set_color_mask( i915
, GL_TRUE
);
541 set_draw_region( i915
, &screen
->back
);
543 draw_quad(i915
, x0
, x1
, y0
, y1
,
544 intel
->clear_red
, intel
->clear_green
,
545 intel
->clear_blue
, intel
->clear_alpha
,
549 if (mask
& BUFFER_BIT_STENCIL
) {
550 set_stencil_replace( i915
,
551 intel
->ctx
.Stencil
.WriteMask
[0],
552 intel
->ctx
.Stencil
.Clear
);
554 set_color_mask( i915
, GL_FALSE
);
555 set_draw_region( i915
, &screen
->front
); /* could be either? */
557 draw_quad( i915
, x0
, x1
, y0
, y1
, 0, 0, 0, 0, 0, 0, 0, 0 );
560 UNLOCK_HARDWARE(intel
);
562 SET_STATE( i915
, state
);
567 * Copy the window contents named by dPriv to the rotated (or reflected)
569 * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source.
572 i915RotateWindow(intelContextPtr intel
, __DRIdrawablePrivate
*dPriv
,
575 i915ContextPtr i915
= I915_CONTEXT( intel
);
576 intelScreenPrivate
*screen
= intel
->intelScreen
;
577 const GLuint cpp
= screen
->cpp
;
578 drm_clip_rect_t fullRect
;
579 GLuint textureFormat
, srcOffset
, srcPitch
;
580 const drm_clip_rect_t
*clipRects
;
585 int origNumClipRects
;
586 drm_clip_rect_t
*origRects
;
589 * set up hardware state
591 intelFlush( &intel
->ctx
);
593 SET_STATE( i915
, meta
);
594 set_initial_state( i915
);
595 set_no_texture( i915
);
596 set_vertex_format( i915
);
597 set_no_depth_stencil_write( i915
);
598 set_color_mask( i915
, GL_TRUE
);
600 LOCK_HARDWARE(intel
);
602 /* save current drawing origin and cliprects (restored at end) */
603 xOrig
= intel
->drawX
;
604 yOrig
= intel
->drawY
;
605 origNumClipRects
= intel
->numClipRects
;
606 origRects
= intel
->pClipRects
;
608 if (!intel
->numClipRects
)
612 * set drawing origin, cliprects for full-screen access to rotated screen
616 fullRect
.x2
= screen
->rotatedWidth
;
617 fullRect
.y2
= screen
->rotatedHeight
;
620 intel
->numClipRects
= 1;
621 intel
->pClipRects
= &fullRect
;
623 set_draw_region( i915
, &screen
->rotated
);
626 textureFormat
= MAPSURF_32BIT
| MT_32BIT_ARGB8888
;
628 textureFormat
= MAPSURF_16BIT
| MT_16BIT_RGB565
;
630 if (srcBuf
== BUFFER_BIT_FRONT_LEFT
) {
631 srcPitch
= screen
->front
.pitch
; /* in bytes */
632 srcOffset
= screen
->front
.offset
; /* bytes */
633 clipRects
= dPriv
->pClipRects
;
634 numClipRects
= dPriv
->numClipRects
;
637 srcPitch
= screen
->back
.pitch
; /* in bytes */
638 srcOffset
= screen
->back
.offset
; /* bytes */
639 clipRects
= dPriv
->pBackClipRects
;
640 numClipRects
= dPriv
->numBackClipRects
;
643 /* set the whole screen up as a texture to avoid alignment issues */
644 set_tex_rect_source(i915
,
651 enable_texture_blend_replace(i915
);
654 * loop over the source window's cliprects
656 for (i
= 0; i
< numClipRects
; i
++) {
657 int srcX0
= clipRects
[i
].x1
;
658 int srcY0
= clipRects
[i
].y1
;
659 int srcX1
= clipRects
[i
].x2
;
660 int srcY1
= clipRects
[i
].y2
;
661 GLfloat verts
[4][2], tex
[4][2];
664 /* build vertices for four corners of clip rect */
665 verts
[0][0] = srcX0
; verts
[0][1] = srcY0
;
666 verts
[1][0] = srcX1
; verts
[1][1] = srcY0
;
667 verts
[2][0] = srcX1
; verts
[2][1] = srcY1
;
668 verts
[3][0] = srcX0
; verts
[3][1] = srcY1
;
670 /* .. and texcoords */
671 tex
[0][0] = srcX0
; tex
[0][1] = srcY0
;
672 tex
[1][0] = srcX1
; tex
[1][1] = srcY0
;
673 tex
[2][0] = srcX1
; tex
[2][1] = srcY1
;
674 tex
[3][0] = srcX0
; tex
[3][1] = srcY1
;
676 /* transform coords to rotated screen coords */
677 for (j
= 0; j
< 4; j
++) {
678 matrix23TransformCoordf(&screen
->rotMatrix
,
679 &verts
[j
][0], &verts
[j
][1]);
682 /* draw polygon to map source image to dest region */
683 draw_poly(i915
, 255, 255, 255, 255, 4, verts
, tex
);
685 } /* cliprect loop */
687 intelFlushBatchLocked( intel
, GL_FALSE
, GL_FALSE
, GL_FALSE
);
690 /* restore original drawing origin and cliprects */
691 intel
->drawX
= xOrig
;
692 intel
->drawY
= yOrig
;
693 intel
->numClipRects
= origNumClipRects
;
694 intel
->pClipRects
= origRects
;
696 UNLOCK_HARDWARE(intel
);
698 SET_STATE( i915
, state
);