static ULONG WINAPI IWineD3DVolumeTextureImpl_Release(IWineD3DVolumeTexture *iface) { IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; ULONG ref; TRACE("(%p) : Releasing from %d\n", This, This->resource.ref); ref = InterlockedDecrement(&This->resource.ref); if (!ref) { volumetexture_cleanup(This); This->resource.parent_ops->wined3d_object_destroyed(This->resource.parent); HeapFree(GetProcessHeap(), 0, This); } return ref; }
HRESULT volumetexture_init(IWineD3DVolumeTextureImpl *texture, UINT width, UINT height, UINT depth, UINT levels, IWineD3DDeviceImpl *device, DWORD usage, WINED3DFORMAT format, WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops #ifdef VBOX_WITH_WDDM , HANDLE *shared_handle , void **pavClientMem #endif ) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_format_desc *format_desc = getFormatDescEntry(format, gl_info); UINT tmp_w, tmp_h, tmp_d; unsigned int i; HRESULT hr; #ifdef VBOX_WITH_WDDM if (shared_handle) { ERR("shared handle support for volume textures not impemented yet, ignoring!"); } #endif /* TODO: It should only be possible to create textures for formats * that are reported as supported. */ if (WINED3DFMT_UNKNOWN >= format) { 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, levels, WINED3DRTYPE_VOLUMETEXTURE, device, 0, usage, format_desc, pool, parent, parent_ops #ifdef VBOX_WITH_WDDM , shared_handle, pavClientMem #endif ); 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; /* Generate all the surfaces. */ tmp_w = width; tmp_h = height; tmp_d = depth; for (i = 0; i < texture->baseTexture.levels; ++i) { /* Create the volume. */ #ifdef VBOX_WITH_WDDM hr = IWineD3DDeviceParent_CreateVolume(device->device_parent, parent, tmp_w, tmp_h, tmp_d, format, pool, usage, &texture->volumes[i] , shared_handle, pavClientMem ? pavClientMem[i] : NULL); #else hr = IWineD3DDeviceParent_CreateVolume(device->device_parent, parent, tmp_w, tmp_h, tmp_d, format, pool, usage, &texture->volumes[i]); #endif if (FAILED(hr)) { ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr); texture->volumes[i] = NULL; volumetexture_cleanup(texture); return hr; } /* Set its container to this texture. */ IWineD3DVolume_SetContainer(texture->volumes[i], (IWineD3DBase *)texture); /* 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); } texture->baseTexture.internal_preload = volumetexture_internal_preload; return WINED3D_OK; }
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; }