Merge branch 'gallium-drm-driver-drescriptor'
[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 "main/glheader.h"
29 #include "main/macros.h"
30 #include "main/mtypes.h"
31 #include "main/colormac.h"
32
33 #include "intel_buffers.h"
34 #include "intel_fbo.h"
35 #include "intel_screen.h"
36 #include "intel_span.h"
37 #include "intel_regions.h"
38 #include "intel_tex.h"
39
40 #include "swrast/swrast.h"
41
42 static void
43 intel_set_span_functions(struct intel_context *intel,
44 struct gl_renderbuffer *rb);
45
46 #undef DBG
47 #define DBG 0
48
49 #define LOCAL_VARS \
50 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
51 const GLint yScale = rb->Name ? 1 : -1; \
52 const GLint yBias = rb->Name ? 0 : rb->Height - 1; \
53 int minx = 0, miny = 0; \
54 int maxx = rb->Width; \
55 int maxy = rb->Height; \
56 int pitch = irb->region->pitch * irb->region->cpp; \
57 void *buf = irb->region->buffer->virtual; \
58 GLuint p; \
59 (void) p; \
60 (void)buf; (void)pitch; /* unused for non-gttmap. */ \
61
62 #define HW_CLIPLOOP()
63 #define HW_ENDCLIPLOOP()
64
65 #define Y_FLIP(_y) ((_y) * yScale + yBias)
66
67 #define HW_LOCK()
68
69 #define HW_UNLOCK()
70
71 /* Convenience macros to avoid typing the address argument over and over */
72 #define NO_TILE(_X, _Y) (((_Y) * irb->region->pitch + (_X)) * irb->region->cpp)
73
74 /* r5g6b5 color span and pixel functions */
75 #define SPANTMP_PIXEL_FMT GL_RGB
76 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
77 #define TAG(x) intel_##x##_RGB565
78 #define TAG2(x,y) intel_##x##y_RGB565
79 #include "spantmp2.h"
80
81 /* a4r4g4b4 color span and pixel functions */
82 #define SPANTMP_PIXEL_FMT GL_BGRA
83 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
84 #define TAG(x) intel_##x##_ARGB4444
85 #define TAG2(x,y) intel_##x##y_ARGB4444
86 #include "spantmp2.h"
87
88 /* a1r5g5b5 color span and pixel functions */
89 #define SPANTMP_PIXEL_FMT GL_BGRA
90 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
91 #define TAG(x) intel_##x##_ARGB1555
92 #define TAG2(x,y) intel_##x##y##_ARGB1555
93 #include "spantmp2.h"
94
95 /* a8r8g8b8 color span and pixel functions */
96 #define SPANTMP_PIXEL_FMT GL_BGRA
97 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
98 #define TAG(x) intel_##x##_ARGB8888
99 #define TAG2(x,y) intel_##x##y##_ARGB8888
100 #include "spantmp2.h"
101
102 /* x8r8g8b8 color span and pixel functions */
103 #define SPANTMP_PIXEL_FMT GL_BGR
104 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
105 #define TAG(x) intel_##x##_xRGB8888
106 #define TAG2(x,y) intel_##x##y##_xRGB8888
107 #include "spantmp2.h"
108
109 /* a8 color span and pixel functions */
110 #define SPANTMP_PIXEL_FMT GL_ALPHA
111 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_BYTE
112 #define TAG(x) intel_##x##_A8
113 #define TAG2(x,y) intel_##x##y##_A8
114 #include "spantmp2.h"
115
116 #define LOCAL_DEPTH_VARS \
117 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
118 const GLint yScale = rb->Name ? 1 : -1; \
119 const GLint yBias = rb->Name ? 0 : rb->Height - 1; \
120 int minx = 0, miny = 0; \
121 int maxx = rb->Width; \
122 int maxy = rb->Height; \
123 int pitch = irb->region->pitch * irb->region->cpp; \
124 void *buf = irb->region->buffer->virtual; \
125 (void)buf; (void)pitch; /* unused for non-gttmap. */ \
126
127 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
128
129 /* z16 depthbuffer functions. */
130 #define VALUE_TYPE GLushort
131 #define WRITE_DEPTH(_x, _y, d) \
132 (*(uint16_t *)(irb->region->buffer->virtual + NO_TILE(_x, _y)) = d)
133 #define READ_DEPTH(d, _x, _y) \
134 d = *(uint16_t *)(irb->region->buffer->virtual + NO_TILE(_x, _y))
135 #define TAG(x) intel_##x##_z16
136 #include "depthtmp.h"
137
138 /* z24_s8 and z24_x8 depthbuffer functions. */
139 #define VALUE_TYPE GLuint
140 #define WRITE_DEPTH(_x, _y, d) \
141 (*(uint32_t *)(irb->region->buffer->virtual + NO_TILE(_x, _y)) = d)
142 #define READ_DEPTH(d, _x, _y) \
143 d = *(uint32_t *)(irb->region->buffer->virtual + NO_TILE(_x, _y))
144 #define TAG(x) intel_##x##_z24_s8
145 #include "depthtmp.h"
146
147 void
148 intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb)
149 {
150 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
151
152 if (irb == NULL || irb->region == NULL)
153 return;
154
155 drm_intel_gem_bo_map_gtt(irb->region->buffer);
156
157 intel_set_span_functions(intel, rb);
158 }
159
160 void
161 intel_renderbuffer_unmap(struct intel_context *intel,
162 struct gl_renderbuffer *rb)
163 {
164 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
165
166 if (irb == NULL || irb->region == NULL)
167 return;
168
169 drm_intel_gem_bo_unmap_gtt(irb->region->buffer);
170
171 rb->GetRow = NULL;
172 rb->PutRow = NULL;
173 }
174
175 /**
176 * Map or unmap all the renderbuffers which we may need during
177 * software rendering.
178 * XXX in the future, we could probably convey extra information to
179 * reduce the number of mappings needed. I.e. if doing a glReadPixels
180 * from the depth buffer, we really only need one mapping.
181 *
182 * XXX Rewrite this function someday.
183 * We can probably just loop over all the renderbuffer attachments,
184 * map/unmap all of them, and not worry about the _ColorDrawBuffers
185 * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
186 */
187 static void
188 intel_map_unmap_framebuffer(struct intel_context *intel,
189 struct gl_framebuffer *fb,
190 GLboolean map)
191 {
192 GLuint i;
193
194 /* color draw buffers */
195 for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
196 if (map)
197 intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[i]);
198 else
199 intel_renderbuffer_unmap(intel, fb->_ColorDrawBuffers[i]);
200 }
201
202 /* color read buffer */
203 if (map)
204 intel_renderbuffer_map(intel, fb->_ColorReadBuffer);
205 else
206 intel_renderbuffer_unmap(intel, fb->_ColorReadBuffer);
207
208 /* check for render to textures */
209 for (i = 0; i < BUFFER_COUNT; i++) {
210 struct gl_renderbuffer_attachment *att =
211 fb->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 intel_tex_map_images(intel, intel_texture_object(tex));
218 else
219 intel_tex_unmap_images(intel, intel_texture_object(tex));
220 }
221 }
222
223 /* depth buffer (Note wrapper!) */
224 if (fb->_DepthBuffer) {
225 if (map)
226 intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped);
227 else
228 intel_renderbuffer_unmap(intel, fb->_DepthBuffer->Wrapped);
229 }
230
231 /* stencil buffer (Note wrapper!) */
232 if (fb->_StencilBuffer) {
233 if (map)
234 intel_renderbuffer_map(intel, fb->_StencilBuffer->Wrapped);
235 else
236 intel_renderbuffer_unmap(intel, fb->_StencilBuffer->Wrapped);
237 }
238
239 intel_check_front_buffer_rendering(intel);
240 }
241
242 /**
243 * Prepare for software rendering. Map current read/draw framebuffers'
244 * renderbuffes and all currently bound texture objects.
245 *
246 * Old note: Moved locking out to get reasonable span performance.
247 */
248 void
249 intelSpanRenderStart(GLcontext * ctx)
250 {
251 struct intel_context *intel = intel_context(ctx);
252 GLuint i;
253
254 intel_flush(&intel->ctx);
255 intel_prepare_render(intel);
256
257 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
258 if (ctx->Texture.Unit[i]._ReallyEnabled) {
259 struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
260
261 intel_finalize_mipmap_tree(intel, i);
262 intel_tex_map_images(intel, intel_texture_object(texObj));
263 }
264 }
265
266 intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_TRUE);
267 if (ctx->ReadBuffer != ctx->DrawBuffer)
268 intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE);
269 }
270
271 /**
272 * Called when done software rendering. Unmap the buffers we mapped in
273 * the above function.
274 */
275 void
276 intelSpanRenderFinish(GLcontext * ctx)
277 {
278 struct intel_context *intel = intel_context(ctx);
279 GLuint i;
280
281 _swrast_flush(ctx);
282
283 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
284 if (ctx->Texture.Unit[i]._ReallyEnabled) {
285 struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
286 intel_tex_unmap_images(intel, intel_texture_object(texObj));
287 }
288 }
289
290 intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_FALSE);
291 if (ctx->ReadBuffer != ctx->DrawBuffer)
292 intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE);
293 }
294
295
296 void
297 intelInitSpanFuncs(GLcontext * ctx)
298 {
299 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
300 swdd->SpanRenderStart = intelSpanRenderStart;
301 swdd->SpanRenderFinish = intelSpanRenderFinish;
302 }
303
304 void
305 intel_map_vertex_shader_textures(GLcontext *ctx)
306 {
307 struct intel_context *intel = intel_context(ctx);
308 int i;
309
310 if (ctx->VertexProgram._Current == NULL)
311 return;
312
313 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
314 if (ctx->Texture.Unit[i]._ReallyEnabled &&
315 ctx->VertexProgram._Current->Base.TexturesUsed[i] != 0) {
316 struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
317
318 intel_tex_map_images(intel, intel_texture_object(texObj));
319 }
320 }
321 }
322
323 void
324 intel_unmap_vertex_shader_textures(GLcontext *ctx)
325 {
326 struct intel_context *intel = intel_context(ctx);
327 int i;
328
329 if (ctx->VertexProgram._Current == NULL)
330 return;
331
332 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
333 if (ctx->Texture.Unit[i]._ReallyEnabled &&
334 ctx->VertexProgram._Current->Base.TexturesUsed[i] != 0) {
335 struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
336
337 intel_tex_unmap_images(intel, intel_texture_object(texObj));
338 }
339 }
340 }
341
342 /**
343 * Plug in appropriate span read/write functions for the given renderbuffer.
344 * These are used for the software fallbacks.
345 */
346 static void
347 intel_set_span_functions(struct intel_context *intel,
348 struct gl_renderbuffer *rb)
349 {
350 struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
351
352 switch (irb->Base.Format) {
353 case MESA_FORMAT_A8:
354 intel_InitPointers_A8(rb);
355 break;
356 case MESA_FORMAT_RGB565:
357 intel_InitPointers_RGB565(rb);
358 break;
359 case MESA_FORMAT_ARGB4444:
360 intel_InitPointers_ARGB4444(rb);
361 break;
362 case MESA_FORMAT_ARGB1555:
363 intel_InitPointers_ARGB1555(rb);
364 break;
365 case MESA_FORMAT_XRGB8888:
366 intel_InitPointers_xRGB8888(rb);
367 break;
368 case MESA_FORMAT_ARGB8888:
369 intel_InitPointers_ARGB8888(rb);
370 break;
371 case MESA_FORMAT_Z16:
372 intel_InitDepthPointers_z16(rb);
373 break;
374 case MESA_FORMAT_X8_Z24:
375 case MESA_FORMAT_S8_Z24:
376 intel_InitDepthPointers_z24_s8(rb);
377 break;
378 default:
379 _mesa_problem(NULL,
380 "Unexpected MesaFormat %d in intelSetSpanFunctions",
381 irb->Base.Format);
382 break;
383 }
384 }