1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "svga_cmd.h" 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "pipe/p_state.h" 29bf215546Sopenharmony_ci#include "pipe/p_defines.h" 30bf215546Sopenharmony_ci#include "util/u_inlines.h" 31bf215546Sopenharmony_ci#include "os/os_thread.h" 32bf215546Sopenharmony_ci#include "util/format/u_format.h" 33bf215546Sopenharmony_ci#include "util/u_math.h" 34bf215546Sopenharmony_ci#include "util/u_memory.h" 35bf215546Sopenharmony_ci#include "util/u_string.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "svga_format.h" 38bf215546Sopenharmony_ci#include "svga_screen.h" 39bf215546Sopenharmony_ci#include "svga_context.h" 40bf215546Sopenharmony_ci#include "svga_resource_texture.h" 41bf215546Sopenharmony_ci#include "svga_sampler_view.h" 42bf215546Sopenharmony_ci#include "svga_debug.h" 43bf215546Sopenharmony_ci#include "svga_surface.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_civoid 47bf215546Sopenharmony_cisvga_debug_describe_sampler_view(char *buf, const struct svga_sampler_view *sv) 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci char res[128]; 50bf215546Sopenharmony_ci debug_describe_resource(res, sv->texture); 51bf215546Sopenharmony_ci sprintf(buf, "svga_sampler_view<%s,[%u,%u]>", 52bf215546Sopenharmony_ci res, sv->min_lod, sv->max_lod); 53bf215546Sopenharmony_ci} 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_cistruct svga_sampler_view * 57bf215546Sopenharmony_cisvga_get_tex_sampler_view(struct pipe_context *pipe, 58bf215546Sopenharmony_ci struct pipe_resource *pt, 59bf215546Sopenharmony_ci unsigned min_lod, unsigned max_lod) 60bf215546Sopenharmony_ci{ 61bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 62bf215546Sopenharmony_ci struct svga_screen *ss = svga_screen(pipe->screen); 63bf215546Sopenharmony_ci struct svga_texture *tex = svga_texture(pt); 64bf215546Sopenharmony_ci struct svga_sampler_view *sv = NULL; 65bf215546Sopenharmony_ci SVGA3dSurface1Flags flags = SVGA3D_SURFACE_HINT_TEXTURE; 66bf215546Sopenharmony_ci SVGA3dSurfaceFormat format = svga_translate_format(ss, pt->format, 67bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW); 68bf215546Sopenharmony_ci boolean view = TRUE; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci assert(pt); 71bf215546Sopenharmony_ci assert(min_lod <= max_lod); 72bf215546Sopenharmony_ci assert(max_lod <= pt->last_level); 73bf215546Sopenharmony_ci assert(!svga_have_vgpu10(svga)); 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci /* Is a view needed */ 76bf215546Sopenharmony_ci { 77bf215546Sopenharmony_ci /* 78bf215546Sopenharmony_ci * Can't control max lod. For first level views and when we only 79bf215546Sopenharmony_ci * look at one level we disable mip filtering to achive the same 80bf215546Sopenharmony_ci * results as a view. 81bf215546Sopenharmony_ci */ 82bf215546Sopenharmony_ci if (min_lod == 0 && max_lod >= pt->last_level) 83bf215546Sopenharmony_ci view = FALSE; 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci if (ss->debug.no_sampler_view) 86bf215546Sopenharmony_ci view = FALSE; 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci if (ss->debug.force_sampler_view) 89bf215546Sopenharmony_ci view = TRUE; 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci /* First try the cache */ 93bf215546Sopenharmony_ci if (view) { 94bf215546Sopenharmony_ci mtx_lock(&ss->tex_mutex); 95bf215546Sopenharmony_ci if (tex->cached_view && 96bf215546Sopenharmony_ci tex->cached_view->min_lod == min_lod && 97bf215546Sopenharmony_ci tex->cached_view->max_lod == max_lod) { 98bf215546Sopenharmony_ci svga_sampler_view_reference(&sv, tex->cached_view); 99bf215546Sopenharmony_ci mtx_unlock(&ss->tex_mutex); 100bf215546Sopenharmony_ci SVGA_DBG(DEBUG_VIEWS, "svga: Sampler view: reuse %p, %u %u, last %u\n", 101bf215546Sopenharmony_ci pt, min_lod, max_lod, pt->last_level); 102bf215546Sopenharmony_ci svga_validate_sampler_view(svga_context(pipe), sv); 103bf215546Sopenharmony_ci return sv; 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci mtx_unlock(&ss->tex_mutex); 106bf215546Sopenharmony_ci } 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci sv = CALLOC_STRUCT(svga_sampler_view); 109bf215546Sopenharmony_ci if (!sv) 110bf215546Sopenharmony_ci return NULL; 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci pipe_reference_init(&sv->reference, 1); 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci /* Note: we're not refcounting the texture resource here to avoid 115bf215546Sopenharmony_ci * a circular dependency. 116bf215546Sopenharmony_ci */ 117bf215546Sopenharmony_ci sv->texture = pt; 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci sv->min_lod = min_lod; 120bf215546Sopenharmony_ci sv->max_lod = max_lod; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci /* No view needed just use the whole texture */ 123bf215546Sopenharmony_ci if (!view) { 124bf215546Sopenharmony_ci SVGA_DBG(DEBUG_VIEWS, 125bf215546Sopenharmony_ci "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", 126bf215546Sopenharmony_ci pt, min_lod, max_lod, 127bf215546Sopenharmony_ci max_lod - min_lod + 1, 128bf215546Sopenharmony_ci pt->width0, 129bf215546Sopenharmony_ci pt->height0, 130bf215546Sopenharmony_ci pt->depth0, 131bf215546Sopenharmony_ci pt->last_level); 132bf215546Sopenharmony_ci sv->key.cachable = 0; 133bf215546Sopenharmony_ci sv->handle = tex->handle; 134bf215546Sopenharmony_ci debug_reference(&sv->reference, 135bf215546Sopenharmony_ci (debug_reference_descriptor)svga_debug_describe_sampler_view, 0); 136bf215546Sopenharmony_ci return sv; 137bf215546Sopenharmony_ci } 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci SVGA_DBG(DEBUG_VIEWS, 140bf215546Sopenharmony_ci "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n", 141bf215546Sopenharmony_ci pt, min_lod, max_lod, 142bf215546Sopenharmony_ci max_lod - min_lod + 1, 143bf215546Sopenharmony_ci pt->width0, 144bf215546Sopenharmony_ci pt->height0, 145bf215546Sopenharmony_ci pt->depth0, 146bf215546Sopenharmony_ci pt->last_level); 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci sv->age = tex->age; 149bf215546Sopenharmony_ci sv->handle = svga_texture_view_surface(svga, tex, 150bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW, 151bf215546Sopenharmony_ci flags, format, 152bf215546Sopenharmony_ci min_lod, 153bf215546Sopenharmony_ci max_lod - min_lod + 1, 154bf215546Sopenharmony_ci -1, 1, -1, FALSE, 155bf215546Sopenharmony_ci &sv->key); 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci if (!sv->handle) { 158bf215546Sopenharmony_ci sv->key.cachable = 0; 159bf215546Sopenharmony_ci sv->handle = tex->handle; 160bf215546Sopenharmony_ci debug_reference(&sv->reference, 161bf215546Sopenharmony_ci (debug_reference_descriptor) 162bf215546Sopenharmony_ci svga_debug_describe_sampler_view, 0); 163bf215546Sopenharmony_ci return sv; 164bf215546Sopenharmony_ci } 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci mtx_lock(&ss->tex_mutex); 167bf215546Sopenharmony_ci svga_sampler_view_reference(&tex->cached_view, sv); 168bf215546Sopenharmony_ci mtx_unlock(&ss->tex_mutex); 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci debug_reference(&sv->reference, 171bf215546Sopenharmony_ci (debug_reference_descriptor) 172bf215546Sopenharmony_ci svga_debug_describe_sampler_view, 0); 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci return sv; 175bf215546Sopenharmony_ci} 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_civoid 179bf215546Sopenharmony_cisvga_validate_sampler_view(struct svga_context *svga, 180bf215546Sopenharmony_ci struct svga_sampler_view *v) 181bf215546Sopenharmony_ci{ 182bf215546Sopenharmony_ci struct svga_texture *tex = svga_texture(v->texture); 183bf215546Sopenharmony_ci unsigned numFaces; 184bf215546Sopenharmony_ci unsigned age = 0; 185bf215546Sopenharmony_ci int i; 186bf215546Sopenharmony_ci unsigned k; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci assert(svga); 189bf215546Sopenharmony_ci assert(!svga_have_vgpu10(svga)); 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci if (v->handle == tex->handle) 192bf215546Sopenharmony_ci return; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci age = tex->age; 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci if (tex->b.target == PIPE_TEXTURE_CUBE) 197bf215546Sopenharmony_ci numFaces = 6; 198bf215546Sopenharmony_ci else 199bf215546Sopenharmony_ci numFaces = 1; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci for (i = v->min_lod; i <= v->max_lod; i++) { 202bf215546Sopenharmony_ci for (k = 0; k < numFaces; k++) { 203bf215546Sopenharmony_ci assert(i < ARRAY_SIZE(tex->view_age)); 204bf215546Sopenharmony_ci if (v->age < tex->view_age[i]) 205bf215546Sopenharmony_ci svga_texture_copy_handle(svga, 206bf215546Sopenharmony_ci tex->handle, 0, 0, 0, i, k, 207bf215546Sopenharmony_ci v->handle, 0, 0, 0, i - v->min_lod, k, 208bf215546Sopenharmony_ci u_minify(tex->b.width0, i), 209bf215546Sopenharmony_ci u_minify(tex->b.height0, i), 210bf215546Sopenharmony_ci u_minify(tex->b.depth0, i)); 211bf215546Sopenharmony_ci } 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci v->age = age; 215bf215546Sopenharmony_ci} 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_civoid 219bf215546Sopenharmony_cisvga_destroy_sampler_view_priv(struct svga_sampler_view *v) 220bf215546Sopenharmony_ci{ 221bf215546Sopenharmony_ci struct svga_texture *tex = svga_texture(v->texture); 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci if (v->handle != tex->handle) { 224bf215546Sopenharmony_ci struct svga_screen *ss = svga_screen(v->texture->screen); 225bf215546Sopenharmony_ci SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle); 226bf215546Sopenharmony_ci svga_screen_surface_destroy(ss, &v->key, 227bf215546Sopenharmony_ci svga_was_texture_rendered_to(tex), 228bf215546Sopenharmony_ci &v->handle); 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci /* Note: we're not refcounting the texture resource here to avoid 232bf215546Sopenharmony_ci * a circular dependency. 233bf215546Sopenharmony_ci */ 234bf215546Sopenharmony_ci v->texture = NULL; 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci FREE(v); 237bf215546Sopenharmony_ci} 238