#include "intel_buffers.h"
#include "intel_bufmgr.h"
#include "intel_chipset.h"
-#include "intel_extensions.h"
#include "intel_fbo.h"
#include "intel_regions.h"
#include "intel_screen.h"
-#include "intel_span.h"
#include "intel_tex.h"
#include "i915_drm.h"
intelSetTexBuffer2,
};
+static void
+intelDRI2Flush(__DRIdrawable *drawable)
+{
+ struct intel_context *intel = drawable->driContextPriv->driverPrivate;
+
+ if (intel->gen < 4)
+ INTEL_FIREVERTICES(intel);
+
+ if (intel->batch->map != intel->batch->ptr)
+ intel_batchbuffer_flush(intel->batch);
+}
+
+static void
+intelDRI2FlushInvalidate(__DRIdrawable *drawable)
+{
+ struct intel_context *intel = drawable->driContextPriv->driverPrivate;
+
+ intelDRI2Flush(drawable);
+ drawable->validBuffers = GL_FALSE;
+
+ /* We're using FlushInvalidate as an indicator that a frame is
+ * done. It's only called immediately after SwapBuffers, so it
+ * won't affect front-buffer rendering or applications explicitly
+ * managing swap regions using MESA_copy_buffer.
+ *
+ * Wait for the swapbuffers before the one we just emitted, so we don't
+ * get too many swaps outstanding for apps that are GPU-heavy but not
+ * CPU-heavy.
+ *
+ * Unfortunately, we don't have a handle to the batch containing the swap,
+ * and getting our hands on that doesn't seem worth it, so we just use the
+ * first batch we emitted after the last swap.
+ */
+ if (intel->first_post_swapbuffers_batch != NULL) {
+ drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
+ drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
+ intel->first_post_swapbuffers_batch = NULL;
+ }
+}
+
+static const struct __DRI2flushExtensionRec intelFlushExtension = {
+ { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+ intelDRI2Flush,
+ intelDRI2FlushInvalidate,
+};
+
static const __DRIextension *intelScreenExtensions[] = {
&driReadDrawableExtension,
&intelTexOffsetExtension.base,
&intelTexBufferExtension.base,
+ &intelFlushExtension.base,
NULL
};
static GLboolean
intel_init_bufmgr(intelScreenPrivate *intelScreen)
{
- int gem_kernel = 0;
- struct drm_i915_getparam gp;
__DRIscreen *spriv = intelScreen->driScrnPriv;
int num_fences = 0;
intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
- gp.param = I915_PARAM_HAS_GEM;
- gp.value = &gem_kernel;
-
- (void) drmCommandWriteRead(spriv->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
-
- /* If we've got a new enough DDX that's initializing GEM and giving us
- * object handles for the shared buffers, use that.
- */
- if (!intelScreen->driScrnPriv->dri2.enabled &&
- intelScreen->driScrnPriv->ddx_version.minor < 9) {
- fprintf(stderr, "[%s:%u] Error initializing GEM.\n",
- __func__, __LINE__);
- return GL_FALSE;
- }
-
intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
/* Otherwise, use the classic buffer manager. */
if (intelScreen->bufmgr == NULL) {
return GL_TRUE;
}
-struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
-{
- /*
- * This should probably change to have the screen allocate a dummy
- * context at screen creation. For now just use the current context.
- */
-
- GET_CURRENT_CONTEXT(ctx);
- if (ctx == NULL) {
- _mesa_problem(NULL, "No current context in intelScreenContext\n");
- return NULL;
- }
- return intel_context(ctx);
-}
-
/**
* This is the driver specific part of the createNewScreen entry point.
* Called when using DRI2.
intelScreenPrivate *intelScreen;
GLenum fb_format[3];
GLenum fb_type[3];
- /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
- * support pageflipping at all.
- */
+
static const GLenum back_buffer_modes[] = {
- GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+ GLX_NONE, GLX_SWAP_UNDEFINED_OML,
+ GLX_SWAP_EXCHANGE_OML, GLX_SWAP_COPY_OML
};
uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
int color;