radeon/winsys: keep screen pointer in winsys v2
authorChristian König <christian.koenig@amd.com>
Wed, 25 Sep 2013 11:59:56 +0000 (13:59 +0200)
committerChristian König <christian.koenig@amd.com>
Wed, 25 Sep 2013 17:41:31 +0000 (19:41 +0200)
Only create one screen for each winsys instance.
This helps with buffer sharing and interop handling.

v2: rebased and some minor cleanup

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/radeonsi/radeonsi_pipe.c
src/gallium/targets/r300/drm_target.c
src/gallium/targets/r600/drm_target.c
src/gallium/targets/radeonsi/drm_target.c
src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
src/gallium/winsys/radeon/drm/radeon_winsys.h

index 063bc0922a13a887cbb7c8c0e3ad912e51069fbd..125a1b595208da299b5378e3a5c11b88dc6cef57 100644 (file)
@@ -540,6 +540,9 @@ static void r300_destroy_screen(struct pipe_screen* pscreen)
     struct r300_screen* r300screen = r300_screen(pscreen);
     struct radeon_winsys *rws = radeon_winsys(pscreen);
 
+    if (rws && !radeon_winsys_unref(rws))
+      return;
+
     pipe_mutex_destroy(r300screen->cmask_mutex);
 
     if (rws)
index 50ff06c9f0da734086ec674e3c6be31ba6f4ac5a..d86bb18034a6eb4bba940bc3edd2866de656db14 100644 (file)
@@ -958,6 +958,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)
        if (rscreen == NULL)
                return;
 
+       if (!radeon_winsys_unref(rscreen->b.ws))
+               return;
+
        pipe_mutex_destroy(rscreen->aux_context_lock);
        rscreen->aux_context->destroy(rscreen->aux_context);
 
index 138268ca418ae2f6debbffa7c6a573b2bfdee908..16ec51fa63b9d1ab2f201f2c1a18d7aa5e83bf25 100644 (file)
@@ -648,6 +648,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)
        if (rscreen == NULL)
                return;
 
+       if (!radeon_winsys_unref(rscreen->b.ws))
+               return;
+
        if (rscreen->fences.bo) {
                struct r600_fence_block *entry, *tmp;
 
index 111abd41856dee132966a0111d9d1cc1698332c5..2c10bbd7bb1b55cd9f8cc15a4530e7f7bc19c1e8 100644 (file)
 #include "target-helpers/inline_debug_helper.h"
 #include "state_tracker/drm_driver.h"
 #include "radeon/drm/radeon_drm_public.h"
+#include "radeon/drm/radeon_winsys.h"
 #include "r300/r300_public.h"
 
 static struct pipe_screen *
 create_screen(int fd)
 {
    struct radeon_winsys *sws;
-   struct pipe_screen *screen;
 
    sws = radeon_drm_winsys_create(fd);
    if (!sws)
       return NULL;
 
-   screen = r300_screen_create(sws);
-   if (!screen)
-      return NULL;
+   if (!sws->screen) {
+      sws->screen = r300_screen_create(sws);
+      if (!sws->screen)
+         return NULL;
 
-   screen = debug_screen_wrap(screen);
+      sws->screen = debug_screen_wrap(sws->screen);
+   }
 
-   return screen;
+   return sws->screen;
 }
 
 DRM_DRIVER_DESCRIPTOR("r300", "radeon", create_screen, NULL)
index c93c4dbe5294b61fc1093a4a3eb737a9f9317777..28004ac58e23b213398640bf6499c2b23b27a60e 100644 (file)
 #include "state_tracker/drm_driver.h"
 #include "target-helpers/inline_debug_helper.h"
 #include "radeon/drm/radeon_drm_public.h"
+#include "radeon/drm/radeon_winsys.h"
 #include "r600/r600_public.h"
 
 static struct pipe_screen *create_screen(int fd)
 {
    struct radeon_winsys *radeon;
-   struct pipe_screen *screen;
 
    radeon = radeon_drm_winsys_create(fd);
    if (!radeon)
       return NULL;
 
-   screen = r600_screen_create(radeon);
-   if (!screen)
-      return NULL;
+   if (!radeon->screen) {
+      radeon->screen = r600_screen_create(radeon);
+      if (!radeon->screen)
+         return NULL;
 
-   screen = debug_screen_wrap(screen);
+      radeon->screen = debug_screen_wrap(radeon->screen);
+   }
 
-   return screen;
+   return radeon->screen;
 }
 
 static const struct drm_conf_ret throttle_ret = {
index 7e124cae129067553d779b3ad18f7b7351b2fe87..9eef368529f6d3119d52d5f03943fafd7fa9b1fc 100644 (file)
 #include "state_tracker/drm_driver.h"
 #include "target-helpers/inline_debug_helper.h"
 #include "radeon/drm/radeon_drm_public.h"
+#include "radeon/drm/radeon_winsys.h"
 #include "radeonsi/radeonsi_public.h"
 
 static struct pipe_screen *create_screen(int fd)
 {
    struct radeon_winsys *radeon;
-   struct pipe_screen *screen;
 
    radeon = radeon_drm_winsys_create(fd);
    if (!radeon)
       return NULL;
 
-   screen = radeonsi_screen_create(radeon);
-   if (!screen)
-      return NULL;
+   if (!radeon->screen) {
+      radeon->screen = radeonsi_screen_create(radeon);
+      if (!radeon->screen)
+         return NULL;
 
-   screen = debug_screen_wrap(screen);
+      radeon->screen = debug_screen_wrap(radeon->screen);
+   }
 
-   return screen;
+   return radeon->screen;
 }
 
 static const struct drm_conf_ret throttle_ret = {
index 61f091323f4d334e3ff3e12ac3f486585cacbf27..4f43093d71dec829e071417136be38a0d7f88b50 100644 (file)
@@ -424,10 +424,6 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
 {
     struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
 
-    if (!pipe_reference(&ws->base.reference, NULL)) {
-        return;
-    }
-
     if (ws->thread) {
         ws->kill_thread = 1;
         pipe_semaphore_signal(&ws->cs_queued);
index 1367982850cb9ba22cc1a2716d1a4cb29a2fd10a..581cd841cd8626fe66ba1e2995dc142d83d1ef7d 100644 (file)
@@ -207,6 +207,11 @@ struct radeon_winsys {
      */
     struct pipe_reference reference;
 
+    /**
+     * The screen object this winsys was created for
+     */
+    struct pipe_screen *screen;
+
     /**
      * Destroy this winsys.
      *
@@ -501,6 +506,16 @@ struct radeon_winsys {
                             enum radeon_value_id value);
 };
 
+/**
+ * Decrement the winsys reference count.
+ *
+ * \param ws The winsys this function is called for.
+ */
+static INLINE boolean radeon_winsys_unref(struct radeon_winsys *ws)
+{
+   return pipe_reference(&ws->reference, NULL);
+}
+
 static INLINE void radeon_emit(struct radeon_winsys_cs *cs, uint32_t value)
 {
     cs->buf[cs->cdw++] = value;