struct svga_winsys_surface * svga_texture_view_surface(struct svga_context *svga, struct svga_texture *tex, unsigned bind_flags, SVGA3dSurfaceFlags flags, SVGA3dSurfaceFormat format, unsigned start_mip, unsigned num_mip, int layer_pick, unsigned num_layers, int zslice_pick, struct svga_host_surface_cache_key *key) /* OUT */ { struct svga_screen *ss = svga_screen(svga->pipe.screen); struct svga_winsys_surface *handle; uint32_t i, j; unsigned z_offset = 0; SVGA_DBG(DEBUG_PERF, "svga: Create surface view: layer %d zslice %d mips %d..%d\n", layer_pick, zslice_pick, start_mip, start_mip+num_mip-1); key->flags = flags; key->format = format; key->numMipLevels = num_mip; key->size.width = u_minify(tex->b.b.width0, start_mip); key->size.height = u_minify(tex->b.b.height0, start_mip); key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1; key->cachable = 1; key->arraySize = 1; key->numFaces = 1; key->sampleCount = tex->b.b.nr_samples; if (key->sampleCount > 1) { key->flags |= SVGA3D_SURFACE_MASKABLE_ANTIALIAS; } if (tex->b.b.target == PIPE_TEXTURE_CUBE && layer_pick < 0) { key->flags |= SVGA3D_SURFACE_CUBEMAP; key->numFaces = 6; } else if (tex->b.b.target == PIPE_TEXTURE_1D_ARRAY || tex->b.b.target == PIPE_TEXTURE_2D_ARRAY) { key->arraySize = num_layers; } if (key->format == SVGA3D_FORMAT_INVALID) { key->cachable = 0; return NULL; } SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n"); handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT, key); if (!handle) { key->cachable = 0; return NULL; } SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle); if (layer_pick < 0) layer_pick = 0; if (zslice_pick >= 0) z_offset = zslice_pick; for (i = 0; i < key->numMipLevels; i++) { for (j = 0; j < key->numFaces * key->arraySize; j++) { if (svga_is_texture_level_defined(tex, j + layer_pick, i + start_mip)) { unsigned depth = (zslice_pick < 0 ? u_minify(tex->b.b.depth0, i + start_mip) : 1); svga_texture_copy_handle(svga, tex->handle, 0, 0, z_offset, i + start_mip, j + layer_pick, handle, 0, 0, 0, i, j, u_minify(tex->b.b.width0, i + start_mip), u_minify(tex->b.b.height0, i + start_mip), depth); } } } return handle; }
struct svga_winsys_surface * svga_texture_view_surface(struct svga_context *svga, struct svga_texture *tex, SVGA3dSurfaceFlags flags, SVGA3dSurfaceFormat format, unsigned start_mip, unsigned num_mip, int face_pick, int zslice_pick, struct svga_host_surface_cache_key *key) /* OUT */ { struct svga_screen *ss = svga_screen(svga->pipe.screen); struct svga_winsys_surface *handle; uint32_t i, j; unsigned z_offset = 0; SVGA_DBG(DEBUG_PERF, "svga: Create surface view: face %d zslice %d mips %d..%d\n", face_pick, zslice_pick, start_mip, start_mip+num_mip-1); key->flags = flags; key->format = format; key->numMipLevels = num_mip; key->size.width = u_minify(tex->b.b.width0, start_mip); key->size.height = u_minify(tex->b.b.height0, start_mip); key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1; key->cachable = 1; assert(key->size.depth == 1); if (tex->b.b.target == PIPE_TEXTURE_CUBE && face_pick < 0) { key->flags |= SVGA3D_SURFACE_CUBEMAP; key->numFaces = 6; } else { key->numFaces = 1; } if (key->format == SVGA3D_FORMAT_INVALID) { key->cachable = 0; return NULL; } SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n"); handle = svga_screen_surface_create(ss, key); if (!handle) { key->cachable = 0; return NULL; } SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle); if (face_pick < 0) face_pick = 0; if (zslice_pick >= 0) z_offset = zslice_pick; for (i = 0; i < key->numMipLevels; i++) { for (j = 0; j < key->numFaces; j++) { if (svga_is_texture_level_defined(tex, j + face_pick, i + start_mip)) { unsigned depth = (zslice_pick < 0 ? u_minify(tex->b.b.depth0, i + start_mip) : 1); svga_texture_copy_handle(svga, tex->handle, 0, 0, z_offset, i + start_mip, j + face_pick, handle, 0, 0, 0, i, j, u_minify(tex->b.b.width0, i + start_mip), u_minify(tex->b.b.height0, i + start_mip), depth); } } } return handle; }