diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index d88282fea9b..a452e0b586a 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -78,7 +78,20 @@ void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture } /* Context activation is done by the caller. */ -void wined3d_volume_load(const struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) +static void wined3d_volume_allocate_texture(const struct wined3d_volume *volume, + const struct wined3d_context *context) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_format *format = volume->resource.format; + + GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, volume->texture_level, format->glInternal, + volume->resource.width, volume->resource.height, volume->resource.depth, + 0, format->glFormat, format->glType, NULL)); + checkGLcall("glTexImage3D"); +} + +/* Context activation is done by the caller. */ +void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; @@ -89,19 +102,28 @@ void wined3d_volume_load(const struct wined3d_volume *volume, struct wined3d_con volume_bind_and_dirtify(volume, context); - GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, volume->texture_level, format->glInternal, + if (!(volume->flags & WINED3D_VFLAG_ALLOCATED)) + { + wined3d_volume_allocate_texture(volume, context); + volume->flags |= WINED3D_VFLAG_ALLOCATED; + } + + GL_EXTCALL(glTexSubImage3DEXT(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0, volume->resource.width, volume->resource.height, volume->resource.depth, - 0, format->glFormat, format->glType, volume->resource.allocatedMemory)); - checkGLcall("glTexImage3D"); + format->glFormat, format->glType, volume->resource.allocatedMemory)); + checkGLcall("glTexSubImage3D"); } /* Do not call while under the GL lock. */ static void volume_unload(struct wined3d_resource *resource) { + struct wined3d_volume *volume = volume_from_resource(resource); + TRACE("texture %p.\n", resource); /* The whole content is shadowed on This->resource.allocatedMemory, and * the texture name is managed by the VolumeTexture container. */ + volume->flags &= ~WINED3D_VFLAG_ALLOCATED; resource_unload(resource); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ba7f03f942e..564ab6789d8 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2051,6 +2051,7 @@ void wined3d_texture_apply_state_changes(struct wined3d_texture *texture, void wined3d_texture_set_dirty(struct wined3d_texture *texture, BOOL dirty) DECLSPEC_HIDDEN; #define WINED3D_VFLAG_LOCKED 0x00000001 +#define WINED3D_VFLAG_ALLOCATED 0x00000002 struct wined3d_volume { @@ -2070,7 +2071,7 @@ static inline struct wined3d_volume *volume_from_resource(struct wined3d_resourc } void volume_add_dirty_box(struct wined3d_volume *volume, const struct wined3d_box *dirty_box) DECLSPEC_HIDDEN; -void wined3d_volume_load(const struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) DECLSPEC_HIDDEN; +void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) DECLSPEC_HIDDEN; void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container) DECLSPEC_HIDDEN; struct wined3d_surface_dib