[intel] Move bufmgr back to context instead of screen, fixing glthreads.
[mesa.git] / src / mesa / drivers / dri / intel / intel_span.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
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:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
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.
25 *
26 **************************************************************************/
27
28 #include "glheader.h"
29 #include "macros.h"
30 #include "mtypes.h"
31 #include "colormac.h"
32
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"
39
40 #include "swrast/swrast.h"
41
42 /*
43 break intelWriteRGBASpan_ARGB8888
44 */
45
46 #undef DBG
47 #define DBG 0
48
49 #define LOCAL_VARS \
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;\
56 GLuint p; \
57 assert(irb->pfMap);\
58 (void) p;
59
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.
63 */
64 #define HW_CLIPLOOP() \
65 do { \
66 int _nc = intel->numClipRects; \
67 while ( _nc-- ) { \
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;
72
73
74
75
76 #define Y_FLIP(_y) ((_y) * yScale + yBias)
77
78 #define HW_LOCK()
79
80 #define HW_UNLOCK()
81
82 /* 16 bit, RGB565 color spanline and pixel functions
83 */
84 #define SPANTMP_PIXEL_FMT GL_RGB
85 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
86
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)
90 #include "spantmp2.h"
91
92 /* 32 bit, ARGB8888 color spanline and pixel functions
93 */
94 #define SPANTMP_PIXEL_FMT GL_BGRA
95 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
96
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"
101
102
103 #define LOCAL_DEPTH_VARS \
104 struct intel_context *intel = intel_context(ctx); \
105 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
106 const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \
107 const GLint yScale = irb->RenderToTexture ? 1 : -1; \
108 const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
109 char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \
110 (intel->drawY * pitch + intel->drawX) * irb->region->cpp;
111
112
113 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
114
115 /**
116 ** 16-bit depthbuffer functions.
117 **/
118 #define WRITE_DEPTH( _x, _y, d ) \
119 ((GLushort *)buf)[(_x) + (_y) * pitch] = d;
120
121 #define READ_DEPTH( d, _x, _y ) \
122 d = ((GLushort *)buf)[(_x) + (_y) * pitch];
123
124
125 #define TAG(x) intel##x##_z16
126 #include "depthtmp.h"
127
128
129 /**
130 ** 24/8-bit interleaved depth/stencil functions
131 ** Note: we're actually reading back combined depth+stencil values.
132 ** The wrappers in main/depthstencil.c are used to extract the depth
133 ** and stencil values.
134 **/
135 /* Change ZZZS -> SZZZ */
136 #define WRITE_DEPTH( _x, _y, d ) { \
137 GLuint tmp = ((d) >> 8) | ((d) << 24); \
138 ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \
139 }
140
141 /* Change SZZZ -> ZZZS */
142 #define READ_DEPTH( d, _x, _y ) { \
143 GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \
144 d = (tmp << 8) | (tmp >> 24); \
145 }
146
147 #define TAG(x) intel##x##_z24_s8
148 #include "depthtmp.h"
149
150
151 /**
152 ** 8-bit stencil function (XXX FBO: This is obsolete)
153 **/
154 #define WRITE_STENCIL( _x, _y, d ) { \
155 GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \
156 tmp &= 0xffffff; \
157 tmp |= ((d) << 24); \
158 ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \
159 }
160
161 #define READ_STENCIL( d, _x, _y ) \
162 d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24;
163
164 #define TAG(x) intel##x##_z24_s8
165 #include "stenciltmp.h"
166
167
168
169 /**
170 * Map or unmap all the renderbuffers which we may need during
171 * software rendering.
172 * XXX in the future, we could probably convey extra information to
173 * reduce the number of mappings needed. I.e. if doing a glReadPixels
174 * from the depth buffer, we really only need one mapping.
175 *
176 * XXX Rewrite this function someday.
177 * We can probably just loop over all the renderbuffer attachments,
178 * map/unmap all of them, and not worry about the _ColorDrawBuffers
179 * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
180 */
181 static void
182 intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
183 {
184 GLcontext *ctx = &intel->ctx;
185 GLuint i, j;
186 struct intel_renderbuffer *irb;
187
188 /* color draw buffers */
189 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
190 for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) {
191 struct gl_renderbuffer *rb =
192 ctx->DrawBuffer->_ColorDrawBuffers[i][j];
193 irb = intel_renderbuffer(rb);
194 if (irb) {
195 /* this is a user-created intel_renderbuffer */
196 if (irb->region) {
197 if (map)
198 intel_region_map(intel, irb->region);
199 else
200 intel_region_unmap(intel, irb->region);
201 irb->pfMap = irb->region->map;
202 irb->pfPitch = irb->region->pitch;
203 }
204 }
205 }
206 }
207
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;
213 if (tex) {
214 /* render to texture */
215 ASSERT(att->Renderbuffer);
216 if (map) {
217 struct gl_texture_image *texImg;
218 texImg = tex->Image[att->CubeMapFace][att->TextureLevel];
219 intel_tex_map_images(intel, intel_texture_object(tex));
220 }
221 else {
222 intel_tex_unmap_images(intel, intel_texture_object(tex));
223 }
224 }
225 }
226
227 /* color read buffers */
228 irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
229 if (irb && irb->region) {
230 if (map)
231 intel_region_map(intel, irb->region);
232 else
233 intel_region_unmap(intel, irb->region);
234 irb->pfMap = irb->region->map;
235 irb->pfPitch = irb->region->pitch;
236 }
237
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.
242 */
243 #if 0
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);
249 if (irbBack) {
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;
256 }
257 else {
258 irbFront->pfMap = irbBack->region->map;
259 irbFront->pfPitch = irbBack->region->pitch;
260 irbBack->pfMap = irbFront->region->map;
261 irbBack->pfPitch = irbFront->region->pitch;
262 }
263 }
264 }
265 #endif
266
267 /* depth buffer (Note wrapper!) */
268 if (ctx->DrawBuffer->_DepthBuffer) {
269 irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
270 if (irb && irb->region && irb->Base.Name != 0) {
271 if (map) {
272 intel_region_map(intel, irb->region);
273 irb->pfMap = irb->region->map;
274 irb->pfPitch = irb->region->pitch;
275 }
276 else {
277 intel_region_unmap(intel, irb->region);
278 irb->pfMap = NULL;
279 irb->pfPitch = 0;
280 }
281 }
282 }
283
284 /* stencil buffer (Note wrapper!) */
285 if (ctx->DrawBuffer->_StencilBuffer) {
286 irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
287 if (irb && irb->region && irb->Base.Name != 0) {
288 if (map) {
289 intel_region_map(intel, irb->region);
290 irb->pfMap = irb->region->map;
291 irb->pfPitch = irb->region->pitch;
292 }
293 else {
294 intel_region_unmap(intel, irb->region);
295 irb->pfMap = NULL;
296 irb->pfPitch = 0;
297 }
298 }
299 }
300 }
301
302
303
304 /**
305 * Prepare for softare rendering. Map current read/draw framebuffers'
306 * renderbuffes and all currently bound texture objects.
307 *
308 * Old note: Moved locking out to get reasonable span performance.
309 */
310 void
311 intelSpanRenderStart(GLcontext * ctx)
312 {
313 struct intel_context *intel = intel_context(ctx);
314 GLuint i;
315
316 intelFinish(&intel->ctx);
317 LOCK_HARDWARE(intel);
318
319 #if 0
320 /* Just map the framebuffer and all textures. Bufmgr code will
321 * take care of waiting on the necessary fences:
322 */
323 intel_region_map(intel, intel->front_region);
324 intel_region_map(intel, intel->back_region);
325 intel_region_map(intel, intel->depth_region);
326 #endif
327
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));
332 }
333 }
334
335 intel_map_unmap_buffers(intel, GL_TRUE);
336 }
337
338 /**
339 * Called when done softare rendering. Unmap the buffers we mapped in
340 * the above function.
341 */
342 void
343 intelSpanRenderFinish(GLcontext * ctx)
344 {
345 struct intel_context *intel = intel_context(ctx);
346 GLuint i;
347
348 _swrast_flush(ctx);
349
350 /* Now unmap the framebuffer:
351 */
352 #if 0
353 intel_region_unmap(intel, intel->front_region);
354 intel_region_unmap(intel, intel->back_region);
355 intel_region_unmap(intel, intel->depth_region);
356 #endif
357
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));
362 }
363 }
364
365 intel_map_unmap_buffers(intel, GL_FALSE);
366
367 UNLOCK_HARDWARE(intel);
368 }
369
370
371 void
372 intelInitSpanFuncs(GLcontext * ctx)
373 {
374 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
375 swdd->SpanRenderStart = intelSpanRenderStart;
376 swdd->SpanRenderFinish = intelSpanRenderFinish;
377 }
378
379
380 /**
381 * Plug in appropriate span read/write functions for the given renderbuffer.
382 * These are used for the software fallbacks.
383 */
384 void
385 intel_set_span_functions(struct gl_renderbuffer *rb)
386 {
387 if (rb->_ActualFormat == GL_RGB5) {
388 /* 565 RGB */
389 intelInitPointers_RGB565(rb);
390 }
391 else if (rb->_ActualFormat == GL_RGBA8) {
392 /* 8888 RGBA */
393 intelInitPointers_ARGB8888(rb);
394 }
395 else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) {
396 intelInitDepthPointers_z16(rb);
397 }
398 else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */
399 rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
400 intelInitDepthPointers_z24_s8(rb);
401 }
402 else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { /* XXX FBO remove */
403 intelInitStencilPointers_z24_s8(rb);
404 }
405 else {
406 _mesa_problem(NULL,
407 "Unexpected _ActualFormat in intelSetSpanFunctions");
408 }
409 }