static void wined3d_view_invalidate_location(struct wined3d_resource *resource, const struct wined3d_view_desc *desc, DWORD location) { unsigned int i, sub_resource_idx, layer_count; struct wined3d_texture *texture; if (resource->type == WINED3D_RTYPE_BUFFER) { wined3d_buffer_invalidate_location(buffer_from_resource(resource), location); return; } texture = texture_from_resource(resource); sub_resource_idx = desc->u.texture.layer_idx * texture->level_count + desc->u.texture.level_idx; layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? desc->u.texture.layer_count : 1; for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count) wined3d_texture_invalidate_location(texture, sub_resource_idx, location); }
void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *view) { struct wined3d_texture *texture = texture_from_resource(view->resource); unsigned int i, j, layer_count, level_count, base_level, max_level; const struct wined3d_gl_info *gl_info; struct wined3d_context *context; struct gl_texture *gl_tex; DWORD location; BOOL srgb; TRACE("view %p.\n", view); context = context_acquire(view->resource->device, NULL, 0); gl_info = context->gl_info; layer_count = view->desc.u.texture.layer_count; level_count = view->desc.u.texture.level_count; base_level = view->desc.u.texture.level_idx; max_level = base_level + level_count - 1; srgb = !!(texture->flags & WINED3D_TEXTURE_IS_SRGB); location = srgb ? WINED3D_LOCATION_TEXTURE_SRGB : WINED3D_LOCATION_TEXTURE_RGB; for (i = 0; i < layer_count; ++i) wined3d_texture_load_location(texture, i * level_count + base_level, context, location); if (view->gl_view.name) { shader_resource_view_bind_and_dirtify(view, context); } else { wined3d_texture_bind_and_dirtify(texture, context, srgb); gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, base_level); gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, max_level); } if (gl_info->supported[ARB_SAMPLER_OBJECTS]) GL_EXTCALL(glBindSampler(context->active_texture, 0)); gl_tex = wined3d_texture_get_gl_texture(texture, srgb); if (context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) { gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); gl_tex->sampler_desc.srgb_decode = FALSE; } gl_info->fbo_ops.glGenerateMipmap(texture->target); checkGLcall("glGenerateMipMap()"); for (i = 0; i < layer_count; ++i) { for (j = base_level + 1; j <= max_level; ++j) { wined3d_texture_validate_location(texture, i * level_count + j, location); wined3d_texture_invalidate_location(texture, i * level_count + j, ~location); } } if (!view->gl_view.name) { gl_tex->base_level = base_level; gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1); } context_release(context); }
/* Context activation is done by the caller. */ BOOL wined3d_volume_load_location(struct wined3d_volume *volume, struct wined3d_context *context, DWORD location) { DWORD required_access = volume_access_from_location(location); unsigned int sub_resource_idx = volume->texture_level; struct wined3d_texture *texture = volume->container; struct wined3d_texture_sub_resource *sub_resource; sub_resource = &texture->sub_resources[sub_resource_idx]; TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location), wined3d_debug_location(sub_resource->locations)); if ((sub_resource->locations & location) == location) { TRACE("Location(s) already up to date.\n"); return TRUE; } if ((texture->resource.access_flags & required_access) != required_access) { ERR("Operation requires %#x access, but volume only has %#x.\n", required_access, texture->resource.access_flags); return FALSE; } if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location)) return FALSE; if (sub_resource->locations & WINED3D_LOCATION_DISCARDED) { TRACE("Volume previously discarded, nothing to do.\n"); wined3d_texture_validate_location(texture, sub_resource_idx, location); wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED); goto done; } switch (location) { case WINED3D_LOCATION_TEXTURE_RGB: case WINED3D_LOCATION_TEXTURE_SRGB: if (sub_resource->locations & WINED3D_LOCATION_SYSMEM) { struct wined3d_const_bo_address data = {0, volume->resource.heap_memory}; wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_volume_upload_data(volume, context, &data); } else if (sub_resource->locations & WINED3D_LOCATION_BUFFER) { struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL}; wined3d_texture_bind_and_dirtify(texture, context, location == WINED3D_LOCATION_TEXTURE_SRGB); wined3d_volume_upload_data(volume, context, &data); } else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) { wined3d_volume_srgb_transfer(volume, context, TRUE); } else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB) { wined3d_volume_srgb_transfer(volume, context, FALSE); } else { FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations)); return FALSE; } break; case WINED3D_LOCATION_SYSMEM: if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { struct wined3d_bo_address data = {0, volume->resource.heap_memory}; if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) wined3d_texture_bind_and_dirtify(texture, context, FALSE); else wined3d_texture_bind_and_dirtify(texture, context, TRUE); wined3d_volume_download_data(volume, context, &data); ++texture->download_count; } else { FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", wined3d_debug_location(sub_resource->locations)); return FALSE; } break; case WINED3D_LOCATION_BUFFER: if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) wined3d_texture_bind_and_dirtify(texture, context, FALSE); else wined3d_texture_bind_and_dirtify(texture, context, TRUE); wined3d_volume_download_data(volume, context, &data); } else { FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", wined3d_debug_location(sub_resource->locations)); return FALSE; } break; default: FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), wined3d_debug_location(sub_resource->locations)); return FALSE; } done: wined3d_texture_validate_location(texture, sub_resource_idx, location); if (location != WINED3D_LOCATION_SYSMEM && wined3d_volume_can_evict(volume)) wined3d_volume_evict_sysmem(volume); return TRUE; }
static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) { wined3d_resource_free_sysmem(&volume->resource); wined3d_texture_invalidate_location(volume->container, volume->texture_level, WINED3D_LOCATION_SYSMEM); }