[PATCH 2/3] wined3d: Handle partial updates to 3D textures in wined3d_texture_gl_upload_bo().
Henri Verbeet
hverbeet at gmail.com
Thu Mar 11 05:52:06 CST 2021
On Wed, 10 Mar 2021 at 15:11, Jan Sikorski <jsikorski at codeweavers.com> wrote:
> static void wined3d_texture_gl_upload_bo(const struct wined3d_format *src_format, GLenum target,
> - unsigned int level, unsigned int src_row_pitch, unsigned int dst_x, unsigned int dst_y,
> + unsigned int level, unsigned int src_row_pitch, unsigned int src_slice_pitch, unsigned int dst_x, unsigned int dst_y,
> unsigned int dst_z, unsigned int update_w, unsigned int update_h, unsigned int update_d,
> const BYTE *addr, BOOL srgb, struct wined3d_texture *dst_texture,
> const struct wined3d_gl_info *gl_info)
That line is a bit on the long side. (For reference, there's a soft
limit at 100 columns, and a hard limit at 120 columns.)
> @@ -2213,7 +2213,9 @@ static void wined3d_texture_gl_upload_bo(const struct wined3d_format *src_format
> }
> else
> {
> - unsigned int y, y_count;
> + unsigned int slice_to_row_pitch = src_slice_pitch / src_row_pitch;
"src_row_pitch" may be 0.
> + if (src_slice_pitch && slice_to_row_pitch * src_row_pitch == src_slice_pitch)
> {
> - if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
> - {
> - GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y + y, dst_z,
> - update_w, update_h, update_d, format_gl->format, format_gl->type, addr));
> - }
> - else if (target == GL_TEXTURE_1D)
> - {
> - gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, dst_x,
> - update_w, format_gl->format, format_gl->type, addr);
> - }
> - else
> + gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, slice_to_row_pitch);
> + z_count = 1;
> + }
So essentially,
if (src_slice_pitch && src_row_pitch && !(src_slice_pitch % src_row_pitch))
{
gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,
src_slice_pitch / src_row_pitch);
...
}
right? The row pitch probably needs a similar alignment check,
although unaligned pitches are perhaps rare enough that we've never
run into them.
> + for (y = 0; y < y_count; ++y)
> {
> - gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y + y,
> - update_w, update_h, format_gl->format, format_gl->type, addr);
> + upload_addr = addr;
> + if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
> + {
> + GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y + y, dst_z + z,
> + update_w, update_h, update_d, format_gl->format, format_gl->type, upload_addr));
> + }
> + else if (target == GL_TEXTURE_1D)
> + {
> + gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, dst_x,
> + update_w, format_gl->format, format_gl->type, upload_addr);
> + }
> + else
> + {
> + gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y + y,
> + update_w, update_h, format_gl->format, format_gl->type, upload_addr);
> + }
> + upload_addr += src_row_pitch;
> }
Incrementing "upload_addr" does nothing here, it's reset again at the
start of the loop. It would probably be best to simply use "&addr[z *
slice_pitch + y * row_pitch]".
You'd also need to handle slice pitches for compressed formats.
More information about the wine-devel
mailing list