diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-06-12 12:09:34 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-06-12 12:09:34 -0400 |
commit | 1036ef2bf468611d37b5df06fc4424f2002e3837 (patch) | |
tree | f0859a6d903c2570a0a00c918da88139f8f7d065 /src/mesa/drivers/dri/intel | |
parent | 917f8bc1a85e61311cef6478127b387df70fba14 (diff) | |
parent | 1cd0afffc9edbcac690f8ab436aecfced26b0aba (diff) |
Merge master and fix conflicts
Diffstat (limited to 'src/mesa/drivers/dri/intel')
31 files changed, 1350 insertions, 501 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 4ae9b118a3..4919828131 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -32,6 +32,8 @@ #include "main/mtypes.h" #include "main/context.h" #include "main/enums.h" +#include "main/texformat.h" +#include "main/colormac.h" #include "intel_blit.h" #include "intel_buffers.h" @@ -484,10 +486,9 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) const GLbitfield bufBit = 1 << buf; if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { /* OK, clear this renderbuffer */ - struct intel_region *irb_region = - intel_get_rb_region(fb, buf); + struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, buf); dri_bo *write_buffer = - intel_region_buffer(intel, irb_region, + intel_region_buffer(intel, irb->region, all ? INTEL_WRITE_FULL : INTEL_WRITE_PART); @@ -495,15 +496,13 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) GLint pitch, cpp; GLuint BR13, CMD; - ASSERT(irb_region); - - pitch = irb_region->pitch; - cpp = irb_region->cpp; + pitch = irb->region->pitch; + cpp = irb->region->cpp; DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", __FUNCTION__, - irb_region->buffer, (pitch * cpp), - irb_region->draw_offset, + irb->region->buffer, (pitch * cpp), + irb->region->draw_offset, b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1); BR13 = 0xf0 << 16; @@ -529,7 +528,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) } #ifndef I915 - if (irb_region->tiling != I915_TILING_NONE) { + if (irb->region->tiling != I915_TILING_NONE) { CMD |= XY_DST_TILED; pitch /= 4; } @@ -540,9 +539,36 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) clearVal = clear_depth; } else { - clearVal = (cpp == 4) - ? intel->ClearColor8888 : intel->ClearColor565; - } + uint8_t clear[4]; + GLclampf *color = ctx->Color.ClearColor; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + switch (irb->texformat->MesaFormat) { + case MESA_FORMAT_ARGB8888: + clearVal = intel->ClearColor8888; + break; + case MESA_FORMAT_RGB565: + clearVal = intel->ClearColor565; + break; + case MESA_FORMAT_ARGB4444: + clearVal = PACK_COLOR_4444(clear[3], clear[0], + clear[1], clear[2]); + break; + case MESA_FORMAT_ARGB1555: + clearVal = PACK_COLOR_1555(clear[3], clear[0], + clear[1], clear[2]); + break; + default: + _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n", + irb->texformat->MesaFormat); + clearVal = 0; + } + } + /* _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", buf, irb->Base.Name); @@ -558,7 +584,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) OUT_BATCH((b.y2 << 16) | b.x2); OUT_RELOC(write_buffer, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - irb_region->draw_offset); + irb->region->draw_offset); OUT_BATCH(clearVal); ADVANCE_BATCH(); clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index b7c7eeb368..23ba3b9ef6 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -35,6 +35,9 @@ #include "intel_batchbuffer.h" #include "intel_regions.h" +static GLboolean +intel_bufferobj_unmap(GLcontext * ctx, + GLenum target, struct gl_buffer_object *obj); /** Allocates a new dri_bo to store the data for the buffer object. */ static void @@ -100,8 +103,15 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - assert(!obj->Pointer); /* Mesa should have unmapped it */ + /* Buffer objects are automatically unmapped when deleting according + * to the spec, but Mesa doesn't do UnmapBuffer for us at context destroy + * (though it does if you call glDeleteBuffers) + */ + if (obj->Pointer) + intel_bufferobj_unmap(ctx, 0, obj); + + _mesa_free(intel_obj->sys_buffer); if (intel_obj->region) { intel_bufferobj_release_region(intel, intel_obj); } @@ -142,7 +152,23 @@ intel_bufferobj_data(GLcontext * ctx, dri_bo_unreference(intel_obj->buffer); intel_obj->buffer = NULL; } + _mesa_free(intel_obj->sys_buffer); + intel_obj->sys_buffer = NULL; + if (size != 0) { +#ifdef I915 + /* On pre-965, stick VBOs in system memory, as we're always doing swtnl + * with their contents anyway. + */ + if (target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER) { + intel_obj->sys_buffer = _mesa_malloc(size); + if (intel_obj->sys_buffer != NULL) { + if (data != NULL) + memcpy(intel_obj->sys_buffer, data, size); + return; + } + } +#endif intel_bufferobj_alloc_buffer(intel, intel_obj); if (data != NULL) @@ -172,7 +198,10 @@ intel_bufferobj_subdata(GLcontext * ctx, if (intel_obj->region) intel_bufferobj_cow(intel, intel_obj); - dri_bo_subdata(intel_obj->buffer, offset, size, data); + if (intel_obj->sys_buffer) + memcpy((char *)intel_obj->sys_buffer + offset, data, size); + else + dri_bo_subdata(intel_obj->buffer, offset, size, data); } @@ -204,11 +233,16 @@ intel_bufferobj_map(GLcontext * ctx, { struct intel_context *intel = intel_context(ctx); struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + GLboolean read_only = (access == GL_READ_ONLY_ARB); + GLboolean write_only = (access == GL_WRITE_ONLY_ARB); - /* XXX: Translate access to flags arg below: - */ assert(intel_obj); + if (intel_obj->sys_buffer) { + obj->Pointer = intel_obj->sys_buffer; + return obj->Pointer; + } + if (intel_obj->region) intel_bufferobj_cow(intel, intel_obj); @@ -217,7 +251,14 @@ intel_bufferobj_map(GLcontext * ctx, return NULL; } - dri_bo_map(intel_obj->buffer, GL_TRUE); + if (write_only && intel->intelScreen->kernel_exec_fencing) { + drm_intel_gem_bo_map_gtt(intel_obj->buffer); + intel_obj->mapped_gtt = GL_TRUE; + } else { + drm_intel_bo_map(intel_obj->buffer, !read_only); + intel_obj->mapped_gtt = GL_FALSE; + } + obj->Pointer = intel_obj->buffer->virtual; return obj->Pointer; } @@ -235,7 +276,11 @@ intel_bufferobj_unmap(GLcontext * ctx, assert(intel_obj); if (intel_obj->buffer != NULL) { assert(obj->Pointer); - dri_bo_unmap(intel_obj->buffer); + if (intel_obj->mapped_gtt) { + drm_intel_gem_bo_unmap_gtt(intel_obj->buffer); + } else { + drm_intel_bo_unmap(intel_obj->buffer); + } obj->Pointer = NULL; } return GL_TRUE; @@ -254,6 +299,18 @@ intel_bufferobj_buffer(struct intel_context *intel, } } + if (intel_obj->buffer == NULL) { + intel_bufferobj_alloc_buffer(intel, intel_obj); + intel_bufferobj_subdata(&intel->ctx, + GL_ARRAY_BUFFER_ARB, + 0, + intel_obj->Base.Size, + intel_obj->sys_buffer, + &intel_obj->Base); + _mesa_free(intel_obj->sys_buffer); + intel_obj->sys_buffer = NULL; + } + return intel_obj->buffer; } diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.h b/src/mesa/drivers/dri/intel/intel_buffer_objects.h index bf6dbd58f2..0431015631 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.h @@ -42,10 +42,13 @@ struct intel_buffer_object { struct gl_buffer_object Base; dri_bo *buffer; /* the low-level buffer manager's buffer handle */ + /** System memory buffer data, if not using a BO to store the data. */ + void *sys_buffer; struct intel_region *region; /* Is there a zero-copy texture associated with this (pixel) buffer object? */ + GLboolean mapped_gtt; }; diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 0929a2c223..df5c3fc176 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -157,7 +157,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) /* Do this here, not core Mesa, since this function is called from * many places within the driver. */ - if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (ctx->NewState & _NEW_BUFFERS) { /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ _mesa_update_framebuffer(ctx); /* this updates the DrawBuffer's Width/Height if it's a FBO */ @@ -202,6 +202,8 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) intel_batchbuffer_flush(intel->batch); intel->front_cliprects = GL_TRUE; colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); + + intel->front_buffer_dirty = GL_TRUE; } else { if (!intel->constant_cliprect && intel->front_cliprects) @@ -274,7 +276,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) ctx->Driver.Enable(ctx, GL_DEPTH_TEST, (ctx->Depth.Test && fb->Visual.depthBits > 0)); ctx->Driver.Enable(ctx, GL_STENCIL_TEST, - (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0)); + (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0)); } else { /* Mesa's Stencil._Enabled field is updated when @@ -319,6 +321,23 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) static void intelDrawBuffer(GLcontext * ctx, GLenum mode) { + if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { + struct intel_context *const intel = intel_context(ctx); + const GLboolean was_front_buffer_rendering = + intel->is_front_buffer_rendering; + + intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT) + || (mode == GL_FRONT); + + /* If we weren't front-buffer rendering before but we are now, make sure + * that the front-buffer has actually been allocated. + */ + if (!was_front_buffer_rendering && intel->is_front_buffer_rendering) { + intel_update_renderbuffers(intel->driContext, + intel->driContext->driDrawablePriv); + } + } + intel_draw_buffer(ctx, ctx->DrawBuffer); } diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index 28281b3861..309ac1923b 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -30,6 +30,7 @@ #include "main/enums.h" #include "main/image.h" #include "main/mtypes.h" +#include "main/arrayobj.h" #include "main/attrib.h" #include "main/blend.h" #include "main/bufferobj.h" @@ -38,6 +39,7 @@ #include "main/enable.h" #include "main/macros.h" #include "main/matrix.h" +#include "main/polygon.h" #include "main/texstate.h" #include "main/shaders.h" #include "main/stencil.h" @@ -51,6 +53,7 @@ #include "intel_clear.h" #include "intel_fbo.h" #include "intel_pixel.h" +#include "intel_regions.h" #define FILE_DEBUG_FLAG DEBUG_BLIT @@ -65,6 +68,45 @@ BUFFER_BIT_COLOR6 | \ BUFFER_BIT_COLOR7) + +/** + * Per-context one-time init of things for intl_clear_tris(). + * Basically set up a private array object for vertex/color arrays. + */ +static void +init_clear(GLcontext *ctx) +{ + struct intel_context *intel = intel_context(ctx); + struct gl_array_object *arraySave = NULL; + const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name; + const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name; + + /* create new array object */ + intel->clear.arrayObj = _mesa_new_array_object(ctx, ~0); + + /* save current array object, bind new one */ + _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); + + /* one-time setup of vertex arrays (pos, color) */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), intel->clear.color); + _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), intel->clear.vertices); + _mesa_Enable(GL_COLOR_ARRAY); + _mesa_Enable(GL_VERTEX_ARRAY); + + /* restore original array object */ + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); + _mesa_reference_array_object(ctx, &arraySave, NULL); + + /* restore original buffer objects */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer); +} + + + /** * Perform glClear where mask contains only color, depth, and/or stencil. * @@ -77,14 +119,16 @@ void intel_clear_tris(GLcontext *ctx, GLbitfield mask) { struct intel_context *intel = intel_context(ctx); - GLfloat vertices[4][3]; - GLfloat color[4][4]; GLfloat dst_z; struct gl_framebuffer *fb = ctx->DrawBuffer; int i; GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; GLuint saved_shader_program = 0; unsigned int saved_active_texture; + struct gl_array_object *arraySave = NULL; + + if (!intel->clear.arrayObj) + init_clear(ctx); assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0); @@ -93,10 +137,10 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask) GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | + GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT | GL_TRANSFORM_BIT | GL_CURRENT_BIT); - _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); saved_active_texture = ctx->Texture.CurrentUnit; /* Disable existing GL state we don't want to apply to a clear. */ @@ -114,6 +158,7 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask) _mesa_Disable(GL_CLIP_PLANE3); _mesa_Disable(GL_CLIP_PLANE4); _mesa_Disable(GL_CLIP_PLANE5); + _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { saved_fp_enable = GL_TRUE; _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); @@ -146,13 +191,14 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask) } } + /* save current array object, bind our private one */ + _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); + intel_meta_set_passthrough_transform(intel); for (i = 0; i < 4; i++) { - color[i][0] = ctx->Color.ClearColor[0]; - color[i][1] = ctx->Color.ClearColor[1]; - color[i][2] = ctx->Color.ClearColor[2]; - color[i][3] = ctx->Color.ClearColor[3]; + COPY_4FV(intel->clear.color[i], ctx->Color.ClearColor); } /* convert clear Z from [0,1] to NDC coord in [-1,1] */ @@ -161,23 +207,18 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask) /* Prepare the vertices, which are the same regardless of which buffer we're * drawing to. */ - vertices[0][0] = fb->_Xmin; - vertices[0][1] = fb->_Ymin; - vertices[0][2] = dst_z; - vertices[1][0] = fb->_Xmax; - vertices[1][1] = fb->_Ymin; - vertices[1][2] = dst_z; - vertices[2][0] = fb->_Xmax; - vertices[2][1] = fb->_Ymax; - vertices[2][2] = dst_z; - vertices[3][0] = fb->_Xmin; - vertices[3][1] = fb->_Ymax; - vertices[3][2] = dst_z; - - _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); - _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); - _mesa_Enable(GL_COLOR_ARRAY); - _mesa_Enable(GL_VERTEX_ARRAY); + intel->clear.vertices[0][0] = fb->_Xmin; + intel->clear.vertices[0][1] = fb->_Ymin; + intel->clear.vertices[0][2] = dst_z; + intel->clear.vertices[1][0] = fb->_Xmax; + intel->clear.vertices[1][1] = fb->_Ymin; + intel->clear.vertices[1][2] = dst_z; + intel->clear.vertices[2][0] = fb->_Xmax; + intel->clear.vertices[2][1] = fb->_Ymax; + intel->clear.vertices[2][2] = dst_z; + intel->clear.vertices[3][0] = fb->_Xmin; + intel->clear.vertices[3][1] = fb->_Ymax; + intel->clear.vertices[3][2] = dst_z; while (mask != 0) { GLuint this_mask = 0; @@ -215,8 +256,10 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask) /* Control writing of the stencil clear value to stencil. */ if (this_mask & BUFFER_BIT_STENCIL) { _mesa_Enable(GL_STENCIL_TEST); - _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, + _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, + GL_REPLACE, GL_REPLACE, GL_REPLACE); + _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, + ctx->Stencil.Clear, ctx->Stencil.WriteMask[0]); } else { _mesa_Disable(GL_STENCIL_TEST); @@ -238,8 +281,11 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask) if (saved_shader_program) _mesa_UseProgramObjectARB(saved_shader_program); - _mesa_PopClientAttrib(); _mesa_PopAttrib(); + + /* restore current array object */ + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); + _mesa_reference_array_object(ctx, &arraySave, NULL); } static const char *buffer_names[] = { @@ -267,7 +313,6 @@ static const char *buffer_names[] = { static void intelClear(GLcontext *ctx, GLbitfield mask) { - struct intel_context *intel = intel_context(ctx); const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); GLbitfield tri_mask = 0; GLbitfield blit_mask = 0; @@ -295,7 +340,7 @@ intelClear(GLcontext *ctx, GLbitfield mask) = intel_get_rb_region(fb, BUFFER_STENCIL); if (stencilRegion) { /* have hw stencil */ - if (IS_965(intel->intelScreen->deviceID) || + if (stencilRegion->tiling == I915_TILING_Y || (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { /* We have to use the 3D engine if we're clearing a partial mask * of the stencil buffer, or if we're on a 965 which has a tiled @@ -312,9 +357,10 @@ intelClear(GLcontext *ctx, GLbitfield mask) /* HW depth */ if (mask & BUFFER_BIT_DEPTH) { + const struct intel_region *irb = intel_get_rb_region(fb, BUFFER_DEPTH); + /* clear depth with whatever method is used for stencil (see above) */ - if (IS_965(intel->intelScreen->deviceID) || - tri_mask & BUFFER_BIT_STENCIL) + if (irb->tiling == I915_TILING_Y || tri_mask & BUFFER_BIT_STENCIL) tri_mask |= BUFFER_BIT_DEPTH; else blit_mask |= BUFFER_BIT_DEPTH; diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index a664e74936..f88b37d0f3 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -28,6 +28,7 @@ #include "main/glheader.h" #include "main/context.h" +#include "main/arrayobj.h" #include "main/extensions.h" #include "main/framebuffer.h" #include "main/imports.h" @@ -173,6 +174,24 @@ intelGetString(GLcontext * ctx, GLenum name) } } +static unsigned +intel_bits_per_pixel(const struct intel_renderbuffer *rb) +{ + switch (rb->Base._ActualFormat) { + case GL_RGB5: + case GL_DEPTH_COMPONENT16: + return 16; + case GL_RGB8: + case GL_RGBA8: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH24_STENCIL8_EXT: + case GL_STENCIL_INDEX8_EXT: + return 32; + default: + return 0; + } +} + void intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) { @@ -180,7 +199,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct intel_renderbuffer *rb; struct intel_region *region, *depth_region; struct intel_context *intel = context->driverPrivate; - __DRIbuffer *buffers; + __DRIbuffer *buffers = NULL; __DRIscreen *screen; int i, count; unsigned int attachments[10]; @@ -192,22 +211,63 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) screen = intel->intelScreen->driScrnPriv; - i = 0; - if (intel_fb->color_rb[0]) - attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - if (intel_fb->color_rb[1]) - attachments[i++] = __DRI_BUFFER_BACK_LEFT; - if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH)) - attachments[i++] = __DRI_BUFFER_DEPTH; - if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL)) - attachments[i++] = __DRI_BUFFER_STENCIL; - - buffers = (*screen->dri2.loader->getBuffers)(drawable, - &drawable->w, - &drawable->h, - attachments, i, - &count, - drawable->loaderPrivate); + if (screen->dri2.loader + && (screen->dri2.loader->base.version > 2) + && (screen->dri2.loader->getBuffersWithFormat != NULL)) { + struct intel_renderbuffer *depth_rb; + struct intel_renderbuffer *stencil_rb; + + i = 0; + if ((intel->is_front_buffer_rendering || !intel_fb->color_rb[1]) + && intel_fb->color_rb[0]) { + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]); + } + + if (intel_fb->color_rb[1]) { + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[1]); + } + + depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + + if ((depth_rb != NULL) && (stencil_rb != NULL)) { + attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + attachments[i++] = intel_bits_per_pixel(depth_rb); + } else if (depth_rb != NULL) { + attachments[i++] = __DRI_BUFFER_DEPTH; + attachments[i++] = intel_bits_per_pixel(depth_rb); + } else if (stencil_rb != NULL) { + attachments[i++] = __DRI_BUFFER_STENCIL; + attachments[i++] = intel_bits_per_pixel(stencil_rb); + } + + buffers = + (*screen->dri2.loader->getBuffersWithFormat)(drawable, + &drawable->w, + &drawable->h, + attachments, i / 2, + &count, + drawable->loaderPrivate); + } else if (screen->dri2.loader) { + i = 0; + if (intel_fb->color_rb[0]) + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + if (intel_fb->color_rb[1]) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH)) + attachments[i++] = __DRI_BUFFER_DEPTH; + if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL)) + attachments[i++] = __DRI_BUFFER_STENCIL; + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, + &drawable->h, + attachments, i, + &count, + drawable->loaderPrivate); + } if (buffers == NULL) return; @@ -235,6 +295,11 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) region_name = "dri2 front buffer"; break; + case __DRI_BUFFER_FAKE_FRONT_LEFT: + rb = intel_fb->color_rb[0]; + region_name = "dri2 fake front buffer"; + break; + case __DRI_BUFFER_BACK_LEFT: rb = intel_fb->color_rb[1]; region_name = "dri2 back buffer"; @@ -245,6 +310,11 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) region_name = "dri2 depth buffer"; break; + case __DRI_BUFFER_DEPTH_STENCIL: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + region_name = "dri2 depth / stencil buffer"; + break; + case __DRI_BUFFER_STENCIL: rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); region_name = "dri2 stencil buffer"; @@ -291,6 +361,23 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) intel_renderbuffer_set_region(rb, region); intel_region_release(®ion); + + if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + if (rb != NULL) { + struct intel_region *stencil_region = NULL; + + if (rb->region) { + dri_bo_flink(rb->region->buffer, &name); + if (name == buffers[i].name) + continue; + } + + intel_region_reference(&stencil_region, region); + intel_renderbuffer_set_region(rb, stencil_region); + intel_region_release(&stencil_region); + } + } } driUpdateFramebufferSize(&intel->ctx, drawable); @@ -307,7 +394,7 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) if (!driContext->driScreenPriv->dri2.enabled) return; - if (!intel->internal_viewport_call) { + if (!intel->internal_viewport_call && ctx->DrawBuffer->Name == 0) { intel_update_renderbuffers(driContext, driContext->driDrawablePriv); if (driContext->driDrawablePriv != driContext->driReadablePriv) intel_update_renderbuffers(driContext, driContext->driReadablePriv); @@ -391,6 +478,27 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) if (intel->batch->map != intel->batch->ptr) intel_batchbuffer_flush(intel->batch); + + if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) { + __DRIscreen *const screen = intel->intelScreen->driScrnPriv; + + if (screen->dri2.loader && + (screen->dri2.loader->base.version >= 2) + && (screen->dri2.loader->flushFrontBuffer != NULL)) { + (*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable, + intel->driDrawable->loaderPrivate); + + /* Only clear the dirty bit if front-buffer rendering is no longer + * enabled. This is done so that the dirty bit can only be set in + * glDrawBuffer. Otherwise the dirty bit would have to be set at + * each of N places that do rendering. This has worse performances, + * but it is much easier to get correct. + */ + if (intel->is_front_buffer_rendering) { + intel->front_buffer_dirty = GL_FALSE; + } + } + } } void @@ -442,6 +550,9 @@ intelInitDriverFunctions(struct dd_function_table *functions) functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; intelInitTextureFuncs(functions); + intelInitTextureImageFuncs(functions); + intelInitTextureSubImageFuncs(functions); + intelInitTextureCopyImageFuncs(functions); intelInitStateFuncs(functions); intelInitClearFuncs(functions); intelInitBufferFuncs(functions); @@ -502,8 +613,6 @@ intelInitContext(struct intel_context *intel, } } - ctx->Const.MaxTextureMaxAnisotropy = 2.0; - /* This doesn't yet catch all non-conformant rendering, but it's a * start. */ @@ -544,6 +653,13 @@ intelInitContext(struct intel_context *intel, _mesa_init_point(ctx); ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ + if (IS_965(intelScreen->deviceID)) { + if (MAX_WIDTH > 8192) + ctx->Const.MaxRenderbufferSize = 8192; + } else { + if (MAX_WIDTH > 2048) + ctx->Const.MaxRenderbufferSize = 2048; + } /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); @@ -611,6 +727,9 @@ intelInitContext(struct intel_context *intel, else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) { _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); } + intel->use_texture_tiling = driQueryOptionb(&intel->optionCache, + "texture_tiling"); + intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z"); intel->prim.primitive = ~0; @@ -650,6 +769,9 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) INTEL_FIREVERTICES(intel); + if (intel->clear.arrayObj) + _mesa_delete_array_object(&intel->ctx, intel->clear.arrayObj); + intel->vtbl.destroy(intel); release_texture_heaps = (intel->ctx.Shared->RefCount == 1); @@ -669,13 +791,64 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel->prim.vb_bo = NULL; if (release_texture_heaps) { - /* This share group is about to go away, free our private - * texture object data. + /* Nothing is currently done here to free texture heaps; + * but we're not using the texture heap utilities, so I + * rather think we shouldn't. I've taken a look, and can't + * find any private texture data hanging around anywhere, but + * I'm not yet certain there isn't any at all... */ - if (INTEL_DEBUG & DEBUG_TEXTURE) + /* if (INTEL_DEBUG & DEBUG_TEXTURE) fprintf(stderr, "do something to free texture heaps\n"); + */ } + /* XXX In intelMakeCurrent() below, the context's static regions are + * referenced inside the frame buffer; it's listed as a hack, + * with a comment of "XXX FBO temporary fix-ups!", but + * as long as it's there, we should release the regions here. + * The do/while loop around the block is used to allow the + * "continue" statements inside the block to exit the block, + * to avoid many layers of "if" constructs. + */ + do { + __DRIdrawablePrivate * driDrawPriv = intel->driDrawable; + struct intel_framebuffer *intel_fb; + struct intel_renderbuffer *irbDepth, *irbStencil; + if (!driDrawPriv) { + /* We're already detached from the drawable; exit this block. */ + continue; + } + intel_fb = (struct intel_framebuffer *) driDrawPriv->driverPrivate; + if (!intel_fb) { + /* The frame buffer is already gone; exit this block. */ + continue; + } + irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + irbStencil = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + + /* If the regions of the frame buffer still match the regions + * of the context, release them. If they've changed somehow, + * leave them alone. + */ + if (intel_fb->color_rb[0] && intel_fb->color_rb[0]->region == intel->front_region) { + intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL); + } + if (intel_fb->color_rb[1] && intel_fb->color_rb[1]->region == intel->back_region) { + intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL); + } + + if (irbDepth && irbDepth->region == intel->depth_region) { + intel_renderbuffer_set_region(irbDepth, NULL); + } + /* Usually, the stencil buffer is the same as the depth buffer; + * but they're handled separately in MakeCurrent, so we'll + * handle them separately here. + */ + if (irbStencil && irbStencil->region == intel->depth_region) { + intel_renderbuffer_set_region(irbStencil, NULL); + } + } while (0); + intel_region_release(&intel->front_region); intel_region_release(&intel->back_region); intel_region_release(&intel->depth_region); @@ -684,6 +857,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) /* free the Mesa context */ _mesa_free_context_data(&intel->ctx); + + } } @@ -712,7 +887,10 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, if (driDrawPriv != driReadPriv) intel_update_renderbuffers(driContextPriv, driReadPriv); } else { - /* XXX FBO temporary fix-ups! */ + /* XXX FBO temporary fix-ups! These are released in + * intelDextroyContext(), above. Changes here should be + * reflected there. + */ /* if the renderbuffers don't have regions, init them from the context */ struct intel_renderbuffer *irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index d635f3f50d..7d3c80bb21 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -48,6 +48,8 @@ #define DV_PF_555 (1<<8) #define DV_PF_565 (2<<8) #define DV_PF_8888 (3<<8) +#define DV_PF_4444 (8<<8) +#define DV_PF_1555 (9<<8) struct intel_region; struct intel_context; @@ -159,12 +161,22 @@ struct intel_context struct { struct gl_fragment_program *bitmap_fp; struct gl_vertex_program *passthrough_vp; + struct gl_buffer_object *texcoord_vbo; struct gl_fragment_program *saved_fp; GLboolean saved_fp_enable; struct gl_vertex_program *saved_vp; GLboolean saved_vp_enable; + struct gl_fragment_program *tex2d_fp; + + GLboolean saved_texcoord_enable; + struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; + GLenum saved_texcoord_type; + GLsizei saved_texcoord_size, saved_texcoord_stride; + const void *saved_texcoord_ptr; + int saved_active_texture; + GLint saved_vp_x, saved_vp_y; GLsizei saved_vp_width, saved_vp_height; GLenum saved_matrix_mode; @@ -213,6 +225,14 @@ struct intel_context GLuint ClearColor565; GLuint ClearColor8888; + /* info for intel_clear_tris() */ + struct + { + struct gl_array_object *arrayObj; + GLfloat vertices[4][3]; + GLfloat color[4][4]; + } clear; + /* Offsets of fields within the current vertex: */ GLuint coloroffset; @@ -262,11 +282,32 @@ struct intel_context * flush time while the lock is held. */ GLboolean constant_cliprect; + /** * In !constant_cliprect mode, set to true if the front cliprects should be * used instead of back. */ GLboolean front_cliprects; + + /** + * Set if rendering has occured to the drawable's front buffer. + * + * This is used in the DRI2 case to detect that glFlush should also copy + * the contents of the fake front buffer to the real front buffer. + */ + GLboolean front_buffer_dirty; + + /** + * Track whether front-buffer rendering is currently enabled + * + * A separate flag is used to track this in order to support MRT more + * easily. + */ + GLboolean is_front_buffer_rendering; + + GLboolean use_texture_tiling; + GLboolean use_early_z; + drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ int perf_boxes; @@ -319,6 +360,7 @@ extern char *__progname; #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1)) +#define IS_POWER_OF_TWO(val) (((val) & (val - 1)) == 0) #define INTEL_FIREVERTICES(intel) \ do { \ @@ -520,6 +562,9 @@ void intel_viewport(GLcontext * ctx, GLint x, GLint y, void intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable); +void i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region, + uint32_t buffer_id); + /*====================================================================== * Inline conversion functions. * These are better-typed than the macros used previously: @@ -530,4 +575,10 @@ intel_context(GLcontext * ctx) return (struct intel_context *) ctx; } +static INLINE GLboolean +is_power_of_two(uint32_t value) +{ + return (value & (value - 1)) == 0; +} + #endif diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c index f04638206d..a9dfe281cb 100644 --- a/src/mesa/drivers/dri/intel/intel_decode.c +++ b/src/mesa/drivers/dri/intel/intel_decode.c @@ -800,6 +800,7 @@ static int decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i830) { unsigned int len, i, c, opcode, word, map, sampler, instr; + char *format; struct { uint32_t opcode; @@ -1001,6 +1002,35 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i (*failures)++; } return len; + case 0x85: + len = (data[0] & 0x0000000f) + 2; + + if (len != 2) + fprintf(out, "Bad count in 3DSTATE_DEST_BUFFER_VARIABLES\n"); + if (count < 2) + BUFFER_FAIL(count, len, "3DSTATE_DEST_BUFFER_VARIABLES"); + + instr_out(data, hw_offset, 0, + "3DSTATE_DEST_BUFFER_VARIABLES\n"); + + switch ((data[1] >> 8) & 0xf) { + case 0x0: format = "g8"; break; + case 0x1: format = "x1r5g5b5"; break; + case 0x2: format = "r5g6b5"; break; + case 0x3: format = "a8r8g8b8"; break; + case 0x4: format = "ycrcb_swapy"; break; + case 0x5: format = "ycrcb_normal"; break; + case 0x6: format = "ycrcb_swapuv"; break; + case 0x7: format = "ycrcb_swapuvy"; break; + case 0x8: format = "a4r4g4b4"; break; + case 0x9: format = "a1r5g5b5"; break; + case 0xa: format = "a2r10g10b10"; break; + default: format = "BAD"; break; + } + instr_out(data, hw_offset, 1, "%s format, early Z %sabled\n", + format, + (data[1] & (1 << 31)) ? "en" : "dis"); + return len; } for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c index 9ec1b4ec2f..1e8b1878ab 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions.c +++ b/src/mesa/drivers/dri/intel/intel_extensions.c @@ -48,6 +48,7 @@ #define need_GL_EXT_point_parameters #define need_GL_EXT_secondary_color #define need_GL_EXT_stencil_two_side +#define need_GL_APPLE_vertex_array_object #define need_GL_ATI_separate_stencil #define need_GL_ATI_envmap_bumpmap #define need_GL_NV_point_sprite @@ -95,6 +96,7 @@ static const struct dri_extension card_extensions[] = { { "GL_EXT_texture_lod_bias", NULL }, { "GL_3DFX_texture_compression_FXT1", NULL }, { "GL_APPLE_client_storage", NULL }, + { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions}, { "GL_MESA_pack_invert", NULL }, { "GL_MESA_ycbcr_texture", NULL }, { "GL_NV_blend_square", NULL }, diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index a401f730ba..0ea413aee1 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -119,6 +119,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, rb->RedBits = 5; rb->GreenBits = 6; rb->BlueBits = 5; + irb->texformat = &_mesa_texformat_rgb565; cpp = 2; break; case GL_RGB: @@ -132,6 +133,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, rb->GreenBits = 8; rb->BlueBits = 8; rb->AlphaBits = 0; + irb->texformat = &_mesa_texformat_argb8888; /* XXX: Need xrgb8888 */ cpp = 4; break; case GL_RGBA: @@ -148,6 +150,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, rb->GreenBits = 8; rb->BlueBits = 8; rb->AlphaBits = 8; + irb->texformat = &_mesa_texformat_argb8888; cpp = 4; break; case GL_STENCIL_INDEX: @@ -160,12 +163,14 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, rb->DataType = GL_UNSIGNED_INT_24_8_EXT; rb->StencilBits = 8; cpp = 4; + irb->texformat = &_mesa_texformat_s8_z24; break; case GL_DEPTH_COMPONENT16: rb->_ActualFormat = GL_DEPTH_COMPONENT16; rb->DataType = GL_UNSIGNED_SHORT; rb->DepthBits = 16; cpp = 2; + irb->texformat = &_mesa_texformat_z16; break; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT24: @@ -174,6 +179,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, rb->DataType = GL_UNSIGNED_INT_24_8_EXT; rb->DepthBits = 24; cpp = 4; + irb->texformat = &_mesa_texformat_s8_z24; break; case GL_DEPTH_STENCIL_EXT: case GL_DEPTH24_STENCIL8_EXT: @@ -182,6 +188,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, rb->DepthBits = 24; rb->StencilBits = 8; cpp = 4; + irb->texformat = &_mesa_texformat_s8_z24; break; default: _mesa_problem(ctx, @@ -210,7 +217,8 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width, height, pitch); - irb->region = intel_region_alloc(intel, cpp, width, height, pitch, + irb->region = intel_region_alloc(intel, I915_TILING_NONE, + cpp, width, height, pitch, GL_TRUE); if (!irb->region) return GL_FALSE; /* out of memory? */ @@ -322,6 +330,7 @@ intel_create_renderbuffer(GLenum intFormat) irb->Base.GreenBits = 6; irb->Base.BlueBits = 5; irb->Base.DataType = GL_UNSIGNED_BYTE; + irb->texformat = &_mesa_texformat_rgb565; break; case GL_RGB8: irb->Base._ActualFormat = GL_RGB8; @@ -331,6 +340,7 @@ intel_create_renderbuffer(GLenum intFormat) irb->Base.BlueBits = 8; irb->Base.AlphaBits = 0; irb->Base.DataType = GL_UNSIGNED_BYTE; + irb->texformat = &_mesa_texformat_argb8888; /* XXX: Need xrgb8888 */ break; case GL_RGBA8: irb->Base._ActualFormat = GL_RGBA8; @@ -340,24 +350,28 @@ intel_create_renderbuffer(GLenum intFormat) irb->Base.BlueBits = 8; irb->Base.AlphaBits = 8; irb->Base.DataType = GL_UNSIGNED_BYTE; + irb->texformat = &_mesa_texformat_argb8888; break; case GL_STENCIL_INDEX8_EXT: irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT; irb->Base._BaseFormat = GL_STENCIL_INDEX; irb->Base.StencilBits = 8; irb->Base.DataType = GL_UNSIGNED_BYTE; + irb->texformat = &_mesa_texformat_s8_z24; break; case GL_DEPTH_COMPONENT16: irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; irb->Base._BaseFormat = GL_DEPTH_COMPONENT; irb->Base.DepthBits = 16; irb->Base.DataType = GL_UNSIGNED_SHORT; + irb->texformat = &_mesa_texformat_z16; break; case GL_DEPTH_COMPONENT24: irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; irb->Base._BaseFormat = GL_DEPTH_COMPONENT; irb->Base.DepthBits = 24; irb->Base.DataType = GL_UNSIGNED_INT; + irb->texformat = &_mesa_texformat_s8_z24; break; case GL_DEPTH24_STENCIL8_EXT: irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; @@ -365,6 +379,7 @@ intel_create_renderbuffer(GLenum intFormat) irb->Base.DepthBits = 24; irb->Base.StencilBits = 8; irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; + irb->texformat = &_mesa_texformat_s8_z24; break; default: _mesa_problem(NULL, @@ -449,6 +464,8 @@ static GLboolean intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, struct gl_texture_image *texImage) { + irb->texformat = texImage->TexFormat; + if (texImage->TexFormat == &_mesa_texformat_argb8888) { irb->Base._ActualFormat = GL_RGBA8; irb->Base._BaseFormat = GL_RGBA; @@ -458,9 +475,21 @@ intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, else if (texImage->TexFormat == &_mesa_texformat_rgb565) { irb->Base._ActualFormat = GL_RGB5; irb->Base._BaseFormat = GL_RGB; - irb->Base.DataType = GL_UNSIGNED_SHORT; + irb->Base.DataType = GL_UNSIGNED_BYTE; DBG("Render to RGB5 texture OK\n"); } + else if (texImage->TexFormat == &_mesa_texformat_argb1555) { + irb->Base._ActualFormat = GL_RGB5_A1; + irb->Base._BaseFormat = GL_RGBA; + irb->Base.DataType = GL_UNSIGNED_BYTE; + DBG("Render to ARGB1555 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_argb4444) { + irb->Base._ActualFormat = GL_RGBA4; + irb->Base._BaseFormat = GL_RGBA; + irb->Base.DataType = GL_UNSIGNED_BYTE; + DBG("Render to ARGB4444 texture OK\n"); + } else if (texImage->TexFormat == &_mesa_texformat_z16) { irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; irb->Base._BaseFormat = GL_DEPTH_COMPONENT; @@ -546,9 +575,10 @@ intel_render_texture(GLcontext * ctx, ASSERT(newImage); - if (newImage->Border != 0) { - /* Fallback on drawing to a texture with a border, which won't have a - * miptree. + intel_image = intel_texture_image(newImage); + if (!intel_image->mt) { + /* Fallback on drawing to a texture that doesn't have a miptree + * (has a border, width/height 0, etc.) */ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); _mesa_render_texture(ctx, fb, att); @@ -579,7 +609,6 @@ intel_render_texture(GLcontext * ctx, irb->Base.RefCount); /* point the renderbufer's region to the texture image region */ - intel_image = intel_texture_image(newImage); if (irb->region != intel_image->mt->region) { if (irb->region) intel_region_release(&irb->region); @@ -631,11 +660,11 @@ intel_finish_render_texture(GLcontext * ctx, static void intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) { - struct intel_context *intel = intel_context(ctx); const struct intel_renderbuffer *depthRb = intel_get_renderbuffer(fb, BUFFER_DEPTH); const struct intel_renderbuffer *stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL); + int i; if (stencilRb && stencilRb != depthRb) { /* we only support combined depth/stencil buffers, not separate @@ -644,32 +673,26 @@ intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; } - /* check that texture color buffers are a format we can render into */ - { - const struct gl_texture_format *supportedFormat; - GLuint i; + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; + struct intel_renderbuffer *irb = intel_renderbuffer(rb); - /* The texture format we can render into seems to depend on the - * screen depth. There currently seems to be a problem when - * rendering into a rgb565 texture when the screen is abgr8888. - */ + if (rb == NULL) + continue; + + if (irb == NULL) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + continue; + } - if (intel->ctx.Visual.rgbBits >= 24) - supportedFormat = &_mesa_texformat_argb8888; - else - supportedFormat = &_mesa_texformat_rgb565; - - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - const struct gl_texture_object *texObj = - fb->Attachment[BUFFER_COLOR0 + i].Texture; - if (texObj) { - const struct gl_texture_image *texImg = - texObj->Image[0][texObj->BaseLevel]; - if (texImg && texImg->TexFormat != supportedFormat) { - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; - break; - } - } + switch (irb->texformat->MesaFormat) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_ARGB4444: + break; + default: + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; } } } diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index 7226ee026f..f0665af482 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -61,6 +61,8 @@ struct intel_renderbuffer struct gl_renderbuffer Base; struct intel_region *region; + const struct gl_texture_format *texformat; + GLuint vbl_pending; /**< vblank sequence number of pending flip */ uint8_t *span_cache; diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c new file mode 100644 index 0000000000..1060fbd9e5 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <eric@anholt.net> + * + */ + +#include "main/glheader.h" +#include "main/enums.h" +#include "main/image.h" +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/bufferobj.h" +#include "main/teximage.h" +#include "main/texenv.h" +#include "main/texobj.h" +#include "main/texstate.h" +#include "main/texparam.h" +#include "main/varray.h" +#include "main/attrib.h" +#include "main/enable.h" +#include "main/buffers.h" +#include "main/fbobject.h" +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/depth.h" +#include "main/hash.h" +#include "main/mipmap.h" +#include "main/blend.h" +#include "glapi/dispatch.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_pixel.h" +#include "intel_tex.h" +#include "intel_mipmap_tree.h" + +static const char *intel_fp_tex2d = + "!!ARBfp1.0\n" + "TEX result.color, fragment.texcoord[0], texture[0], 2D;\n" + "END\n"; + +static GLboolean +intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name, + int level, int width, int height) +{ + struct intel_context *intel = intel_context(ctx); + GLfloat vertices[4][2]; + GLint status; + + /* Set to source from the previous level */ + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level - 1); + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1); + + /* Set to draw into the current level */ + _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + tex_name, + level); + /* Choose to render to the color attachment. */ + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + + status = _mesa_CheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return GL_FALSE; + + intel_meta_set_passthrough_transform(intel); + + /* XXX: Doing it right would involve setting up the transformation to do + * 0-1 mapping or something, and not changing the vertex data. + */ + vertices[0][0] = 0; + vertices[0][1] = 0; + vertices[1][0] = width; + vertices[1][1] = 0; + vertices[2][0] = width; + vertices[2][1] = height; + vertices[3][0] = 0; + vertices[3][1] = height; + + _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); + _mesa_Enable(GL_VERTEX_ARRAY); + intel_meta_set_default_texrect(intel); + + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + + intel_meta_restore_texcoords(intel); + intel_meta_restore_transform(intel); + + return GL_TRUE; +} + +static GLboolean +intel_generate_mipmap_2d(GLcontext *ctx, + GLenum target, + struct gl_texture_object *texObj) +{ + struct intel_context *intel = intel_context(ctx); + GLint old_active_texture; + int level, max_levels, start_level, end_level; + GLuint fb_name; + GLboolean success = GL_FALSE; + struct gl_framebuffer *saved_fbo = NULL; + + _mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | + GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | + GL_DEPTH_BUFFER_BIT); + _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + old_active_texture = ctx->Texture.CurrentUnit; + _mesa_reference_framebuffer(&saved_fbo, ctx->DrawBuffer); + + _mesa_Disable(GL_POLYGON_STIPPLE); + _mesa_Disable(GL_DEPTH_TEST); + _mesa_Disable(GL_STENCIL_TEST); + _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + _mesa_DepthMask(GL_FALSE); + + /* Bind the given texture to GL_TEXTURE_2D with linear filtering for our + * minification. + */ + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB); + _mesa_Enable(GL_TEXTURE_2D); + _mesa_BindTexture(GL_TEXTURE_2D, texObj->Name); + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_NEAREST); + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + /* Bind the new renderbuffer to the color attachment point. */ + _mesa_GenFramebuffersEXT(1, &fb_name); + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_name); + + intel_meta_set_fragment_program(intel, &intel->meta.tex2d_fp, + intel_fp_tex2d); + intel_meta_set_passthrough_vertex_program(intel); + + max_levels = _mesa_max_texture_levels(ctx, texObj->Target); + start_level = texObj->BaseLevel; + end_level = texObj->MaxLevel; + + /* Loop generating level+1 from level. */ + for (level = start_level; level < end_level && level < max_levels - 1; level++) { + const struct gl_texture_image *srcImage; + int width, height; + + srcImage = _mesa_select_tex_image(ctx, texObj, target, level); + if (srcImage->Border != 0) + goto fail; + + width = srcImage->Width / 2; + if (width < 1) + width = 1; + height = srcImage->Height / 2; + if (height < 1) + height = 1; + + if (width == srcImage->Width && + height == srcImage->Height) { + /* Neither _mesa_max_texture_levels nor texObj->MaxLevel are the + * maximum texture level for the object, so break out when we've gone + * over the edge. + */ + break; + } + + /* Make sure that there's space allocated for the target level. + * We could skip this if there's already space allocated and save some + * time. + */ + _mesa_TexImage2D(GL_TEXTURE_2D, level + 1, srcImage->InternalFormat, + width, height, 0, + GL_RGBA, GL_UNSIGNED_INT, NULL); + + if (!intel_generate_mipmap_level(ctx, texObj->Name, level + 1, + width, height)) + goto fail; + } + + success = GL_TRUE; + +fail: + intel_meta_restore_fragment_program(intel); + intel_meta_restore_vertex_program(intel); + + _mesa_DeleteFramebuffersEXT(1, &fb_name); + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); + if (saved_fbo) + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, saved_fbo->Name); + _mesa_reference_framebuffer(&saved_fbo, NULL); + _mesa_PopClientAttrib(); + _mesa_PopAttrib(); + + return success; +} + + +/** + * Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap + * level). + * + * The texture object's miptree must be mapped. + * + * It would be really nice if this was just called by Mesa whenever mipmaps + * needed to be regenerated, rather than us having to remember to do so in + * each texture image modification path. + * + * This function should also include an accelerated path. + */ +void +intel_generate_mipmap(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + int face, i; + + /* HW path */ + if (target == GL_TEXTURE_2D && + ctx->Extensions.EXT_framebuffer_object && + ctx->Extensions.ARB_fragment_program && + ctx->Extensions.ARB_vertex_program) { + GLboolean success; + + /* We'll be accessing this texture using GL entrypoints, which should + * be resilient against other access to this texture. + */ + _mesa_unlock_texture(ctx, texObj); + success = intel_generate_mipmap_2d(ctx, target, texObj); + _mesa_lock_texture(ctx, texObj); + + if (success) + return; + } + + /* SW path */ + intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel); + _mesa_generate_mipmap(ctx, target, texObj); + intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel); + + /* Update the level information in our private data in the new images, since + * it didn't get set as part of a normal TexImage path. + */ + for (face = 0; face < nr_faces; face++) { + for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { + struct intel_texture_image *intelImage; + + intelImage = intel_texture_image(texObj->Image[face][i]); + if (intelImage == NULL) + break; + + intelImage->level = i; + intelImage->face = face; + /* Unreference the miptree to signal that the new Data is a bare + * pointer from mesa. + */ + intel_miptree_release(intel, &intelImage->mt); + } + } +} diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 6e1e034e53..0d34f28311 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -57,14 +57,16 @@ intel_miptree_create_internal(struct intel_context *intel, GLuint last_level, GLuint width0, GLuint height0, - GLuint depth0, GLuint cpp, GLuint compress_byte) + GLuint depth0, GLuint cpp, GLuint compress_byte, + uint32_t tiling) { GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); - DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, + DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); + _mesa_lookup_enum_by_nr(internal_format), + first_level, last_level, mt); mt->target = target_to_target(target); mt->internal_format = internal_format; @@ -80,15 +82,16 @@ intel_miptree_create_internal(struct intel_context *intel, #ifdef I915 if (IS_945(intel->intelScreen->deviceID)) - ok = i945_miptree_layout(intel, mt); + ok = i945_miptree_layout(intel, mt, tiling); else - ok = i915_miptree_layout(intel, mt); + ok = i915_miptree_layout(intel, mt, tiling); #else - ok = brw_miptree_layout(intel, mt); + ok = brw_miptree_layout(intel, mt, tiling); #endif if (!ok) { free(mt); + DBG("%s not okay - returning NULL\n", __FUNCTION__); return NULL; } @@ -107,10 +110,18 @@ intel_miptree_create(struct intel_context *intel, GLboolean expect_accelerated_upload) { struct intel_mipmap_tree *mt; + uint32_t tiling; + + if (intel->use_texture_tiling && compress_byte == 0 && + intel->intelScreen->kernel_exec_fencing) + tiling = I915_TILING_X; + else + tiling = I915_TILING_NONE; mt = intel_miptree_create_internal(intel, target, internal_format, first_level, last_level, width0, - height0, depth0, cpp, compress_byte); + height0, depth0, cpp, compress_byte, + tiling); /* * pitch == 0 || height == 0 indicates the null texture */ @@ -118,6 +129,7 @@ intel_miptree_create(struct intel_context *intel, return NULL; mt->region = intel_region_alloc(intel, + tiling, mt->cpp, mt->pitch, mt->total_height, @@ -147,7 +159,8 @@ intel_miptree_create_for_region(struct intel_context *intel, mt = intel_miptree_create_internal(intel, target, internal_format, first_level, last_level, region->width, region->height, 1, - region->cpp, compress_byte); + region->cpp, compress_byte, + I915_TILING_NONE); if (!mt) return mt; #if 0 @@ -185,6 +198,7 @@ intel_miptree_create_for_region(struct intel_context *intel, int intel_miptree_pitch_align (struct intel_context *intel, struct intel_mipmap_tree *mt, + uint32_t tiling, int pitch) { #ifdef I915 @@ -205,6 +219,11 @@ int intel_miptree_pitch_align (struct intel_context *intel, pitch_align = 4; } + if (tiling == I915_TILING_X) + pitch_align = 512; + else if (tiling == I915_TILING_Y) + pitch_align = 128; + pitch = ALIGN(pitch * mt->cpp, pitch_align); #ifdef I915 diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 4060b9df78..3af9966827 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -148,6 +148,7 @@ intel_miptree_create_for_region(struct intel_context *intel, int intel_miptree_pitch_align (struct intel_context *intel, struct intel_mipmap_tree *mt, + uint32_t tiling, int pitch); void intel_miptree_reference(struct intel_mipmap_tree **dst, @@ -218,10 +219,13 @@ void intel_miptree_image_copy(struct intel_context *intel, /* i915_mipmap_tree.c: */ GLboolean i915_miptree_layout(struct intel_context *intel, - struct intel_mipmap_tree *mt); + struct intel_mipmap_tree *mt, + uint32_t tiling); GLboolean i945_miptree_layout(struct intel_context *intel, - struct intel_mipmap_tree *mt); + struct intel_mipmap_tree *mt, + uint32_t tiling); GLboolean brw_miptree_layout(struct intel_context *intel, - struct intel_mipmap_tree *mt); + struct intel_mipmap_tree *mt, + uint32_t tiling); #endif diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index fc0ac0b79c..36a684b3b8 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -27,9 +27,12 @@ #include "main/enums.h" #include "main/state.h" +#include "main/bufferobj.h" #include "main/context.h" #include "main/enable.h" #include "main/matrix.h" +#include "main/texstate.h" +#include "main/varray.h" #include "main/viewport.h" #include "swrast/swrast.h" #include "shader/arbprogram.h" @@ -334,6 +337,85 @@ intel_meta_restore_fragment_program(struct intel_context *intel) _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); } +static const float default_texcoords[4][2] = { { 0.0, 0.0 }, + { 1.0, 0.0 }, + { 1.0, 1.0 }, + { 0.0, 1.0 } }; + +void +intel_meta_set_default_texrect(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + struct gl_client_array *old_texcoord_array; + + intel->meta.saved_active_texture = ctx->Texture.CurrentUnit; + if (intel->meta.saved_array_vbo == NULL) { + _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, + ctx->Array.ArrayBufferObj); + } + + old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; + intel->meta.saved_texcoord_type = old_texcoord_array->Type; + intel->meta.saved_texcoord_size = old_texcoord_array->Size; + intel->meta.saved_texcoord_stride = old_texcoord_array->Stride; + intel->meta.saved_texcoord_enable = old_texcoord_array->Enabled; + intel->meta.saved_texcoord_ptr = old_texcoord_array->Ptr; + _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, + old_texcoord_array->BufferObj); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0); + + if (intel->meta.texcoord_vbo == NULL) { + GLuint vbo_name; + + _mesa_GenBuffersARB(1, &vbo_name); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), + default_texcoords, GL_STATIC_DRAW_ARB); + _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, + ctx->Array.ArrayBufferObj); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + intel->meta.texcoord_vbo->Name); + } + _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); + + _mesa_Enable(GL_TEXTURE_COORD_ARRAY); +} + +void +intel_meta_restore_texcoords(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + + /* Restore the old TexCoordPointer */ + if (intel->meta.saved_texcoord_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + intel->meta.saved_texcoord_vbo->Name); + _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + + _mesa_TexCoordPointer(intel->meta.saved_texcoord_size, + intel->meta.saved_texcoord_type, + intel->meta.saved_texcoord_stride, + intel->meta.saved_texcoord_ptr); + if (!intel->meta.saved_texcoord_enable) + _mesa_Disable(GL_TEXTURE_COORD_ARRAY); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0 + + intel->meta.saved_active_texture); + + if (intel->meta.saved_array_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + intel->meta.saved_array_vbo->Name); + _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + void intelInitPixelFuncs(struct dd_function_table *functions) { @@ -355,5 +437,7 @@ intel_free_pixel_state(struct intel_context *intel) _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, NULL); _mesa_reference_fragprog(ctx, &intel->meta.bitmap_fp, NULL); + _mesa_reference_fragprog(ctx, &intel->meta.tex2d_fp, NULL); + _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, NULL); } diff --git a/src/mesa/drivers/dri/intel/intel_pixel.h b/src/mesa/drivers/dri/intel/intel_pixel.h index cb41fa182c..6acf0813c8 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.h +++ b/src/mesa/drivers/dri/intel/intel_pixel.h @@ -40,6 +40,9 @@ void intel_meta_set_fragment_program(struct intel_context *intel, const char *prog_string); void intel_meta_restore_fragment_program(struct intel_context *intel); void intel_free_pixel_state(struct intel_context *intel); +void intel_meta_set_default_texrect(struct intel_context *intel); +void intel_meta_set_default_texrect(struct intel_context *intel); +void intel_meta_restore_texcoords(struct intel_context *intel); GLboolean intel_check_blit_fragment_ops(GLcontext * ctx, GLboolean src_alpha_is_one); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 1db7f5594e..80d3239189 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -360,7 +360,6 @@ intel_texture_bitmap(GLcontext * ctx, "END\n"; GLuint texname; GLfloat vertices[4][4]; - GLfloat texcoords[4][2]; GLint old_active_texture; GLubyte *unpacked_bitmap; GLubyte *a8_bitmap; @@ -401,6 +400,14 @@ intel_texture_bitmap(GLcontext * ctx, return GL_FALSE; } + if (!ctx->Extensions.ARB_texture_non_power_of_two && + (!is_power_of_two(width) || !is_power_of_two(height))) { + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, + "glBitmap() fallback: NPOT texture\n"); + return GL_FALSE; + } + /* Check that we can load in a texture this big. */ if (width > (1 << (ctx->Const.MaxTextureLevels - 1)) || height > (1 << (ctx->Const.MaxTextureLevels - 1))) { @@ -485,22 +492,12 @@ intel_texture_bitmap(GLcontext * ctx, vertices[3][2] = dst_z; vertices[3][3] = 1.0; - texcoords[0][0] = 0.0; - texcoords[0][1] = 0.0; - texcoords[1][0] = 1.0; - texcoords[1][1] = 0.0; - texcoords[2][0] = 1.0; - texcoords[2][1] = 1.0; - texcoords[3][0] = 0.0; - texcoords[3][1] = 1.0; - _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); - _mesa_ClientActiveTextureARB(GL_TEXTURE0); - _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); _mesa_Enable(GL_VERTEX_ARRAY); - _mesa_Enable(GL_TEXTURE_COORD_ARRAY); + intel_meta_set_default_texrect(intel); CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); intel_meta_restore_fragment_program(intel); intel_meta_restore_vertex_program(intel); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index e8d5ac8569..46d27f1a93 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -70,7 +70,6 @@ intel_texture_drawpixels(GLcontext * ctx, struct intel_context *intel = intel_context(ctx); GLuint texname; GLfloat vertices[4][4]; - GLfloat texcoords[4][2]; GLfloat z; GLint old_active_texture; GLenum internalFormat; @@ -97,7 +96,7 @@ intel_texture_drawpixels(GLcontext * ctx, /* We don't have a way to generate fragments with stencil values which * will set the resulting stencil value. */ - if (format == GL_STENCIL_INDEX) + if (format == GL_STENCIL_INDEX || format == GL_DEPTH_STENCIL) return GL_FALSE; /* Check that we can load in a texture this big. */ @@ -120,6 +119,14 @@ intel_texture_drawpixels(GLcontext * ctx, return GL_FALSE; } + if (!ctx->Extensions.ARB_texture_non_power_of_two && + (!is_power_of_two(width) || !is_power_of_two(height))) { + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, + "glDrawPixels() fallback: NPOT texture\n"); + return GL_FALSE; + } + _mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_CURRENT_BIT); _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); @@ -169,22 +176,13 @@ intel_texture_drawpixels(GLcontext * ctx, vertices[3][2] = z; vertices[3][3] = 1.0; - texcoords[0][0] = 0.0; - texcoords[0][1] = 0.0; - texcoords[1][0] = 1.0; - texcoords[1][1] = 0.0; - texcoords[2][0] = 1.0; - texcoords[2][1] = 1.0; - texcoords[3][0] = 0.0; - texcoords[3][1] = 1.0; - _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); - _mesa_ClientActiveTextureARB(GL_TEXTURE0); - _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); _mesa_Enable(GL_VERTEX_ARRAY); - _mesa_Enable(GL_TEXTURE_COORD_ARRAY); + intel_meta_set_default_texrect(intel); + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); @@ -208,7 +206,6 @@ intel_stencil_drawpixels(GLcontext * ctx, struct intel_context *intel = intel_context(ctx); GLuint texname, rb_name, fb_name, old_fb_name; GLfloat vertices[4][2]; - GLfloat texcoords[4][2]; struct intel_renderbuffer *irb; struct intel_renderbuffer *depth_irb; struct gl_renderbuffer *rb; @@ -273,6 +270,14 @@ intel_stencil_drawpixels(GLcontext * ctx, return GL_FALSE; } + if (!ctx->Extensions.ARB_texture_non_power_of_two && + (!is_power_of_two(width) || !is_power_of_two(height))) { + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, + "glDrawPixels(GL_STENCIL_INDEX) fallback: NPOT texture\n"); + return GL_FALSE; + } + _mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); @@ -343,7 +348,6 @@ intel_stencil_drawpixels(GLcontext * ctx, _mesa_free(stencil_pixels); intel_meta_set_passthrough_transform(intel); - vertices[0][0] = x; vertices[0][1] = y; vertices[1][0] = x + width * ctx->Pixel.ZoomX; @@ -353,22 +357,13 @@ intel_stencil_drawpixels(GLcontext * ctx, vertices[3][0] = x; vertices[3][1] = y + height * ctx->Pixel.ZoomY; - texcoords[0][0] = 0.0; - texcoords[0][1] = 0.0; - texcoords[1][0] = 1.0; - texcoords[1][1] = 0.0; - texcoords[2][0] = 1.0; - texcoords[2][1] = 1.0; - texcoords[3][0] = 0.0; - texcoords[3][1] = 1.0; - _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); - _mesa_ClientActiveTextureARB(GL_TEXTURE0); - _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); _mesa_Enable(GL_VERTEX_ARRAY); - _mesa_Enable(GL_TEXTURE_COORD_ARRAY); + intel_meta_set_default_texrect(intel); + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); diff --git a/src/mesa/drivers/dri/intel/intel_reg.h b/src/mesa/drivers/dri/intel/intel_reg.h index 57ac8f0cc1..d19f1bae34 100644 --- a/src/mesa/drivers/dri/intel/intel_reg.h +++ b/src/mesa/drivers/dri/intel/intel_reg.h @@ -189,6 +189,19 @@ #define S7_DEPTH_OFFSET_CONST_MASK ~0 +/* p143 */ +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + /* Primitive dispatch on 830-945 */ #define _3DPRIMITIVE (CMD_3D | (0x1f << 24)) #define PRIM_INDIRECT (1<<23) diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 0aa5b8c02c..49bcb3c1dd 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -52,17 +52,74 @@ #define FILE_DEBUG_FLAG DEBUG_REGION +/* This should be set to the maximum backtrace size desired. + * Set it to 0 to disable backtrace debugging. + */ +#define DEBUG_BACKTRACE_SIZE 0 + +#if DEBUG_BACKTRACE_SIZE == 0 +/* Use the standard debug output */ +#define _DBG(...) DBG(__VA_ARGS__) +#else +/* Use backtracing debug output */ +#define _DBG(...) {debug_backtrace(); DBG(__VA_ARGS__);} + +/* Backtracing debug support */ +#include <execinfo.h> + +static void +debug_backtrace(void) +{ + void *trace[DEBUG_BACKTRACE_SIZE]; + char **strings = NULL; + int traceSize; + register int i; + + traceSize = backtrace(trace, DEBUG_BACKTRACE_SIZE); + strings = backtrace_symbols(trace, traceSize); + if (strings == NULL) { + DBG("no backtrace:"); + return; + } + + /* Spit out all the strings with a colon separator. Ignore + * the first, since we don't really care about the call + * to debug_backtrace() itself. Skip until the final "/" in + * the trace to avoid really long lines. + */ + for (i = 1; i < traceSize; i++) { + char *p = strings[i], *slash = strings[i]; + while (*p) { + if (*p++ == '/') { + slash = p; + } + } + + DBG("%s:", slash); + } + + /* Free up the memory, and we're done */ + free(strings); +} + +#endif + + + /* XXX: Thread safety? */ GLubyte * intel_region_map(struct intel_context *intel, struct intel_region *region) { - DBG("%s\n", __FUNCTION__); + _DBG("%s %p\n", __FUNCTION__, region); if (!region->map_refcount++) { if (region->pbo) intel_region_cow(intel, region); - dri_bo_map(region->buffer, GL_TRUE); + if (intel->intelScreen->kernel_exec_fencing) + drm_intel_gem_bo_map_gtt(region->buffer); + else + dri_bo_map(region->buffer, GL_TRUE); region->map = region->buffer->virtual; } @@ -72,9 +129,12 @@ intel_region_map(struct intel_context *intel, struct intel_region *region) void intel_region_unmap(struct intel_context *intel, struct intel_region *region) { - DBG("%s\n", __FUNCTION__); + _DBG("%s %p\n", __FUNCTION__, region); if (!--region->map_refcount) { - dri_bo_unmap(region->buffer); + if (intel->intelScreen->kernel_exec_fencing) + drm_intel_gem_bo_unmap_gtt(region->buffer); + else + dri_bo_unmap(region->buffer); region->map = NULL; } } @@ -87,10 +147,10 @@ intel_region_alloc_internal(struct intel_context *intel, { struct intel_region *region; - DBG("%s\n", __FUNCTION__); - - if (buffer == NULL) + if (buffer == NULL) { + _DBG("%s <-- NULL\n", __FUNCTION__); return NULL; + } region = calloc(sizeof(*region), 1); region->cpp = cpp; @@ -104,15 +164,18 @@ intel_region_alloc_internal(struct intel_context *intel, region->tiling = I915_TILING_NONE; region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE; + _DBG("%s <-- %p\n", __FUNCTION__, region); return region; } struct intel_region * intel_region_alloc(struct intel_context *intel, + uint32_t tiling, GLuint cpp, GLuint width, GLuint height, GLuint pitch, GLboolean expect_accelerated_upload) { dri_bo *buffer; + struct intel_region *region; if (expect_accelerated_upload) { buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region", @@ -122,7 +185,16 @@ intel_region_alloc(struct intel_context *intel, pitch * cpp * height, 64); } - return intel_region_alloc_internal(intel, cpp, width, height, pitch, buffer); + region = intel_region_alloc_internal(intel, cpp, width, height, + pitch, buffer); + + if (tiling != I915_TILING_NONE) { + assert(((pitch * cpp) & 511) == 0); + drm_intel_bo_set_tiling(buffer, &tiling, pitch * cpp); + drm_intel_bo_get_tiling(buffer, ®ion->tiling, ®ion->bit_6_swizzle); + } + + return region; } struct intel_region * @@ -158,7 +230,7 @@ void intel_region_reference(struct intel_region **dst, struct intel_region *src) { if (src) - DBG("%s %p %d\n", __FUNCTION__, src, src->refcount); + _DBG("%s %p %d\n", __FUNCTION__, src, src->refcount); assert(*dst == NULL); if (src) { @@ -172,10 +244,12 @@ intel_region_release(struct intel_region **region_handle) { struct intel_region *region = *region_handle; - if (region == NULL) + if (region == NULL) { + _DBG("%s NULL\n", __FUNCTION__); return; + } - DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1); + _DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1); ASSERT(region->refcount > 0); region->refcount--; @@ -251,7 +325,7 @@ intel_region_data(struct intel_context *intel, { GLboolean locked = GL_FALSE; - DBG("%s\n", __FUNCTION__); + _DBG("%s\n", __FUNCTION__); if (intel == NULL) return; @@ -293,7 +367,7 @@ intel_region_copy(struct intel_context *intel, GLuint src_offset, GLuint srcx, GLuint srcy, GLuint width, GLuint height) { - DBG("%s\n", __FUNCTION__); + _DBG("%s\n", __FUNCTION__); if (intel == NULL) return; @@ -326,7 +400,7 @@ intel_region_fill(struct intel_context *intel, GLuint dstx, GLuint dsty, GLuint width, GLuint height, GLuint color) { - DBG("%s\n", __FUNCTION__); + _DBG("%s\n", __FUNCTION__); if (intel == NULL) return; @@ -356,6 +430,8 @@ intel_region_attach_pbo(struct intel_context *intel, if (region->pbo == pbo) return; + _DBG("%s %p %p\n", __FUNCTION__, region, pbo); + /* If there is already a pbo attached, break the cow tie now. * Don't call intel_region_release_pbo() as that would * unnecessarily allocate a new buffer we would have to immediately @@ -385,6 +461,7 @@ void intel_region_release_pbo(struct intel_context *intel, struct intel_region *region) { + _DBG("%s %p\n", __FUNCTION__, region); assert(region->buffer == region->pbo->buffer); region->pbo->region = NULL; region->pbo = NULL; @@ -412,7 +489,7 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region) assert(region->cpp * region->pitch * region->height == pbo->Base.Size); - DBG("%s (%d bytes)\n", __FUNCTION__, pbo->Base.Size); + _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, pbo->Base.Size); /* Now blit from the texture buffer to the new buffer: */ @@ -459,6 +536,10 @@ intel_recreate_static(struct intel_context *intel, if (region == NULL) { region = calloc(sizeof(*region), 1); region->refcount = 1; + _DBG("%s creating new region %p\n", __FUNCTION__, region); + } + else { + _DBG("%s %p\n", __FUNCTION__, region); } if (intel->ctx.Visual.rgbBits == 24) diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index 45e2bf4e77..bd3c8e7325 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -73,7 +73,8 @@ struct intel_region * copied by calling intel_reference_region(). */ struct intel_region *intel_region_alloc(struct intel_context *intel, - GLuint cpp, GLuint width, + uint32_t tiling, + GLuint cpp, GLuint width, GLuint height, GLuint pitch, GLboolean expect_accelerated_upload); diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 65e62947ef..8da96ede64 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -49,6 +49,10 @@ #include "i915_drm.h" #include "i830_dri.h" +#define DRI_CONF_TEXTURE_TILING(def) \ + DRI_CONF_OPT_BEGIN(texture_tiling, bool, def) \ + DRI_CONF_DESC(en, "Enable texture tiling") \ + DRI_CONF_OPT_END \ PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -64,6 +68,17 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects") DRI_CONF_DESC_END DRI_CONF_OPT_END + +#ifdef I915 + DRI_CONF_TEXTURE_TILING(false) +#else + DRI_CONF_TEXTURE_TILING(true) +#endif + + DRI_CONF_OPT_BEGIN(early_z, bool, false) + DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).") + DRI_CONF_OPT_END + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY DRI_CONF_FORCE_S3TC_ENABLE(false) @@ -76,7 +91,7 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_SECTION_END DRI_CONF_END; -const GLuint __driNConfigOptions = 8; +const GLuint __driNConfigOptions = 10; #ifdef USE_NEW_INTERFACE static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; @@ -236,7 +251,7 @@ intel_get_param(__DRIscreenPrivate *psp, int param, int *value) ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); if (ret) { - fprintf(stderr, "drm_i915_getparam: %d\n", ret); + _mesa_warning(NULL, "drm_i915_getparam: %d", ret); return GL_FALSE; } diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index c3a873f1ab..34b78ebc1a 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -29,6 +29,7 @@ #include "main/macros.h" #include "main/mtypes.h" #include "main/colormac.h" +#include "main/texformat.h" #include "intel_buffers.h" #include "intel_fbo.h" @@ -313,6 +314,22 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #define INTEL_TAG(x) x##_RGB565 #include "intel_spantmp.h" +/* a4r4g4b4 color span and pixel functions */ +#define INTEL_PIXEL_FMT GL_BGRA +#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV +#define INTEL_READ_VALUE(offset) pread_16(irb, offset) +#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v) +#define INTEL_TAG(x) x##_ARGB4444 +#include "intel_spantmp.h" + +/* a1r5g5b5 color span and pixel functions */ +#define INTEL_PIXEL_FMT GL_BGRA +#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV +#define INTEL_READ_VALUE(offset) pread_16(irb, offset) +#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v) +#define INTEL_TAG(x) x##_ARGB1555 +#include "intel_spantmp.h" + /* a8r8g8b8 color span and pixel functions */ #define INTEL_PIXEL_FMT GL_BGRA #define INTEL_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV @@ -561,8 +578,8 @@ intel_set_span_functions(struct intel_context *intel, else tiling = I915_TILING_NONE; - if (rb->_ActualFormat == GL_RGB5) { - /* 565 RGB */ + switch (irb->texformat->MesaFormat) { + case MESA_FORMAT_RGB565: switch (tiling) { case I915_TILING_NONE: default: @@ -575,38 +592,67 @@ intel_set_span_functions(struct intel_context *intel, intel_YTile_InitPointers_RGB565(rb); break; } - } - else if (rb->_ActualFormat == GL_RGB8) { - /* 8888 RGBx */ + break; + case MESA_FORMAT_ARGB4444: switch (tiling) { case I915_TILING_NONE: default: - intelInitPointers_xRGB8888(rb); + intelInitPointers_ARGB4444(rb); break; case I915_TILING_X: - intel_XTile_InitPointers_xRGB8888(rb); + intel_XTile_InitPointers_ARGB4444(rb); break; case I915_TILING_Y: - intel_YTile_InitPointers_xRGB8888(rb); + intel_YTile_InitPointers_ARGB4444(rb); break; } - } - else if (rb->_ActualFormat == GL_RGBA8) { - /* 8888 RGBA */ + break; + case MESA_FORMAT_ARGB1555: switch (tiling) { case I915_TILING_NONE: default: - intelInitPointers_ARGB8888(rb); + intelInitPointers_ARGB1555(rb); break; case I915_TILING_X: - intel_XTile_InitPointers_ARGB8888(rb); + intel_XTile_InitPointers_ARGB1555(rb); break; case I915_TILING_Y: - intel_YTile_InitPointers_ARGB8888(rb); + intel_YTile_InitPointers_ARGB1555(rb); break; } - } - else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) { + break; + case MESA_FORMAT_ARGB8888: + if (rb->AlphaBits == 0) { /* XXX: Need xRGB8888 Mesa format */ + /* 8888 RGBx */ + switch (tiling) { + case I915_TILING_NONE: + default: + intelInitPointers_xRGB8888(rb); + break; + case I915_TILING_X: + intel_XTile_InitPointers_xRGB8888(rb); + break; + case I915_TILING_Y: + intel_YTile_InitPointers_xRGB8888(rb); + break; + } + } else { + /* 8888 RGBA */ + switch (tiling) { + case I915_TILING_NONE: + default: + intelInitPointers_ARGB8888(rb); + break; + case I915_TILING_X: + intel_XTile_InitPointers_ARGB8888(rb); + break; + case I915_TILING_Y: + intel_YTile_InitPointers_ARGB8888(rb); + break; + } + } + break; + case MESA_FORMAT_Z16: switch (tiling) { case I915_TILING_NONE: default: @@ -619,51 +665,57 @@ intel_set_span_functions(struct intel_context *intel, intel_YTile_InitDepthPointers_z16(rb); break; } - } - else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24) { - switch (tiling) { - case I915_TILING_NONE: - default: - intelInitDepthPointers_z24(rb); - break; - case I915_TILING_X: - intel_XTile_InitDepthPointers_z24(rb); - break; - case I915_TILING_Y: - intel_YTile_InitDepthPointers_z24(rb); - break; - } - } - else if (rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { - switch (tiling) { - case I915_TILING_NONE: - default: - intelInitDepthPointers_z24_s8(rb); - break; - case I915_TILING_X: - intel_XTile_InitDepthPointers_z24_s8(rb); - break; - case I915_TILING_Y: - intel_YTile_InitDepthPointers_z24_s8(rb); - break; - } - } - else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { - switch (tiling) { - case I915_TILING_NONE: - default: - intelInitStencilPointers_z24_s8(rb); - break; - case I915_TILING_X: - intel_XTile_InitStencilPointers_z24_s8(rb); - break; - case I915_TILING_Y: - intel_YTile_InitStencilPointers_z24_s8(rb); - break; + break; + case MESA_FORMAT_S8_Z24: + /* There are a few different ways SW asks us to access the S8Z24 data: + * Z24 depth-only depth reads + * S8Z24 depth reads + * S8Z24 stencil reads. + */ + if (rb->_ActualFormat == GL_DEPTH_COMPONENT24) { + switch (tiling) { + case I915_TILING_NONE: + default: + intelInitDepthPointers_z24(rb); + break; + case I915_TILING_X: + intel_XTile_InitDepthPointers_z24(rb); + break; + case I915_TILING_Y: + intel_YTile_InitDepthPointers_z24(rb); + break; + } + } else if (rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { + switch (tiling) { + case I915_TILING_NONE: + default: + intelInitDepthPointers_z24_s8(rb); + break; + case I915_TILING_X: + intel_XTile_InitDepthPointers_z24_s8(rb); + break; + case I915_TILING_Y: + intel_YTile_InitDepthPointers_z24_s8(rb); + break; + } + } else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { + switch (tiling) { + case I915_TILING_NONE: + default: + intelInitStencilPointers_z24_s8(rb); + break; + case I915_TILING_X: + intel_XTile_InitStencilPointers_z24_s8(rb); + break; + case I915_TILING_Y: + intel_YTile_InitStencilPointers_z24_s8(rb); + break; + } } - } - else { + break; + default: _mesa_problem(NULL, - "Unexpected _ActualFormat in intelSetSpanFunctions"); + "Unexpected MesaFormat in intelSetSpanFunctions"); + break; } } diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c index ae0994b183..df63f29a42 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.c +++ b/src/mesa/drivers/dri/intel/intel_tex.c @@ -158,81 +158,11 @@ timed_memcpy(void *dest, const void *src, size_t n) } #endif /* DO_DEBUG */ -/** - * Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap - * level). - * - * The texture object's miptree must be mapped. - * - * It would be really nice if this was just called by Mesa whenever mipmaps - * needed to be regenerated, rather than us having to remember to do so in - * each texture image modification path. - * - * This function should also include an accelerated path. - */ -void -intel_generate_mipmap(GLcontext *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_object *intelObj = intel_texture_object(texObj); - GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - int face, i; - - _mesa_generate_mipmap(ctx, target, texObj); - - /* Update the level information in our private data in the new images, since - * it didn't get set as part of a normal TexImage path. - */ - for (face = 0; face < nr_faces; face++) { - for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { - struct intel_texture_image *intelImage; - - intelImage = intel_texture_image(texObj->Image[face][i]); - if (intelImage == NULL) - break; - - intelImage->level = i; - intelImage->face = face; - /* Unreference the miptree to signal that the new Data is a bare - * pointer from mesa. - */ - intel_miptree_release(intel, &intelImage->mt); - } - } -} - -static void intelGenerateMipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_object *intelObj = intel_texture_object(texObj); - - intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel); - intel_generate_mipmap(ctx, target, texObj); - intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel); -} - void intelInitTextureFuncs(struct dd_function_table *functions) { functions->ChooseTextureFormat = intelChooseTextureFormat; - functions->TexImage1D = intelTexImage1D; - functions->TexImage2D = intelTexImage2D; - functions->TexImage3D = intelTexImage3D; - functions->TexSubImage1D = intelTexSubImage1D; - functions->TexSubImage2D = intelTexSubImage2D; - functions->TexSubImage3D = intelTexSubImage3D; - functions->CopyTexImage1D = intelCopyTexImage1D; - functions->CopyTexImage2D = intelCopyTexImage2D; - functions->CopyTexSubImage1D = intelCopyTexSubImage1D; - functions->CopyTexSubImage2D = intelCopyTexSubImage2D; - functions->GetTexImage = intelGetTexImage; - functions->GenerateMipmap = intelGenerateMipmap; - - /* compressed texture functions */ - functions->CompressedTexImage2D = intelCompressedTexImage2D; - functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D; - functions->GetCompressedTexImage = intelGetCompressedTexImage; + functions->GenerateMipmap = intel_generate_mipmap; functions->NewTextureObject = intelNewTextureObject; functions->NewTextureImage = intelNewTextureImage; diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index f5372d82fb..471aa2a240 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -35,116 +35,17 @@ void intelInitTextureFuncs(struct dd_function_table *functions); +void intelInitTextureImageFuncs(struct dd_function_table *functions); + +void intelInitTextureSubImageFuncs(struct dd_function_table *functions); + +void intelInitTextureCopyImageFuncs(struct dd_function_table *functions); + const struct gl_texture_format *intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, GLenum format, GLenum type); - -void intelTexImage3D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexSubImage3D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexImage2D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexSubImage2D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexImage1D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexSubImage1D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLint border); - -void intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border); - -void intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint x, GLint y, GLsizei width); - -void intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, GLsizei width, GLsizei height); - -void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ); - -void intelCompressedTexSubImage2D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, - GLvoid *pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); void intelSetTexBuffer(__DRIcontext *pDRICtx, diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 08437aa0e2..260235b1eb 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -118,8 +118,12 @@ do_copy_texsubimage(struct intel_context *intel, dstx += x - orig_x; dsty += y - orig_y; - /* image_offset may be non-page-aligned, but that's illegal for tiling. */ - assert(intelImage->mt->region->tiling == I915_TILING_NONE); + /* Can't blit to tiled buffers with non-tile-aligned offset. */ + if (intelImage->mt->region->tiling != I915_TILING_NONE && + (image_offset & 4095) != 0) { + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } if (ctx->ReadBuffer->Name == 0) { /* reading from a window, adjust x, y */ @@ -158,17 +162,14 @@ do_copy_texsubimage(struct intel_context *intel, /* GL_SGIS_generate_mipmap */ if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); + intel_generate_mipmap(ctx, target, texObj); } return GL_TRUE; } - - - -void +static void intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border) @@ -214,7 +215,8 @@ intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, width, border); } -void + +static void intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, @@ -231,6 +233,14 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, if (border) goto fail; + /* Setup or redefine the texture object, mipmap tree and texture + * image. Don't populate yet. + */ + ctx->Driver.TexImage2D(ctx, target, level, internalFormat, + width, height, border, + GL_RGBA, CHAN_TYPE, NULL, + &ctx->DefaultPacking, texObj, texImage); + srcx = x; srcy = y; dstx = 0; @@ -241,15 +251,6 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, &width, &height)) return; - /* Setup or redefine the texture object, mipmap tree and texture - * image. Don't populate yet. - */ - ctx->Driver.TexImage2D(ctx, target, level, internalFormat, - width, height, border, - GL_RGBA, CHAN_TYPE, NULL, - &ctx->DefaultPacking, texObj, texImage); - - if (!do_copy_texsubimage(intel_context(ctx), target, intel_texture_image(texImage), internalFormat, 0, 0, x, y, width, height)) @@ -263,7 +264,7 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, } -void +static void intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { @@ -288,8 +289,7 @@ intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, } - -void +static void intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) @@ -302,7 +302,6 @@ intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, _mesa_select_tex_image(ctx, texObj, target, level); GLenum internalFormat = texImage->InternalFormat; - /* Need to check texture is compatible with source format. */ @@ -317,3 +316,13 @@ intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, xoffset, yoffset, x, y, width, height); } } + + +void +intelInitTextureCopyImageFuncs(struct dd_function_table *functions) +{ + functions->CopyTexImage1D = intelCopyTexImage1D; + functions->CopyTexImage2D = intelCopyTexImage2D; + functions->CopyTexSubImage1D = intelCopyTexSubImage1D; + functions->CopyTexSubImage2D = intelCopyTexSubImage2D; +} diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 71561cf85c..e9a3823078 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -208,7 +208,7 @@ try_pbo_upload(struct intel_context *intel, if (!pbo || intel->ctx._ImageTransferState || unpack->SkipPixels || unpack->SkipRows) { - _mesa_printf("%s: failure 1\n", __FUNCTION__); + DBG("%s: failure 1\n", __FUNCTION__); return GL_FALSE; } @@ -248,7 +248,6 @@ try_pbo_upload(struct intel_context *intel, } - static GLboolean try_pbo_zcopy(struct intel_context *intel, struct intel_texture_image *intelImage, @@ -264,7 +263,7 @@ try_pbo_zcopy(struct intel_context *intel, if (!pbo || intel->ctx._ImageTransferState || unpack->SkipPixels || unpack->SkipRows) { - _mesa_printf("%s: failure 1\n", __FUNCTION__); + DBG("%s: failure 1\n", __FUNCTION__); return GL_FALSE; } @@ -283,7 +282,7 @@ try_pbo_zcopy(struct intel_context *intel, dst_stride = intelImage->mt->pitch; if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) { - _mesa_printf("%s: failure 2\n", __FUNCTION__); + DBG("%s: failure 2\n", __FUNCTION__); return GL_FALSE; } @@ -293,10 +292,6 @@ try_pbo_zcopy(struct intel_context *intel, } - - - - static void intelTexImage(GLcontext * ctx, GLint dims, @@ -307,7 +302,8 @@ intelTexImage(GLcontext * ctx, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, - struct gl_texture_image *texImage, GLsizei imageSize, int compressed) + struct gl_texture_image *texImage, GLsizei imageSize, + GLboolean compressed) { struct intel_context *intel = intel_context(ctx); struct intel_texture_object *intelObj = intel_texture_object(texObj); @@ -315,8 +311,7 @@ intelTexImage(GLcontext * ctx, GLint postConvWidth = width; GLint postConvHeight = height; GLint texelBytes, sizeInBytes; - GLuint dstRowStride, srcRowStride = texImage->RowStride; - + GLuint dstRowStride = 0, srcRowStride = texImage->RowStride; DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); @@ -464,8 +459,6 @@ intelTexImage(GLcontext * ctx, DBG("pbo upload failed\n"); } - - /* intelCopyTexImage calls this function with pixels == NULL, with * the expectation that the mipmap tree will be set up but nothing * more will be done. This is where those calls return: @@ -483,7 +476,7 @@ intelTexImage(GLcontext * ctx, LOCK_HARDWARE(intel); if (intelImage->mt) { - if (pixels) + if (pixels != NULL) texImage->Data = intel_miptree_image_map(intel, intelImage->mt, intelImage->face, @@ -509,8 +502,9 @@ intelTexImage(GLcontext * ctx, } DBG("Upload image %dx%dx%d row_len %d " - "pitch %d\n", - width, height, depth, width * texelBytes, dstRowStride); + "pitch %d pixels %d compressed %d\n", + width, height, depth, width * texelBytes, dstRowStride, + pixels ? 1 : 0, compressed); /* Copy data. Would like to know when it's ok for us to eg. use * the blitter to copy. Or, use the hardware to do the format @@ -523,7 +517,7 @@ intelTexImage(GLcontext * ctx, _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch, 0, 0, intelImage->mt->level[level].width, - intelImage->mt->level[level].height/4, + (intelImage->mt->level[level].height+3)/4, pixels, srcRowStride, 0, 0); @@ -539,25 +533,26 @@ intelTexImage(GLcontext * ctx, format, type, pixels, unpack)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, texObj); - } } _mesa_unmap_teximage_pbo(ctx, unpack); if (intelImage->mt) { - if (pixels) + if (pixels != NULL) intel_miptree_image_unmap(intel, intelImage->mt); texImage->Data = NULL; } UNLOCK_HARDWARE(intel); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, texObj); + } } -void + +static void intelTexImage3D(GLcontext * ctx, GLenum target, GLint level, GLint internalFormat, @@ -570,11 +565,11 @@ intelTexImage3D(GLcontext * ctx, { intelTexImage(ctx, 3, target, level, internalFormat, width, height, depth, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); + format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); } -void +static void intelTexImage2D(GLcontext * ctx, GLenum target, GLint level, GLint internalFormat, @@ -586,10 +581,11 @@ intelTexImage2D(GLcontext * ctx, { intelTexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); + format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); } -void + +static void intelTexImage1D(GLcontext * ctx, GLenum target, GLint level, GLint internalFormat, @@ -601,21 +597,24 @@ intelTexImage1D(GLcontext * ctx, { intelTexImage(ctx, 1, target, level, internalFormat, width, 1, 1, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); + format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); } -void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) + +static void +intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) { intelTexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, - 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); + 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE); } + /** * Need to map texture image into memory before copying image data, * then unmap it. @@ -624,11 +623,17 @@ static void intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels, struct gl_texture_object *texObj, - struct gl_texture_image *texImage, int compressed) + struct gl_texture_image *texImage, GLboolean compressed) { struct intel_context *intel = intel_context(ctx); struct intel_texture_image *intelImage = intel_texture_image(texImage); + /* If we're reading from a texture that has been rendered to, need to + * make sure rendering is complete. + * We could probably predicate this on texObj->_RenderToTexture + */ + intelFlush(ctx); + /* Map */ if (intelImage->mt) { /* Image is stored in hardware format in a buffer managed by the @@ -672,28 +677,29 @@ intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level, } } -void + +static void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { intel_get_tex_image(ctx, target, level, format, type, pixels, - texObj, texImage, 0); - - + texObj, texImage, GL_FALSE); } -void + +static void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, GLvoid *pixels, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { intel_get_tex_image(ctx, target, level, 0, 0, pixels, - texObj, texImage, 1); + texObj, texImage, GL_TRUE); } + void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch) @@ -802,3 +808,16 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) */ intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); } + + +void +intelInitTextureImageFuncs(struct dd_function_table *functions) +{ + functions->TexImage1D = intelTexImage1D; + functions->TexImage2D = intelTexImage2D; + functions->TexImage3D = intelTexImage3D; + functions->GetTexImage = intelGetTexImage; + + functions->CompressedTexImage2D = intelCompressedTexImage2D; + functions->GetCompressedTexImage = intelGetCompressedTexImage; +} diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index e6f9a41779..2c1b722b7f 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -52,7 +52,9 @@ GLuint intel_compressed_alignment(GLenum internalFormat) return alignment; } -void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt ) +void i945_miptree_layout_2d( struct intel_context *intel, + struct intel_mipmap_tree *mt, + uint32_t tiling ) { GLint align_h = 2, align_w = 4; GLuint level; @@ -92,7 +94,7 @@ void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tr /* Pitch must be a whole number of dwords, even though we * express it in texels. */ - mt->pitch = intel_miptree_pitch_align (intel, mt, mt->pitch); + mt->pitch = intel_miptree_pitch_align (intel, mt, tiling, mt->pitch); mt->total_height = 0; for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index dbc90e6f9b..7bc25b6bcb 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -38,5 +38,7 @@ static GLuint minify( GLuint d ) return MAX2(1, d>>1); } -extern void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt ); +extern void i945_miptree_layout_2d(struct intel_context *intel, + struct intel_mipmap_tree *mt, + uint32_t tiling); extern GLuint intel_compressed_alignment(GLenum); diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c index f86de56897..1f27131dac 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c @@ -101,11 +101,6 @@ intelTexSubimage(GLcontext * ctx, _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); if (intelImage->mt) { @@ -114,13 +109,15 @@ intelTexSubimage(GLcontext * ctx, } UNLOCK_HARDWARE(intel); -} - - + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, texObj); + } +} -void +static void intelTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, @@ -132,18 +129,15 @@ intelTexSubImage3D(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - intelTexSubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, packing, texObj, texImage); - } - -void +static void intelTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, @@ -155,17 +149,15 @@ intelTexSubImage2D(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - intelTexSubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, format, type, pixels, packing, texObj, texImage); - } -void +static void intelTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, @@ -182,10 +174,9 @@ intelTexSubImage1D(GLcontext * ctx, xoffset, 0, 0, width, 1, 1, format, type, pixels, packing, texObj, texImage); - } -void +static void intelCompressedTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, @@ -199,3 +190,14 @@ intelCompressedTexSubImage2D(GLcontext * ctx, fprintf(stderr, "stubbed CompressedTexSubImage2D: %dx%d@%dx%d\n", width, height, xoffset, yoffset); } + + + +void +intelInitTextureSubImageFuncs(struct dd_function_table *functions) +{ + functions->TexSubImage1D = intelTexSubImage1D; + functions->TexSubImage2D = intelTexSubImage2D; + functions->TexSubImage3D = intelTexSubImage3D; + functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D; +} diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index 05a375e1f3..b5cb7597d1 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -241,7 +241,7 @@ intel_tex_map_level_images(struct intel_context *intel, struct intel_texture_image *intelImage = intel_texture_image(intelObj->base.Image[face][level]); - if (intelImage->mt) { + if (intelImage && intelImage->mt) { intelImage->base.Data = intel_miptree_image_map(intel, intelImage->mt, @@ -268,7 +268,7 @@ intel_tex_unmap_level_images(struct intel_context *intel, struct intel_texture_image *intelImage = intel_texture_image(intelObj->base.Image[face][level]); - if (intelImage->mt) { + if (intelImage && intelImage->mt) { intel_miptree_image_unmap(intel, intelImage->mt); intelImage->base.Data = NULL; } |