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"
38 #include "i830_context.h"
41 /* A large amount of state doesn't need to be uploaded.
43 #define ACTIVE (I830_UPLOAD_INVARIENT | \
44 I830_UPLOAD_TEXBLEND(0) | \
45 I830_UPLOAD_STIPPLE | \
47 I830_UPLOAD_BUFFERS | \
51 #define SET_STATE( i830, STATE ) \
53 assert(!i830->intel.prim.flush); \
54 i830->current->emitted = 0; \
55 i830->current = &i830->STATE; \
56 i830->current->emitted = 0; \
59 /* Operations where the 3D engine is decoupled temporarily from the
60 * current GL state and used for other purposes than simply rendering
63 static void set_initial_state( i830ContextPtr i830
)
65 memcpy(&i830
->meta
, &i830
->initial
, sizeof(i830
->meta
) );
66 i830
->meta
.active
= ACTIVE
;
67 i830
->meta
.emitted
= 0;
71 static void set_no_depth_stencil_write( i830ContextPtr i830
)
73 /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
75 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
76 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_STENCIL_WRITE
;
77 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
78 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_STENCIL_WRITE
;
81 /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
83 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
84 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
85 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
86 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
88 i830
->meta
.emitted
&= ~I830_UPLOAD_CTX
;
91 /* Set stencil unit to replace always with the reference value.
93 static void set_stencil_replace( i830ContextPtr i830
,
97 /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE )
99 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
100 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
103 /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE )
105 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
106 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
107 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
108 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
110 /* ctx->Driver.StencilMask( ctx, s_mask )
112 i830
->meta
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
113 i830
->meta
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_WRITE_MASK
|
114 STENCIL_WRITE_MASK((s_mask
&0xff)));
116 /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE )
118 i830
->meta
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_OPS_MASK
);
119 i830
->meta
.Ctx
[I830_CTXREG_STENCILTST
] |=
120 (ENABLE_STENCIL_PARMS
|
121 STENCIL_FAIL_OP(STENCILOP_REPLACE
) |
122 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE
) |
123 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE
));
125 /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 )
127 i830
->meta
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_TEST_MASK
;
128 i830
->meta
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_TEST_MASK
|
129 STENCIL_TEST_MASK(0xff));
131 i830
->meta
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_REF_VALUE_MASK
|
132 ENABLE_STENCIL_TEST_FUNC_MASK
);
133 i830
->meta
.Ctx
[I830_CTXREG_STENCILTST
] |=
134 (ENABLE_STENCIL_REF_VALUE
|
135 ENABLE_STENCIL_TEST_FUNC
|
136 STENCIL_REF_VALUE((s_clear
&0xff)) |
137 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
));
141 i830
->meta
.emitted
&= ~I830_UPLOAD_CTX
;
145 static void set_color_mask( i830ContextPtr i830
, GLboolean state
)
147 const GLuint mask
= ((1 << WRITEMASK_RED_SHIFT
) |
148 (1 << WRITEMASK_GREEN_SHIFT
) |
149 (1 << WRITEMASK_BLUE_SHIFT
) |
150 (1 << WRITEMASK_ALPHA_SHIFT
));
152 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~mask
;
155 i830
->meta
.Ctx
[I830_CTXREG_ENABLES_2
] |=
156 (i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] & mask
);
159 i830
->meta
.emitted
&= ~I830_UPLOAD_CTX
;
162 /* Installs a one-stage passthrough texture blend pipeline. Is there
163 * more that can be done to turn off texturing?
165 static void set_no_texture( i830ContextPtr i830
)
167 static const struct gl_tex_env_combine_state comb
= {
169 { GL_TEXTURE
, 0, 0, }, { GL_TEXTURE
, 0, 0, },
170 { GL_SRC_COLOR
, 0, 0 }, { GL_SRC_ALPHA
, 0, 0 },
174 i830
->meta
.TexBlendWordsUsed
[0] =
175 i830SetTexEnvCombine( i830
, & comb
, 0, TEXBLENDARG_TEXEL0
,
176 i830
->meta
.TexBlend
[0], NULL
);
178 i830
->meta
.TexBlend
[0][0] |= TEXOP_LAST_STAGE
;
179 i830
->meta
.emitted
&= ~I830_UPLOAD_TEXBLEND(0);
182 /* Set up a single element blend stage for 'replace' texturing with no
185 static void enable_texture_blend_replace( i830ContextPtr i830
)
187 static const struct gl_tex_env_combine_state comb
= {
188 GL_REPLACE
, GL_REPLACE
,
189 { GL_TEXTURE
, GL_TEXTURE
, GL_TEXTURE
}, { GL_TEXTURE
, GL_TEXTURE
, GL_TEXTURE
, },
190 { GL_SRC_COLOR
, GL_SRC_COLOR
, GL_SRC_COLOR
}, { GL_SRC_ALPHA
, GL_SRC_ALPHA
, GL_SRC_ALPHA
},
194 i830
->meta
.TexBlendWordsUsed
[0] =
195 i830SetTexEnvCombine( i830
, & comb
, 0, TEXBLENDARG_TEXEL0
,
196 i830
->meta
.TexBlend
[0], NULL
);
198 i830
->meta
.TexBlend
[0][0] |= TEXOP_LAST_STAGE
;
199 i830
->meta
.emitted
&= ~I830_UPLOAD_TEXBLEND(0);
201 /* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */
202 /* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */
207 /* Set up an arbitary piece of memory as a rectangular texture
208 * (including the front or back buffer).
210 static void set_tex_rect_source( i830ContextPtr i830
,
214 GLuint pitch
, /* in bytes */
215 GLuint textureFormat
)
218 GLuint
*setup
= i830
->meta
.Tex
[0];
220 /* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
221 /* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
223 setup
[I830_TEXREG_TM0LI
] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2
|
224 (LOAD_TEXTURE_MAP0
<< 0) | 4);
225 setup
[I830_TEXREG_TM0S0
] = (TM0S0_USE_FENCE
| offset
);
226 setup
[I830_TEXREG_TM0S1
] = (((height
- 1) << TM0S1_HEIGHT_SHIFT
) |
227 ((width
- 1) << TM0S1_WIDTH_SHIFT
) |
229 setup
[I830_TEXREG_TM0S2
] = ((((pitch
/ 4) - 1) << TM0S2_PITCH_SHIFT
));
230 setup
[I830_TEXREG_TM0S3
] &= ~TM0S3_MAX_MIP_MASK
;
231 setup
[I830_TEXREG_TM0S3
] &= ~TM0S3_MIN_MIP_MASK
;
232 setup
[I830_TEXREG_TM0S3
] |= ((numLevels
- 1)*4) << TM0S3_MIN_MIP_SHIFT
;
234 setup
[I830_TEXREG_MCS
] = (_3DSTATE_MAP_COORD_SET_CMD
|
236 ENABLE_TEXCOORD_PARAMS
|
237 TEXCOORDS_ARE_IN_TEXELUNITS
|
238 TEXCOORDTYPE_CARTESIAN
|
240 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP
) |
242 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP
));
244 i830
->meta
.emitted
&= ~I830_UPLOAD_TEX(0);
248 /* Select between front and back draw buffers.
250 static void set_draw_region( i830ContextPtr i830
,
251 const intelRegion
*region
)
253 i830
->meta
.Buffer
[I830_DESTREG_CBUFADDR1
] =
254 (BUF_3D_ID_COLOR_BACK
| BUF_3D_PITCH(region
->pitch
) | BUF_3D_USE_FENCE
);
255 i830
->meta
.Buffer
[I830_DESTREG_CBUFADDR2
] = region
->offset
;
256 i830
->meta
.emitted
&= ~I830_UPLOAD_BUFFERS
;
259 /* Setup an arbitary draw format, useful for targeting
260 * texture or agp memory.
263 static void set_draw_format( i830ContextPtr i830
,
267 i830
->meta
.Buffer
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
268 DSTORG_VERT_BIAS(0x8) | /* .5 */
276 static void set_vertex_format( i830ContextPtr i830
)
278 i830
->meta
.Ctx
[I830_CTXREG_VF
] = (_3DSTATE_VFT0_CMD
|
283 i830
->meta
.Ctx
[I830_CTXREG_VF2
] = (_3DSTATE_VFT1_CMD
|
284 VFT1_TEX0_FMT(TEXCOORDFMT_2D
) |
285 VFT1_TEX1_FMT(TEXCOORDFMT_2D
) |
286 VFT1_TEX2_FMT(TEXCOORDFMT_2D
) |
287 VFT1_TEX3_FMT(TEXCOORDFMT_2D
));
288 i830
->meta
.emitted
&= ~I830_UPLOAD_CTX
;
292 static void draw_quad(i830ContextPtr i830
,
293 GLfloat x0
, GLfloat x1
,
294 GLfloat y0
, GLfloat y1
,
295 GLubyte red
, GLubyte green
,
296 GLubyte blue
, GLubyte alpha
,
297 GLfloat s0
, GLfloat s1
,
298 GLfloat t0
, GLfloat t1
)
300 GLuint vertex_size
= 8;
301 GLuint
*vb
= intelEmitInlinePrimitiveLocked( &i830
->intel
,
309 /* fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", */
311 /* x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); */
314 /* initial vertex, left bottom */
319 tmp
.v
.color
.red
= red
;
320 tmp
.v
.color
.green
= green
;
321 tmp
.v
.color
.blue
= blue
;
322 tmp
.v
.color
.alpha
= alpha
;
323 tmp
.v
.specular
.red
= 0;
324 tmp
.v
.specular
.green
= 0;
325 tmp
.v
.specular
.blue
= 0;
326 tmp
.v
.specular
.alpha
= 0;
329 for (i
= 0 ; i
< 8 ; i
++)
336 for (i
= 0 ; i
< 8 ; i
++)
343 for (i
= 0 ; i
< 8 ; i
++)
350 for (i
= 0 ; i
< 8 ; i
++)
353 /* fprintf(stderr, "%s: DV1: %x\n", */
354 /* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */
357 static void draw_poly(i830ContextPtr i830
,
358 GLubyte red
, GLubyte green
, GLubyte blue
, GLubyte alpha
,
361 GLfloat texcoords
[][2])
363 GLuint vertex_size
= 8;
364 GLuint
*vb
= intelEmitInlinePrimitiveLocked( &i830
->intel
,
366 numVerts
* vertex_size
,
371 /* initial constant vertex fields */
374 tmp
.v
.color
.red
= red
;
375 tmp
.v
.color
.green
= green
;
376 tmp
.v
.color
.blue
= blue
;
377 tmp
.v
.color
.alpha
= alpha
;
378 tmp
.v
.specular
.red
= 0;
379 tmp
.v
.specular
.green
= 0;
380 tmp
.v
.specular
.blue
= 0;
381 tmp
.v
.specular
.alpha
= 0;
383 for (k
= 0; k
< numVerts
; k
++) {
384 tmp
.v
.x
= verts
[k
][0];
385 tmp
.v
.y
= verts
[k
][1];
386 tmp
.v
.u0
= texcoords
[k
][0];
387 tmp
.v
.v0
= texcoords
[k
][1];
389 for (i
= 0 ; i
< vertex_size
; i
++)
397 i830ClearWithTris(intelContextPtr intel
, GLbitfield mask
,
399 GLint cx
, GLint cy
, GLint cw
, GLint ch
)
401 i830ContextPtr i830
= I830_CONTEXT( intel
);
402 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
403 intelScreenPrivate
*screen
= intel
->intelScreen
;
406 INTEL_FIREVERTICES(intel
);
407 SET_STATE( i830
, meta
);
408 set_initial_state( i830
);
409 /* set_no_texture( i830 ); */
410 set_vertex_format( i830
);
412 LOCK_HARDWARE(intel
);
426 /* Don't do any clipping to screen - these are window coordinates.
427 * The active cliprects will be applied as for any other geometry.
430 if(mask
& BUFFER_BIT_FRONT_LEFT
) {
431 set_no_depth_stencil_write( i830
);
432 set_color_mask( i830
, GL_TRUE
);
433 set_draw_region( i830
, &screen
->front
);
434 draw_quad(i830
, x0
, x1
, y0
, y1
,
435 intel
->clear_red
, intel
->clear_green
,
436 intel
->clear_blue
, intel
->clear_alpha
,
440 if(mask
& BUFFER_BIT_BACK_LEFT
) {
441 set_no_depth_stencil_write( i830
);
442 set_color_mask( i830
, GL_TRUE
);
443 set_draw_region( i830
, &screen
->back
);
445 draw_quad(i830
, x0
, x1
, y0
, y1
,
446 intel
->clear_red
, intel
->clear_green
,
447 intel
->clear_blue
, intel
->clear_alpha
,
451 if(mask
& BUFFER_BIT_STENCIL
) {
452 set_stencil_replace( i830
,
453 intel
->ctx
.Stencil
.WriteMask
[0],
454 intel
->ctx
.Stencil
.Clear
);
456 set_color_mask( i830
, GL_FALSE
);
457 set_draw_region( i830
, &screen
->front
);
458 draw_quad( i830
, x0
, x1
, y0
, y1
, 0, 0, 0, 0, 0, 0, 0, 0 );
461 UNLOCK_HARDWARE(intel
);
463 INTEL_FIREVERTICES(intel
);
464 SET_STATE( i830
, state
);
471 i830TryTextureReadPixels( GLcontext
*ctx
,
472 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
473 GLenum format
, GLenum type
,
474 const struct gl_pixelstore_attrib
*pack
,
477 i830ContextPtr i830
= I830_CONTEXT(ctx
);
478 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
479 intelScreenPrivate
*screen
= i830
->intel
.intelScreen
;
480 GLint pitch
= pack
->RowLength
? pack
->RowLength
: width
;
481 __DRIdrawablePrivate
*dPriv
= i830
->intel
.driDrawable
;
483 GLenum glTextureFormat
;
484 int src_offset
= i830
->meta
.Buffer
[I830_DESTREG_CBUFADDR2
];
485 int destOffset
= intelAgpOffsetFromVirtual( &i830
->intel
, pixels
);
486 int destFormat
, depthFormat
, destPitch
;
489 if (INTEL_DEBUG
& DEBUG_PIXEL
)
490 fprintf(stderr
, "%s\n", __FUNCTION__
);
493 if ( ctx
->_ImageTransferState
||
497 fprintf(stderr
, "%s: check_color failed\n", __FUNCTION__
);
501 switch (screen
->fbFormat
) {
503 textureFormat
= MAPSURF_16BIT
| MT_16BIT_RGB565
;
504 glTextureFormat
= GL_RGB
;
507 textureFormat
= MAPSURF_16BIT
| MT_16BIT_ARGB1555
;
508 glTextureFormat
= GL_RGBA
;
511 textureFormat
= MAPSURF_32BIT
| MT_32BIT_ARGB8888
;
512 glTextureFormat
= GL_RGBA
;
515 fprintf(stderr
, "%s: textureFormat failed %x\n", __FUNCTION__
,
522 case GL_UNSIGNED_SHORT_5_6_5
:
523 if (format
!= GL_RGB
) return GL_FALSE
;
524 destFormat
= COLR_BUF_RGB565
;
525 depthFormat
= DEPTH_FRMT_16_FIXED
;
526 destPitch
= pitch
* 2;
528 case GL_UNSIGNED_INT_8_8_8_8_REV
:
529 if (format
!= GL_BGRA
) return GL_FALSE
;
530 destFormat
= COLR_BUF_ARGB8888
;
531 depthFormat
= DEPTH_FRMT_24_FIXED_8_OTHER
;
532 destPitch
= pitch
* 4;
535 fprintf(stderr
, "%s: destFormat failed %s\n", __FUNCTION__
,
536 _mesa_lookup_enum_by_nr(type
));
540 destFormat
|= (0x02<<24);
542 /* fprintf(stderr, "type: %s destFormat: %x\n", */
543 /* _mesa_lookup_enum_by_nr(type), */
548 SET_STATE( i830
, meta
);
549 set_initial_state( i830
);
550 set_no_depth_stencil_write( i830
);
552 LOCK_HARDWARE( intel
);
554 intelWaitForIdle( intel
); /* required by GL */
556 if (!driClipRectToFramebuffer(ctx
->ReadBuffer
, &x
, &y
, &width
, &height
)) {
557 UNLOCK_HARDWARE( intel
);
558 SET_STATE(i830
, state
);
559 fprintf(stderr
, "%s: cliprect failed\n", __FUNCTION__
);
564 /* FIXME -- Just emit the correct state
566 if (i830SetParam(i830
->driFd
, I830_SETPARAM_CBUFFER_PITCH
,
568 UNLOCK_HARDWARE( intel
);
569 SET_STATE(i830
, state
);
570 fprintf(stderr
, "%s: setparam failed\n", __FUNCTION__
);
576 y
= dPriv
->h
- y
- height
;
581 /* Set the frontbuffer up as a large rectangular texture.
583 set_tex_rect_source( i830
,
591 enable_texture_blend_replace( i830
);
594 /* Set the 3d engine to draw into the agp memory
597 set_draw_region( i830
, destOffset
);
598 set_draw_format( i830
, destFormat
, depthFormat
);
601 /* Draw a single quad, no cliprects:
603 i830
->intel
.numClipRects
= 1;
604 i830
->intel
.pClipRects
= &tmp
;
605 i830
->intel
.pClipRects
[0].x1
= 0;
606 i830
->intel
.pClipRects
[0].y1
= 0;
607 i830
->intel
.pClipRects
[0].x2
= width
;
608 i830
->intel
.pClipRects
[0].y2
= height
;
613 x
, x
+width
, y
, y
+height
);
615 intelWindowMoved( intel
);
617 UNLOCK_HARDWARE( intel
);
618 intelFinish( ctx
); /* required by GL */
620 SET_STATE( i830
, state
);
626 i830TryTextureDrawPixels( GLcontext
*ctx
,
627 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
628 GLenum format
, GLenum type
,
629 const struct gl_pixelstore_attrib
*unpack
,
630 const GLvoid
*pixels
)
632 intelContextPtr intel
= INTEL_CONTEXT(ctx
);
633 i830ContextPtr i830
= I830_CONTEXT(ctx
);
634 GLint pitch
= unpack
->RowLength
? unpack
->RowLength
: width
;
635 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
637 GLenum glTextureFormat
;
638 int dst_offset
= i830
->meta
.Buffer
[I830_DESTREG_CBUFADDR2
];
639 int src_offset
= intelAgpOffsetFromVirtual( intel
, pixels
);
641 if (INTEL_DEBUG
& DEBUG_PIXEL
)
642 fprintf(stderr
, "%s\n", __FUNCTION__
);
644 /* Todo -- upload images that aren't in agp space, then texture
648 if ( !intelIsAgpMemory( intel
, pixels
, pitch
*height
) ) {
649 fprintf(stderr
, "%s: intelIsAgpMemory failed\n", __FUNCTION__
);
653 /* Todo -- don't want to clobber all the drawing state like we do
654 * for readpixels -- most of this state can be handled just fine.
656 if ( ctx
->_ImageTransferState
||
659 ctx
->Color
.AlphaEnabled
||
662 ctx
->Scissor
.Enabled
||
663 ctx
->Stencil
.Enabled
||
664 !ctx
->Color
.ColorMask
[0] ||
665 !ctx
->Color
.ColorMask
[1] ||
666 !ctx
->Color
.ColorMask
[2] ||
667 !ctx
->Color
.ColorMask
[3] ||
668 ctx
->Color
.ColorLogicOpEnabled
||
669 ctx
->Texture
._EnabledUnits
||
670 ctx
->Depth
.OcclusionTest
) {
671 fprintf(stderr
, "%s: other tests failed\n", __FUNCTION__
);
675 /* Todo -- remove these restrictions:
677 if (ctx
->Pixel
.ZoomX
!= 1.0F
||
678 ctx
->Pixel
.ZoomY
!= -1.0F
)
684 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
685 if (format
!= GL_BGRA
) return GL_FALSE
;
686 textureFormat
= MAPSURF_16BIT
| MT_16BIT_ARGB1555
;
687 glTextureFormat
= GL_RGBA
;
689 case GL_UNSIGNED_SHORT_5_6_5
:
690 if (format
!= GL_RGB
) return GL_FALSE
;
691 textureFormat
= MAPSURF_16BIT
| MT_16BIT_RGB565
;
692 glTextureFormat
= GL_RGB
;
694 case GL_UNSIGNED_SHORT_8_8_MESA
:
695 if (format
!= GL_YCBCR_MESA
) return GL_FALSE
;
696 textureFormat
= (MAPSURF_422
| MT_422_YCRCB_SWAPY
697 /* | TM0S1_COLORSPACE_CONVERSION */
699 glTextureFormat
= GL_YCBCR_MESA
;
701 case GL_UNSIGNED_SHORT_8_8_REV_MESA
:
702 if (format
!= GL_YCBCR_MESA
) return GL_FALSE
;
703 textureFormat
= (MAPSURF_422
| MT_422_YCRCB_NORMAL
704 /* | TM0S1_COLORSPACE_CONVERSION */
706 glTextureFormat
= GL_YCBCR_MESA
;
708 case GL_UNSIGNED_INT_8_8_8_8_REV
:
709 if (format
!= GL_BGRA
) return GL_FALSE
;
710 textureFormat
= MAPSURF_32BIT
| MT_32BIT_ARGB8888
;
711 glTextureFormat
= GL_RGBA
;
714 fprintf(stderr
, "%s: destFormat failed\n", __FUNCTION__
);
720 SET_STATE( i830
, meta
);
722 LOCK_HARDWARE( intel
);
724 intelWaitForIdle( intel
); /* required by GL */
726 y
-= height
; /* cope with pixel zoom */
728 if (!driClipRectToFramebuffer(ctx
->ReadBuffer
, &x
, &y
, &width
, &height
)) {
729 UNLOCK_HARDWARE( intel
);
730 SET_STATE(i830
, state
);
731 fprintf(stderr
, "%s: cliprect failed\n", __FUNCTION__
);
736 y
= dPriv
->h
- y
- height
;
738 set_initial_state( i830
);
740 /* Set the pixel image up as a rectangular texture.
742 set_tex_rect_source( i830
,
746 pitch
, /* XXXX!!!! -- /2 sometimes */
750 enable_texture_blend_replace( i830
);
753 /* Draw to the current draw buffer:
755 set_draw_offset( i830
, dst_offset
);
757 /* Draw a quad, use regular cliprects
759 /* fprintf(stderr, "x: %d y: %d width %d height %d\n", x, y, width, height); */
762 x
, x
+width
, y
, y
+height
,
764 0, width
, 0, height
);
766 intelWindowMoved( intel
);
768 UNLOCK_HARDWARE( intel
);
769 intelFinish( ctx
); /* required by GL */
771 SET_STATE(i830
, state
);
779 * Copy the window contents named by dPriv to the rotated (or reflected)
781 * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source.
784 i830RotateWindow(intelContextPtr intel
, __DRIdrawablePrivate
*dPriv
,
787 i830ContextPtr i830
= I830_CONTEXT( intel
);
788 intelScreenPrivate
*screen
= intel
->intelScreen
;
789 const GLuint cpp
= screen
->cpp
;
790 drm_clip_rect_t fullRect
;
791 GLuint textureFormat
, srcOffset
, srcPitch
;
792 const drm_clip_rect_t
*clipRects
;
797 int origNumClipRects
;
798 drm_clip_rect_t
*origRects
;
801 * set up hardware state
803 intelFlush( &intel
->ctx
);
805 SET_STATE( i830
, meta
);
806 set_initial_state( i830
);
807 set_no_texture( i830
);
808 set_vertex_format( i830
);
809 set_no_depth_stencil_write( i830
);
810 set_color_mask( i830
, GL_FALSE
);
812 LOCK_HARDWARE(intel
);
814 /* save current drawing origin and cliprects (restored at end) */
815 xOrig
= intel
->drawX
;
816 yOrig
= intel
->drawY
;
817 origNumClipRects
= intel
->numClipRects
;
818 origRects
= intel
->pClipRects
;
820 if (!intel
->numClipRects
)
824 * set drawing origin, cliprects for full-screen access to rotated screen
828 fullRect
.x2
= screen
->rotatedWidth
;
829 fullRect
.y2
= screen
->rotatedHeight
;
832 intel
->numClipRects
= 1;
833 intel
->pClipRects
= &fullRect
;
835 set_draw_region( i830
, &screen
->rotated
);
838 textureFormat
= MAPSURF_32BIT
| MT_32BIT_ARGB8888
;
840 textureFormat
= MAPSURF_16BIT
| MT_16BIT_RGB565
;
842 if (srcBuf
== BUFFER_BIT_FRONT_LEFT
) {
843 srcPitch
= screen
->front
.pitch
; /* in bytes */
844 srcOffset
= screen
->front
.offset
; /* bytes */
845 clipRects
= dPriv
->pClipRects
;
846 numClipRects
= dPriv
->numClipRects
;
849 srcPitch
= screen
->back
.pitch
; /* in bytes */
850 srcOffset
= screen
->back
.offset
; /* bytes */
851 clipRects
= dPriv
->pBackClipRects
;
852 numClipRects
= dPriv
->numBackClipRects
;
855 /* set the whole screen up as a texture to avoid alignment issues */
856 set_tex_rect_source(i830
,
863 enable_texture_blend_replace(i830
);
866 * loop over the source window's cliprects
868 for (i
= 0; i
< numClipRects
; i
++) {
869 int srcX0
= clipRects
[i
].x1
;
870 int srcY0
= clipRects
[i
].y1
;
871 int srcX1
= clipRects
[i
].x2
;
872 int srcY1
= clipRects
[i
].y2
;
873 GLfloat verts
[4][2], tex
[4][2];
876 /* build vertices for four corners of clip rect */
877 verts
[0][0] = srcX0
; verts
[0][1] = srcY0
;
878 verts
[1][0] = srcX1
; verts
[1][1] = srcY0
;
879 verts
[2][0] = srcX1
; verts
[2][1] = srcY1
;
880 verts
[3][0] = srcX0
; verts
[3][1] = srcY1
;
882 /* .. and texcoords */
883 tex
[0][0] = srcX0
; tex
[0][1] = srcY0
;
884 tex
[1][0] = srcX1
; tex
[1][1] = srcY0
;
885 tex
[2][0] = srcX1
; tex
[2][1] = srcY1
;
886 tex
[3][0] = srcX0
; tex
[3][1] = srcY1
;
888 /* transform coords to rotated screen coords */
890 for (j
= 0; j
< 4; j
++) {
891 matrix23TransformCoordf(&screen
->rotMatrix
,
892 &verts
[j
][0], &verts
[j
][1]);
895 /* draw polygon to map source image to dest region */
896 draw_poly(i830
, 255, 255, 255, 255, 4, verts
, tex
);
898 } /* cliprect loop */
900 assert(!intel
->prim
.flush
);
901 intelFlushBatchLocked( intel
, GL_FALSE
, GL_FALSE
, GL_FALSE
);
904 /* restore original drawing origin and cliprects */
905 intel
->drawX
= xOrig
;
906 intel
->drawY
= yOrig
;
907 intel
->numClipRects
= origNumClipRects
;
908 intel
->pClipRects
= origRects
;
910 UNLOCK_HARDWARE(intel
);
912 SET_STATE( i830
, state
);