summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel/intel_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/intel/intel_context.c')
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c226
1 files changed, 202 insertions, 24 deletions
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(&region);
+
+ 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);