/* Context activation is done by the caller. */ void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context, BOOL srgb_mode) { volume_bind_and_dirtify(volume, context, srgb_mode); if (srgb_mode) { if (!(volume->flags & WINED3D_VFLAG_SRGB_ALLOCATED)) { wined3d_volume_allocate_texture(volume, context, TRUE); volume->flags |= WINED3D_VFLAG_SRGB_ALLOCATED; } wined3d_volume_load_location(volume, context, WINED3D_LOCATION_TEXTURE_SRGB); } else { if (!(volume->flags & WINED3D_VFLAG_ALLOCATED)) { wined3d_volume_allocate_texture(volume, context, FALSE); volume->flags |= WINED3D_VFLAG_ALLOCATED; } wined3d_volume_load_location(volume, context, WINED3D_LOCATION_TEXTURE_RGB); } }
/* Context activation is done by the caller. */ static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) { IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; const struct wined3d_format *format = This->resource.format; TRACE("iface %p, level %u, srgb %#x, format %s (%#x).\n", iface, gl_level, srgb_mode, debug_d3dformat(format->id), format->id); volume_bind_and_dirtify(iface); TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n", GL_TEXTURE_3D, gl_level, format->glInternal, This->currentDesc.Width, This->currentDesc.Height, This->currentDesc.Depth, 0, format->glFormat, format->glType, This->resource.allocatedMemory); ENTER_GL(); GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, gl_level, format->glInternal, This->currentDesc.Width, This->currentDesc.Height, This->currentDesc.Depth, 0, format->glFormat, format->glType, This->resource.allocatedMemory)); checkGLcall("glTexImage3D"); LEAVE_GL(); /* When adding code releasing This->resource.allocatedMemory to save data keep in mind that * GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by default if supported(GL_APPLE_client_storage). * Thus do not release This->resource.allocatedMemory if GL_APPLE_client_storage is supported. */ return WINED3D_OK; }
/* Context activation is done by the caller. */ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume, struct wined3d_context *context, BOOL dest_is_srgb) { struct wined3d_bo_address data; /* Optimizations are possible, but the effort should be put into either * implementing EXT_SRGB_DECODE in the driver or finding out why we * picked the wrong copy for the original upload and fixing that. * * Also keep in mind that we want to avoid using resource.allocatedMemory * for DEFAULT pool surfaces. */ WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n"); data.buffer_object = 0; data.addr = HeapAlloc(GetProcessHeap(), 0, volume->resource.size); if (!data.addr) return; volume_bind_and_dirtify(volume, context, !dest_is_srgb); wined3d_volume_download_data(volume, context, &data); volume_bind_and_dirtify(volume, context, dest_is_srgb); wined3d_volume_upload_data(volume, context, &data); HeapFree(GetProcessHeap(), 0, data.addr); }
/* Context activation is done by the caller. */ void volume_load(const struct wined3d_volume *volume, struct wined3d_context *context, UINT level, BOOL srgb_mode) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; TRACE("volume %p, context %p, level %u, srgb %#x, format %s (%#x).\n", volume, context, level, srgb_mode, debug_d3dformat(format->id), format->id); volume_bind_and_dirtify(volume, context); GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, level, format->glInternal, volume->resource.width, volume->resource.height, volume->resource.depth, 0, format->glFormat, format->glType, volume->resource.allocatedMemory)); checkGLcall("glTexImage3D"); /* When adding code releasing volume->resource.allocatedMemory to save * data keep in mind that GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by * default if supported(GL_APPLE_client_storage). Thus do not release * volume->resource.allocatedMemory if GL_APPLE_client_storage is * supported. */ }
/* Context activation is done by the caller. */ static void wined3d_volume_load_location(struct wined3d_volume *volume, struct wined3d_context *context, DWORD location) { DWORD required_access = volume_access_from_location(location); TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), wined3d_debug_location(volume->locations)); if ((volume->locations & location) == location) { TRACE("Location(s) already up to date.\n"); return; } if ((volume->resource.access_flags & required_access) != required_access) { ERR("Operation requires %#x access, but volume only has %#x.\n", required_access, volume->resource.access_flags); return; } switch (location) { case WINED3D_LOCATION_TEXTURE_RGB: case WINED3D_LOCATION_TEXTURE_SRGB: if ((location == WINED3D_LOCATION_TEXTURE_RGB && !(volume->flags & WINED3D_VFLAG_ALLOCATED)) || (location == WINED3D_LOCATION_TEXTURE_SRGB && !(volume->flags & WINED3D_VFLAG_SRGB_ALLOCATED))) ERR("Trying to load (s)RGB texture without prior allocation.\n"); if (volume->locations & WINED3D_LOCATION_DISCARDED) { TRACE("Volume previously discarded, nothing to do.\n"); wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); } else if (volume->locations & WINED3D_LOCATION_SYSMEM) { struct wined3d_bo_address data = {0, volume->resource.allocatedMemory}; wined3d_volume_upload_data(volume, context, &data); } else if (volume->locations & WINED3D_LOCATION_BUFFER) { struct wined3d_bo_address data = {volume->pbo, NULL}; wined3d_volume_upload_data(volume, context, &data); } else if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) { wined3d_volume_srgb_transfer(volume, context, TRUE); } else if (volume->locations & WINED3D_LOCATION_TEXTURE_SRGB) { wined3d_volume_srgb_transfer(volume, context, FALSE); } else { FIXME("Implement texture loading from %s.\n", wined3d_debug_location(volume->locations)); return; } wined3d_volume_validate_location(volume, location); if (volume->resource.pool == WINED3D_POOL_MANAGED && volume->download_count < 10) wined3d_volume_evict_sysmem(volume); break; case WINED3D_LOCATION_SYSMEM: if (!volume->resource.allocatedMemory || !volume->resource.heap_memory) { ERR("Trying to load WINED3D_LOCATION_SYSMEM without setting it up first.\n"); return; } if (volume->locations & WINED3D_LOCATION_DISCARDED) { TRACE("Volume previously discarded, nothing to do.\n"); wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); } else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { struct wined3d_bo_address data = {0, volume->resource.allocatedMemory}; if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) volume_bind_and_dirtify(volume, context, FALSE); else volume_bind_and_dirtify(volume, context, TRUE); volume->download_count++; wined3d_volume_download_data(volume, context, &data); } else { FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", wined3d_debug_location(volume->locations)); return; } wined3d_volume_validate_location(volume, WINED3D_LOCATION_SYSMEM); break; case WINED3D_LOCATION_BUFFER: if (!volume->pbo || !(volume->flags & WINED3D_VFLAG_PBO)) ERR("Trying to load WINED3D_LOCATION_BUFFER without setting it up first.\n"); if (volume->locations & WINED3D_LOCATION_DISCARDED) { TRACE("Volume previously discarded, nothing to do.\n"); wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_DISCARDED); } else if (volume->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { struct wined3d_bo_address data = {volume->pbo, NULL}; if (volume->locations & WINED3D_LOCATION_TEXTURE_RGB) volume_bind_and_dirtify(volume, context, FALSE); else volume_bind_and_dirtify(volume, context, TRUE); wined3d_volume_download_data(volume, context, &data); } else { FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", wined3d_debug_location(volume->locations)); return; } wined3d_volume_validate_location(volume, WINED3D_LOCATION_BUFFER); break; default: FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), wined3d_debug_location(volume->locations)); } }