Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / gallium / state_trackers / dri / common / dri_screen.c
index 53053a74c4c7b615f8cfc9127c6085a8cf5b8c90..252ad1768d80d89fc0b5140758711794764611fd 100644 (file)
  */
 
 #include "utils.h"
-#ifndef __NOT_HAVE_DRM_H
-#include "vblank.h"
-#endif
 #include "xmlpool.h"
 
 #include "dri_screen.h"
-#include "dri_context.h"
-#include "dri_drawable.h"
-#include "dri_st_api.h"
-#include "dri1_helper.h"
-#ifndef __NOT_HAVE_DRM_H
-#include "dri1.h"
-#include "dri2.h"
-#else
-#include "drisw.h"
-#endif
 
 #include "util/u_inlines.h"
 #include "pipe/p_screen.h"
 #include "pipe/p_format.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
 
 #include "util/u_debug.h"
 
@@ -63,9 +50,9 @@ PUBLIC const char __driConfigOptions[] =
    DRI_CONF_ALLOW_LARGE_TEXTURES(1)
    DRI_CONF_SECTION_END DRI_CONF_END;
 
-const uint __driNConfigOptions = 3;
+static const uint __driNConfigOptions = 3;
 
-const __DRIconfig **
+static const __DRIconfig **
 dri_fill_in_modes(struct dri_screen *screen,
                  unsigned pixel_bits)
 {
@@ -73,14 +60,14 @@ dri_fill_in_modes(struct dri_screen *screen,
    __DRIconfig **configs_r5g6b5 = NULL;
    __DRIconfig **configs_a8r8g8b8 = NULL;
    __DRIconfig **configs_x8r8g8b8 = NULL;
-   unsigned num_modes;
    uint8_t depth_bits_array[5];
    uint8_t stencil_bits_array[5];
-   uint8_t msaa_samples_array[2];
+   uint8_t msaa_samples_array[5];
    unsigned depth_buffer_factor;
    unsigned back_buffer_factor;
    unsigned msaa_samples_factor;
-   struct pipe_screen *p_screen = screen->pipe_screen;
+   unsigned i;
+   struct pipe_screen *p_screen = screen->base.screen;
    boolean pf_r5g6b5, pf_a8r8g8b8, pf_x8r8g8b8;
    boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32;
 
@@ -93,35 +80,35 @@ dri_fill_in_modes(struct dri_screen *screen,
    depth_buffer_factor = 1;
 
    pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
-                                           PIPE_TEXTURE_2D,
-                                           PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+                                           PIPE_TEXTURE_2D, 0,
+                                           PIPE_BIND_DEPTH_STENCIL, 0);
    pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
-                                           PIPE_TEXTURE_2D,
-                                           PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
-   pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
-                                           PIPE_TEXTURE_2D,
-                                           PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
-   pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM,
-                                           PIPE_TEXTURE_2D,
-                                           PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+                                           PIPE_TEXTURE_2D, 0,
+                                           PIPE_BIND_DEPTH_STENCIL, 0);
+   pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+                                           PIPE_TEXTURE_2D, 0,
+                                           PIPE_BIND_DEPTH_STENCIL, 0);
+   pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+                                           PIPE_TEXTURE_2D, 0,
+                                           PIPE_BIND_DEPTH_STENCIL, 0);
    pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM,
-                                              PIPE_TEXTURE_2D,
-                                              PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
+                                              PIPE_TEXTURE_2D, 0,
+                                              PIPE_BIND_RENDER_TARGET, 0);
    pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM,
-                                              PIPE_TEXTURE_2D,
-                                              PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
+                                              PIPE_TEXTURE_2D, 0,
+                                              PIPE_BIND_RENDER_TARGET, 0);
    pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM,
-                                            PIPE_TEXTURE_2D,
-                                            PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
+                                            PIPE_TEXTURE_2D, 0,
+                                            PIPE_BIND_RENDER_TARGET, 0);
 
    /* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
    if (dri_with_format(screen->sPriv)) {
       pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
-                                             PIPE_TEXTURE_2D,
-                                             PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+                                             PIPE_TEXTURE_2D, 0,
+                                             PIPE_BIND_DEPTH_STENCIL, 0);
       pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
-                                             PIPE_TEXTURE_2D,
-                                             PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+                                             PIPE_TEXTURE_2D, 0,
+                                             PIPE_BIND_DEPTH_STENCIL, 0);
    } else {
       pf_z16 = FALSE;
       pf_z32 = FALSE;
@@ -147,22 +134,39 @@ dri_fill_in_modes(struct dri_screen *screen,
    }
 
    msaa_samples_array[0] = 0;
-   msaa_samples_array[1] = 4;
    back_buffer_factor = 3;
-   msaa_samples_factor = 2;
 
-   num_modes =
-      depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
+   /* also test color for msaa 2/4/6/8 - just assume it'll work for all depth buffers */
+   if (pf_r5g6b5) {
+      msaa_samples_factor = 1;
+      for (i = 1; i < 5; i++) {
+         if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM,
+                                                  PIPE_TEXTURE_2D, i*2,
+                                                  PIPE_BIND_RENDER_TARGET, 0)) {
+            msaa_samples_array[msaa_samples_factor] = i * 2;
+            msaa_samples_factor++;
+         }
+      }
 
-   if (pf_r5g6b5)
       configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
                                         depth_bits_array, stencil_bits_array,
                                         depth_buffer_factor, back_buffer_modes,
                                         back_buffer_factor,
                                         msaa_samples_array, msaa_samples_factor,
                                         GL_TRUE);
+   }
+
+   if (pf_a8r8g8b8) {
+      msaa_samples_factor = 1;
+      for (i = 1; i < 5; i++) {
+         if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM,
+                                                  PIPE_TEXTURE_2D, i*2,
+                                                  PIPE_BIND_RENDER_TARGET, 0)) {
+            msaa_samples_array[msaa_samples_factor] = i * 2;
+            msaa_samples_factor++;
+         }
+      }
 
-   if (pf_a8r8g8b8)
       configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
                                           depth_bits_array,
                                           stencil_bits_array,
@@ -172,8 +176,19 @@ dri_fill_in_modes(struct dri_screen *screen,
                                           msaa_samples_array,
                                           msaa_samples_factor,
                                           GL_TRUE);
+   }
+
+   if (pf_x8r8g8b8) {
+      msaa_samples_factor = 1;
+      for (i = 1; i < 5; i++) {
+         if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM,
+                                                  PIPE_TEXTURE_2D, i*2,
+                                                  PIPE_BIND_RENDER_TARGET, 0)) {
+            msaa_samples_array[msaa_samples_factor] = i * 2;
+            msaa_samples_factor++;
+         }
+      }
 
-   if (pf_x8r8g8b8)
       configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
                                           depth_bits_array,
                                           stencil_bits_array,
@@ -183,6 +198,7 @@ dri_fill_in_modes(struct dri_screen *screen,
                                           msaa_samples_array,
                                           msaa_samples_factor,
                                           GL_TRUE);
+   }
 
    if (pixel_bits == 16) {
       configs = configs_r5g6b5;
@@ -211,7 +227,7 @@ dri_fill_in_modes(struct dri_screen *screen,
  */
 void
 dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
-                   const __GLcontextModes *mode)
+                   const struct gl_config *mode)
 {
    memset(stvis, 0, sizeof(*stvis));
 
@@ -242,8 +258,8 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
                                           PIPE_FORMAT_X8Z24_UNORM;
       } else {
         stvis->depth_stencil_format = (screen->sd_depth_bits_last) ?
-                                          PIPE_FORMAT_Z24S8_UNORM:
-                                          PIPE_FORMAT_S8Z24_UNORM;
+                                          PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+                                          PIPE_FORMAT_S8_USCALED_Z24_UNORM;
       }
       break;
    case 32:
@@ -268,91 +284,111 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
    /* let the state tracker allocate the accum buffer */
 }
 
-#ifndef __NOT_HAVE_DRM_H
+static boolean
+dri_get_egl_image(struct st_manager *smapi,
+                  void *egl_image,
+                  struct st_egl_image *stimg)
+{
+   struct dri_screen *screen = (struct dri_screen *)smapi;
+   __DRIimage *img = NULL;
+
+   if (screen->lookup_egl_image) {
+      img = screen->lookup_egl_image(screen, egl_image);
+   }
+
+   if (!img)
+      return FALSE;
+
+   stimg->texture = NULL;
+   pipe_resource_reference(&stimg->texture, img->texture);
+   stimg->face = img->face;
+   stimg->level = img->level;
+   stimg->zslice = img->zslice;
+
+   return TRUE;
+}
 
-/**
- * Get information about previous buffer swaps.
- */
 static int
-dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
+dri_get_param(struct st_manager *smapi,
+              enum st_manager_param param)
 {
-   if (dPriv == NULL || dPriv->driverPrivate == NULL || sInfo == NULL)
-      return -1;
-   else
+   struct dri_screen *screen = (struct dri_screen *)smapi;
+
+   switch(param) {
+   case ST_MANAGER_BROKEN_INVALIDATE:
+      return screen->broken_invalidate;
+   default:
       return 0;
+   }
 }
 
-#endif
-
 static void
 dri_destroy_option_cache(struct dri_screen * screen)
 {
    int i;
 
-   for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
-      FREE(screen->optionCache.info[i].name);
-      FREE(screen->optionCache.info[i].ranges);
+   if (screen->optionCache.info) {
+      for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
+         FREE(screen->optionCache.info[i].name);
+         FREE(screen->optionCache.info[i].ranges);
+      }
+      FREE(screen->optionCache.info);
    }
 
-   FREE(screen->optionCache.info);
    FREE(screen->optionCache.values);
 }
 
 void
-dri_destroy_screen(__DRIscreen * sPriv)
+dri_destroy_screen_helper(struct dri_screen * screen)
 {
-   struct dri_screen *screen = dri_screen(sPriv);
+   if (screen->st_api && screen->st_api->destroy)
+      screen->st_api->destroy(screen->st_api);
 
-   dri1_destroy_pipe_context(screen);
+   if (screen->base.screen)
+      screen->base.screen->destroy(screen->base.screen);
 
-   if (screen->smapi)
-      dri_destroy_st_manager(screen->smapi);
+   dri_destroy_option_cache(screen);
+}
 
-   if (screen->pipe_screen)
-      screen->pipe_screen->destroy(screen->pipe_screen);
+void
+dri_destroy_screen(__DRIscreen * sPriv)
+{
+   struct dri_screen *screen = dri_screen(sPriv);
 
-   dri_destroy_option_cache(screen);
+   dri_destroy_screen_helper(screen);
 
    FREE(screen);
    sPriv->private = NULL;
    sPriv->extensions = NULL;
 }
 
-#ifndef __NOT_HAVE_DRM_H
-
-const struct __DriverAPIRec driDriverAPI = {
-   .DestroyScreen = dri_destroy_screen,
-   .CreateContext = dri_create_context,
-   .DestroyContext = dri_destroy_context,
-   .CreateBuffer = dri_create_buffer,
-   .DestroyBuffer = dri_destroy_buffer,
-   .MakeCurrent = dri_make_current,
-   .UnbindContext = dri_unbind_context,
-   .GetSwapInfo = dri_get_swap_info,
-   .GetDrawableMSC = driDrawableGetMSC32,
-   .WaitForMSC = driWaitForMSC32,
-   .InitScreen2 = dri2_init_screen,
-
-   .InitScreen = dri1_init_screen,
-   .SwapBuffers = dri1_swap_buffers,
-   .CopySubBuffer = dri1_copy_sub_buffer,
-};
-
-#else
-
-const struct __DriverAPIRec driDriverAPI = {
-   .DestroyScreen = dri_destroy_screen,
-   .CreateContext = dri_create_context,
-   .DestroyContext = dri_destroy_context,
-   .CreateBuffer = dri_create_buffer,
-   .DestroyBuffer = dri_destroy_buffer,
-   .MakeCurrent = dri_make_current,
-   .UnbindContext = dri_unbind_context,
-
-   .InitScreen = drisw_init_screen,
-   .SwapBuffers = drisw_swap_buffers,
-};
-
-#endif
+const __DRIconfig **
+dri_init_screen_helper(struct dri_screen *screen,
+                       struct pipe_screen *pscreen,
+                       unsigned pixel_bits)
+{
+   screen->base.screen = pscreen;
+   if (!screen->base.screen) {
+      debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
+      return NULL;
+   }
+
+   screen->base.get_egl_image = dri_get_egl_image;
+   screen->base.get_param = dri_get_param;
+
+   screen->st_api = st_gl_api_create();
+   if (!screen->st_api)
+      return NULL;
+
+   if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES))
+      screen->target = PIPE_TEXTURE_2D;
+   else
+      screen->target = PIPE_TEXTURE_RECT;
+
+   driParseOptionInfo(&screen->optionCache,
+                      __driConfigOptions, __driNConfigOptions);
+
+   return dri_fill_in_modes(screen, pixel_bits);
+}
 
 /* vim: set sw=3 ts=8 sts=3 expandtab: */