st/mesa: try to find exact format matching user format and type for DrawPixels
authorMarek Olšák <maraeo@gmail.com>
Tue, 12 Feb 2013 21:09:24 +0000 (22:09 +0100)
committerMarek Olšák <maraeo@gmail.com>
Thu, 14 Feb 2013 13:51:46 +0000 (14:51 +0100)
Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_format.c
src/mesa/state_tracker/st_format.h

index ba4f17a3da3594831a8bcede2cd399becde25f21..e282bf98dbfb6128d6c6b80b5ec5408f7534a220 100644 (file)
@@ -484,19 +484,29 @@ make_texture(struct st_context *st,
    gl_format mformat;
    struct pipe_resource *pt;
    enum pipe_format pipeFormat;
-   GLenum baseInternalFormat, intFormat;
-
-   intFormat = internal_format(ctx, format, type);
-   baseInternalFormat = _mesa_base_tex_format(ctx, intFormat);
+   GLenum baseInternalFormat;
 
    /* Choose a pixel format for the temp texture which will hold the
     * image to draw.
     */
-   pipeFormat = st_choose_format(st, intFormat, format, type,
-                                 PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW,
-                                 FALSE);
-   assert(pipeFormat != PIPE_FORMAT_NONE);
-   mformat = st_pipe_format_to_mesa_format(pipeFormat);
+   pipeFormat = st_choose_matching_format(pipe->screen, PIPE_BIND_SAMPLER_VIEW,
+                                          format, type, unpack->SwapBytes);
+
+   if (pipeFormat != PIPE_FORMAT_NONE) {
+      mformat = st_pipe_format_to_mesa_format(pipeFormat);
+      baseInternalFormat = _mesa_get_format_base_format(mformat);
+   }
+   else {
+      /* Use the generic approach. */
+      GLenum intFormat = internal_format(ctx, format, type);
+
+      baseInternalFormat = _mesa_base_tex_format(ctx, intFormat);
+      pipeFormat = st_choose_format(st, intFormat, format, type,
+                                    PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW,
+                                    FALSE);
+      assert(pipeFormat != PIPE_FORMAT_NONE);
+      mformat = st_pipe_format_to_mesa_format(pipeFormat);
+   }
 
    pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
    if (!pixels)
index ac70e9292ead217d23dc5f62a0950984f98ff926..f8ff024db0a0b13942952d59b54ab06a3841c8c0 100644 (file)
@@ -560,32 +560,6 @@ st_CompressedTexImage(struct gl_context *ctx, GLuint dims,
 }
 
 
-static enum pipe_format
-choose_matching_format(struct pipe_screen *screen, unsigned bind,
-                       GLenum format, GLenum type, GLboolean swapBytes)
-{
-   gl_format mesa_format;
-
-   for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) {
-      if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) {
-         continue;
-      }
-
-      if (_mesa_format_matches_format_and_type(mesa_format, format, type,
-                                               swapBytes)) {
-         enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format);
-
-         if (format &&
-             screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0,
-                                         bind)) {
-            return format;
-         }
-         /* It's unlikely to find 2 matching Mesa formats. */
-         break;
-      }
-   }
-   return PIPE_FORMAT_NONE;
-}
 
 
 /**
@@ -683,8 +657,8 @@ st_GetTexImage(struct gl_context * ctx,
 
    /* Choose the destination format by finding the best match
     * for the format+type combo. */
-   dst_format = choose_matching_format(screen, bind, format, type,
-                                       ctx->Pack.SwapBytes);
+   dst_format = st_choose_matching_format(screen, bind, format, type,
+                                         ctx->Pack.SwapBytes);
 
    if (dst_format == PIPE_FORMAT_NONE) {
       GLenum dst_glformat;
index 02969b995975c17ecd11cec8e72f98a12bbcfc08..5fd44e76d6a1249ef59502fc2b51a928a3414fb0 100644 (file)
@@ -1674,6 +1674,41 @@ st_choose_renderbuffer_format(struct st_context *st,
 }
 
 
+/**
+ * Given an OpenGL user-requested format and type, and swapBytes state,
+ * return the format which exactly matches those parameters, so that
+ * a memcpy-based transfer can be done.
+ *
+ * If no format is supported, return PIPE_FORMAT_NONE.
+ */
+enum pipe_format
+st_choose_matching_format(struct pipe_screen *screen, unsigned bind,
+                         GLenum format, GLenum type, GLboolean swapBytes)
+{
+   gl_format mesa_format;
+
+   for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) {
+      if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) {
+         continue;
+      }
+
+      if (_mesa_format_matches_format_and_type(mesa_format, format, type,
+                                               swapBytes)) {
+         enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format);
+
+         if (format &&
+             screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0,
+                                         bind)) {
+            return format;
+         }
+         /* It's unlikely to find 2 matching Mesa formats. */
+         break;
+      }
+   }
+   return PIPE_FORMAT_NONE;
+}
+
+
 /**
  * Called via ctx->Driver.ChooseTextureFormat().
  */
index aee624d24923672b685a70d93b460cceca3d6923..3db409b74e06248bf0b0bed3df1002e97cdfcf59 100644 (file)
@@ -57,6 +57,9 @@ extern enum pipe_format
 st_choose_renderbuffer_format(struct st_context *st,
                               GLenum internalFormat, unsigned sample_count);
 
+extern enum pipe_format
+st_choose_matching_format(struct pipe_screen *screen, unsigned bind,
+                         GLenum format, GLenum type, GLboolean swapBytes);
 
 extern gl_format
 st_ChooseTextureFormat(struct gl_context * ctx, GLenum target,