[PATCH 3/8] wined3d: Implement support for 1D textures.

Henri Verbeet hverbeet at codeweavers.com
Mon Apr 2 15:58:23 CDT 2018


From: Sven Hesse <shesse at codeweavers.com>

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/context.c               |  20 ++-
 dlls/wined3d/device.c                |  17 +++
 dlls/wined3d/directx.c               |  14 ++
 dlls/wined3d/glsl_shader.c           |   7 +
 dlls/wined3d/nvidia_texture_shader.c |   3 +
 dlls/wined3d/resource.c              |   1 +
 dlls/wined3d/shader.c                |   3 +-
 dlls/wined3d/texture.c               | 284 ++++++++++++++++++++++++++++-------
 dlls/wined3d/utils.c                 |   1 +
 dlls/wined3d/view.c                  |   5 +
 dlls/wined3d/wined3d_private.h       |   2 +
 include/wine/wined3d.h               |   5 +-
 12 files changed, 306 insertions(+), 56 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 47eb42e9f71..4b2f26359b7 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -144,7 +144,8 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
         gl_info->fbo_ops.glFramebufferTexture(fbo_target, attachment,
                 resource->object, resource->level);
     }
-    else if (resource->target == GL_TEXTURE_2D_ARRAY || resource->target == GL_TEXTURE_3D)
+    else if (resource->target == GL_TEXTURE_1D_ARRAY || resource->target == GL_TEXTURE_2D_ARRAY
+            || resource->target == GL_TEXTURE_3D)
     {
         if (!gl_info->fbo_ops.glFramebufferTextureLayer)
         {
@@ -155,6 +156,11 @@ static void context_attach_gl_texture_fbo(struct wined3d_context *context,
         gl_info->fbo_ops.glFramebufferTextureLayer(fbo_target, attachment,
                 resource->object, resource->level, resource->layer);
     }
+    else if (resource->target == GL_TEXTURE_1D)
+    {
+        gl_info->fbo_ops.glFramebufferTexture1D(fbo_target, attachment,
+                resource->target, resource->object, resource->level);
+    }
     else
     {
         gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, attachment,
@@ -242,6 +248,8 @@ static void context_dump_fbo_attachment(const struct wined3d_gl_info *gl_info, G
     }
     texture_type[] =
     {
+        {GL_TEXTURE_1D,                   GL_TEXTURE_BINDING_1D,                   "1d",          WINED3D_GL_EXT_NONE},
+        {GL_TEXTURE_1D_ARRAY,             GL_TEXTURE_BINDING_1D_ARRAY,             "1d-array",    EXT_TEXTURE_ARRAY},
         {GL_TEXTURE_2D,                   GL_TEXTURE_BINDING_2D,                   "2d",          WINED3D_GL_EXT_NONE},
         {GL_TEXTURE_RECTANGLE_ARB,        GL_TEXTURE_BINDING_RECTANGLE_ARB,        "rectangle",   ARB_TEXTURE_RECTANGLE},
         {GL_TEXTURE_2D_ARRAY,             GL_TEXTURE_BINDING_2D_ARRAY,             "2d-array" ,   EXT_TEXTURE_ARRAY},
@@ -1742,6 +1750,7 @@ void context_bind_dummy_textures(const struct wined3d_device *device, const stru
     {
         GL_EXTCALL(glActiveTexture(GL_TEXTURE0 + i));
 
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
         gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
 
         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
@@ -1757,7 +1766,10 @@ void context_bind_dummy_textures(const struct wined3d_device *device, const stru
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures->tex_cube_array);
 
         if (gl_info->supported[EXT_TEXTURE_ARRAY])
+        {
+            gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
+        }
 
         if (gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
             gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_BUFFER, textures->tex_buffer);
@@ -2491,6 +2503,12 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint
             case GL_NONE:
                 /* nothing to do */
                 break;
+            case GL_TEXTURE_1D:
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
+                break;
+            case GL_TEXTURE_1D_ARRAY:
+                gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
+                break;
             case GL_TEXTURE_2D:
                 gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
                 break;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index adaa4f10000..cc42dba45df 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -630,6 +630,12 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
      * to each texture stage when the currently set D3D texture is NULL. */
     context_active_texture(context, gl_info, 0);
 
+    gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d);
+    TRACE("Dummy 1D texture given name %u.\n", textures->tex_1d);
+    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, textures->tex_1d);
+    gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 1, 0,
+            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+
     gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d);
     TRACE("Dummy 2D texture given name %u.\n", textures->tex_2d);
     gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, textures->tex_2d);
@@ -681,6 +687,12 @@ static void create_dummy_textures(struct wined3d_device *device, struct wined3d_
 
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
     {
+        gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_1d_array);
+        TRACE("Dummy 1D array texture given name %u.\n", textures->tex_1d_array);
+        gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D_ARRAY, textures->tex_1d_array);
+        gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA8, 1, 1, 0,
+                    GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+
         gl_info->gl_ops.gl.p_glGenTextures(1, &textures->tex_2d_array);
         TRACE("Dummy 2D array texture given name %u.\n", textures->tex_2d_array);
         gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D_ARRAY, textures->tex_2d_array);
@@ -748,7 +760,10 @@ static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d
         gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_buffer);
 
     if (gl_info->supported[EXT_TEXTURE_ARRAY])
+    {
         gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d_array);
+        gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d_array);
+    }
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP_ARRAY])
         gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_cube_array);
@@ -763,6 +778,7 @@ static void destroy_dummy_textures(struct wined3d_device *device, struct wined3d
         gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_rect);
 
     gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_2d);
+    gl_info->gl_ops.gl.p_glDeleteTextures(1, &dummy_textures->tex_1d);
 
     checkGLcall("delete dummy textures");
 
@@ -5055,6 +5071,7 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso
 
     switch (type)
     {
+        case WINED3D_RTYPE_TEXTURE_1D:
         case WINED3D_RTYPE_TEXTURE_2D:
         case WINED3D_RTYPE_TEXTURE_3D:
             for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 3bd63c3c074..7deefaf82dc 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -5320,6 +5320,20 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
             gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
             break;
 
+        case WINED3D_RTYPE_TEXTURE_1D:
+            allowed_usage = WINED3DUSAGE_DYNAMIC
+                    | WINED3DUSAGE_SOFTWAREPROCESSING
+                    | WINED3DUSAGE_TEXTURE
+                    | WINED3DUSAGE_QUERY_FILTER
+                    | WINED3DUSAGE_QUERY_GENMIPMAP
+                    | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+                    | WINED3DUSAGE_QUERY_SRGBREAD
+                    | WINED3DUSAGE_QUERY_SRGBWRITE
+                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+                    | WINED3DUSAGE_QUERY_WRAPANDMIP;
+            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_1D;
+            break;
+
         case WINED3D_RTYPE_TEXTURE_2D:
             allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                     | WINED3DUSAGE_RENDERTARGET
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index e920fac3907..0bc6aa02319 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2576,6 +2576,13 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
                     sampler_type = "samplerCube";
                 break;
 
+            case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY:
+                if (shadow_sampler)
+                    sampler_type = "sampler1DArrayShadow";
+                else
+                    sampler_type = "sampler1DArray";
+                break;
+
             case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
                 if (shadow_sampler)
                     sampler_type = "sampler2DArrayShadow";
diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c
index 0baa414e57d..20db62739b5 100644
--- a/dlls/wined3d/nvidia_texture_shader.c
+++ b/dlls/wined3d/nvidia_texture_shader.c
@@ -69,6 +69,9 @@ static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD st
                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
                 checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
                 break;
+            default:
+                FIXME("Unhandled target %#x.\n", state->textures[stage]->target);
+                break;
         }
     }
     else
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index a95d6f50b68..2a6fa6ad7ec 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -75,6 +75,7 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
     resource_types[] =
     {
         {WINED3D_RTYPE_BUFFER,      0,                              WINED3D_GL_RES_TYPE_BUFFER},
+        {WINED3D_RTYPE_TEXTURE_1D,  0,                              WINED3D_GL_RES_TYPE_TEX_1D},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_TEX_2D},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_TEX_RECT},
         {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_RB},
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 93079e89120..c20c1da14bc 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -3871,8 +3871,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
             switch (texture->target)
             {
                 /* RECT textures are distinguished from 2D textures via np2_fixup */
-                case GL_TEXTURE_RECTANGLE_ARB:
-                case GL_TEXTURE_2D:
+                default:
                     break;
 
                 case GL_TEXTURE_3D:
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 9e6b599c8e9..b56e6e4e65e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -445,7 +445,10 @@ static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *
     GLenum target;
 
     level_count = texture->level_count;
-    layer_count = texture->target == GL_TEXTURE_2D_ARRAY ? 1 : texture->layer_count;
+    if (texture->target == GL_TEXTURE_1D_ARRAY || texture->target == GL_TEXTURE_2D_ARRAY)
+        layer_count = 1;
+    else
+        layer_count = texture->layer_count;
 
     for (layer = 0; layer < layer_count; ++layer)
     {
@@ -472,10 +475,16 @@ static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *
                         format->glFormat, format->glType, NULL));
                 checkGLcall("glTexImage3D");
             }
+            else if (target == GL_TEXTURE_1D)
+            {
+                gl_info->gl_ops.gl.p_glTexImage1D(target, level, gl_internal_format,
+                        width, 0, format->glFormat, format->glType, NULL);
+            }
             else
             {
-                gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format,
-                        width, height, 0, format->glFormat, format->glType, NULL);
+                gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format, width,
+                        target == GL_TEXTURE_1D_ARRAY ? texture->layer_count : height, 0,
+                        format->glFormat, format->glType, NULL);
                 checkGLcall("glTexImage2D");
             }
         }
@@ -509,6 +518,13 @@ static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture
             GL_EXTCALL(glTexStorage3DMultisample(texture->target, samples,
                     gl_internal_format, width, height, texture->layer_count, GL_FALSE));
             break;
+        case GL_TEXTURE_1D_ARRAY:
+            GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
+                    gl_internal_format, width, texture->layer_count));
+            break;
+        case GL_TEXTURE_1D:
+            GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, gl_internal_format, width));
+            break;
         default:
             GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
                     gl_internal_format, width, height));
@@ -1782,7 +1798,12 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
     target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
     level = sub_resource_idx % texture->level_count;
 
-    if (target == GL_TEXTURE_2D_ARRAY)
+    if (target == GL_TEXTURE_1D_ARRAY)
+    {
+        dst_y = sub_resource_idx / texture->level_count;
+        update_h = 1;
+    }
+    else if (target == GL_TEXTURE_2D_ARRAY)
     {
         dst_z = sub_resource_idx / texture->level_count;
         update_d = 1;
@@ -1860,7 +1881,12 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
                 target, level, dst_x, dst_y, dst_z, update_w, update_h,
                 update_d, internal, dst_slice_pitch, addr);
 
-        if (dst_row_pitch == src_row_pitch)
+        if (target == GL_TEXTURE_1D)
+        {
+            GL_EXTCALL(glCompressedTexSubImage1D(target, level, dst_x,
+                    update_w, internal, dst_row_pitch, addr));
+        }
+        else if (dst_row_pitch == src_row_pitch)
         {
             if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
             {
@@ -1915,6 +1941,11 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
             GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y, dst_z,
                     update_w, update_h, update_d, format->glFormat, format->glType, bo.addr));
         }
+        else if (target == GL_TEXTURE_1D)
+        {
+            gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, dst_x,
+                    update_w, format->glFormat, format->glType, bo.addr);
+        }
         else
         {
             gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y,
@@ -2247,6 +2278,142 @@ static const struct wined3d_resource_ops texture_resource_ops =
     texture_resource_sub_resource_unmap,
 };
 
+/* Context activation is done by the caller. */
+static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        const struct wined3d_context *context, const struct wined3d_bo_address *data)
+{
+    const struct wined3d_format *format = texture->resource.format;
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+
+    if (format->conv_byte_count)
+    {
+        FIXME("Attempting to download a converted texture, format %s.\n",
+                debug_d3dformat(format->id));
+        return;
+    }
+
+    if (data->buffer_object)
+    {
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
+        checkGLcall("glBindBuffer");
+    }
+
+    gl_info->gl_ops.gl.p_glGetTexImage(texture->target, sub_resource_idx,
+            format->glFormat, format->glType, data->addr);
+    checkGLcall("glGetTexImage");
+
+    if (data->buffer_object)
+    {
+        GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+        checkGLcall("glBindBuffer");
+    }
+}
+
+/* Context activation is done by the caller. */
+static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
+        struct wined3d_context *context, DWORD location)
+{
+    struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
+    unsigned int row_pitch, slice_pitch;
+
+    TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
+            texture, sub_resource_idx, context, wined3d_debug_location(location));
+
+    if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
+        return FALSE;
+
+    switch (location)
+    {
+        case WINED3D_LOCATION_TEXTURE_RGB:
+        case WINED3D_LOCATION_TEXTURE_SRGB:
+            if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
+            {
+                struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
+                struct wined3d_box src_box;
+
+                data.addr += sub_resource->offset;
+                wined3d_texture_bind_and_dirtify(texture, context,
+                        location == WINED3D_LOCATION_TEXTURE_SRGB);
+                wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+                wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
+                wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
+                        &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
+            }
+            else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
+            {
+                struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
+                struct wined3d_box src_box;
+
+                wined3d_texture_bind_and_dirtify(texture, context,
+                        location == WINED3D_LOCATION_TEXTURE_SRGB);
+                wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
+                wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
+                wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
+                        &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
+            }
+            else
+            {
+                FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
+                return FALSE;
+            }
+            break;
+
+        case WINED3D_LOCATION_SYSMEM:
+            if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+            {
+                struct wined3d_bo_address data = {0, texture->resource.heap_memory};
+
+                data.addr += sub_resource->offset;
+                if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+                    wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+                else
+                    wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+
+                texture1d_download_data(texture, sub_resource_idx, context, &data);
+                ++texture->download_count;
+            }
+            else
+            {
+                FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
+                        wined3d_debug_location(sub_resource->locations));
+                return FALSE;
+            }
+            break;
+
+        case WINED3D_LOCATION_BUFFER:
+            if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+            {
+                struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
+
+                if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
+                    wined3d_texture_bind_and_dirtify(texture, context, FALSE);
+                else
+                    wined3d_texture_bind_and_dirtify(texture, context, TRUE);
+
+                texture1d_download_data(texture, sub_resource_idx, context, &data);
+            }
+            else
+            {
+                FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
+                        wined3d_debug_location(sub_resource->locations));
+                return FALSE;
+            }
+            break;
+
+        default:
+            FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
+                    wined3d_debug_location(sub_resource->locations));
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+static const struct wined3d_texture_ops texture1d_ops =
+{
+    texture1d_load_location,
+};
+
 static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
         unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device,
         void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_texture_ops *texture_ops)
@@ -2443,6 +2610,46 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
 
     list_init(&texture->renderbuffers);
 
+    switch (desc->resource_type)
+    {
+        case WINED3D_RTYPE_TEXTURE_1D:
+            if (layer_count > 1)
+                texture->target = GL_TEXTURE_1D_ARRAY;
+            else
+                texture->target = GL_TEXTURE_1D;
+            break;
+
+        case WINED3D_RTYPE_TEXTURE_2D:
+            if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
+            {
+                texture->target = GL_TEXTURE_CUBE_MAP_ARB;
+            }
+            else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
+            {
+                if (layer_count > 1)
+                    texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+                else
+                    texture->target = GL_TEXTURE_2D_MULTISAMPLE;
+            }
+            else
+            {
+                if (layer_count > 1)
+                    texture->target = GL_TEXTURE_2D_ARRAY;
+                else
+                    texture->target = GL_TEXTURE_2D;
+            }
+            break;
+
+        case WINED3D_RTYPE_TEXTURE_3D:
+            texture->target = GL_TEXTURE_3D;
+            break;
+
+        default:
+            ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
+            wined3d_texture_cleanup_sync(texture);
+            return WINED3DERR_INVALIDCALL;
+    }
+
     /* Precalculated scaling for 'faked' non power of two texture coords. */
     if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT)
     {
@@ -2451,41 +2658,16 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
         texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS);
         texture->target = GL_TEXTURE_RECTANGLE_ARB;
     }
+    else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
+    {
+        texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
+        texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
+        texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
+    }
     else
     {
-        if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
-        {
-            texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
-            texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
-            texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
-        }
-        else
-        {
-            texture->pow2_matrix[0] = 1.0f;
-            texture->pow2_matrix[5] = 1.0f;
-        }
-        if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
-        {
-            texture->target = GL_TEXTURE_3D;
-        }
-        else if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
-        {
-            texture->target = GL_TEXTURE_CUBE_MAP_ARB;
-        }
-        else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
-        {
-            if (layer_count > 1)
-                texture->target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
-            else
-                texture->target = GL_TEXTURE_2D_MULTISAMPLE;
-        }
-        else
-        {
-            if (layer_count > 1)
-                texture->target = GL_TEXTURE_2D_ARRAY;
-            else
-                texture->target = GL_TEXTURE_2D;
-        }
+        texture->pow2_matrix[0] = 1.0f;
+        texture->pow2_matrix[5] = 1.0f;
     }
     texture->pow2_matrix[10] = 1.0f;
     texture->pow2_matrix[15] = 1.0f;
@@ -2982,6 +3164,7 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
         UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
 {
+    const struct wined3d_texture_ops *texture_ops;
     struct wined3d_texture *object;
     HRESULT hr;
 
@@ -3028,29 +3211,28 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
         }
     }
 
-    if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
-            sub_resources[level_count * layer_count]))))
-        return E_OUTOFMEMORY;
-
     switch (desc->resource_type)
     {
+        case WINED3D_RTYPE_TEXTURE_1D:
+            texture_ops = &texture1d_ops;
+            break;
         case WINED3D_RTYPE_TEXTURE_2D:
-            hr = wined3d_texture_init(object, desc, layer_count, level_count,
-                    flags, device, parent, parent_ops, &texture2d_ops);
+            texture_ops = &texture2d_ops;
             break;
-
         case WINED3D_RTYPE_TEXTURE_3D:
-            hr = wined3d_texture_init(object, desc, layer_count, level_count,
-                    flags, device, parent, parent_ops, &texture3d_ops);
+            texture_ops = &texture3d_ops;
             break;
-
         default:
             ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
-            hr = WINED3DERR_INVALIDCALL;
-            break;
+            return WINED3DERR_INVALIDCALL;
     }
 
-    if (FAILED(hr))
+    if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
+            sub_resources[level_count * layer_count]))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = wined3d_texture_init(object, desc, layer_count,
+            level_count, flags, device, parent, parent_ops, texture_ops)))
     {
         WARN("Failed to initialize texture, returning %#x.\n", hr);
         heap_free(object);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 8b2019d671d..0775f53b7a5 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -4269,6 +4269,7 @@ const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
 #define WINED3D_TO_STR(x) case x: return #x
         WINED3D_TO_STR(WINED3D_RTYPE_NONE);
         WINED3D_TO_STR(WINED3D_RTYPE_BUFFER);
+        WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_1D);
         WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_2D);
         WINED3D_TO_STR(WINED3D_RTYPE_TEXTURE_3D);
 #undef WINED3D_TO_STR
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 05167f4be9c..c98ebfb7ee8 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -59,6 +59,11 @@ static GLenum get_texture_view_target(const struct wined3d_gl_info *gl_info,
         {GL_TEXTURE_2D_MULTISAMPLE,       WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
         {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0,                          GL_TEXTURE_2D_MULTISAMPLE},
         {GL_TEXTURE_2D_MULTISAMPLE_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
+
+        {GL_TEXTURE_1D,       0,                          GL_TEXTURE_1D},
+        {GL_TEXTURE_1D,       WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
+        {GL_TEXTURE_1D_ARRAY, 0,                          GL_TEXTURE_1D},
+        {GL_TEXTURE_1D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_1D_ARRAY},
     };
     unsigned int i;
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a25d984a4f5..cdea1125f36 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2859,11 +2859,13 @@ struct wined3d_state
 
 struct wined3d_dummy_textures
 {
+    GLuint tex_1d;
     GLuint tex_2d;
     GLuint tex_rect;
     GLuint tex_3d;
     GLuint tex_cube;
     GLuint tex_cube_array;
+    GLuint tex_1d_array;
     GLuint tex_2d_array;
     GLuint tex_buffer;
     GLuint tex_2d_ms;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 4e390cc960a..446e98b96f1 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -690,8 +690,9 @@ enum wined3d_resource_type
 {
     WINED3D_RTYPE_NONE                      = 0,
     WINED3D_RTYPE_BUFFER                    = 1,
-    WINED3D_RTYPE_TEXTURE_2D                = 2,
-    WINED3D_RTYPE_TEXTURE_3D                = 3,
+    WINED3D_RTYPE_TEXTURE_1D                = 2,
+    WINED3D_RTYPE_TEXTURE_2D                = 3,
+    WINED3D_RTYPE_TEXTURE_3D                = 4,
 };
 
 enum wined3d_query_type
-- 
2.11.0




More information about the wine-devel mailing list