Signed-off-by: Sven Hesse shesse@codeweavers.com --- dlls/wined3d/texture.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index ddbe340dc8..03871d7158 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1623,6 +1623,41 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s context, box, data, row_pitch, slice_pitch); }
+/* This call just uploads data, the caller is responsible for binding the + * correct texture. */ +/* Context activation is done by the caller. */ +static void texture1d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_box *box, + const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) +{ + FIXME("Not implemented.\n"); +} + +/* 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) +{ + FIXME("Not implemented.\n"); + return FALSE; +} + +static void texture1d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) +{ + FIXME("Not implemented.\n"); +} + +static void texture1d_cleanup_sub_resources(struct wined3d_texture *texture) +{ +} + +static const struct wined3d_texture_ops texture1d_ops = +{ + texture1d_upload_data, + texture1d_load_location, + texture1d_prepare_texture, + texture1d_cleanup_sub_resources, +}; + static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_context *context, const struct wined3d_box *box, const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch) @@ -2036,6 +2071,123 @@ static const struct wined3d_resource_ops texture_resource_ops = texture_resource_sub_resource_unmap, };
+static HRESULT texture1d_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) +{ + struct wined3d_device_parent *device_parent = device->device_parent; + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; + struct wined3d_surface *surfaces; + unsigned int i, j; + HRESULT hr; + + if (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. */ + if (WINED3DFMT_UNKNOWN >= desc->format) + { + WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); + return WINED3DERR_INVALIDCALL; + } + + if (desc->usage & WINED3DUSAGE_DYNAMIC && desc->pool == WINED3D_POOL_MANAGED) + FIXME("Trying to create a managed texture with dynamic usage.\n"); + + if ((desc->width & (desc->width - 1)) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) + { + WARN("Attempted to create a NPOT 1D texture (%u) without GL support.\n", desc->width); + return WINED3DERR_INVALIDCALL; + } + + if (desc->width > gl_info->limits.texture_size && (desc->usage & WINED3DUSAGE_TEXTURE)) + { + WARN("Dimensions (%ux) exceed the maximum texture size.\n", desc->width); + return WINED3DERR_NOTAVAILABLE; + } + + /* Calculate levels for mip mapping. */ + if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) + { + if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) + { + WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + } + + if (level_count != 1) + { + WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + } + } + + if (FAILED(hr = wined3d_texture_init(texture, &texture1d_ops, layer_count, level_count, desc, + flags, device, parent, parent_ops, &texture_resource_ops))) + { + WARN("Failed to initialize texture, returning %#x.\n", hr); + return hr; + } + + texture->pow2_matrix[0] = 1.0f; + texture->pow2_matrix[5] = 1.0f; + texture->pow2_matrix[10] = 1.0f; + texture->pow2_matrix[15] = 1.0f; + texture->target = (layer_count > 1) ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D; + + if (wined3d_texture_use_pbo(texture, gl_info)) + texture->resource.map_binding = WINED3D_LOCATION_BUFFER; + + if (level_count > ~(SIZE_T)0 / layer_count + || !(surfaces = wined3d_calloc(level_count * layer_count, sizeof(*surfaces)))) + { + wined3d_texture_cleanup_sync(texture); + return E_OUTOFMEMORY; + } + + /* Generate all the surfaces. */ + for (i = 0; i < texture->level_count; ++i) + { + for (j = 0; j < texture->layer_count; ++j) + { + struct wined3d_texture_sub_resource *sub_resource; + unsigned int idx = j * texture->level_count + i; + struct wined3d_surface *surface; + + surface = &surfaces[idx]; + surface->container = texture; + surface->texture_target = texture->target; + surface->texture_level = i; + surface->texture_layer = j; + list_init(&surface->renderbuffers); + list_init(&surface->overlays); + + sub_resource = &texture->sub_resources[idx]; + sub_resource->locations = WINED3D_LOCATION_DISCARDED; + sub_resource->u.surface = surface; + + if (FAILED(hr = device_parent->ops->surface_created(device_parent, + texture, idx, &sub_resource->parent, &sub_resource->parent_ops))) + { + WARN("Failed to create surface parent, hr %#x.\n", hr); + sub_resource->parent = NULL; + wined3d_texture_cleanup_sync(texture); + return hr; + } + + TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops); + + TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface); + } + } + + return WINED3D_OK; +} + static HRESULT 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) @@ -2965,6 +3117,10 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
switch (desc->resource_type) { + case WINED3D_RTYPE_TEXTURE_1D: + hr = texture1d_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); + break; + case WINED3D_RTYPE_TEXTURE_2D: hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); break;