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 "simple_list.h"
33 #include "i810screen.h"
36 #include "i810context.h"
38 #include "i810state.h"
39 #include "i810ioctl.h"
44 static void i810SetTexImages( i810ContextPtr imesa
,
45 struct gl_texture_object
*tObj
)
47 GLuint height
, width
, pitch
, i
, textureFormat
, log_pitch
;
48 i810TextureObjectPtr t
= (i810TextureObjectPtr
) tObj
->DriverData
;
49 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
51 GLint log2Width
, log2Height
;
53 /* fprintf(stderr, "%s\n", __FUNCTION__); */
55 switch (baseImage
->Format
) {
59 textureFormat
= MI1_FMT_16BPP
| MI1_PF_16BPP_RGB565
;
62 case GL_LUMINANCE_ALPHA
:
66 textureFormat
= MI1_FMT_16BPP
| MI1_PF_16BPP_ARGB4444
;
69 textureFormat
= MI1_FMT_8CI
| MI1_PF_8CI_ARGB4444
;
74 textureFormat
= MI1_FMT_422
| MI1_PF_422_YCRCB_SWAP_Y
75 | MI1_COLOR_CONV_ENABLE
;
79 fprintf(stderr
, "i810SetTexImages: bad image->Format\n" );
83 driCalculateTextureFirstLastLevel( (driTextureObject
*) t
);
85 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
87 log2Width
= tObj
->Image
[0][t
->base
.firstLevel
]->WidthLog2
;
88 log2Height
= tObj
->Image
[0][t
->base
.firstLevel
]->HeightLog2
;
90 /* Figure out the amount of memory required to hold all the mipmap
91 * levels. Choose the smallest pitch to accomodate the largest
94 width
= tObj
->Image
[0][t
->base
.firstLevel
]->Width
* t
->texelBytes
;
95 for (pitch
= 32, log_pitch
=2 ; pitch
< width
; pitch
*= 2 )
98 /* All images must be loaded at this pitch. Count the number of
101 for ( height
= i
= 0 ; i
< numLevels
; i
++ ) {
102 t
->image
[i
].image
= tObj
->Image
[0][t
->base
.firstLevel
+ i
];
103 t
->image
[i
].offset
= height
* pitch
;
104 t
->image
[i
].internalFormat
= baseImage
->Format
;
105 height
+= t
->image
[i
].image
->Height
;
109 t
->base
.totalSize
= height
*pitch
;
111 t
->dirty
= I810_UPLOAD_TEX0
| I810_UPLOAD_TEX1
;
112 t
->Setup
[I810_TEXREG_MI1
] = (MI1_MAP_0
| textureFormat
| log_pitch
);
113 t
->Setup
[I810_TEXREG_MI2
] = (MI2_DIMENSIONS_ARE_LOG2
|
114 (log2Height
<< 16) | log2Width
);
115 t
->Setup
[I810_TEXREG_MLL
] = (GFX_OP_MAP_LOD_LIMITS
|
119 ((numLevels
- 1) << MLL_MIN_MIP_SHIFT
));
121 LOCK_HARDWARE( imesa
);
122 i810UploadTexImagesLocked( imesa
, t
);
123 UNLOCK_HARDWARE( imesa
);
126 /* ================================================================
127 * Texture combine functions
130 #define I810_DISABLE 0
131 #define I810_PASSTHRU 1
132 #define I810_REPLACE 2
133 #define I810_MODULATE 3
136 #define I810_ALPHA_BLEND 6
138 #define I810_MAX_COMBFUNC 8
141 static GLuint i810_color_combine
[][I810_MAX_COMBFUNC
] =
146 /* Disable combiner stage
148 ( GFX_OP_MAP_COLOR_STAGES
|
153 MC_ARG1_ITERATED_COLOR
|
157 MC_OP_ARG1
), /* actually passthru */
161 ( GFX_OP_MAP_COLOR_STAGES
|
166 MC_ARG1_ITERATED_COLOR
|
174 ( GFX_OP_MAP_COLOR_STAGES
|
187 ( GFX_OP_MAP_COLOR_STAGES
|
194 MC_ARG2_ITERATED_COLOR
|
200 ( GFX_OP_MAP_COLOR_STAGES
|
205 MC_ARG1_COLOR_FACTOR
|
209 MC_OP_LIN_BLEND_TEX0_ALPHA
),
213 ( GFX_OP_MAP_COLOR_STAGES
|
218 MC_ARG1_COLOR_FACTOR
|
220 MC_ARG2_ITERATED_COLOR
|
222 MC_OP_LIN_BLEND_TEX0_COLOR
),
224 /* GL_BLEND according to alpha
226 ( GFX_OP_MAP_COLOR_STAGES
|
233 MC_ARG2_ITERATED_COLOR
|
235 MC_OP_LIN_BLEND_TEX0_ALPHA
),
239 ( GFX_OP_MAP_COLOR_STAGES
|
246 MC_ARG2_ITERATED_COLOR
|
254 /* Disable combiner stage (Note: disables all subsequent stages)
256 ( GFX_OP_MAP_COLOR_STAGES
|
270 ( GFX_OP_MAP_COLOR_STAGES
|
275 MC_ARG1_CURRENT_COLOR
|
283 ( GFX_OP_MAP_COLOR_STAGES
|
296 ( GFX_OP_MAP_COLOR_STAGES
|
303 MC_ARG2_CURRENT_COLOR
|
309 ( GFX_OP_MAP_COLOR_STAGES
|
314 MC_ARG1_COLOR_FACTOR
|
318 MC_OP_LIN_BLEND_TEX1_ALPHA
),
322 ( GFX_OP_MAP_COLOR_STAGES
|
327 MC_ARG1_COLOR_FACTOR
|
329 MC_ARG2_CURRENT_COLOR
|
331 MC_OP_LIN_BLEND_TEX1_COLOR
),
333 /* GL_BLEND according to alpha
335 ( GFX_OP_MAP_COLOR_STAGES
|
342 MC_ARG2_CURRENT_COLOR
|
344 MC_OP_LIN_BLEND_TEX1_ALPHA
),
348 ( GFX_OP_MAP_COLOR_STAGES
|
355 MC_ARG2_CURRENT_COLOR
|
361 static GLuint i810_alpha_combine
[][I810_MAX_COMBFUNC
] =
366 /* Disable combiner stage
368 ( GFX_OP_MAP_ALPHA_STAGES
|
371 MA_ARG1_ITERATED_ALPHA
|
379 ( GFX_OP_MAP_ALPHA_STAGES
|
382 MA_ARG1_ITERATED_ALPHA
|
390 ( GFX_OP_MAP_ALPHA_STAGES
|
393 MA_ARG1_ITERATED_ALPHA
|
401 ( GFX_OP_MAP_ALPHA_STAGES
|
404 MA_ARG1_ITERATED_ALPHA
|
412 ( GFX_OP_MAP_ALPHA_STAGES
|
415 MA_ARG1_ALPHA_FACTOR
|
417 MA_ARG2_ALPHA_FACTOR
|
423 ( GFX_OP_MAP_ALPHA_STAGES
|
426 MA_ARG1_ALPHA_FACTOR
|
428 MA_ARG2_ITERATED_ALPHA
|
430 MA_OP_LIN_BLEND_TEX0_ALPHA
),
432 /* GL_BLEND according to alpha (same as above)
434 ( GFX_OP_MAP_ALPHA_STAGES
|
437 MA_ARG1_ALPHA_FACTOR
|
439 MA_ARG2_ITERATED_ALPHA
|
441 MA_OP_LIN_BLEND_TEX0_ALPHA
),
445 ( GFX_OP_MAP_ALPHA_STAGES
|
448 MA_ARG1_ITERATED_ALPHA
|
458 /* Disable combiner stage
460 ( GFX_OP_MAP_ALPHA_STAGES
|
463 MA_ARG1_CURRENT_ALPHA
|
465 MA_ARG2_CURRENT_ALPHA
|
471 ( GFX_OP_MAP_ALPHA_STAGES
|
474 MA_ARG1_CURRENT_ALPHA
|
476 MA_ARG2_CURRENT_ALPHA
|
482 ( GFX_OP_MAP_ALPHA_STAGES
|
485 MA_ARG1_CURRENT_ALPHA
|
493 ( GFX_OP_MAP_ALPHA_STAGES
|
496 MA_ARG1_CURRENT_ALPHA
|
504 ( GFX_OP_MAP_ALPHA_STAGES
|
507 MA_ARG1_ALPHA_FACTOR
|
509 MA_ARG2_ALPHA_FACTOR
|
515 ( GFX_OP_MAP_ALPHA_STAGES
|
518 MA_ARG1_ALPHA_FACTOR
|
520 MA_ARG2_ITERATED_ALPHA
|
522 MA_OP_LIN_BLEND_TEX1_ALPHA
),
524 /* GL_BLEND according to alpha (same as above)
526 ( GFX_OP_MAP_ALPHA_STAGES
|
529 MA_ARG1_ALPHA_FACTOR
|
531 MA_ARG2_ITERATED_ALPHA
|
533 MA_OP_LIN_BLEND_TEX1_ALPHA
),
537 ( GFX_OP_MAP_ALPHA_STAGES
|
540 MA_ARG1_CURRENT_ALPHA
|
551 static void i810UpdateTexEnv( GLcontext
*ctx
, GLuint unit
)
553 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
554 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
555 const struct gl_texture_object
*tObj
= texUnit
->_Current
;
556 const GLuint format
= tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
557 GLuint color_combine
, alpha_combine
;
559 switch (texUnit
->EnvMode
) {
561 if (format
== GL_ALPHA
) {
562 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
563 alpha_combine
= i810_alpha_combine
[unit
][I810_REPLACE
];
564 } else if (format
== GL_LUMINANCE
|| format
== GL_RGB
) {
565 color_combine
= i810_color_combine
[unit
][I810_REPLACE
];
566 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
568 color_combine
= i810_color_combine
[unit
][I810_REPLACE
];
569 alpha_combine
= i810_alpha_combine
[unit
][I810_REPLACE
];
574 if (format
== GL_ALPHA
) {
575 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
576 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
578 color_combine
= i810_color_combine
[unit
][I810_MODULATE
];
579 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
586 color_combine
= i810_color_combine
[unit
][I810_ALPHA_BLEND
];
587 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
590 color_combine
= i810_color_combine
[unit
][I810_REPLACE
];
591 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
595 case GL_LUMINANCE_ALPHA
:
597 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
598 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
610 color_combine
= i810_color_combine
[unit
][I810_BLEND
];
611 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
614 case GL_LUMINANCE_ALPHA
:
615 color_combine
= i810_color_combine
[unit
][I810_BLEND
];
616 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
619 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
620 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
623 color_combine
= i810_color_combine
[unit
][I810_BLEND
];
624 alpha_combine
= i810_alpha_combine
[unit
][I810_BLEND
];
636 color_combine
= i810_color_combine
[unit
][I810_ADD
];
637 alpha_combine
= i810_alpha_combine
[unit
][I810_PASSTHRU
];
640 case GL_LUMINANCE_ALPHA
:
641 color_combine
= i810_color_combine
[unit
][I810_ADD
];
642 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
645 color_combine
= i810_color_combine
[unit
][I810_PASSTHRU
];
646 alpha_combine
= i810_alpha_combine
[unit
][I810_MODULATE
];
649 color_combine
= i810_color_combine
[unit
][I810_ADD
];
650 alpha_combine
= i810_alpha_combine
[unit
][I810_ADD
];
662 if (alpha_combine
!= imesa
->Setup
[I810_CTXREG_MA0
+ unit
] ||
663 color_combine
!= imesa
->Setup
[I810_CTXREG_MC0
+ unit
])
665 I810_STATECHANGE( imesa
, I810_UPLOAD_CTX
);
666 imesa
->Setup
[I810_CTXREG_MA0
+ unit
] = alpha_combine
;
667 imesa
->Setup
[I810_CTXREG_MC0
+ unit
] = color_combine
;
674 static void i810UpdateTexUnit( GLcontext
*ctx
, GLuint unit
)
676 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
677 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
679 if (texUnit
->_ReallyEnabled
== TEXTURE_2D_BIT
)
681 struct gl_texture_object
*tObj
= texUnit
->_Current
;
682 i810TextureObjectPtr t
= (i810TextureObjectPtr
)tObj
->DriverData
;
684 /* Upload teximages (not pipelined)
686 if (t
->base
.dirty_images
[0]) {
687 I810_FIREVERTICES(imesa
);
688 i810SetTexImages( imesa
, tObj
);
689 if (!t
->base
.memBlock
) {
690 FALLBACK( imesa
, I810_FALLBACK_TEXTURE
, GL_TRUE
);
695 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0) {
696 FALLBACK( imesa
, I810_FALLBACK_TEXTURE
, GL_TRUE
);
700 /* Update state if this is a different texture object to last
703 if (imesa
->CurrentTexObj
[unit
] != t
) {
704 I810_STATECHANGE(imesa
, (I810_UPLOAD_TEX0
<<unit
));
705 imesa
->CurrentTexObj
[unit
] = t
;
706 t
->base
.bound
|= (1U << unit
);
708 driUpdateTextureLRU( (driTextureObject
*) t
); /* XXX: should be locked */
712 /* Update texture environment if texture object image format or
713 * texture environment state has changed.
715 if (tObj
->Image
[0][tObj
->BaseLevel
]->Format
!= imesa
->TexEnvImageFmt
[unit
]) {
716 imesa
->TexEnvImageFmt
[unit
] = tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
717 i810UpdateTexEnv( ctx
, unit
);
720 else if (texUnit
->_ReallyEnabled
) {
721 FALLBACK( imesa
, I810_FALLBACK_TEXTURE
, GL_TRUE
);
723 else /*if (imesa->CurrentTexObj[unit])*/ {
724 imesa
->CurrentTexObj
[unit
] = 0;
725 imesa
->TexEnvImageFmt
[unit
] = 0;
726 imesa
->dirty
&= ~(I810_UPLOAD_TEX0
<<unit
);
727 imesa
->Setup
[I810_CTXREG_MA0
+ unit
] =
728 i810_alpha_combine
[unit
][I810_DISABLE
];
729 imesa
->Setup
[I810_CTXREG_MC0
+ unit
] =
730 i810_color_combine
[unit
][I810_DISABLE
];
731 I810_STATECHANGE( imesa
, I810_UPLOAD_CTX
);
736 void i810UpdateTextureState( GLcontext
*ctx
)
738 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
739 /* fprintf(stderr, "%s\n", __FUNCTION__); */
740 FALLBACK( imesa
, I810_FALLBACK_TEXTURE
, GL_FALSE
);
741 i810UpdateTexUnit( ctx
, 0 );
742 i810UpdateTexUnit( ctx
, 1 );