if (trans->map) {
if (ptrans->usage & PIPE_TRANSFER_WRITE) {
- vc4_store_tiled_image(rsc->bo->map + slice->offset,
+ vc4_store_tiled_image(rsc->bo->map + slice->offset +
+ ptrans->box.z * rsc->cube_map_stride,
slice->stride,
trans->map, ptrans->stride,
slice->tiling, rsc->cpp,
enum pipe_format format = prsc->format;
char *buf;
- vc4_flush_for_bo(pctx, rsc->bo);
+ if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+ uint32_t size = rsc->bo->size;
+ vc4_bo_unreference(&rsc->bo);
+ rsc->bo = vc4_bo_alloc(vc4->screen, size, "resource");
+ }
+
+ if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED))
+ vc4_flush_for_bo(pctx, rsc->bo);
+
+ if (usage & PIPE_TRANSFER_WRITE)
+ rsc->writes++;
trans = util_slab_alloc(&vc4->transfer_pool);
if (!trans)
return NULL;
- /* XXX: Handle DISCARD_WHOLE_RESOURCE, DONTBLOCK, UNSYNCHRONIZED,
- * DISCARD_WHOLE_RESOURCE, PERSISTENT, COHERENT.
- */
+ /* XXX: Handle DONTBLOCK, DISCARD_RANGE, PERSISTENT, COHERENT. */
/* util_slab_alloc() doesn't zero: */
memset(trans, 0, sizeof(*trans));
trans->map = malloc(ptrans->stride * ptrans->box.height);
if (usage & PIPE_TRANSFER_READ) {
vc4_load_tiled_image(trans->map, ptrans->stride,
- buf + slice->offset,
+ buf + slice->offset +
+ box->z * rsc->cube_map_stride,
slice->stride,
slice->tiling, rsc->cpp,
&ptrans->box);
return buf + slice->offset +
box->y / util_format_get_blockheight(format) * ptrans->stride +
box->x / util_format_get_blockwidth(format) * rsc->cpp +
- box->z * slice->size0;
+ box->z * rsc->cube_map_stride;
}
struct pipe_resource *prsc)
{
struct vc4_resource *rsc = vc4_resource(prsc);
+ pipe_resource_reference(&rsc->shadow_parent, NULL);
vc4_bo_unreference(&rsc->bo);
free(rsc);
}
struct pipe_resource *prsc = &rsc->base.b;
uint32_t width = prsc->width0;
uint32_t height = prsc->height0;
- uint32_t depth = prsc->depth0;
+ uint32_t pot_width = util_next_power_of_two(width);
+ uint32_t pot_height = util_next_power_of_two(height);
uint32_t offset = 0;
uint32_t utile_w = vc4_utile_width(rsc->cpp);
uint32_t utile_h = vc4_utile_height(rsc->cpp);
for (int i = prsc->last_level; i >= 0; i--) {
struct vc4_resource_slice *slice = &rsc->slices[i];
- uint32_t level_width = u_minify(width, i);
- uint32_t level_height = u_minify(height, i);
+
+ uint32_t level_width, level_height;
+ if (i == 0) {
+ level_width = width;
+ level_height = height;
+ } else {
+ level_width = u_minify(pot_width, i);
+ level_height = u_minify(pot_height, i);
+ }
if (rsc->tiled == VC4_TILING_FORMAT_LINEAR) {
slice->tiling = VC4_TILING_FORMAT_LINEAR;
slice->offset = offset;
slice->stride = level_width * rsc->cpp;
- slice->size0 = level_height * slice->stride;
+ slice->size = level_height * slice->stride;
- /* Note, since we have cubes but no 3D, depth is invariant
- * with miplevel.
- */
- offset += slice->size0 * depth;
+ offset += slice->size;
}
/* The texture base pointer that has to point to level 0 doesn't have
for (int i = 0; i <= prsc->last_level; i++)
rsc->slices[i].offset += page_align_offset;
}
+
+ /* Cube map faces appear as whole miptrees at a page-aligned offset
+ * from the first face's miptree.
+ */
+ if (prsc->target == PIPE_TEXTURE_CUBE) {
+ rsc->cube_map_stride = align(rsc->slices[0].offset +
+ rsc->slices[0].size, 4096);
+ }
}
static struct vc4_resource *
return format;
}
-static struct pipe_resource *
+struct pipe_resource *
vc4_resource_create(struct pipe_screen *pscreen,
const struct pipe_resource *tmpl)
{
rsc->bo = vc4_bo_alloc(vc4_screen(pscreen),
rsc->slices[0].offset +
- rsc->slices[0].size0 * prsc->depth0,
+ rsc->slices[0].size +
+ rsc->cube_map_stride * (prsc->array_size - 1),
"resource");
if (!rsc->bo)
goto fail;
util_blitter_save_vertex_buffer_slot(vc4->blitter, vc4->vertexbuf.vb);
util_blitter_save_vertex_elements(vc4->blitter, vc4->vtx);
- util_blitter_save_vertex_shader(vc4->blitter, vc4->prog.vs);
+ util_blitter_save_vertex_shader(vc4->blitter, vc4->prog.bind_vs);
util_blitter_save_rasterizer(vc4->blitter, vc4->rasterizer);
util_blitter_save_viewport(vc4->blitter, &vc4->viewport);
util_blitter_save_scissor(vc4->blitter, &vc4->scissor);
- util_blitter_save_fragment_shader(vc4->blitter, vc4->prog.fs);
+ util_blitter_save_fragment_shader(vc4->blitter, vc4->prog.bind_fs);
util_blitter_save_blend(vc4->blitter, vc4->blend);
util_blitter_save_depth_stencil_alpha(vc4->blitter, vc4->zsa);
util_blitter_save_stencil_ref(vc4->blitter, &vc4->stencil_ref);
render_blit(pctx, &info);
}
+void
+vc4_update_shadow_baselevel_texture(struct pipe_context *pctx,
+ struct pipe_sampler_view *view)
+{
+ struct vc4_resource *shadow = vc4_resource(view->texture);
+ struct vc4_resource *orig = vc4_resource(shadow->shadow_parent);
+ assert(orig);
+
+ if (shadow->writes == orig->writes)
+ return;
+
+ for (int i = 0; i <= shadow->base.b.last_level; i++) {
+ struct pipe_box box = {
+ .x = 0,
+ .y = 0,
+ .z = 0,
+ .width = u_minify(shadow->base.b.width0, i),
+ .height = u_minify(shadow->base.b.height0, i),
+ .depth = 1,
+ };
+
+ util_resource_copy_region(pctx,
+ &shadow->base.b, i, 0, 0, 0,
+ &orig->base.b,
+ view->u.tex.first_level + i,
+ &box);
+ }
+
+ shadow->writes = orig->writes;
+}
+
void
vc4_resource_screen_init(struct pipe_screen *pscreen)
{