static void svga_texture_destroy(struct pipe_screen *screen, struct pipe_resource *pt) { struct svga_screen *ss = svga_screen(screen); struct svga_texture *tex = svga_texture(pt); ss->texture_timestamp++; svga_sampler_view_reference(&tex->cached_view, NULL); /* DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); */ SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle); svga_screen_surface_destroy(ss, &tex->key, &tex->handle); ss->hud.total_resource_bytes -= tex->size; FREE(tex->defined); FREE(tex->rendered_to); FREE(tex); assert(ss->hud.num_resources > 0); if (ss->hud.num_resources > 0) ss->hud.num_resources--; }
void svga_cleanup_tss_binding(struct svga_context *svga) { int i; unsigned count = MAX2( svga->curr.num_textures, svga->state.hw_draw.num_views ); for (i = 0; i < count; i++) { struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; svga_sampler_view_reference(&view->v, NULL); pipe_texture_reference( &svga->curr.texture[i], NULL ); pipe_texture_reference( &view->texture, NULL ); view->dirty = 1; } }
static void svga_texture_destroy(struct pipe_screen *screen, struct pipe_resource *pt) { struct svga_screen *ss = svga_screen(screen); struct svga_texture *tex = (struct svga_texture *)pt; ss->texture_timestamp++; svga_sampler_view_reference(&tex->cached_view, NULL); /* DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); */ SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle); svga_screen_surface_destroy(ss, &tex->key, &tex->handle); FREE(tex); }
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_context *svga = svga_context(pipe); struct svga_screen *ss = svga_screen(pipe->screen); struct svga_texture *tex = svga_texture(pt); struct svga_sampler_view *sv = NULL; SVGA3dSurfaceFlags flags = SVGA3D_SURFACE_HINT_TEXTURE; SVGA3dSurfaceFormat format = svga_translate_format(ss, pt->format, PIPE_BIND_SAMPLER_VIEW); boolean view = TRUE; assert(pt); assert(min_lod <= max_lod); assert(max_lod <= pt->last_level); assert(!svga_have_vgpu10(svga)); /* 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 (ss->debug.no_sampler_view) view = FALSE; if (ss->debug.force_sampler_view) view = TRUE; } /* First try the cache */ if (view) { mtx_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); mtx_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; } mtx_unlock(&ss->tex_mutex); } sv = CALLOC_STRUCT(svga_sampler_view); if (!sv) return NULL; pipe_reference_init(&sv->reference, 1); /* Note: we're not refcounting the texture resource here to avoid * a circular dependency. */ 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; debug_reference(&sv->reference, (debug_reference_descriptor)svga_debug_describe_sampler_view, 0); 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(svga, tex, PIPE_BIND_SAMPLER_VIEW, flags, format, min_lod, max_lod - min_lod + 1, -1, 1, -1, FALSE, &sv->key); if (!sv->handle) { sv->key.cachable = 0; sv->handle = tex->handle; debug_reference(&sv->reference, (debug_reference_descriptor) svga_debug_describe_sampler_view, 0); return sv; } mtx_lock(&ss->tex_mutex); svga_sampler_view_reference(&tex->cached_view, sv); mtx_unlock(&ss->tex_mutex); debug_reference(&sv->reference, (debug_reference_descriptor) svga_debug_describe_sampler_view, 0); return sv; }
static int update_tss_binding(struct svga_context *svga, unsigned dirty ) { unsigned i; unsigned count = MAX2( svga->curr.num_textures, svga->state.hw_draw.num_views ); unsigned min_lod; unsigned max_lod; struct { struct { unsigned unit; struct svga_hw_view_state *view; } bind[PIPE_MAX_SAMPLERS]; unsigned bind_count; } queue; queue.bind_count = 0; for (i = 0; i < count; i++) { const struct svga_sampler_state *s = svga->curr.sampler[i]; struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; /* get min max lod */ if (svga->curr.texture[i]) { min_lod = MAX2(s->view_min_lod, 0); max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level); } else { min_lod = 0; max_lod = 0; } if (view->texture != svga->curr.texture[i] || view->min_lod != min_lod || view->max_lod != max_lod) { svga_sampler_view_reference(&view->v, NULL); pipe_texture_reference( &view->texture, svga->curr.texture[i] ); view->dirty = TRUE; view->min_lod = min_lod; view->max_lod = max_lod; if (svga->curr.texture[i]) view->v = svga_get_tex_sampler_view(&svga->pipe, svga->curr.texture[i], min_lod, max_lod); } if (view->dirty) { queue.bind[queue.bind_count].unit = i; queue.bind[queue.bind_count].view = view; queue.bind_count++; } else if (view->v) { svga_validate_sampler_view(svga, view->v); } } svga->state.hw_draw.num_views = svga->curr.num_textures; if (queue.bind_count) { SVGA3dTextureState *ts; if (SVGA3D_BeginSetTextureState( svga->swc, &ts, queue.bind_count ) != PIPE_OK) goto fail; for (i = 0; i < queue.bind_count; i++) { ts[i].stage = queue.bind[i].unit; ts[i].name = SVGA3D_TS_BIND_TEXTURE; if (queue.bind[i].view->v) { svga->swc->surface_relocation(svga->swc, &ts[i].value, queue.bind[i].view->v->handle, PIPE_BUFFER_USAGE_GPU_READ); } else { ts[i].value = SVGA3D_INVALID_ID; } queue.bind[i].view->dirty = FALSE; } SVGA_FIFOCommitAll( svga->swc ); } return 0; fail: return PIPE_ERROR_OUT_OF_MEMORY; }
static int update_tss_binding(struct svga_context *svga, unsigned dirty ) { boolean reemit = svga->rebind.texture_samplers; unsigned i; unsigned count = MAX2( svga->curr.num_sampler_views, svga->state.hw_draw.num_views ); unsigned min_lod; unsigned max_lod; struct bind_queue queue; queue.bind_count = 0; for (i = 0; i < count; i++) { const struct svga_sampler_state *s = svga->curr.sampler[i]; struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; struct pipe_resource *texture = NULL; /* get min max lod */ if (svga->curr.sampler_views[i]) { min_lod = MAX2(s->view_min_lod, 0); max_lod = MIN2(s->view_max_lod, svga->curr.sampler_views[i]->texture->last_level); texture = svga->curr.sampler_views[i]->texture; } else { min_lod = 0; max_lod = 0; } if (view->texture != texture || view->min_lod != min_lod || view->max_lod != max_lod) { svga_sampler_view_reference(&view->v, NULL); pipe_resource_reference( &view->texture, texture ); view->dirty = TRUE; view->min_lod = min_lod; view->max_lod = max_lod; if (texture) view->v = svga_get_tex_sampler_view(&svga->pipe, texture, min_lod, max_lod); } /* * We need to reemit non-null texture bindings, even when they are not * dirty, to ensure that the resources are paged in. */ if (view->dirty || (reemit && view->v)) { queue.bind[queue.bind_count].unit = i; queue.bind[queue.bind_count].view = view; queue.bind_count++; } if (!view->dirty && view->v) { svga_validate_sampler_view(svga, view->v); } } svga->state.hw_draw.num_views = svga->curr.num_sampler_views; if (queue.bind_count) { SVGA3dTextureState *ts; if (SVGA3D_BeginSetTextureState( svga->swc, &ts, queue.bind_count ) != PIPE_OK) goto fail; for (i = 0; i < queue.bind_count; i++) { struct svga_winsys_surface *handle; ts[i].stage = queue.bind[i].unit; ts[i].name = SVGA3D_TS_BIND_TEXTURE; if (queue.bind[i].view->v) { handle = queue.bind[i].view->v->handle; } else { handle = NULL; } svga->swc->surface_relocation(svga->swc, &ts[i].value, handle, SVGA_RELOC_READ); queue.bind[i].view->dirty = FALSE; } SVGA_FIFOCommitAll( svga->swc ); } svga->rebind.texture_samplers = FALSE; return 0; fail: return PIPE_ERROR_OUT_OF_MEMORY; }