struct pipe_transfer *ptrans;
enum pipe_format format = prsc->format;
uint32_t op = 0;
+ uint32_t offset;
char *buf;
int ret = 0;
*pptrans = ptrans;
- 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;
+ if (rsc->layer_first) {
+ offset = slice->offset +
+ box->y / util_format_get_blockheight(format) * ptrans->stride +
+ box->x / util_format_get_blockwidth(format) * rsc->cpp +
+ box->z * rsc->layer_size;
+ } else {
+ offset = slice->offset +
+ box->y / util_format_get_blockheight(format) * ptrans->stride +
+ box->x / util_format_get_blockwidth(format) * rsc->cpp +
+ box->z * slice->size0;
+ }
+
+ return buf + offset;
fail:
fd_resource_transfer_unmap(pctx, ptrans);
uint32_t width = prsc->width0;
uint32_t height = prsc->height0;
uint32_t depth = prsc->depth0;
+ /* in layer_first layout, the level (slice) contains just one
+ * layer (since in fact the layer contains the slices)
+ */
+ uint32_t layers_in_level = rsc->layer_first ? 1 : prsc->array_size;
for (level = 0; level <= prsc->last_level; level++) {
struct fd_resource_slice *slice = fd_resource_slice(rsc, level);
- slice->pitch = align(width, 32);
+ slice->pitch = width = align(width, 32);
slice->offset = size;
- slice->size0 = align(slice->pitch * height * rsc->cpp, alignment);
+ /* 1d array, 2d array, 3d textures (but not cube!) must all have the
+ * same layer size for each miplevel on a3xx. These are also the
+ * targets that have non-1 alignment.
+ */
+ if (level == 0 || layers_in_level == 1 || alignment == 1)
+ slice->size0 = align(slice->pitch * height * rsc->cpp, alignment);
+ else
+ slice->size0 = rsc->slices[0].size0;
- size += slice->size0 * depth * prsc->array_size;
+ size += slice->size0 * depth * layers_in_level;
width = u_minify(width, 1);
height = u_minify(height, 1);
assert(rsc->cpp);
+ if (is_a4xx(fd_screen(pscreen))) {
+ switch (tmpl->target) {
+ case PIPE_TEXTURE_3D:
+ /* TODO 3D_ARRAY? */
+ rsc->layer_first = false;
+ break;
+ default:
+ rsc->layer_first = true;
+ break;
+ }
+ }
+
size = setup_slices(rsc, slice_alignment(pscreen, tmpl));
+ if (rsc->layer_first) {
+ rsc->layer_size = align(size, 4096);
+ size = rsc->layer_size * prsc->array_size;
+ }
+
realloc_bo(rsc, size);
if (!rsc->bo)
goto fail;