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 **************************************************************************/
33 #include "intel_fbo.h"
34 #include "intel_screen.h"
35 #include "intel_span.h"
36 #include "intel_regions.h"
37 #include "intel_ioctl.h"
38 #include "intel_tex.h"
40 #include "swrast/swrast.h"
43 break intelWriteRGBASpan_ARGB8888
50 struct intel_context *intel = intel_context(ctx); \
51 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
52 const GLint yScale = irb->RenderToTexture ? 1 : -1; \
53 const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
54 GLubyte *buf = (GLubyte *) irb->pfMap \
55 + (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\
60 /* XXX FBO: this is identical to the macro in spantmp2.h except we get
61 * the cliprect info from the context, not the driDrawable.
62 * Move this into spantmp2.h someday.
64 #define HW_CLIPLOOP() \
66 int _nc = intel->numClipRects; \
68 int minx = intel->pClipRects[_nc].x1 - intel->drawX; \
69 int miny = intel->pClipRects[_nc].y1 - intel->drawY; \
70 int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \
71 int maxy = intel->pClipRects[_nc].y2 - intel->drawY;
76 #define Y_FLIP(_y) ((_y) * yScale + yBias)
82 /* 16 bit, RGB565 color spanline and pixel functions
84 #define SPANTMP_PIXEL_FMT GL_RGB
85 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
87 #define TAG(x) intel##x##_RGB565
88 #define TAG2(x,y) intel##x##_RGB565##y
89 #define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2)
92 /* 32 bit, ARGB8888 color spanline and pixel functions
94 #define SPANTMP_PIXEL_FMT GL_BGRA
95 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
97 #define TAG(x) intel##x##_ARGB8888
98 #define TAG2(x,y) intel##x##_ARGB8888##y
99 #define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4)
100 #include "spantmp2.h"
102 #define LOCAL_DEPTH_VARS \
103 struct intel_context *intel = intel_context(ctx); \
104 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
105 const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \
106 const GLint yScale = irb->RenderToTexture ? 1 : -1; \
107 const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
108 char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \
109 (intel->drawY * pitch + intel->drawX) * irb->region->cpp;
112 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
115 ** 16-bit depthbuffer functions.
117 #define VALUE_TYPE GLushort
119 #define WRITE_DEPTH( _x, _y, d ) \
120 ((GLushort *)buf)[(_x) + (_y) * pitch] = d;
122 #define READ_DEPTH( d, _x, _y ) \
123 d = ((GLushort *)buf)[(_x) + (_y) * pitch];
126 #define TAG(x) intel##x##_z16
127 #include "depthtmp.h"
131 ** 24/8-bit interleaved depth/stencil functions
132 ** Note: we're actually reading back combined depth+stencil values.
133 ** The wrappers in main/depthstencil.c are used to extract the depth
134 ** and stencil values.
136 #define VALUE_TYPE GLuint
138 /* Change ZZZS -> SZZZ */
139 #define WRITE_DEPTH( _x, _y, d ) { \
140 GLuint tmp = ((d) >> 8) | ((d) << 24); \
141 ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \
144 /* Change SZZZ -> ZZZS */
145 #define READ_DEPTH( d, _x, _y ) { \
146 GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \
147 d = (tmp << 8) | (tmp >> 24); \
150 #define TAG(x) intel##x##_z24_s8
151 #include "depthtmp.h"
155 ** 8-bit stencil function (XXX FBO: This is obsolete)
157 #define WRITE_STENCIL( _x, _y, d ) { \
158 GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \
160 tmp |= ((d) << 24); \
161 ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \
164 #define READ_STENCIL( d, _x, _y ) \
165 d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24;
167 #define TAG(x) intel##x##_z24_s8
168 #include "stenciltmp.h"
173 * Map or unmap all the renderbuffers which we may need during
174 * software rendering.
175 * XXX in the future, we could probably convey extra information to
176 * reduce the number of mappings needed. I.e. if doing a glReadPixels
177 * from the depth buffer, we really only need one mapping.
179 * XXX Rewrite this function someday.
180 * We can probably just loop over all the renderbuffer attachments,
181 * map/unmap all of them, and not worry about the _ColorDrawBuffers
182 * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
185 intel_map_unmap_buffers(struct intel_context
*intel
, GLboolean map
)
187 GLcontext
*ctx
= &intel
->ctx
;
189 struct intel_renderbuffer
*irb
;
191 /* color draw buffers */
192 for (j
= 0; j
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; j
++) {
193 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[j
];
194 irb
= intel_renderbuffer(rb
);
196 /* this is a user-created intel_renderbuffer */
199 intel_region_map(intel
, irb
->region
);
201 intel_region_unmap(intel
, irb
->region
);
202 irb
->pfMap
= irb
->region
->map
;
203 irb
->pfPitch
= irb
->region
->pitch
;
208 /* check for render to textures */
209 for (i
= 0; i
< BUFFER_COUNT
; i
++) {
210 struct gl_renderbuffer_attachment
*att
=
211 ctx
->DrawBuffer
->Attachment
+ i
;
212 struct gl_texture_object
*tex
= att
->Texture
;
214 /* render to texture */
215 ASSERT(att
->Renderbuffer
);
217 struct gl_texture_image
*texImg
;
218 texImg
= tex
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
219 intel_tex_map_images(intel
, intel_texture_object(tex
));
222 intel_tex_unmap_images(intel
, intel_texture_object(tex
));
227 /* color read buffers */
228 irb
= intel_renderbuffer(ctx
->ReadBuffer
->_ColorReadBuffer
);
229 if (irb
&& irb
->region
) {
231 intel_region_map(intel
, irb
->region
);
233 intel_region_unmap(intel
, irb
->region
);
234 irb
->pfMap
= irb
->region
->map
;
235 irb
->pfPitch
= irb
->region
->pitch
;
238 /* Account for front/back color page flipping.
239 * The span routines use the pfMap and pfPitch fields which will
240 * swap the front/back region map/pitch if we're page flipped.
241 * Do this after mapping, above, so the map field is valid.
244 if (map
&& ctx
->DrawBuffer
->Name
== 0) {
245 struct intel_renderbuffer
*irbFront
246 = intel_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_FRONT_LEFT
);
247 struct intel_renderbuffer
*irbBack
248 = intel_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_BACK_LEFT
);
250 /* double buffered */
251 if (intel
->sarea
->pf_current_page
== 0) {
252 irbFront
->pfMap
= irbFront
->region
->map
;
253 irbFront
->pfPitch
= irbFront
->region
->pitch
;
254 irbBack
->pfMap
= irbBack
->region
->map
;
255 irbBack
->pfPitch
= irbBack
->region
->pitch
;
258 irbFront
->pfMap
= irbBack
->region
->map
;
259 irbFront
->pfPitch
= irbBack
->region
->pitch
;
260 irbBack
->pfMap
= irbFront
->region
->map
;
261 irbBack
->pfPitch
= irbFront
->region
->pitch
;
267 /* depth buffer (Note wrapper!) */
268 if (ctx
->DrawBuffer
->_DepthBuffer
) {
269 irb
= intel_renderbuffer(ctx
->DrawBuffer
->_DepthBuffer
->Wrapped
);
270 if (irb
&& irb
->region
) {
272 intel_region_map(intel
, irb
->region
);
273 irb
->pfMap
= irb
->region
->map
;
274 irb
->pfPitch
= irb
->region
->pitch
;
277 intel_region_unmap(intel
, irb
->region
);
278 irb
->pfMap
= irb
->region
->map
;
279 irb
->pfPitch
= irb
->region
->pitch
;
284 /* stencil buffer (Note wrapper!) */
285 if (ctx
->DrawBuffer
->_StencilBuffer
) {
286 irb
= intel_renderbuffer(ctx
->DrawBuffer
->_StencilBuffer
->Wrapped
);
287 if (irb
&& irb
->region
) {
289 intel_region_map(intel
, irb
->region
);
290 irb
->pfMap
= irb
->region
->map
;
291 irb
->pfPitch
= irb
->region
->pitch
;
294 intel_region_unmap(intel
, irb
->region
);
295 irb
->pfMap
= irb
->region
->map
;
296 irb
->pfPitch
= irb
->region
->pitch
;
305 * Prepare for softare rendering. Map current read/draw framebuffers'
306 * renderbuffes and all currently bound texture objects.
308 * Old note: Moved locking out to get reasonable span performance.
311 intelSpanRenderStart(GLcontext
* ctx
)
313 struct intel_context
*intel
= intel_context(ctx
);
316 intelFinish(&intel
->ctx
);
317 LOCK_HARDWARE(intel
);
320 /* Just map the framebuffer and all textures. Bufmgr code will
321 * take care of waiting on the necessary fences:
323 intel_region_map(intel
, intel
->front_region
);
324 intel_region_map(intel
, intel
->back_region
);
325 intel_region_map(intel
, intel
->depth_region
);
328 for (i
= 0; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++) {
329 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
330 struct gl_texture_object
*texObj
= ctx
->Texture
.Unit
[i
]._Current
;
331 intel_tex_map_images(intel
, intel_texture_object(texObj
));
335 intel_map_unmap_buffers(intel
, GL_TRUE
);
339 * Called when done softare rendering. Unmap the buffers we mapped in
340 * the above function.
343 intelSpanRenderFinish(GLcontext
* ctx
)
345 struct intel_context
*intel
= intel_context(ctx
);
350 /* Now unmap the framebuffer:
353 intel_region_unmap(intel
, intel
->front_region
);
354 intel_region_unmap(intel
, intel
->back_region
);
355 intel_region_unmap(intel
, intel
->depth_region
);
358 for (i
= 0; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++) {
359 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
) {
360 struct gl_texture_object
*texObj
= ctx
->Texture
.Unit
[i
]._Current
;
361 intel_tex_unmap_images(intel
, intel_texture_object(texObj
));
365 intel_map_unmap_buffers(intel
, GL_FALSE
);
367 UNLOCK_HARDWARE(intel
);
372 intelInitSpanFuncs(GLcontext
* ctx
)
374 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference(ctx
);
375 swdd
->SpanRenderStart
= intelSpanRenderStart
;
376 swdd
->SpanRenderFinish
= intelSpanRenderFinish
;
381 * Plug in appropriate span read/write functions for the given renderbuffer.
382 * These are used for the software fallbacks.
385 intel_set_span_functions(struct gl_renderbuffer
*rb
)
387 if (rb
->_ActualFormat
== GL_RGB5
) {
389 intelInitPointers_RGB565(rb
);
391 else if (rb
->_ActualFormat
== GL_RGBA8
) {
393 intelInitPointers_ARGB8888(rb
);
395 else if (rb
->_ActualFormat
== GL_DEPTH_COMPONENT16
) {
396 intelInitDepthPointers_z16(rb
);
398 else if (rb
->_ActualFormat
== GL_DEPTH_COMPONENT24
|| /* XXX FBO remove */
399 rb
->_ActualFormat
== GL_DEPTH24_STENCIL8_EXT
) {
400 intelInitDepthPointers_z24_s8(rb
);
402 else if (rb
->_ActualFormat
== GL_STENCIL_INDEX8_EXT
) { /* XXX FBO remove */
403 intelInitStencilPointers_z24_s8(rb
);
407 "Unexpected _ActualFormat in intelSetSpanFunctions");