st/dri: minor formatting clean-ups in dri_context.c
[mesa.git] / src / gallium / state_trackers / dri / common / dri_context.c
index f14f4130bf4b2158a73f5e9f834c41724ed0a846..ee3c8be860b020ce7830cea7be495f5275d7c648 100644 (file)
 #include "dri_screen.h"
 #include "dri_drawable.h"
 #include "dri_context.h"
-#include "dri_st_api.h"
+#include "state_tracker/drm_driver.h"
 
 #include "pipe/p_context.h"
 #include "state_tracker/st_context.h"
 
 static void
-dri_init_extensions(struct dri_context *ctx)
+dri_fill_st_options(struct st_config_options *options,
+                    const struct driOptionCache * optionCache)
 {
-   struct st_context *st = (struct st_context *) ctx->st;
-
-   /* New extensions should be added in mesa/state_tracker/st_extensions.c
-    * and not in this file. */
-   driInitExtensions(st->ctx, NULL, GL_FALSE);
+   options->disable_blend_func_extended =
+      driQueryOptionb(optionCache, "disable_blend_func_extended");
+   options->disable_glsl_line_continuations =
+      driQueryOptionb(optionCache, "disable_glsl_line_continuations");
+   options->disable_shader_bit_encoding =
+      driQueryOptionb(optionCache, "disable_shader_bit_encoding");
+   options->force_glsl_extensions_warn =
+      driQueryOptionb(optionCache, "force_glsl_extensions_warn");
+   options->force_glsl_version =
+      driQueryOptioni(optionCache, "force_glsl_version");
+   options->force_s3tc_enable =
+      driQueryOptionb(optionCache, "force_s3tc_enable");
 }
 
 GLboolean
-dri_create_context(const __GLcontextModes * visual,
-                  __DRIcontext * cPriv, void *sharedContextPrivate)
+dri_create_context(gl_api api, const struct gl_config * visual,
+                  __DRIcontext * cPriv,
+                  unsigned major_version,
+                  unsigned minor_version,
+                  uint32_t flags,
+                  unsigned *error,
+                  void *sharedContextPrivate)
 {
-   struct st_api *stapi = dri_get_st_api();
    __DRIscreen *sPriv = cPriv->driScreenPriv;
    struct dri_screen *screen = dri_screen(sPriv);
+   struct st_api *stapi = screen->st_api;
    struct dri_context *ctx = NULL;
    struct st_context_iface *st_share = NULL;
-   struct st_visual stvis;
+   struct st_context_attribs attribs;
+   enum st_context_error ctx_err = 0;
+
+   memset(&attribs, 0, sizeof(attribs));
+   switch (api) {
+   case API_OPENGLES:
+      attribs.profile = ST_PROFILE_OPENGL_ES1;
+      break;
+   case API_OPENGLES2:
+      attribs.profile = ST_PROFILE_OPENGL_ES2;
+      break;
+   case API_OPENGL_COMPAT:
+   case API_OPENGL_CORE:
+      attribs.profile = api == API_OPENGL_COMPAT ? ST_PROFILE_DEFAULT
+                                                 : ST_PROFILE_OPENGL_CORE;
+      attribs.major = major_version;
+      attribs.minor = minor_version;
+
+      if ((flags & __DRI_CTX_FLAG_DEBUG) != 0)
+        attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
+
+      if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
+        attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
+      break;
+   default:
+      *error = __DRI_CTX_ERROR_BAD_API;
+      goto fail;
+   }
 
    if (sharedContextPrivate) {
       st_share = ((struct dri_context *)sharedContextPrivate)->st;
    }
 
    ctx = CALLOC_STRUCT(dri_context);
-   if (ctx == NULL)
+   if (ctx == NULL) {
+      *error = __DRI_CTX_ERROR_NO_MEMORY;
       goto fail;
+   }
 
    cPriv->driverPrivate = ctx;
    ctx->cPriv = cPriv;
    ctx->sPriv = sPriv;
-   ctx->lock = screen->drmLock;
-
-   driParseConfigFiles(&ctx->optionCache,
-                      &screen->optionCache, sPriv->myNum, "dri");
 
-   dri_fill_st_visual(&stvis, screen, visual);
-   ctx->st = stapi->create_context(stapi, screen->smapi, &stvis, st_share);
-   if (ctx->st == NULL)
+   dri_fill_st_options(&attribs.options, &screen->optionCache);
+   dri_fill_st_visual(&attribs.visual, screen, visual);
+   ctx->st = stapi->create_context(stapi, &screen->base, &attribs, &ctx_err,
+                                  st_share);
+   if (ctx->st == NULL) {
+      switch (ctx_err) {
+      case ST_CONTEXT_SUCCESS:
+        *error = __DRI_CTX_ERROR_SUCCESS;
+        break;
+      case ST_CONTEXT_ERROR_NO_MEMORY:
+        *error = __DRI_CTX_ERROR_NO_MEMORY;
+        break;
+      case ST_CONTEXT_ERROR_BAD_API:
+        *error = __DRI_CTX_ERROR_BAD_API;
+        break;
+      case ST_CONTEXT_ERROR_BAD_VERSION:
+        *error = __DRI_CTX_ERROR_BAD_VERSION;
+        break;
+      case ST_CONTEXT_ERROR_BAD_FLAG:
+        *error = __DRI_CTX_ERROR_BAD_FLAG;
+        break;
+      case ST_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE:
+        *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
+        break;
+      case ST_CONTEXT_ERROR_UNKNOWN_FLAG:
+        *error = __DRI_CTX_ERROR_UNKNOWN_FLAG;
+        break;
+      }
       goto fail;
+   }
    ctx->st->st_manager_private = (void *) ctx;
+   ctx->stapi = stapi;
 
-   dri_init_extensions(ctx);
+   if (ctx->st->cso_context) {
+      ctx->pp = pp_init(ctx->st->pipe, screen->pp_enabled, ctx->st->cso_context);
+      ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context);
+   }
 
+   *error = __DRI_CTX_ERROR_SUCCESS;
    return GL_TRUE;
 
  fail:
    if (ctx && ctx->st)
       ctx->st->destroy(ctx->st);
 
-   FREE(ctx);
-   return FALSE;
+   free(ctx);
+   return GL_FALSE;
 }
 
 void
@@ -99,36 +168,40 @@ dri_destroy_context(__DRIcontext * cPriv)
 {
    struct dri_context *ctx = dri_context(cPriv);
 
-   /* note: we are freeing values and nothing more because
-    * driParseConfigFiles allocated values only - the rest
-    * is owned by screen optionCache.
-    */
-   FREE(ctx->optionCache.values);
+   if (ctx->hud) {
+      hud_destroy(ctx->hud);
+   }
 
    /* No particular reason to wait for command completion before
-    * destroying a context, but it is probably worthwhile flushing it
+    * destroying a context, but we flush the context here
     * to avoid having to add code elsewhere to cope with flushing a
     * partially destroyed context.
     */
    ctx->st->flush(ctx->st, 0, NULL);
    ctx->st->destroy(ctx->st);
 
-   FREE(ctx);
+   if (ctx->pp)
+      pp_free(ctx->pp);
+
+   free(ctx);
 }
 
 GLboolean
 dri_unbind_context(__DRIcontext * cPriv)
 {
-   struct st_api *stapi = dri_get_st_api();
-
-   if (cPriv) {
-      struct dri_context *ctx = dri_context(cPriv);
-
-      if (--ctx->bind_count == 0) {
-         if (ctx->st == stapi->get_current(stapi)) {
-            ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
-            stapi->make_current(stapi, NULL, NULL, NULL);
-         }
+   /* dri_util.c ensures cPriv is not null */
+   struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
+   struct dri_context *ctx = dri_context(cPriv);
+   struct st_api *stapi = screen->st_api;
+
+   if (--ctx->bind_count == 0) {
+      if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
+         /* For conformance, unbind is supposed to flush the context.
+          * However, if we do it here we might end up flushing a partially
+          * destroyed context. Instead, we flush in dri_make_current and
+          * in dri_destroy_context which should cover all the cases.
+          */
+         stapi->make_current(stapi, NULL, NULL, NULL);
       }
    }
 
@@ -140,47 +213,53 @@ dri_make_current(__DRIcontext * cPriv,
                 __DRIdrawable * driDrawPriv,
                 __DRIdrawable * driReadPriv)
 {
-   struct st_api *stapi = dri_get_st_api();
-
-   if (cPriv) {
-      struct dri_context *ctx = dri_context(cPriv);
-      struct dri_drawable *draw = dri_drawable(driDrawPriv);
-      struct dri_drawable *read = dri_drawable(driReadPriv);
-      struct st_context_iface *old_st;
+   /* dri_util.c ensures cPriv is not null */
+   struct dri_context *ctx = dri_context(cPriv);
+   struct dri_drawable *draw = dri_drawable(driDrawPriv);
+   struct dri_drawable *read = dri_drawable(driReadPriv);
+   struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);
 
-      old_st = stapi->get_current(stapi);
-      if (old_st && old_st != ctx->st)
-        ctx->st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
+   /* Flush the old context here so we don't have to flush on unbind() */
+   if (old_st && old_st != ctx->st)
+      old_st->flush(old_st, ST_FLUSH_FRONT, NULL);
 
-      ++ctx->bind_count;
+   ++ctx->bind_count;
 
-      if (ctx->dPriv != driDrawPriv) {
-        ctx->dPriv = driDrawPriv;
-         draw->texture_stamp = driDrawPriv->lastStamp - 1;
-      }
-      if (ctx->rPriv != driReadPriv) {
-        ctx->rPriv = driReadPriv;
-         read->texture_stamp = driReadPriv->lastStamp - 1;
-      }
+   if (!driDrawPriv && !driReadPriv)
+      return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL);
+   else if (!driDrawPriv || !driReadPriv)
+      return GL_FALSE;
 
-      stapi->make_current(stapi, ctx->st, draw->stfb, read->stfb);
+   if (ctx->dPriv != driDrawPriv) {
+      ctx->dPriv = driDrawPriv;
+      draw->texture_stamp = driDrawPriv->lastStamp - 1;
    }
-   else {
-      stapi->make_current(stapi, NULL, NULL, NULL);
+   if (ctx->rPriv != driReadPriv) {
+      ctx->rPriv = driReadPriv;
+      read->texture_stamp = driReadPriv->lastStamp - 1;
    }
 
+   ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base);
+
+   // This is ok to call here. If they are already init, it's a no-op.
+   if (draw->textures[ST_ATTACHMENT_BACK_LEFT] && draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]
+      && ctx->pp)
+         pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
+            draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
+
    return GL_TRUE;
 }
 
 struct dri_context *
-dri_get_current(void)
+dri_get_current(__DRIscreen *sPriv)
 {
-   struct st_api *stapi = dri_get_st_api();
+   struct dri_screen *screen = dri_screen(sPriv);
+   struct st_api *stapi = screen->st_api;
    struct st_context_iface *st;
 
    st = stapi->get_current(stapi);
 
-   return (struct dri_context *) (st) ? st->st_manager_private : NULL;
+   return (struct dri_context *) st ? st->st_manager_private : NULL;
 }
 
 /* vim: set sw=3 ts=8 sts=3 expandtab: */