695
695
if (tc->options.parse_renderpass_info) {
696
696
int renderpass_info_idx = next->renderpass_info_idx;
697
697
if (renderpass_info_idx > 0) {
698
/* don't reset if fb state is unflushed */
699
bool fb_no_draw = tc->seen_fb_state && !tc->renderpass_info_recording->has_draw;
700
uint32_t fb_info = tc->renderpass_info_recording->data32[0];
698
701
next->renderpass_info_idx = -1;
699
702
tc_batch_increment_renderpass_info(tc, tc->next, false);
704
tc->renderpass_info_recording->data32[0] = fb_info;
700
705
} else if (tc->renderpass_info_recording->has_draw) {
701
706
tc->renderpass_info_recording->data32[0] = 0;
1460
1465
if (tc->options.parse_renderpass_info) {
1466
/* ensure this is treated as the first fb set if no fb activity has occurred */
1467
if (!tc->renderpass_info_recording->has_draw &&
1468
!tc->renderpass_info_recording->cbuf_clear &&
1469
!tc->renderpass_info_recording->cbuf_load &&
1470
!tc->renderpass_info_recording->zsbuf_load &&
1471
!tc->renderpass_info_recording->zsbuf_clear_partial)
1472
tc->batch_slots[tc->next].first_set_fb = false;
1461
1473
/* store existing zsbuf data for possible persistence */
1462
1474
uint8_t zsbuf = tc->renderpass_info_recording->has_draw ?
3116
3129
unsigned level, unsigned usage,
3117
3130
const struct pipe_box *box,
3118
3131
const void *data, unsigned stride,
3119
unsigned layer_stride)
3132
uintptr_t layer_stride)
3121
3134
struct threaded_context *tc = threaded_context(_pipe);
3124
3137
assert(box->height >= 1);
3125
3138
assert(box->depth >= 1);
3127
3140
size = (box->depth - 1) * layer_stride +
3128
(box->height - 1) * stride +
3141
(box->height - 1) * (uint64_t)stride +
3129
3142
box->width * util_format_get_blocksize(resource->format);
3152
3165
format = util_format_get_depth_only(format);
3153
3166
else if (usage & PIPE_MAP_STENCIL_ONLY)
3154
3167
format = PIPE_FORMAT_S8_UINT;
3155
unsigned stride = util_format_get_stride(format, box->width);
3156
unsigned layer_stride = util_format_get_2d_size(format, stride, box->height);
3157
struct pipe_resource *pres = pipe_buffer_create_with_data(pipe, 0, PIPE_USAGE_STREAM, layer_stride * box->depth, data);
3169
unsigned fmt_stride = util_format_get_stride(format, box->width);
3170
uint64_t fmt_layer_stride = util_format_get_2d_size(format, stride, box->height);
3171
assert(fmt_layer_stride * box->depth <= UINT32_MAX);
3173
struct pipe_resource *pres = pipe_buffer_create(pipe->screen, 0, PIPE_USAGE_STREAM, layer_stride * box->depth);
3174
pipe->buffer_subdata(pipe, pres, PIPE_MAP_WRITE | TC_TRANSFER_MAP_THREADED_UNSYNC, 0, layer_stride * box->depth, data);
3158
3175
struct pipe_box src_box = *box;
3159
3176
src_box.x = src_box.y = src_box.z = 0;
3160
tc->base.resource_copy_region(&tc->base, resource, level, box->x, box->y, box->z, pres, 0, &src_box);
3178
if (fmt_stride == stride && fmt_layer_stride == layer_stride) {
3179
/* if stride matches, single copy is fine*/
3180
tc->base.resource_copy_region(&tc->base, resource, level, box->x, box->y, box->z, pres, 0, &src_box);
3182
/* if stride doesn't match, inline util_copy_box on the GPU and assume the driver will optimize */
3184
for (unsigned z = 0; z < box->depth; ++z, src_box.x = z * layer_stride) {
3185
unsigned dst_x = box->x, dst_y = box->y, width = box->width, height = box->height, dst_z = box->z + z;
3186
int blocksize = util_format_get_blocksize(format);
3187
int blockwidth = util_format_get_blockwidth(format);
3188
int blockheight = util_format_get_blockheight(format);
3190
assert(blocksize > 0);
3191
assert(blockwidth > 0);
3192
assert(blockheight > 0);
3194
dst_x /= blockwidth;
3195
dst_y /= blockheight;
3196
width = DIV_ROUND_UP(width, blockwidth);
3197
height = DIV_ROUND_UP(height, blockheight);
3201
if (width == fmt_stride && width == (unsigned)stride) {
3202
ASSERTED uint64_t size = (uint64_t)height * width;
3204
assert(size <= SIZE_MAX);
3205
assert(dst_x + src_box.width < u_minify(pres->width0, level));
3206
assert(dst_y + src_box.height < u_minify(pres->height0, level));
3207
assert(pres->target != PIPE_TEXTURE_3D || z + src_box.depth < u_minify(pres->depth0, level));
3208
tc->base.resource_copy_region(&tc->base, resource, level, dst_x, dst_y, dst_z, pres, 0, &src_box);
3211
for (unsigned i = 0; i < height; i++, dst_y++, src_box.x += stride)
3212
tc->base.resource_copy_region(&tc->base, resource, level, dst_x, dst_y, dst_z, pres, 0, &src_box);
3161
3217
pipe_resource_reference(&pres, NULL);