From 64da6b05260ab8bea430872b47783d469dcddeeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Mon, 25 Apr 2016 12:25:30 +0200 Subject: [PATCH] wined3d: Implement creating 2D array textures. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/surface.c | 57 ++++++++++++++++++++++++++++++++---------- dlls/wined3d/texture.c | 35 ++++++++++++++++++++------ 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 9c12f48ff39..28da2eb9219 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -993,14 +993,25 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w else internal = format->glInternal; - TRACE("glCompressedTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, " - "format %#x, image_size %#x, addr %p.\n", surface->texture_target, surface->texture_level, + TRACE("Uploading compressed data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, " + "format %#x, image_size %#x, addr %p.\n", + surface->texture_target, surface->texture_level, surface->texture_layer, dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr); if (row_length == src_pitch) { - GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, - dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr)); + if (surface->texture_target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glCompressedTexSubImage3D(surface->texture_target, surface->texture_level, + dst_point->x, dst_point->y, surface->texture_layer, update_w, update_h, 1, + internal, row_count * row_length, addr)); + } + else + { + GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, + dst_point->x, dst_point->y, update_w, update_h, + internal, row_count * row_length, addr)); + } } else { @@ -1010,13 +1021,23 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w * can't use the unpack row length like for glTexSubImage2D. */ for (row = 0, y = dst_point->y; row < row_count; ++row) { - GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, - dst_point->x, y, update_w, format->block_height, internal, row_length, addr)); + if (surface->texture_target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glCompressedTexSubImage3D(surface->texture_target, surface->texture_level, + dst_point->x, y, surface->texture_layer, update_w, format->block_height, 1, + internal, row_length, addr)); + } + else + { + GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level, + dst_point->x, y, update_w, format->block_height, internal, row_length, addr)); + } + y += format->block_height; addr += src_pitch; } } - checkGLcall("glCompressedTexSubImage2D"); + checkGLcall("Upload compressed surface data"); } else { @@ -1025,15 +1046,25 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w addr += src_rect->top * src_pitch; addr += src_rect->left * format->byte_count; - TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, addr %p.\n", - surface->texture_target, surface->texture_level, dst_point->x, dst_point->y, - update_w, update_h, format->glFormat, format->glType, addr); + TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, " + "format %#x, type %#x, addr %p.\n", + surface->texture_target, surface->texture_level, surface->texture_layer, + dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr); gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count); - gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, surface->texture_level, - dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr); + if (surface->texture_target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glTexSubImage3D(surface->texture_target, surface->texture_level, + dst_point->x, dst_point->y, surface->texture_layer, update_w, update_h, 1, + format->glFormat, format->glType, addr)); + } + else + { + gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, surface->texture_level, + dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr); + } gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - checkGLcall("glTexSubImage2D"); + checkGLcall("Upload surface data"); } if (data->buffer_object) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 5e18c4c690a..3a03bb66bec 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1359,10 +1359,10 @@ static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned in /* Context activation is done by the caller. */ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { - UINT sub_count = texture->level_count * texture->layer_count; const struct wined3d_format *format = texture->resource.format; const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_color_key_conversion *conversion; + unsigned int sub_call_count; GLenum internal; UINT i; @@ -1394,7 +1394,10 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType); - for (i = 0; i < sub_count; ++i) + sub_call_count = texture->level_count; + if (texture->target != GL_TEXTURE_2D_ARRAY) + sub_call_count *= texture->layer_count; + for (i = 0; i < sub_call_count; ++i) { struct wined3d_surface *surface = texture->sub_resources[i].u.surface; GLsizei width, height; @@ -1407,12 +1410,22 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi height /= format->height_scale.denominator; } - TRACE("surface %p, target %#x, level %d, width %d, height %d.\n", + TRACE("surface %p, target %#x, level %u, width %u, height %u.\n", surface, surface->texture_target, surface->texture_level, width, height); - gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, - internal, width, height, 0, format->glFormat, format->glType, NULL); - checkGLcall("glTexImage2D"); + if (texture->target == GL_TEXTURE_2D_ARRAY) + { + GL_EXTCALL(glTexImage3D(surface->texture_target, surface->texture_level, + internal, width, height, texture->layer_count, 0, + format->glFormat, format->glType, NULL)); + checkGLcall("glTexImage3D"); + } + else + { + gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level, + internal, width, height, 0, format->glFormat, format->glType, NULL); + checkGLcall("glTexImage2D"); + } } } @@ -1778,8 +1791,12 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 unsigned int i, j; HRESULT hr; - if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count != 1) - FIXME("Array textures not implemented.\n"); + if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1 + && !gl_info->supported[EXT_TEXTURE_ARRAY]) + { + WARN("OpenGL implementation does not support array textures.\n"); + return WINED3DERR_INVALIDCALL; + } /* TODO: It should only be possible to create textures for formats * that are reported as supported. */ @@ -1909,6 +1926,8 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 } if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) texture->target = GL_TEXTURE_CUBE_MAP_ARB; + else if (layer_count > 1) + texture->target = GL_TEXTURE_2D_ARRAY; else texture->target = GL_TEXTURE_2D; }