diff options
Diffstat (limited to 'src/gallium/drivers/svga/svga_sampler_view.c')
-rw-r--r-- | src/gallium/drivers/svga/svga_sampler_view.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/gallium/drivers/svga/svga_sampler_view.c b/src/gallium/drivers/svga/svga_sampler_view.c new file mode 100644 index 00000000000..5386db7d1b4 --- /dev/null +++ b/src/gallium/drivers/svga/svga_sampler_view.c @@ -0,0 +1,199 @@ +/********************************************************** + * Copyright 2008-2009 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + **********************************************************/ + +#include "svga_cmd.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "os/os_thread.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "svga_screen.h" +#include "svga_context.h" +#include "svga_resource_texture.h" +#include "svga_sampler_view.h" +#include "svga_winsys.h" +#include "svga_debug.h" +#include "svga_surface.h" + +#include <util/u_string.h> + + +struct svga_sampler_view * +svga_get_tex_sampler_view(struct pipe_context *pipe, + struct pipe_resource *pt, + unsigned min_lod, unsigned max_lod) +{ + struct svga_screen *ss = svga_screen(pt->screen); + struct svga_texture *tex = svga_texture(pt); + struct svga_sampler_view *sv = NULL; + SVGA3dSurfaceFormat format = svga_translate_format(pt->format); + boolean view = TRUE; + + assert(pt); + assert(min_lod >= 0); + assert(min_lod <= max_lod); + assert(max_lod <= pt->last_level); + + + /* Is a view needed */ + { + /* + * Can't control max lod. For first level views and when we only + * look at one level we disable mip filtering to achive the same + * results as a view. + */ + if (min_lod == 0 && max_lod >= pt->last_level) + view = FALSE; + + if (util_format_is_s3tc(pt->format) && view) { + format = svga_translate_format_render(pt->format); + } + + if (ss->debug.no_sampler_view) + view = FALSE; + + if (ss->debug.force_sampler_view) + view = TRUE; + } + + /* First try the cache */ + if (view) { + pipe_mutex_lock(ss->tex_mutex); + if (tex->cached_view && + tex->cached_view->min_lod == min_lod && + tex->cached_view->max_lod == max_lod) { + svga_sampler_view_reference(&sv, tex->cached_view); + pipe_mutex_unlock(ss->tex_mutex); + SVGA_DBG(DEBUG_VIEWS, "svga: Sampler view: reuse %p, %u %u, last %u\n", + pt, min_lod, max_lod, pt->last_level); + svga_validate_sampler_view(svga_context(pipe), sv); + return sv; + } + pipe_mutex_unlock(ss->tex_mutex); + } + + sv = CALLOC_STRUCT(svga_sampler_view); + pipe_reference_init(&sv->reference, 1); + pipe_resource_reference(&sv->texture, pt); + sv->min_lod = min_lod; + sv->max_lod = max_lod; + + /* No view needed just use the whole texture */ + if (!view) { + SVGA_DBG(DEBUG_VIEWS, + "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", + pt, min_lod, max_lod, + max_lod - min_lod + 1, + pt->width0, + pt->height0, + pt->depth0, + pt->last_level); + sv->key.cachable = 0; + sv->handle = tex->handle; + return sv; + } + + SVGA_DBG(DEBUG_VIEWS, + "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", + pt, min_lod, max_lod, + max_lod - min_lod + 1, + pt->width0, + pt->height0, + pt->depth0, + pt->last_level); + + sv->age = tex->age; + sv->handle = svga_texture_view_surface(pipe, tex, format, + min_lod, + max_lod - min_lod + 1, + -1, -1, + &sv->key); + + if (!sv->handle) { + assert(0); + sv->key.cachable = 0; + sv->handle = tex->handle; + return sv; + } + + pipe_mutex_lock(ss->tex_mutex); + svga_sampler_view_reference(&tex->cached_view, sv); + pipe_mutex_unlock(ss->tex_mutex); + + return sv; +} + +void +svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v) +{ + struct svga_texture *tex = svga_texture(v->texture); + unsigned numFaces; + unsigned age = 0; + int i, k; + + assert(svga); + + if (v->handle == tex->handle) + return; + + age = tex->age; + + if(tex->b.b.target == PIPE_TEXTURE_CUBE) + numFaces = 6; + else + numFaces = 1; + + for (i = v->min_lod; i <= v->max_lod; i++) { + for (k = 0; k < numFaces; k++) { + if (v->age < tex->view_age[i]) + svga_texture_copy_handle(svga, NULL, + tex->handle, 0, 0, 0, i, k, + v->handle, 0, 0, 0, i - v->min_lod, k, + u_minify(tex->b.b.width0, i), + u_minify(tex->b.b.height0, i), + u_minify(tex->b.b.depth0, i)); + } + } + + v->age = age; +} + +void +svga_destroy_sampler_view_priv(struct svga_sampler_view *v) +{ + struct svga_texture *tex = svga_texture(v->texture); + + if(v->handle != tex->handle) { + struct svga_screen *ss = svga_screen(v->texture->screen); + SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle); + svga_screen_surface_destroy(ss, &v->key, &v->handle); + } + pipe_resource_reference(&v->texture, NULL); + FREE(v); +} |