[PATCH 4/5] wined3d: Set GL_UNPACK_ALIGNMENT to 1 when uploading surfaces from user memory.

Matteo Bruni matteo.mystral at gmail.com
Wed Feb 18 07:23:51 CST 2015

2015-02-11 10:46 GMT+01:00 Stefan Dösinger <stefandoesinger at gmail.com>:
> Hash: SHA1
> Am 2015-02-10 um 22:05 schrieb Henri Verbeet:
>> What's a bit awkward about this is that if the pitch isn't a
>> multiple of the pixel byte width it's still not going to work. But
>> I guess this is the best we can do.
> Does this ever happen? D3D9 doesn't allow specifying a manual pitch,
> and ddraw has at most 4 byte pixels and enforces a pitch alignment of
> 4 according to our tests.
> Technically 24-bit RGB8 can have a misaligned pitch, but that isn't
> supported anywhere.

It looks like that's correct WRT the client APIs but not for formats
used internally by wined3d. I tried to set GL_UNPACK_ALIGNMENT to 1 in
context_create and that fails volume_v16u16_test in d3d9:visual on
Mesa. It fails because we're using GL_RGB16 to emulate D3DFMT_V16U16
when NV_texture_shader isn't supported (and the texture is 1x2x2 which
luckily triggers the bug).
I think conversions are the only cases where we can currently get
pitches non multiple of the pixel byte width and we can fix those by
either using a different pitch (we're free to choose it anyway) or
avoiding those 3-channels formats altogether. The attached patch takes
the former approach.

Otherwise I can still go ahead with this patch but it would be a bit
cumbersome to have to set UNPACK_ALIGNMENT every time when once per
context should be enough (unless I'm missing something).
-------------- next part --------------
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 843905a..fa8d768 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1685,7 +1685,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);
     checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);");
-    gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);
+    gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);");
     if (gl_info->supported[ARB_VERTEX_BLEND])
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index d515a3a..c8e4cb1 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -4238,7 +4238,6 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
         format.byte_count = format.conv_byte_count;
         dst_pitch = wined3d_format_calculate_pitch(&format, width);
-        dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
         if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 0d13dd0..91325dc 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -84,7 +84,6 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
         UINT dst_row_pitch, dst_slice_pitch;
         UINT src_row_pitch, src_slice_pitch;
-        UINT alignment = volume->resource.device->surface_alignment;
         if (data->buffer_object)
             ERR("Loading a converted volume from a PBO.\n");
@@ -92,7 +91,6 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
             ERR("Converting a block-based format.\n");
         dst_row_pitch = width * format->conv_byte_count;
-        dst_row_pitch = (dst_row_pitch + alignment - 1) & ~(alignment - 1);
         dst_slice_pitch = dst_row_pitch * height;
         wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch);

More information about the wine-devel mailing list