[PATCH 3/5] wined3d: Handle upload conversion in texture2d_upload_data().

Henri Verbeet hverbeet at codeweavers.com
Wed Mar 21 04:30:51 CDT 2018


For consistency with texture3d_upload_data().

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/surface.c         | 35 ++++---------------
 dlls/wined3d/texture.c         | 77 ++++++++++++++++++++++++++++++++----------
 dlls/wined3d/wined3d_private.h |  4 +--
 3 files changed, 67 insertions(+), 49 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 8f4e1eebba5..2a725e61e1c 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1987,9 +1987,9 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re
     struct wined3d_device *device = texture->resource.device;
     const struct wined3d_color_key_conversion *conversion;
     struct wined3d_texture_sub_resource *sub_resource;
+    const struct wined3d_format *format;
     struct wined3d_bo_address data;
     BYTE *src_mem, *dst_mem = NULL;
-    struct wined3d_format format;
     struct wined3d_box src_box;
     BOOL depth;
 
@@ -2080,9 +2080,9 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re
     wined3d_texture_bind_and_dirtify(texture, context, srgb);
     wined3d_texture_get_pitch(texture, level, &src_row_pitch, &src_slice_pitch);
 
-    format = *texture->resource.format;
+    format = texture->resource.format;
     if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
-        format = *wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
+        format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
 
     /* Don't use PBOs for converted surfaces. During PBO conversion we look at
      * WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is
@@ -2096,35 +2096,12 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re
     }
 
     wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->locations);
-    if (format.conv_byte_count)
-    {
-        /* This code is entered for texture formats which need a fixup. */
-        format.byte_count = format.conv_byte_count;
-        wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch);
-
-        src_mem = context_map_bo_address(context, &data, src_slice_pitch,
-                GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
-        if (!(dst_mem = heap_alloc(dst_slice_pitch)))
-        {
-            ERR("Out of memory (%u).\n", dst_slice_pitch);
-            context_release(context);
-            return FALSE;
-        }
-        format.upload(src_mem, dst_mem, src_row_pitch, src_slice_pitch,
-                dst_row_pitch, dst_slice_pitch, width, height, 1);
-        src_row_pitch = dst_row_pitch;
-        src_slice_pitch = dst_slice_pitch;
-        context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER);
-
-        data.buffer_object = 0;
-        data.addr = dst_mem;
-    }
-    else if (conversion)
+    if (conversion)
     {
         /* This code is only entered for color keying fixups */
         struct wined3d_palette *palette = NULL;
 
-        wined3d_format_calculate_pitch(&format, device->surface_alignment,
+        wined3d_format_calculate_pitch(format, device->surface_alignment,
                 width, height, &dst_row_pitch, &dst_slice_pitch);
 
         src_mem = context_map_bo_address(context, &data, src_slice_pitch,
@@ -2147,7 +2124,7 @@ BOOL texture2d_load_texture(struct wined3d_texture *texture, unsigned int sub_re
         data.addr = dst_mem;
     }
 
-    wined3d_texture_upload_data(texture, sub_resource_idx, context, &format, &src_box,
+    wined3d_texture_upload_data(texture, sub_resource_idx, context, format, &src_box,
             wined3d_const_bo_address(&data), src_row_pitch, src_slice_pitch, 0, 0, 0, srgb);
 
     heap_free(dst_mem);
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index f5892430956..be40e7135b0 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1745,7 +1745,7 @@ HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
 }
 
 void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
-        const struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
+        struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
         const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch,
         unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb)
 {
@@ -1757,14 +1757,17 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
  * correct texture. */
 /* Context activation is done by the caller. */
 static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
-        const struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
+        struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
         const struct wined3d_const_bo_address *data, unsigned int src_row_pitch, unsigned int src_slice_pitch,
         unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     unsigned int update_w = src_box->right - src_box->left;
     unsigned int update_h = src_box->bottom - src_box->top;
+    struct wined3d_bo_address bo;
+    void *converted_mem = NULL;
     unsigned int level, layer;
+    struct wined3d_format f;
     GLenum target;
 
     TRACE("texture %p, sub_resource_idx %u, context %p, format %s, src_box %s, data {%#x:%p}, "
@@ -1784,9 +1787,54 @@ static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int
         update_h /= format->height_scale.denominator;
     }
 
-    if (data->buffer_object)
+    bo.buffer_object = data->buffer_object;
+    bo.addr = (BYTE *)data->addr;
+    if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
     {
-        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
+        bo.addr += (src_box->top / format->block_height) * src_row_pitch;
+        bo.addr += (src_box->left / format->block_width) * format->block_byte_count;
+    }
+    else
+    {
+        bo.addr += src_box->top * src_row_pitch;
+        bo.addr += src_box->left * format->byte_count;
+    }
+
+    if (format->upload)
+    {
+        unsigned int dst_row_pitch, dst_slice_pitch;
+        void *src_mem;
+
+        if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
+            ERR("Converting a block-based format.\n");
+
+        f = *format;
+        f.byte_count = format->conv_byte_count;
+        format = &f;
+
+        wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch);
+
+        if (!(converted_mem = heap_alloc(dst_slice_pitch)))
+        {
+            ERR("Failed to allocate upload buffer.\n");
+            return;
+        }
+
+        src_mem = context_map_bo_address(context, &bo, src_slice_pitch,
+                GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
+        format->upload(src_mem, converted_mem, src_row_pitch, src_slice_pitch,
+                dst_row_pitch, dst_slice_pitch, update_w, update_h, 1);
+        context_unmap_bo_address(context, &bo, GL_PIXEL_UNPACK_BUFFER);
+
+        bo.buffer_object = 0;
+        bo.addr = converted_mem;
+        src_row_pitch = dst_row_pitch;
+        src_slice_pitch = dst_slice_pitch;
+    }
+
+    if (bo.buffer_object)
+    {
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bo.buffer_object));
         checkGLcall("glBindBuffer");
     }
 
@@ -1797,12 +1845,9 @@ static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int
     if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
     {
         unsigned int dst_row_pitch, dst_slice_pitch;
-        const BYTE *addr = data->addr;
+        const BYTE *addr = bo.addr;
         GLenum internal;
 
-        addr += (src_box->top / format->block_height) * src_row_pitch;
-        addr += (src_box->left / format->block_width) * format->block_byte_count;
-
         if (srgb)
             internal = format->glGammaInternal;
         else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
@@ -1859,36 +1904,32 @@ static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int
     }
     else
     {
-        const BYTE *addr = data->addr;
-
-        addr += src_box->top * src_row_pitch;
-        addr += src_box->left * format->byte_count;
-
         TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
                 "format %#x, type %#x, addr %p.\n",
                 target, level, layer, dst_x, dst_y,
-                update_w, update_h, format->glFormat, format->glType, addr);
+                update_w, update_h, format->glFormat, format->glType, bo.addr);
 
         gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_row_pitch / format->byte_count);
         if (target == GL_TEXTURE_2D_ARRAY)
         {
             GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y,
-                    layer, update_w, update_h, 1, format->glFormat, format->glType, addr));
+                    layer, update_w, update_h, 1, format->glFormat, format->glType, bo.addr));
         }
         else
         {
             gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y,
-                    update_w, update_h, format->glFormat, format->glType, addr);
+                    update_w, update_h, format->glFormat, format->glType, bo.addr);
         }
         gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
         checkGLcall("Upload texture data");
     }
 
-    if (data->buffer_object)
+    if (bo.buffer_object)
     {
         GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
         checkGLcall("glBindBuffer");
     }
+    heap_free(converted_mem);
 
     if (wined3d_settings.strict_draw_ordering)
         gl_info->gl_ops.gl.p_glFlush();
@@ -2533,7 +2574,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
  * correct texture. */
 /* Context activation is done by the caller. */
 static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
-        const struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
+        struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
         const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch,
         unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb)
 {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index cb2938b6aca..678c669b7c3 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3084,7 +3084,7 @@ struct gl_texture
 struct wined3d_texture_ops
 {
     void (*texture_upload_data)(struct wined3d_texture *texture, unsigned int sub_resource_idx,
-            const struct wined3d_context *context, const struct wined3d_format *format,
+            struct wined3d_context *context, const struct wined3d_format *format,
             const struct wined3d_box *src_box, const struct wined3d_const_bo_address *data, unsigned int row_pitch,
             unsigned int slice_pitch, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb);
     BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx,
@@ -3294,7 +3294,7 @@ void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
 void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture,
         HWND window, RECT *rect) DECLSPEC_HIDDEN;
 void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
-        const struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
+        struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
         const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch,
         unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb) DECLSPEC_HIDDEN;
 void wined3d_texture_validate_location(struct wined3d_texture *texture,
-- 
2.11.0




More information about the wine-devel mailing list