/*
- Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ Copyright 2003 VMware, Inc.
Copyright (C) Intel Corp. 2006. All Rights Reserved.
- Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ Intel funded Tungsten Graphics to
develop this 3D driver.
-
+
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
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.
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:
- * Keith Whitwell <keith@tungstengraphics.com>
+ * Keith Whitwell <keithw@vmware.com>
*/
}
}
+const char *const brw_vendor_string = "Intel Open Source Technology Center";
+
+const char *
+brw_get_renderer_string(unsigned deviceID)
+{
+ const char *chipset;
+ static char buffer[128];
+
+ switch (deviceID) {
+#undef CHIPSET
+#define CHIPSET(id, symbol, str) case id: chipset = str; break;
+#include "pci_ids/i965_pci_ids.h"
+ default:
+ chipset = "Unknown Intel Chipset";
+ break;
+ }
+
+ (void) driGetRendererString(buffer, chipset, 0);
+ return buffer;
+}
+
static const GLubyte *
intelGetString(struct gl_context * ctx, GLenum name)
{
const struct brw_context *const brw = brw_context(ctx);
- const char *chipset;
- static char buffer[128];
switch (name) {
case GL_VENDOR:
- return (GLubyte *) "Intel Open Source Technology Center";
- break;
+ return (GLubyte *) brw_vendor_string;
case GL_RENDERER:
- switch (brw->intelScreen->deviceID) {
-#undef CHIPSET
-#define CHIPSET(id, family, str) case id: chipset = str; break;
-#include "pci_ids/i965_pci_ids.h"
- default:
- chipset = "Unknown Intel Chipset";
- break;
- }
-
- (void) driGetRendererString(buffer, chipset, 0);
- return (GLubyte *) buffer;
+ return
+ (GLubyte *) brw_get_renderer_string(brw->intelScreen->deviceID);
default:
return NULL;
}
static void
-intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+intel_viewport(struct gl_context *ctx)
{
struct brw_context *brw = brw_context(ctx);
__DRIcontext *driContext = brw->driContext;
- if (brw->saved_viewport)
- brw->saved_viewport(ctx, x, y, w, h);
-
if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
dri2InvalidateDrawable(driContext->driDrawablePriv);
dri2InvalidateDrawable(driContext->driReadablePriv);
brw->NewGLState |= new_state;
}
+#define flushFront(screen) ((screen)->image.loader ? (screen)->image.loader->flushFrontBuffer : (screen)->dri2.loader->flushFrontBuffer)
+
static void
intel_flush_front(struct gl_context *ctx)
{
__DRIscreen *const screen = brw->intelScreen->driScrnPriv;
if (brw->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
- if (screen->dri2.loader->flushFrontBuffer != NULL &&
- driDrawable &&
+ if (flushFront(screen) && driDrawable &&
driDrawable->loaderPrivate) {
/* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT.
intel_resolve_for_dri2_flush(brw, driDrawable);
intel_batchbuffer_flush(brw);
- screen->dri2.loader->flushFrontBuffer(driDrawable,
- driDrawable->loaderPrivate);
+ flushFront(screen)(driDrawable, driDrawable->loaderPrivate);
/* We set the dirty bit in intel_prepare_render() if we're
* front buffer rendering once we get there.
* So EGL still relies on viewport hacks to handle window resizing.
* This should go away with DRI3000.
*/
- if (!brw->driContext->driScreenPriv->dri2.useInvalidate) {
- brw->saved_viewport = functions->Viewport;
+ if (!brw->driContext->driScreenPriv->dri2.useInvalidate)
functions->Viewport = intel_viewport;
- }
functions->Flush = intel_glFlush;
functions->Finish = intelFinish;
functions->QuerySamplesForFormat = brw_query_samples_for_format;
+ functions->NewTransformFeedback = brw_new_transform_feedback;
+ functions->DeleteTransformFeedback = brw_delete_transform_feedback;
+ functions->GetTransformFeedbackVertexCount =
+ brw_get_transform_feedback_vertex_count;
if (brw->gen >= 7) {
functions->BeginTransformFeedback = gen7_begin_transform_feedback;
functions->EndTransformFeedback = gen7_end_transform_feedback;
+ functions->PauseTransformFeedback = gen7_pause_transform_feedback;
+ functions->ResumeTransformFeedback = gen7_resume_transform_feedback;
} else {
functions->BeginTransformFeedback = brw_begin_transform_feedback;
functions->EndTransformFeedback = brw_end_transform_feedback;
ctx->Const.MaxDualSourceDrawBuffers = 1;
ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS;
- ctx->Const.FragmentProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */
ctx->Const.MaxTextureUnits =
MIN2(ctx->Const.MaxTextureCoordUnits,
- ctx->Const.FragmentProgram.MaxTextureImageUnits);
- ctx->Const.VertexProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits);
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
if (brw->gen >= 7)
- ctx->Const.GeometryProgram.MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = BRW_MAX_TEX_UNIT;
else
- ctx->Const.GeometryProgram.MaxTextureImageUnits = 0;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 0;
ctx->Const.MaxCombinedTextureImageUnits =
- ctx->Const.VertexProgram.MaxTextureImageUnits +
- ctx->Const.FragmentProgram.MaxTextureImageUnits +
- ctx->Const.GeometryProgram.MaxTextureImageUnits;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits +
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits +
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits;
ctx->Const.MaxTextureLevels = 14; /* 8192 */
if (ctx->Const.MaxTextureLevels > MAX_TEXTURE_LEVELS)
ctx->Const.MaxArrayTextureLayers = 512;
ctx->Const.MaxTextureRectSize = 1 << 12;
-
+
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
ctx->Const.MaxRenderbufferSize = 8192;
ctx->Const.MaxTransformFeedbackSeparateComponents =
BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS;
- if (brw->gen == 6) {
- ctx->Const.MaxSamples = 4;
- ctx->Const.MaxColorTextureSamples = 4;
- ctx->Const.MaxDepthTextureSamples = 4;
- ctx->Const.MaxIntegerSamples = 4;
- } else if (brw->gen >= 7) {
- ctx->Const.MaxSamples = 8;
- ctx->Const.MaxColorTextureSamples = 8;
- ctx->Const.MaxDepthTextureSamples = 8;
- ctx->Const.MaxIntegerSamples = 8;
- ctx->Const.MaxProgramTextureGatherComponents = 4;
+ ctx->Const.AlwaysUseGetTransformFeedbackVertexCount = true;
+
+ int max_samples;
+ const int *msaa_modes = intel_supported_msaa_modes(brw->intelScreen);
+ const int clamp_max_samples =
+ driQueryOptioni(&brw->optionCache, "clamp_max_samples");
+
+ if (clamp_max_samples < 0) {
+ max_samples = msaa_modes[0];
+ } else {
+ /* Select the largest supported MSAA mode that does not exceed
+ * clamp_max_samples.
+ */
+ max_samples = 0;
+ for (int i = 0; msaa_modes[i] != 0; ++i) {
+ if (msaa_modes[i] <= clamp_max_samples) {
+ max_samples = msaa_modes[i];
+ break;
+ }
+ }
}
+ ctx->Const.MaxSamples = max_samples;
+ ctx->Const.MaxColorTextureSamples = max_samples;
+ ctx->Const.MaxDepthTextureSamples = max_samples;
+ ctx->Const.MaxIntegerSamples = max_samples;
+
+ if (brw->gen >= 7)
+ ctx->Const.MaxProgramTextureGatherComponents = 4;
+
ctx->Const.MinLineWidth = 1.0;
ctx->Const.MinLineWidthAA = 1.0;
ctx->Const.MaxLineWidth = 5.0;
if (brw->gen >= 5 || brw->is_g4x)
ctx->Const.MaxClipPlanes = 8;
- ctx->Const.VertexProgram.MaxNativeInstructions = 16 * 1024;
- ctx->Const.VertexProgram.MaxAluInstructions = 0;
- ctx->Const.VertexProgram.MaxTexInstructions = 0;
- ctx->Const.VertexProgram.MaxTexIndirections = 0;
- ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
- ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
- ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
- ctx->Const.VertexProgram.MaxNativeAttribs = 16;
- ctx->Const.VertexProgram.MaxNativeTemps = 256;
- ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
- ctx->Const.VertexProgram.MaxNativeParameters = 1024;
- ctx->Const.VertexProgram.MaxEnvParams =
- MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
- ctx->Const.VertexProgram.MaxEnvParams);
-
- ctx->Const.FragmentProgram.MaxNativeInstructions = 1024;
- ctx->Const.FragmentProgram.MaxNativeAluInstructions = 1024;
- ctx->Const.FragmentProgram.MaxNativeTexInstructions = 1024;
- ctx->Const.FragmentProgram.MaxNativeTexIndirections = 1024;
- ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
- ctx->Const.FragmentProgram.MaxNativeTemps = 256;
- ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
- ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
- ctx->Const.FragmentProgram.MaxEnvParams =
- MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
- ctx->Const.FragmentProgram.MaxEnvParams);
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeInstructions = 16 * 1024;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxAluInstructions = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexInstructions = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTexIndirections = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAluInstructions = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTexInstructions = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTexIndirections = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAttribs = 16;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeTemps = 256;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeAddressRegs = 1;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters = 1024;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams =
+ MIN2(ctx->Const.Program[MESA_SHADER_VERTEX].MaxNativeParameters,
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxEnvParams);
+
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeInstructions = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAluInstructions = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTexInstructions = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTexIndirections = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAttribs = 12;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeTemps = 256;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeAddressRegs = 0;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeParameters = 1024;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams =
+ MIN2(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxNativeParameters,
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxEnvParams);
/* Fragment shaders use real, 32-bit twos-complement integers for all
* integer types.
*/
- ctx->Const.FragmentProgram.LowInt.RangeMin = 31;
- ctx->Const.FragmentProgram.LowInt.RangeMax = 30;
- ctx->Const.FragmentProgram.LowInt.Precision = 0;
- ctx->Const.FragmentProgram.HighInt = ctx->Const.FragmentProgram.LowInt;
- ctx->Const.FragmentProgram.MediumInt = ctx->Const.FragmentProgram.LowInt;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.RangeMin = 31;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.RangeMax = 30;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt.Precision = 0;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].HighInt = ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MediumInt = ctx->Const.Program[MESA_SHADER_FRAGMENT].LowInt;
+
+ if (brw->gen >= 7) {
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters = MAX_ATOMIC_COUNTERS;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers = BRW_MAX_ABO;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicBuffers = BRW_MAX_ABO;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers = BRW_MAX_ABO;
+ ctx->Const.MaxCombinedAtomicBuffers = 3 * BRW_MAX_ABO;
+ }
/* Gen6 converts quads to polygon in beginning of 3D pipeline,
* but we're not sure how it's actually done for vertex order,
if (brw->gen >= 6) {
ctx->Const.MaxVarying = 32;
- ctx->Const.VertexProgram.MaxOutputComponents = 128;
- ctx->Const.GeometryProgram.MaxInputComponents = 128;
- ctx->Const.GeometryProgram.MaxOutputComponents = 128;
- ctx->Const.FragmentProgram.MaxInputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents = 64;
+ ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 128;
}
/* We want the GLSL compiler to emit code that uses condition codes */
- for (int i = 0; i < MESA_SHADER_TYPES; i++) {
+ for (int i = 0; i < MESA_SHADER_STAGES; i++) {
ctx->ShaderCompilerOptions[i].MaxIfDepth = brw->gen < 6 ? 16 : UINT_MAX;
ctx->ShaderCompilerOptions[i].EmitCondCodes = true;
ctx->ShaderCompilerOptions[i].EmitNoNoise = true;
ctx->ShaderCompilerOptions[i].LowerClipDistance = true;
}
- ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].PreferDP4 = true;
+ ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = true;
+ ctx->ShaderCompilerOptions[MESA_SHADER_GEOMETRY].OptimizeForAOS = true;
+
+ /* ARB_viewport_array */
+ if (brw->gen >= 7 && ctx->API == API_OPENGL_CORE) {
+ ctx->Const.MaxViewports = GEN7_NUM_VIEWPORTS;
+ ctx->Const.ViewportSubpixelBits = 0;
+
+ /* Cast to float before negating becuase MaxViewportWidth is unsigned.
+ */
+ ctx->Const.ViewportBounds.Min = -(float)ctx->Const.MaxViewportWidth;
+ ctx->Const.ViewportBounds.Max = ctx->Const.MaxViewportWidth;
+ }
}
/**
driQueryOptionb(options, "disable_glsl_line_continuations");
}
-bool
+GLboolean
brwCreateContext(gl_api api,
const struct gl_config *mesaVis,
__DRIcontext *driContextPriv,
unsigned major_version,
unsigned minor_version,
uint32_t flags,
+ bool notify_reset,
unsigned *dri_ctx_error,
void *sharedContextPrivate)
{
struct dd_function_table functions;
struct gl_config visual;
+ /* Only allow the __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS flag if the kernel
+ * provides us with context reset notifications.
+ */
+ uint32_t allowed_flags = __DRI_CTX_FLAG_DEBUG
+ | __DRI_CTX_FLAG_FORWARD_COMPATIBLE;
+
+ if (screen->has_context_reset_notification)
+ allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS;
+
+ if (flags & ~allowed_flags) {
+ *dri_ctx_error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
+ return false;
+ }
+
struct brw_context *brw = rzalloc(NULL, struct brw_context);
if (!brw) {
printf("%s: failed to alloc context\n", __FUNCTION__);
brw->is_baytrail = devinfo->is_baytrail;
brw->is_haswell = devinfo->is_haswell;
brw->has_llc = devinfo->has_llc;
- brw->has_hiz = devinfo->has_hiz_and_separate_stencil;
+ brw->has_hiz = devinfo->has_hiz_and_separate_stencil && brw->gen < 8;
brw->has_separate_stencil = devinfo->has_hiz_and_separate_stencil;
brw->has_pln = devinfo->has_pln;
brw->has_compr4 = devinfo->has_compr4;
brw_init_driver_functions(brw, &functions);
+ if (notify_reset)
+ functions.GetGraphicsResetStatus = brw_get_graphics_reset_status;
+
struct gl_context *ctx = &brw->ctx;
if (mesaVis == NULL) {
return false;
}
+ driContextSetFlags(ctx, flags);
+
/* Initialize the software rasterizer and helper modules.
*
* As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for
brw_process_intel_debug_variable(brw);
brw_initialize_context_constants(brw);
+ ctx->Const.ResetStrategy = notify_reset
+ ? GL_LOSE_CONTEXT_ON_RESET_ARB : GL_NO_RESET_NOTIFICATION_ARB;
+
/* Reinitialize the context point state. It depends on ctx->Const values. */
_mesa_init_point(ctx);
- intelInitExtensions(ctx);
-
intel_batchbuffer_init(brw);
+ brw_init_state(brw);
+
+ intelInitExtensions(ctx);
+
intel_fbo_init(brw);
if (brw->gen >= 6) {
brw->prim_restart.in_progress = false;
brw->prim_restart.enable_cut_index = false;
-
- brw_init_state( brw );
+ brw->gs.enabled = false;
if (brw->gen < 6) {
brw->curbe.last_buf = calloc(1, 4096);
brw->perf_debug = true;
}
+ if ((flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) != 0)
+ ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
+
brw_fs_alloc_reg_sets(brw);
brw_vec4_alloc_reg_set(brw);
if (driContextPriv) {
struct gl_context *ctx = &brw->ctx;
struct gl_framebuffer *fb, *readFb;
+ struct intel_renderbuffer *rb = NULL;
if (driDrawPriv == NULL && driReadPriv == NULL) {
fb = _mesa_get_incomplete_framebuffer();
} else {
fb = driDrawPriv->driverPrivate;
readFb = driReadPriv->driverPrivate;
+ rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
}
intel_gles3_srgb_workaround(brw, fb);
intel_gles3_srgb_workaround(brw, readFb);
- intel_prepare_render(brw);
+ if (rb && !rb->mt) {
+ /* If we don't have buffers for the drawable yet, force a call to
+ * getbuffers here so we can have a default drawable size. */
+ intel_prepare_render(brw);
+ }
+
_mesa_make_current(ctx, fb, readFb);
} else {
_mesa_make_current(NULL, NULL, NULL);
struct intel_renderbuffer *rb,
const char *buffer_name);
-void
-intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+static void
+intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable);
+
+static void
+intel_update_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable)
{
struct gl_framebuffer *fb = drawable->driverPrivate;
struct intel_renderbuffer *rb;
- struct brw_context *brw = context->driverPrivate;
__DRIbuffer *buffers = NULL;
int i, count;
const char *region_name;
intel_process_dri2_buffer(brw, drawable, &buffers[i], rb, region_name);
}
+}
+
+void
+intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+{
+ struct brw_context *brw = context->driverPrivate;
+ __DRIscreen *screen = brw->intelScreen->driScrnPriv;
+
+ /* Set this up front, so that in case our buffers get invalidated
+ * while we're getting new buffers, we don't clobber the stamp and
+ * thus ignore the invalidate. */
+ drawable->lastStamp = drawable->dri2.stamp;
+
+ if (unlikely(INTEL_DEBUG & DEBUG_DRI))
+ fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
+
+ if (screen->image.loader)
+ intel_update_image_buffers(brw, drawable);
+ else
+ intel_update_dri2_buffers(brw, drawable);
+
driUpdateFramebufferSize(&brw->ctx, drawable);
}
region);
intel_region_release(®ion);
}
+
+/**
+ * \brief Query DRI image loader to obtain a DRIdrawable's buffers.
+ *
+ * To determine which DRI buffers to request, examine the renderbuffers
+ * attached to the drawable's framebuffer. Then request the buffers from
+ * the image loader
+ *
+ * This is called from intel_update_renderbuffers().
+ *
+ * \param drawable Drawable whose buffers are queried.
+ * \param buffers [out] List of buffers returned by DRI2 query.
+ * \param buffer_count [out] Number of buffers returned.
+ *
+ * \see intel_update_renderbuffers()
+ */
+
+static void
+intel_update_image_buffer(struct brw_context *intel,
+ __DRIdrawable *drawable,
+ struct intel_renderbuffer *rb,
+ __DRIimage *buffer,
+ enum __DRIimageBufferMask buffer_type)
+{
+ struct intel_region *region = buffer->region;
+
+ if (!rb || !region)
+ return;
+
+ unsigned num_samples = rb->Base.Base.NumSamples;
+
+ /* Check and see if we're already bound to the right
+ * buffer object
+ */
+ if (num_samples == 0) {
+ if (rb->mt &&
+ rb->mt->region &&
+ rb->mt->region->bo == region->bo)
+ return;
+ } else {
+ if (rb->mt &&
+ rb->mt->singlesample_mt &&
+ rb->mt->singlesample_mt->region &&
+ rb->mt->singlesample_mt->region->bo == region->bo)
+ return;
+ }
+
+ intel_miptree_release(&rb->mt);
+ rb->mt = intel_miptree_create_for_image_buffer(intel,
+ buffer_type,
+ intel_rb_format(rb),
+ num_samples,
+ region);
+}
+
+static void
+intel_update_image_buffers(struct brw_context *brw, __DRIdrawable *drawable)
+{
+ struct gl_framebuffer *fb = drawable->driverPrivate;
+ __DRIscreen *screen = brw->intelScreen->driScrnPriv;
+ struct intel_renderbuffer *front_rb;
+ struct intel_renderbuffer *back_rb;
+ struct __DRIimageList images;
+ unsigned int format;
+ uint32_t buffer_mask = 0;
+
+ front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+ back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+
+ if (back_rb)
+ format = intel_rb_format(back_rb);
+ else if (front_rb)
+ format = intel_rb_format(front_rb);
+ else
+ return;
+
+ if ((brw->is_front_buffer_rendering || brw->is_front_buffer_reading || !back_rb) && front_rb)
+ buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
+
+ if (back_rb)
+ buffer_mask |= __DRI_IMAGE_BUFFER_BACK;
+
+ (*screen->image.loader->getBuffers) (drawable,
+ driGLFormatToImageFormat(format),
+ &drawable->dri2.stamp,
+ drawable->loaderPrivate,
+ buffer_mask,
+ &images);
+
+ if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
+ drawable->w = images.front->width;
+ drawable->h = images.front->height;
+ intel_update_image_buffer(brw,
+ drawable,
+ front_rb,
+ images.front,
+ __DRI_IMAGE_BUFFER_FRONT);
+ }
+ if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
+ drawable->w = images.back->width;
+ drawable->h = images.back->height;
+ intel_update_image_buffer(brw,
+ drawable,
+ back_rb,
+ images.back,
+ __DRI_IMAGE_BUFFER_BACK);
+ }
+}