intel_span.c revision f9995b30756140724f41daf963fa06167912be7f
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 42static void 43intel_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 147void 148intel_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 160void 161intel_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 */ 187static void 188intel_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 */ 248void 249intelSpanRenderStart(struct gl_context * 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 */ 275void 276intelSpanRenderFinish(struct gl_context * 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 296void 297intelInitSpanFuncs(struct gl_context * ctx) 298{ 299 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); 300 swdd->SpanRenderStart = intelSpanRenderStart; 301 swdd->SpanRenderFinish = intelSpanRenderFinish; 302} 303 304void 305intel_map_vertex_shader_textures(struct gl_context *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 323void 324intel_unmap_vertex_shader_textures(struct gl_context *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 */ 346static void 347intel_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 case MESA_FORMAT_SARGB8: 370 intel_InitPointers_ARGB8888(rb); 371 break; 372 case MESA_FORMAT_Z16: 373 intel_InitDepthPointers_z16(rb); 374 break; 375 case MESA_FORMAT_X8_Z24: 376 case MESA_FORMAT_S8_Z24: 377 intel_InitDepthPointers_z24_s8(rb); 378 break; 379 default: 380 _mesa_problem(NULL, 381 "Unexpected MesaFormat %d in intelSetSpanFunctions", 382 irb->Base.Format); 383 break; 384 } 385} 386