static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource) { struct wined3d_volume *volume = volume_from_resource(sub_resource); /* Cleanup the container. */ volume_set_container(volume, NULL); wined3d_volume_decref(volume); }
static void volumetexture_cleanup(IWineD3DBaseTextureImpl *This) { unsigned int i; TRACE("(%p) : Cleaning up.\n", This); for (i = 0; i < This->baseTexture.level_count; ++i) { struct wined3d_resource *sub_resource = This->baseTexture.sub_resources[i]; if (sub_resource) { IWineD3DVolumeImpl *volume = volume_from_resource(sub_resource); /* Cleanup the container. */ volume_set_container(volume, NULL); IWineD3DVolume_Release((IWineD3DVolume *)volume); } } basetexture_cleanup((IWineD3DBaseTextureImpl *)This); }
HRESULT volumetexture_init(IWineD3DBaseTextureImpl *texture, UINT width, UINT height, UINT depth, UINT levels, IWineD3DDeviceImpl *device, DWORD usage, enum wined3d_format_id format_id, WINED3DPOOL pool, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_format *format = wined3d_get_format(gl_info, format_id); UINT tmp_w, tmp_h, tmp_d; unsigned int i; HRESULT hr; /* TODO: It should only be possible to create textures for formats * that are reported as supported. */ if (WINED3DFMT_UNKNOWN >= format_id) { WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); return WINED3DERR_INVALIDCALL; } if (!gl_info->supported[EXT_TEXTURE3D]) { WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture); return WINED3DERR_INVALIDCALL; } /* Calculate levels for mip mapping. */ if (usage & WINED3DUSAGE_AUTOGENMIPMAP) { if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) { WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); return WINED3DERR_INVALIDCALL; } if (levels > 1) { WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n"); return WINED3DERR_INVALIDCALL; } levels = 1; } else if (!levels) { levels = wined3d_log2i(max(max(width, height), depth)) + 1; TRACE("Calculated levels = %u.\n", levels); } texture->lpVtbl = &IWineD3DVolumeTexture_Vtbl; hr = basetexture_init((IWineD3DBaseTextureImpl *)texture, &volumetexture_ops, 1, levels, WINED3DRTYPE_VOLUMETEXTURE, device, usage, format, pool, parent, parent_ops, &volumetexture_resource_ops); if (FAILED(hr)) { WARN("Failed to initialize basetexture, returning %#x.\n", hr); return hr; } /* Is NP2 support for volumes needed? */ texture->baseTexture.pow2Matrix[0] = 1.0f; texture->baseTexture.pow2Matrix[5] = 1.0f; texture->baseTexture.pow2Matrix[10] = 1.0f; texture->baseTexture.pow2Matrix[15] = 1.0f; texture->baseTexture.target = GL_TEXTURE_3D; /* Generate all the surfaces. */ tmp_w = width; tmp_h = height; tmp_d = depth; for (i = 0; i < texture->baseTexture.level_count; ++i) { IWineD3DVolume *volume; /* Create the volume. */ hr = IWineD3DDeviceParent_CreateVolume(device->device_parent, parent, tmp_w, tmp_h, tmp_d, format_id, pool, usage, &volume); if (FAILED(hr)) { ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr); volumetexture_cleanup(texture); return hr; } /* Set its container to this texture. */ volume_set_container((IWineD3DVolumeImpl *)volume, texture); texture->baseTexture.sub_resources[i] = &((IWineD3DVolumeImpl *)volume)->resource; /* Calculate the next mipmap level. */ tmp_w = max(1, tmp_w >> 1); tmp_h = max(1, tmp_h >> 1); tmp_d = max(1, tmp_d >> 1); } return WINED3D_OK; }