2 * GLX Hardware Device Driver for Intel i810
3 * Copyright (C) 1999 Keith Whitwell
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
21 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include "texformat.h"
29 #include "simple_list.h"
34 #include "i810screen.h"
37 #include "i810context.h"
39 #include "i810state.h"
40 #include "i810ioctl.h"
45 static void i810SetTexImages( i810ContextPtr imesa
,
46 struct gl_texture_object
*tObj
)
48 GLuint height
, width
, pitch
, i
, textureFormat
, log_pitch
;
49 i810TextureObjectPtr t
= (i810TextureObjectPtr
) tObj
->DriverData
;
50 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
52 GLint log2Width
, log2Height
;
54 /* fprintf(stderr, "%s\n", __FUNCTION__); */
57 switch (baseImage
->TexFormat
->MesaFormat
) {
58 case MESA_FORMAT_ARGB1555
:
59 textureFormat
= MI1_FMT_16BPP
| MI1_PF_16BPP_ARGB1555
;
61 case MESA_FORMAT_ARGB4444
:
62 textureFormat
= MI1_FMT_16BPP
| MI1_PF_16BPP_ARGB4444
;
64 case MESA_FORMAT_RGB565
:
65 textureFormat
= MI1_FMT_16BPP
| MI1_PF_16BPP_RGB565
;
67 case MESA_FORMAT_AL88
:
68 textureFormat
= MI1_FMT_16BPP
| MI1_PF_16BPP_AY88
;
70 case MESA_FORMAT_YCBCR
:
71 textureFormat
= MI1_FMT_422
| MI1_PF_422_YCRCB_SWAP_Y
72 | MI1_COLOR_CONV_ENABLE
;
74 case MESA_FORMAT_YCBCR_REV
:
75 textureFormat
= MI1_FMT_422
| MI1_PF_422_YCRCB
76 | MI1_COLOR_CONV_ENABLE
;
79 textureFormat
= MI1_FMT_8CI
| MI1_PF_8CI_ARGB4444
;
84 fprintf(stderr
, "i810SetTexImages: bad image->Format\n" );
88 driCalculateTextureFirstLastLevel( (driTextureObject
*) t
);
90 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
92 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
93 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
95 /* Figure out the amount of memory required to hold all the mipmap
96 * levels. Choose the smallest pitch to accomodate the largest
99 width
= tObj
->Image
[0][t
->base
.firstLevel
]->Width
* t
->texelBytes
;
100 for (pitch
= 32, log_pitch
=2 ; pitch
< width
; pitch
*= 2 )
103 /* All images must be loaded at this pitch. Count the number of
106 for ( height
= i
= 0 ; i
< numLevels
; i
++ ) {
107 t
->image
[i
].image
= tObj
->Image
[0][t
->base
.firstLevel
+ i
];
108 t
->image
[i
].offset
= height
* pitch
;
109 t
->image
[i
].internalFormat
= baseImage
->Format
;
110 height
+= t
->image
[i
].image
->Height
;
114 t
->base
.totalSize
= height
*pitch
;
116 t
->dirty
= I810_UPLOAD_TEX0
| I810_UPLOAD_TEX1
;
117 t
->Setup
[I810_TEXREG_MI1
] = (MI1_MAP_0
| textureFormat
| log_pitch
);
118 t
->Setup
[I810_TEXREG_MI2
] = (MI2_DIMENSIONS_ARE_LOG2
|
119 (log2Height
<< 16) | log2Width
);
120 t
->Setup
[I810_TEXREG_MLL
] = (GFX_OP_MAP_LOD_LIMITS
|
124 ((numLevels
- 1) << MLL_MIN_MIP_SHIFT
));
126 LOCK_HARDWARE( imesa
);
127 i810UploadTexImagesLocked( imesa
, t
);
128 UNLOCK_HARDWARE( imesa
);
131 /* ================================================================
132 * Texture combine functions
135 #define I810_DISABLE 0
136 #define I810_PASSTHRU 1
137 #define I810_REPLACE 2
138 #define I810_MODULATE 3
141 #define I810_ALPHA_BLEND 6
143 #define I810_MAX_COMBFUNC 8
146 static GLuint i810_color_combine
[][I810_MAX_COMBFUNC
] =
151 /* Disable combiner stage
153 ( GFX_OP_MAP_COLOR_STAGES
|
158 MC_ARG1_ITERATED_COLOR
|
162 MC_OP_ARG1
), /* actually passthru */
166 ( GFX_OP_MAP_COLOR_STAGES
|
171 MC_ARG1_ITERATED_COLOR
|
179 ( GFX_OP_MAP_COLOR_STAGES
|
192 ( GFX_OP_MAP_COLOR_STAGES
|
199 MC_ARG2_ITERATED_COLOR
|
205 ( GFX_OP_MAP_COLOR_STAGES
|
210 MC_ARG1_COLOR_FACTOR
|
214 MC_OP_LIN_BLEND_TEX0_ALPHA
),
218 ( GFX_OP_MAP_COLOR_STAGES
|
223 MC_ARG1_COLOR_FACTOR
|
225 MC_ARG2_ITERATED_COLOR
|
227 MC_OP_LIN_BLEND_TEX0_COLOR
),
229 /* GL_BLEND according to alpha
231 ( GFX_OP_MAP_COLOR_STAGES
|
238 MC_ARG2_ITERATED_COLOR
|
240 MC_OP_LIN_BLEND_TEX0_ALPHA
),
244 ( GFX_OP_MAP_COLOR_STAGES
|
251 MC_ARG2_ITERATED_COLOR
|
259 /* Disable combiner stage (Note: disables all subsequent stages)
261 ( GFX_OP_MAP_COLOR_STAGES
|
275 ( GFX_OP_MAP_COLOR_STAGES
|
280 MC_ARG1_CURRENT_COLOR
|
288 ( GFX_OP_MAP_COLOR_STAGES
|
301 ( GFX_OP_MAP_COLOR_STAGES
|
308 MC_ARG2_CURRENT_COLOR
|
314 ( GFX_OP_MAP_COLOR_STAGES
|
319 MC_ARG1_COLOR_FACTOR
|
323 MC_OP_LIN_BLEND_TEX1_ALPHA
),
327 ( GFX_OP_MAP_COLOR_STAGES
|
332 MC_ARG1_COLOR_FACTOR
|
334 MC_ARG2_CURRENT_COLOR
|
336 MC_OP_LIN_BLEND_TEX1_COLOR
),
338 /* GL_BLEND according to alpha
340 ( GFX_OP_MAP_COLOR_STAGES
|
347 MC_ARG2_CURRENT_COLOR
|
349 MC_OP_LIN_BLEND_TEX1_ALPHA
),
353 ( GFX_OP_MAP_COLOR_STAGES
|
360 MC_ARG2_CURRENT_COLOR
|
366 static GLuint i810_alpha_combine
[][I810_MAX_COMBFUNC
] =
371 /* Disable combiner stage
373 ( GFX_OP_MAP_ALPHA_STAGES
|
376 MA_ARG1_ITERATED_ALPHA
|
384 ( GFX_OP_MAP_ALPHA_STAGES
|
387 MA_ARG1_ITERATED_ALPHA
|
395 ( GFX_OP_MAP_ALPHA_STAGES
|
398 MA_ARG1_ITERATED_ALPHA
|
406 ( GFX_OP_MAP_ALPHA_STAGES
|
409 MA_ARG1_ITERATED_ALPHA
|
417 ( GFX_OP_MAP_ALPHA_STAGES
|
420 MA_ARG1_ALPHA_FACTOR
|
422 MA_ARG2_ALPHA_FACTOR
|
428 ( GFX_OP_MAP_ALPHA_STAGES
|
431 MA_ARG1_ALPHA_FACTOR
|
433 MA_ARG2_ITERATED_ALPHA
|
435 MA_OP_LIN_BLEND_TEX0_ALPHA
),
437 /* GL_BLEND according to alpha (same as above)
439 ( GFX_OP_MAP_ALPHA_STAGES
|
442 MA_ARG1_ALPHA_FACTOR
|
444 MA_ARG2_ITERATED_ALPHA
|
446 MA_OP_LIN_BLEND_TEX0_ALPHA
),
450 ( GFX_OP_MAP_ALPHA_STAGES
|
453 MA_ARG1_ITERATED_ALPHA
|
463 /* Disable combiner stage
465 ( GFX_OP_MAP_ALPHA_STAGES
|
468 MA_ARG1_CURRENT_ALPHA
|
470 MA_ARG2_CURRENT_ALPHA
|
476 ( GFX_OP_MAP_ALPHA_STAGES
|
479 MA_ARG1_CURRENT_ALPHA
|
481 MA_ARG2_CURRENT_ALPHA
|
487 ( GFX_OP_MAP_ALPHA_STAGES
|
490 MA_ARG1_CURRENT_ALPHA
|
498 ( GFX_OP_MAP_ALPHA_STAGES
|
501 MA_ARG1_CURRENT_ALPHA
|
509 ( GFX_OP_MAP_ALPHA_STAGES
|
512 MA_ARG1_ALPHA_FACTOR
|
514 MA_ARG2_ALPHA_FACTOR
|
520 ( GFX_OP_MAP_ALPHA_STAGES
|
523 MA_ARG1_ALPHA_FACTOR
|
525 MA_ARG2_ITERATED_ALPHA
|
527 MA_OP_LIN_BLEND_TEX1_ALPHA
),
529 /* GL_BLEND according to alpha (same as above)
531 ( GFX_OP_MAP_ALPHA_STAGES
|
534 MA_ARG1_ALPHA_FACTOR
|
536 MA_ARG2_ITERATED_ALPHA
|
538 MA_OP_LIN_BLEND_TEX1_ALPHA
),
542 ( GFX_OP_MAP_ALPHA_STAGES
|
545 MA_ARG1_CURRENT_ALPHA
|
556 static void i810UpdateTexEnv( GLcontext
*ctx
, GLuint unit
)
558 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
559 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
560 const struct gl_texture_object
*tObj
= texUnit
->_Current
;
561 const GLuint format
= tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
562 GLuint color_combine
, alpha_combine
;
564 switch (texUnit
->EnvMode
) {
566 if (format
== GL_ALPHA
) {
567 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
568 alpha_combine
= i810_alpha_combine
[unit
][I810_REPLACE
];
569 } else if (format
== GL_LUMINANCE
|| format
== GL_RGB
) {
570 color_combine
= i810_color_combine
[unit
][I810_REPLACE
];
571 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
573 color_combine
= i810_color_combine
[unit
][I810_REPLACE
];
574 alpha_combine
= i810_alpha_combine
[unit
][I810_REPLACE
];
579 if (format
== GL_ALPHA
) {
580 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
581 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
583 color_combine
= i810_color_combine
[unit
][I810_MODULATE
];
584 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
591 color_combine
= i810_color_combine
[unit
][I810_ALPHA_BLEND
];
592 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
595 color_combine
= i810_color_combine
[unit
][I810_REPLACE
];
596 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
600 case GL_LUMINANCE_ALPHA
:
602 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
603 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
615 color_combine
= i810_color_combine
[unit
][I810_BLEND
];
616 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
619 case GL_LUMINANCE_ALPHA
:
620 color_combine
= i810_color_combine
[unit
][I810_BLEND
];
621 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
624 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
625 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
628 color_combine
= i810_color_combine
[unit
][I810_BLEND
];
629 alpha_combine
= i810_alpha_combine
[unit
][I810_BLEND
];
641 color_combine
= i810_color_combine
[unit
][I810_ADD
];
642 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
645 case GL_LUMINANCE_ALPHA
:
646 color_combine
= i810_color_combine
[unit
][I810_ADD
];
647 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
650 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
651 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
654 color_combine
= i810_color_combine
[unit
][I810_ADD
];
655 alpha_combine
= i810_alpha_combine
[unit
][I810_ADD
];
667 if (alpha_combine
!= imesa
->Setup
[I810_CTXREG_MA0
+ unit
] ||
668 color_combine
!= imesa
->Setup
[I810_CTXREG_MC0
+ unit
])
670 I810_STATECHANGE( imesa
, I810_UPLOAD_CTX
);
671 imesa
->Setup
[I810_CTXREG_MA0
+ unit
] = alpha_combine
;
672 imesa
->Setup
[I810_CTXREG_MC0
+ unit
] = color_combine
;
679 static void i810UpdateTexUnit( GLcontext
*ctx
, GLuint unit
)
681 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
682 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
684 if (texUnit
->_ReallyEnabled
== TEXTURE_2D_BIT
)
686 struct gl_texture_object
*tObj
= texUnit
->_Current
;
687 i810TextureObjectPtr t
= (i810TextureObjectPtr
)tObj
->DriverData
;
689 /* Upload teximages (not pipelined)
691 if (t
->base
.dirty_images
[0]) {
692 I810_FIREVERTICES(imesa
);
693 i810SetTexImages( imesa
, tObj
);
694 if (!t
->base
.memBlock
) {
695 FALLBACK( imesa
, I810_FALLBACK_TEXTURE
, GL_TRUE
);
700 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0) {
701 FALLBACK( imesa
, I810_FALLBACK_TEXTURE
, GL_TRUE
);
705 /* Update state if this is a different texture object to last
708 if (imesa
->CurrentTexObj
[unit
] != t
) {
709 I810_STATECHANGE(imesa
, (I810_UPLOAD_TEX0
<<unit
));
710 imesa
->CurrentTexObj
[unit
] = t
;
711 t
->base
.bound
|= (1U << unit
);
713 driUpdateTextureLRU( (driTextureObject
*) t
); /* XXX: should be locked */
717 /* Update texture environment if texture object image format or
718 * texture environment state has changed.
720 if (tObj
->Image
[0][tObj
->BaseLevel
]->Format
!= imesa
->TexEnvImageFmt
[unit
]) {
721 imesa
->TexEnvImageFmt
[unit
] = tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
722 i810UpdateTexEnv( ctx
, unit
);
725 else if (texUnit
->_ReallyEnabled
) {
726 FALLBACK( imesa
, I810_FALLBACK_TEXTURE
, GL_TRUE
);
728 else /*if (imesa->CurrentTexObj[unit])*/ {
729 imesa
->CurrentTexObj
[unit
] = 0;
730 imesa
->TexEnvImageFmt
[unit
] = 0;
731 imesa
->dirty
&= ~(I810_UPLOAD_TEX0
<<unit
);
732 imesa
->Setup
[I810_CTXREG_MA0
+ unit
] =
733 i810_alpha_combine
[unit
][I810_DISABLE
];
734 imesa
->Setup
[I810_CTXREG_MC0
+ unit
] =
735 i810_color_combine
[unit
][I810_DISABLE
];
736 I810_STATECHANGE( imesa
, I810_UPLOAD_CTX
);
741 void i810UpdateTextureState( GLcontext
*ctx
)
743 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
744 /* fprintf(stderr, "%s\n", __FUNCTION__); */
745 FALLBACK( imesa
, I810_FALLBACK_TEXTURE
, GL_FALSE
);
746 i810UpdateTexUnit( ctx
, 0 );
747 i810UpdateTexUnit( ctx
, 1 );