mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 00:10:10 +01:00
v3d: Add support for texturing from linear.
Just like vc4, we have to support linear shared BOs for X11 on arbitrary displays. When we're faced with a request to texture from one of those, make a shadow image that we copy using the TFU at the start of the draw call.
This commit is contained in:
parent
976ea90bdc
commit
6ad9e8690d
6 changed files with 110 additions and 3 deletions
|
|
@ -95,6 +95,12 @@ struct v3d_sampler_view {
|
|||
uint8_t texture_shader_state[32];
|
||||
/* V3D 4.x: Texture state struct. */
|
||||
struct v3d_bo *bo;
|
||||
|
||||
/* Actual texture to be read by this sampler view. May be different
|
||||
* from base.texture in the case of having a shadow tiled copy of a
|
||||
* raster texture.
|
||||
*/
|
||||
struct pipe_resource *texture;
|
||||
};
|
||||
|
||||
struct v3d_sampler_state {
|
||||
|
|
|
|||
|
|
@ -828,6 +828,61 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
v3d_update_shadow_texture(struct pipe_context *pctx,
|
||||
struct pipe_sampler_view *pview)
|
||||
{
|
||||
struct v3d_sampler_view *view = v3d_sampler_view(pview);
|
||||
struct v3d_resource *shadow = v3d_resource(view->texture);
|
||||
struct v3d_resource *orig = v3d_resource(pview->texture);
|
||||
|
||||
assert(view->texture != pview->texture);
|
||||
|
||||
if (shadow->writes == orig->writes && orig->bo->private)
|
||||
return;
|
||||
|
||||
perf_debug("Updating %dx%d@%d shadow for linear texture\n",
|
||||
orig->base.width0, orig->base.height0,
|
||||
pview->u.tex.first_level);
|
||||
|
||||
for (int i = 0; i <= shadow->base.last_level; i++) {
|
||||
unsigned width = u_minify(shadow->base.width0, i);
|
||||
unsigned height = u_minify(shadow->base.height0, i);
|
||||
struct pipe_blit_info info = {
|
||||
.dst = {
|
||||
.resource = &shadow->base,
|
||||
.level = i,
|
||||
.box = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.depth = 1,
|
||||
},
|
||||
.format = shadow->base.format,
|
||||
},
|
||||
.src = {
|
||||
.resource = &orig->base,
|
||||
.level = pview->u.tex.first_level + i,
|
||||
.box = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.depth = 1,
|
||||
},
|
||||
.format = orig->base.format,
|
||||
},
|
||||
.mask = util_format_get_mask(orig->base.format),
|
||||
};
|
||||
pctx->blit(pctx, &info);
|
||||
}
|
||||
|
||||
shadow->writes = orig->writes;
|
||||
}
|
||||
|
||||
static struct pipe_surface *
|
||||
v3d_create_surface(struct pipe_context *pctx,
|
||||
struct pipe_resource *ptex,
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ void v3d_resource_screen_init(struct pipe_screen *pscreen);
|
|||
void v3d_resource_context_init(struct pipe_context *pctx);
|
||||
struct pipe_resource *v3d_resource_create(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *tmpl);
|
||||
void v3d_update_shadow_texture(struct pipe_context *pctx,
|
||||
struct pipe_sampler_view *view);
|
||||
uint32_t v3d_layer_offset(struct pipe_resource *prsc, uint32_t level,
|
||||
uint32_t layer);
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ write_tmu_p0(struct v3d_job *job,
|
|||
int unit = v3d_tmu_config_data_get_unit(data);
|
||||
struct pipe_sampler_view *psview = texstate->textures[unit];
|
||||
struct v3d_sampler_view *sview = v3d_sampler_view(psview);
|
||||
struct v3d_resource *rsc = v3d_resource(psview->texture);
|
||||
struct v3d_resource *rsc = v3d_resource(sview->texture);
|
||||
|
||||
cl_aligned_reloc(&job->indirect, uniforms, sview->bo,
|
||||
v3d_tmu_config_data_get_value(data));
|
||||
|
|
|
|||
|
|
@ -126,9 +126,13 @@ v3d_predraw_check_stage_inputs(struct pipe_context *pctx,
|
|||
|
||||
/* Flush writes to textures we're sampling. */
|
||||
for (int i = 0; i < v3d->tex[s].num_textures; i++) {
|
||||
struct pipe_sampler_view *view = v3d->tex[s].textures[i];
|
||||
if (!view)
|
||||
struct pipe_sampler_view *pview = v3d->tex[s].textures[i];
|
||||
if (!pview)
|
||||
continue;
|
||||
struct v3d_sampler_view *view = v3d_sampler_view(pview);
|
||||
|
||||
if (view->texture != view->base.texture)
|
||||
v3d_update_shadow_texture(pctx, &view->base);
|
||||
|
||||
v3d_flush_jobs_writing_resource(v3d, view->texture);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -746,6 +746,7 @@ v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
|
|||
struct v3d_context *v3d = v3d_context(pctx);
|
||||
struct v3d_screen *screen = v3d->screen;
|
||||
struct v3d_sampler_view *so = CALLOC_STRUCT(v3d_sampler_view);
|
||||
struct v3d_resource *rsc = v3d_resource(prsc);
|
||||
|
||||
if (!so)
|
||||
return NULL;
|
||||
|
|
@ -772,6 +773,44 @@ v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
|
|||
so->base.reference.count = 1;
|
||||
so->base.context = pctx;
|
||||
|
||||
/* V3D still doesn't support sampling from raster textures, so we will
|
||||
* have to copy to a temporary tiled texture.
|
||||
*/
|
||||
if (!rsc->tiled) {
|
||||
struct v3d_resource *shadow_parent = rsc;
|
||||
struct pipe_resource tmpl = {
|
||||
.target = prsc->target,
|
||||
.format = prsc->format,
|
||||
.width0 = u_minify(prsc->width0,
|
||||
cso->u.tex.first_level),
|
||||
.height0 = u_minify(prsc->height0,
|
||||
cso->u.tex.first_level),
|
||||
.depth0 = 1,
|
||||
.array_size = 1,
|
||||
.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
|
||||
.last_level = cso->u.tex.last_level - cso->u.tex.first_level,
|
||||
.nr_samples = prsc->nr_samples,
|
||||
};
|
||||
|
||||
/* Create the shadow texture. The rest of the sampler view
|
||||
* setup will use the shadow.
|
||||
*/
|
||||
prsc = v3d_resource_create(pctx->screen, &tmpl);
|
||||
if (!prsc) {
|
||||
free(so);
|
||||
return NULL;
|
||||
}
|
||||
rsc = v3d_resource(prsc);
|
||||
|
||||
/* Flag it as needing update of the contents from the parent. */
|
||||
rsc->writes = shadow_parent->writes - 1;
|
||||
assert(rsc->tiled);
|
||||
|
||||
so->texture = prsc;
|
||||
} else {
|
||||
pipe_resource_reference(&so->texture, prsc);
|
||||
}
|
||||
|
||||
void *map;
|
||||
#if V3D_VERSION >= 40
|
||||
so->bo = v3d_bo_alloc(v3d->screen,
|
||||
|
|
@ -859,6 +898,7 @@ v3d_sampler_view_destroy(struct pipe_context *pctx,
|
|||
|
||||
v3d_bo_unreference(&sview->bo);
|
||||
pipe_resource_reference(&psview->texture, NULL);
|
||||
pipe_resource_reference(&sview->texture, NULL);
|
||||
free(psview);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue