static void i915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) { struct i915_context *i915 = i915_context(pipe); struct pipe_blit_info info = *blit_info; if (util_try_blit_via_copy_region(pipe, &info)) { return; /* done */ } if (info.mask & PIPE_MASK_S) { debug_printf("i915: cannot blit stencil, skipping\n"); info.mask &= ~PIPE_MASK_S; } if (!util_blitter_is_blit_supported(i915->blitter, &info)) { debug_printf("i915: blit unsupported %s -> %s\n", util_format_short_name(info.src.resource->format), util_format_short_name(info.dst.resource->format)); return; } i915_util_blitter_save_states(i915); util_blitter_blit(i915->blitter, &info); }
static void svga_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) { struct svga_context *svga = svga_context(pipe); struct pipe_blit_info info = *blit_info; if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info.src.resource->format) && !util_format_is_pure_integer(info.src.resource->format)) { debug_printf("svga: color resolve unimplemented\n"); return; } if (util_try_blit_via_copy_region(pipe, &info)) { return; /* done */ } if (info.mask & PIPE_MASK_S) { debug_printf("svga: cannot blit stencil, skipping\n"); info.mask &= ~PIPE_MASK_S; } if (!util_blitter_is_blit_supported(svga->blitter, &info)) { debug_printf("svga: blit unsupported %s -> %s\n", util_format_short_name(info.src.resource->format), util_format_short_name(info.dst.resource->format)); return; } /* XXX turn off occlusion and streamout queries */ util_blitter_save_vertex_buffers(svga->blitter, svga->curr.num_vertex_buffers, svga->curr.vb); util_blitter_save_vertex_elements(svga->blitter, (void*)svga->curr.velems); util_blitter_save_vertex_shader(svga->blitter, svga->curr.vs); /*util_blitter_save_geometry_shader(svga->blitter, svga->curr.gs);*/ /*util_blitter_save_so_targets(svga->blitter, svga->num_so_targets, (struct pipe_stream_output_target**)svga->so_targets);*/ util_blitter_save_rasterizer(svga->blitter, (void*)svga->curr.rast); util_blitter_save_viewport(svga->blitter, &svga->curr.viewport); util_blitter_save_scissor(svga->blitter, &svga->curr.scissor); util_blitter_save_fragment_shader(svga->blitter, svga->curr.fs); util_blitter_save_blend(svga->blitter, (void*)svga->curr.blend); util_blitter_save_depth_stencil_alpha(svga->blitter, (void*)svga->curr.depth); util_blitter_save_stencil_ref(svga->blitter, &svga->curr.stencil_ref); /*util_blitter_save_sample_mask(svga->blitter, svga->sample_mask);*/ util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer); util_blitter_save_fragment_sampler_states(svga->blitter, svga->curr.num_samplers, (void**)svga->curr.sampler); util_blitter_save_fragment_sampler_views(svga->blitter, svga->curr.num_sampler_views, svga->curr.sampler_views); /*util_blitter_save_render_condition(svga->blitter, svga->render_cond_query, svga->render_cond_mode);*/ util_blitter_blit(svga->blitter, &info); }
static void fd_clear(struct pipe_context *pctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { struct fd_context *ctx = fd_context(pctx); struct pipe_framebuffer_state *pfb = &ctx->framebuffer; ctx->cleared |= buffers; ctx->resolve |= buffers; ctx->needs_flush = true; if (buffers & PIPE_CLEAR_COLOR) fd_resource(pfb->cbufs[0]->texture)->dirty = true; if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) { fd_resource(pfb->zsbuf->texture)->dirty = true; ctx->gmem_reason |= FD_GMEM_CLEARS_DEPTH_STENCIL; } DBG("%x depth=%f, stencil=%u (%s/%s)", buffers, depth, stencil, util_format_short_name(pipe_surface_format(pfb->cbufs[0])), util_format_short_name(pipe_surface_format(pfb->zsbuf))); ctx->clear(ctx, buffers, color, depth, stencil); ctx->dirty |= FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER | FD_DIRTY_SAMPLE_MASK | FD_DIRTY_PROG | FD_DIRTY_CONSTBUF | FD_DIRTY_BLEND; if (fd_mesa_debug & FD_DBG_DCLEAR) ctx->dirty = 0xffffffff; }
/** * Optimal hardware path for blitting pixels. * Scaling, format conversion, up- and downsampling (resolve) are allowed. */ static void fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info) { struct fd_context *ctx = fd_context(pctx); struct pipe_blit_info info = *blit_info; if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info.src.resource->format) && !util_format_is_pure_integer(info.src.resource->format)) { DBG("color resolve unimplemented"); return; } if (util_try_blit_via_copy_region(pctx, &info)) { return; /* done */ } if (info.mask & PIPE_MASK_S) { DBG("cannot blit stencil, skipping"); info.mask &= ~PIPE_MASK_S; } if (!util_blitter_is_blit_supported(ctx->blitter, &info)) { DBG("blit unsupported %s -> %s", util_format_short_name(info.src.resource->format), util_format_short_name(info.dst.resource->format)); return; } fd_blitter_pipe_begin(ctx); util_blitter_blit(ctx->blitter, &info); fd_blitter_pipe_end(ctx); }
static bool render_blit(struct pipe_context *ctx, struct pipe_blit_info *info) { struct vc4_context *vc4 = vc4_context(ctx); if (!util_blitter_is_blit_supported(vc4->blitter, info)) { fprintf(stderr, "blit unsupported %s -> %s", util_format_short_name(info->src.resource->format), util_format_short_name(info->dst.resource->format)); return false; } 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.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.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); util_blitter_save_sample_mask(vc4->blitter, vc4->sample_mask); util_blitter_save_framebuffer(vc4->blitter, &vc4->framebuffer); util_blitter_save_fragment_sampler_states(vc4->blitter, vc4->fragtex.num_samplers, (void **)vc4->fragtex.samplers); util_blitter_save_fragment_sampler_views(vc4->blitter, vc4->fragtex.num_textures, vc4->fragtex.textures); util_blitter_blit(vc4->blitter, info); return true; }
static bool vc4_render_blit(struct pipe_context *ctx, struct pipe_blit_info *info) { struct vc4_context *vc4 = vc4_context(ctx); if (!util_blitter_is_blit_supported(vc4->blitter, info)) { fprintf(stderr, "blit unsupported %s -> %s\n", util_format_short_name(info->src.resource->format), util_format_short_name(info->dst.resource->format)); return false; } /* Enable the scissor, so we get a minimal set of tiles rendered. */ if (!info->scissor_enable) { info->scissor_enable = true; info->scissor.minx = info->dst.box.x; info->scissor.miny = info->dst.box.y; info->scissor.maxx = info->dst.box.x + info->dst.box.width; info->scissor.maxy = info->dst.box.y + info->dst.box.height; } vc4_blitter_save(vc4); util_blitter_blit(vc4->blitter, info); return true; }
static void fd_clear(struct pipe_context *pctx, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { struct fd_context *ctx = fd_context(pctx); struct pipe_framebuffer_state *pfb = &ctx->framebuffer; struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx); unsigned cleared_buffers; /* for bookkeeping about which buffers have been cleared (and thus * can fully or partially skip mem2gmem) we need to ignore buffers * that have already had a draw, in case apps do silly things like * clear after draw (ie. if you only clear the color buffer, but * something like alpha-test causes side effects from the draw in * the depth buffer, etc) */ cleared_buffers = buffers & (FD_BUFFER_ALL & ~ctx->restore); /* do we have full-screen scissor? */ if (!memcmp(scissor, &ctx->disabled_scissor, sizeof(*scissor))) { ctx->cleared |= cleared_buffers; } else { ctx->partial_cleared |= cleared_buffers; if (cleared_buffers & PIPE_CLEAR_COLOR) ctx->cleared_scissor.color = *scissor; if (cleared_buffers & PIPE_CLEAR_DEPTH) ctx->cleared_scissor.depth = *scissor; if (cleared_buffers & PIPE_CLEAR_STENCIL) ctx->cleared_scissor.stencil = *scissor; } ctx->resolve |= buffers; ctx->needs_flush = true; if (buffers & PIPE_CLEAR_COLOR) fd_resource(pfb->cbufs[0]->texture)->dirty = true; if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) { fd_resource(pfb->zsbuf->texture)->dirty = true; ctx->gmem_reason |= FD_GMEM_CLEARS_DEPTH_STENCIL; } DBG("%x depth=%f, stencil=%u (%s/%s)", buffers, depth, stencil, util_format_short_name(pipe_surface_format(pfb->cbufs[0])), util_format_short_name(pipe_surface_format(pfb->zsbuf))); fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_CLEAR); ctx->clear(ctx, buffers, color, depth, stencil); ctx->dirty |= FD_DIRTY_ZSA | FD_DIRTY_VIEWPORT | FD_DIRTY_RASTERIZER | FD_DIRTY_SAMPLE_MASK | FD_DIRTY_PROG | FD_DIRTY_CONSTBUF | FD_DIRTY_BLEND; if (fd_mesa_debug & FD_DBG_DCLEAR) ctx->dirty = 0xffffffff; }
static void lp_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) { struct llvmpipe_context *lp = llvmpipe_context(pipe); struct pipe_blit_info info = *blit_info; if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info.src.resource->format) && !util_format_is_pure_integer(info.src.resource->format)) { debug_printf("llvmpipe: color resolve unimplemented\n"); return; } if (util_try_blit_via_copy_region(pipe, &info)) { return; /* done */ } if (info.mask & PIPE_MASK_S) { debug_printf("llvmpipe: cannot blit stencil, skipping\n"); info.mask &= ~PIPE_MASK_S; } if (!util_blitter_is_blit_supported(lp->blitter, &info)) { debug_printf("llvmpipe: blit unsupported %s -> %s\n", util_format_short_name(info.src.resource->format), util_format_short_name(info.dst.resource->format)); return; } /* XXX turn off occlusion and streamout queries */ util_blitter_save_vertex_buffers(lp->blitter, lp->num_vertex_buffers, lp->vertex_buffer); util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems); util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs); util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs); /*util_blitter_save_so_targets(lp->blitter, lp->num_so_targets, (struct pipe_stream_output_target**)lp->so_targets);*/ util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer); util_blitter_save_viewport(lp->blitter, &lp->viewport); util_blitter_save_scissor(lp->blitter, &lp->scissor); util_blitter_save_fragment_shader(lp->blitter, lp->fs); util_blitter_save_blend(lp->blitter, (void*)lp->blend); util_blitter_save_depth_stencil_alpha(lp->blitter, (void*)lp->depth_stencil); util_blitter_save_stencil_ref(lp->blitter, &lp->stencil_ref); /*util_blitter_save_sample_mask(sp->blitter, lp->sample_mask);*/ util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer); util_blitter_save_fragment_sampler_states(lp->blitter, lp->num_samplers[PIPE_SHADER_FRAGMENT], (void**)lp->samplers[PIPE_SHADER_FRAGMENT]); util_blitter_save_fragment_sampler_views(lp->blitter, lp->num_sampler_views[PIPE_SHADER_FRAGMENT], lp->sampler_views[PIPE_SHADER_FRAGMENT]); util_blitter_save_render_condition(lp->blitter, lp->render_cond_query, lp->render_cond_mode); util_blitter_blit(lp->blitter, &info); }
void nv30_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) { struct nv30_context *nv30 = nv30_context(pipe); struct pipe_blit_info info = *blit_info; if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info.src.resource->format) && !util_format_is_pure_integer(info.src.resource->format)) { debug_printf("nv30: color resolve unimplemented\n"); return; } if (util_try_blit_via_copy_region(pipe, &info)) { return; /* done */ } if (info.mask & PIPE_MASK_S) { debug_printf("nv30: cannot blit stencil, skipping\n"); info.mask &= ~PIPE_MASK_S; } if (!util_blitter_is_blit_supported(nv30->blitter, &info)) { debug_printf("nv30: blit unsupported %s -> %s\n", util_format_short_name(info.src.resource->format), util_format_short_name(info.dst.resource->format)); return; } /* XXX turn off occlusion queries */ util_blitter_save_vertex_buffer_slot(nv30->blitter, nv30->vtxbuf); util_blitter_save_vertex_elements(nv30->blitter, nv30->vertex); util_blitter_save_vertex_shader(nv30->blitter, nv30->vertprog.program); util_blitter_save_rasterizer(nv30->blitter, nv30->rast); util_blitter_save_viewport(nv30->blitter, &nv30->viewport); util_blitter_save_scissor(nv30->blitter, &nv30->scissor); util_blitter_save_fragment_shader(nv30->blitter, nv30->fragprog.program); util_blitter_save_blend(nv30->blitter, nv30->blend); util_blitter_save_depth_stencil_alpha(nv30->blitter, nv30->zsa); util_blitter_save_stencil_ref(nv30->blitter, &nv30->stencil_ref); util_blitter_save_sample_mask(nv30->blitter, nv30->sample_mask); util_blitter_save_framebuffer(nv30->blitter, &nv30->framebuffer); util_blitter_save_fragment_sampler_states(nv30->blitter, nv30->fragprog.num_samplers, (void**)nv30->fragprog.samplers); util_blitter_save_fragment_sampler_views(nv30->blitter, nv30->fragprog.num_textures, nv30->fragprog.textures); util_blitter_save_render_condition(nv30->blitter, nv30->render_cond_query, nv30->render_cond_mode); util_blitter_blit(nv30->blitter, &info); }
static void sp_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) { struct softpipe_context *sp = softpipe_context(pipe); if (info->render_condition_enable && !softpipe_check_render_cond(sp)) return; if (info->src.resource->nr_samples > 1 && info->dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info->src.resource->format) && !util_format_is_pure_integer(info->src.resource->format)) { debug_printf("softpipe: color resolve unimplemented\n"); return; } if (util_try_blit_via_copy_region(pipe, info)) { return; /* done */ } if (!util_blitter_is_blit_supported(sp->blitter, info)) { debug_printf("softpipe: blit unsupported %s -> %s\n", util_format_short_name(info->src.resource->format), util_format_short_name(info->dst.resource->format)); return; } /* XXX turn off occlusion and streamout queries */ util_blitter_save_vertex_buffer_slot(sp->blitter, sp->vertex_buffer); util_blitter_save_vertex_elements(sp->blitter, sp->velems); util_blitter_save_vertex_shader(sp->blitter, sp->vs); util_blitter_save_geometry_shader(sp->blitter, sp->gs); util_blitter_save_so_targets(sp->blitter, sp->num_so_targets, (struct pipe_stream_output_target**)sp->so_targets); util_blitter_save_rasterizer(sp->blitter, sp->rasterizer); util_blitter_save_viewport(sp->blitter, &sp->viewports[0]); util_blitter_save_scissor(sp->blitter, &sp->scissors[0]); util_blitter_save_fragment_shader(sp->blitter, sp->fs); util_blitter_save_blend(sp->blitter, sp->blend); util_blitter_save_depth_stencil_alpha(sp->blitter, sp->depth_stencil); util_blitter_save_stencil_ref(sp->blitter, &sp->stencil_ref); /*util_blitter_save_sample_mask(sp->blitter, sp->sample_mask);*/ util_blitter_save_framebuffer(sp->blitter, &sp->framebuffer); util_blitter_save_fragment_sampler_states(sp->blitter, sp->num_samplers[PIPE_SHADER_FRAGMENT], (void**)sp->samplers[PIPE_SHADER_FRAGMENT]); util_blitter_save_fragment_sampler_views(sp->blitter, sp->num_sampler_views[PIPE_SHADER_FRAGMENT], sp->sampler_views[PIPE_SHADER_FRAGMENT]); util_blitter_save_render_condition(sp->blitter, sp->render_cond_query, sp->render_cond_cond, sp->render_cond_mode); util_blitter_blit(sp->blitter, info); }
/* Optimal hardware path for blitting pixels. * Scaling, format conversion, up- and downsampling (resolve) are allowed. */ static void fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info) { struct fd_context *ctx = fd_context(pctx); struct pipe_blit_info info = *blit_info; if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info.src.resource->format) && !util_format_is_pure_integer(info.src.resource->format)) { DBG("color resolve unimplemented"); return; } if (util_try_blit_via_copy_region(pctx, &info)) { return; /* done */ } if (info.mask & PIPE_MASK_S) { DBG("cannot blit stencil, skipping"); info.mask &= ~PIPE_MASK_S; } if (!util_blitter_is_blit_supported(ctx->blitter, &info)) { DBG("blit unsupported %s -> %s", util_format_short_name(info.src.resource->format), util_format_short_name(info.dst.resource->format)); return; } util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertexbuf.vb); util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx); util_blitter_save_vertex_shader(ctx->blitter, ctx->prog.vp); util_blitter_save_rasterizer(ctx->blitter, ctx->rasterizer); util_blitter_save_viewport(ctx->blitter, &ctx->viewport); util_blitter_save_scissor(ctx->blitter, &ctx->scissor); util_blitter_save_fragment_shader(ctx->blitter, ctx->prog.fp); util_blitter_save_blend(ctx->blitter, ctx->blend); util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->zsa); util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref); util_blitter_save_sample_mask(ctx->blitter, ctx->sample_mask); util_blitter_save_framebuffer(ctx->blitter, &ctx->framebuffer.base); util_blitter_save_fragment_sampler_states(ctx->blitter, ctx->fragtex.num_samplers, (void **)ctx->fragtex.samplers); util_blitter_save_fragment_sampler_views(ctx->blitter, ctx->fragtex.num_textures, ctx->fragtex.textures); util_blitter_blit(ctx->blitter, &info); }
void r300_texture_reinterpret_format(struct pipe_screen *screen, struct pipe_resource *tex, enum pipe_format new_format) { struct r300_screen *r300screen = r300_screen(screen); SCREEN_DBG(r300screen, DBG_TEX, "r300: texture_reinterpret_format: %s -> %s\n", util_format_short_name(tex->format), util_format_short_name(new_format)); tex->format = new_format; r300_texture_setup_fb_state(r300_screen(screen), r300_texture(tex)); }
/* Copy a block of pixels from one surface to another. */ static void r300_resource_copy_region(struct pipe_context *pipe, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { enum pipe_format old_format = dst->format; enum pipe_format new_format = old_format; boolean is_depth; if (!pipe->screen->is_format_supported(pipe->screen, old_format, src->target, src->nr_samples, PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW, 0) && util_format_is_plain(old_format)) { switch (util_format_get_blocksize(old_format)) { case 1: new_format = PIPE_FORMAT_I8_UNORM; break; case 2: new_format = PIPE_FORMAT_B4G4R4A4_UNORM; break; case 4: new_format = PIPE_FORMAT_B8G8R8A8_UNORM; break; case 8: new_format = PIPE_FORMAT_R16G16B16A16_UNORM; break; default: debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n" "r300: surface_copy: Software fallback doesn't work for tiled textures.\n", util_format_short_name(old_format)); } } is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; if (is_depth) { r300_flush_depth_stencil(pipe, src, src_level, src_box->z); } if (old_format != new_format) { r300_texture_reinterpret_format(pipe->screen, dst, new_format); r300_texture_reinterpret_format(pipe->screen, src, new_format); } r300_hw_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); if (old_format != new_format) { r300_texture_reinterpret_format(pipe->screen, dst, old_format); r300_texture_reinterpret_format(pipe->screen, src, old_format); } }
static void r300_setup_miptree(struct r300_screen *screen, struct r300_resource *tex, boolean align_for_cbzb) { struct pipe_resource *base = &tex->b.b.b; unsigned stride, size, layer_size, nblocksy, i; boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_R350; boolean aligned_for_cbzb; tex->tex.size_in_bytes = 0; SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Making miptree for texture, format %s\n", util_format_short_name(base->format)); for (i = 0; i <= base->last_level; i++) { /* Let's see if this miplevel can be macrotiled. */ tex->tex.macrotile[i] = (tex->tex.macrotile[0] == RADEON_LAYOUT_TILED && r300_texture_macro_switch(tex, i, rv350_mode, DIM_WIDTH) && r300_texture_macro_switch(tex, i, rv350_mode, DIM_HEIGHT)) ? RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR; stride = r300_texture_get_stride(screen, tex, i); /* Compute the number of blocks in Y, see if the CBZB clear can be * used on the texture. */ aligned_for_cbzb = FALSE; if (align_for_cbzb && tex->tex.cbzb_allowed[i]) nblocksy = r300_texture_get_nblocksy(tex, i, &aligned_for_cbzb); else nblocksy = r300_texture_get_nblocksy(tex, i, NULL); layer_size = stride * nblocksy; if (base->nr_samples) { layer_size *= base->nr_samples; } if (base->target == PIPE_TEXTURE_CUBE) size = layer_size * 6; else size = layer_size * u_minify(tex->tex.depth0, i); tex->tex.offset_in_bytes[i] = tex->tex.size_in_bytes; tex->tex.size_in_bytes = tex->tex.offset_in_bytes[i] + size; tex->tex.layer_size_in_bytes[i] = layer_size; tex->tex.stride_in_bytes[i] = stride; tex->tex.stride_in_pixels[i] = stride_to_width(tex->b.b.b.format, stride); tex->tex.cbzb_allowed[i] = tex->tex.cbzb_allowed[i] && aligned_for_cbzb; SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d " "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n", i, u_minify(tex->tex.width0, i), u_minify(tex->tex.height0, i), u_minify(tex->tex.depth0, i), stride, tex->tex.size_in_bytes, tex->tex.macrotile[i] ? "TRUE" : "FALSE"); } }
void fd_gmem_render_tiles(struct fd_batch *batch) { struct fd_context *ctx = batch->ctx; struct pipe_framebuffer_state *pfb = &batch->framebuffer; bool sysmem = false; if (ctx->emit_sysmem_prep) { if (batch->cleared || batch->gmem_reason || (batch->num_draws > 5)) { DBG("GMEM: cleared=%x, gmem_reason=%x, num_draws=%u", batch->cleared, batch->gmem_reason, batch->num_draws); } else if (!(fd_mesa_debug & FD_DBG_NOBYPASS)) { sysmem = true; } } fd_reset_wfi(batch); ctx->stats.batch_total++; if (sysmem) { DBG("%p: rendering sysmem %ux%u (%s/%s)", batch, pfb->width, pfb->height, util_format_short_name(pipe_surface_format(pfb->cbufs[0])), util_format_short_name(pipe_surface_format(pfb->zsbuf))); fd_hw_query_prepare(batch, 1); render_sysmem(batch); ctx->stats.batch_sysmem++; } else { struct fd_gmem_stateobj *gmem = &ctx->gmem; calculate_tiles(batch); DBG("%p: rendering %dx%d tiles %ux%u (%s/%s)", batch, pfb->width, pfb->height, gmem->nbins_x, gmem->nbins_y, util_format_short_name(pipe_surface_format(pfb->cbufs[0])), util_format_short_name(pipe_surface_format(pfb->zsbuf))); fd_hw_query_prepare(batch, gmem->nbins_x * gmem->nbins_y); render_tiles(batch); ctx->stats.batch_gmem++; } flush_ring(batch); }
static void galahad_resource_copy_region(struct pipe_context *_pipe, struct pipe_resource *_dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *_src, unsigned src_level, const struct pipe_box *src_box) { struct galahad_context *glhd_pipe = galahad_context(_pipe); struct galahad_resource *glhd_resource_dst = galahad_resource(_dst); struct galahad_resource *glhd_resource_src = galahad_resource(_src); struct pipe_context *pipe = glhd_pipe->pipe; struct pipe_resource *dst = glhd_resource_dst->resource; struct pipe_resource *src = glhd_resource_src->resource; if (_dst->format != _src->format) { glhd_warn("Format mismatch: Source is %s, destination is %s", util_format_short_name(_src->format), util_format_short_name(_dst->format)); } if ((_src->target == PIPE_BUFFER && _dst->target != PIPE_BUFFER) || (_src->target != PIPE_BUFFER && _dst->target == PIPE_BUFFER)) { glhd_warn("Resource target mismatch: Source is %i, destination is %i", _src->target, _dst->target); } pipe->resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); }
static void r300_tex_print_info(struct r300_resource *tex, const char *func) { fprintf(stderr, "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, " "LastLevel: %i, Size: %i, Format: %s\n", func, tex->tex.macrotile[0] ? "YES" : " NO", tex->tex.microtile ? "YES" : " NO", tex->tex.stride_in_pixels[0], tex->b.b.b.width0, tex->b.b.b.height0, tex->b.b.b.depth0, tex->b.b.b.last_level, tex->tex.size_in_bytes, util_format_short_name(tex->b.b.b.format)); }
static void r300_tex_print_info(struct r300_screen *rscreen, struct r300_texture_desc *desc, const char *func) { fprintf(stderr, "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, " "LastLevel: %i, Size: %i, Format: %s\n", func, desc->macrotile[0] ? "YES" : " NO", desc->microtile ? "YES" : " NO", desc->stride_in_pixels[0], desc->b.b.width0, desc->b.b.height0, desc->b.b.depth0, desc->b.b.last_level, desc->size_in_bytes, util_format_short_name(desc->b.b.format)); }
/* Copy a block of pixels from one surface to another. */ static void r300_resource_copy_region(struct pipe_context *pipe, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct r300_context *r300 = r300_context(pipe); struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; struct pipe_resource old_src = *src; struct pipe_resource old_dst = *dst; struct pipe_resource new_src = old_src; struct pipe_resource new_dst = old_dst; const struct util_format_description *desc = util_format_description(dst->format); struct pipe_box box; /* Fallback for buffers. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } if (r300->zmask_in_use && !r300->locked_zbuffer) { if (fb->zsbuf->texture == src || fb->zsbuf->texture == dst) { r300_decompress_zmask(r300); } } /* Handle non-renderable plain formats. */ if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB || !pipe->screen->is_format_supported(pipe->screen, src->format, src->target, src->nr_samples, PIPE_BIND_SAMPLER_VIEW) || !pipe->screen->is_format_supported(pipe->screen, dst->format, dst->target, dst->nr_samples, PIPE_BIND_RENDER_TARGET))) { switch (util_format_get_blocksize(old_dst.format)) { case 1: new_dst.format = PIPE_FORMAT_I8_UNORM; break; case 2: new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM; break; case 4: new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM; break; case 8: new_dst.format = PIPE_FORMAT_R16G16B16A16_UNORM; break; default: debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n" "r300: surface_copy: Software fallback doesn't work for tiled textures.\n", util_format_short_name(dst->format)); } new_src.format = new_dst.format; } /* Handle compressed formats. */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC || desc->layout == UTIL_FORMAT_LAYOUT_RGTC) { switch (util_format_get_blocksize(old_dst.format)) { case 8: /* 1 pixel = 4 bits, * we set 1 pixel = 2 bytes ===> 4 times larger pixels. */ new_dst.format = PIPE_FORMAT_B4G4R4A4_UNORM; break; case 16: /* 1 pixel = 8 bits, * we set 1 pixel = 4 bytes ===> 4 times larger pixels. */ new_dst.format = PIPE_FORMAT_B8G8R8A8_UNORM; break; } /* Since the pixels are 4 times larger, we must decrease * the image size and the coordinates 4 times. */ new_src.format = new_dst.format; new_dst.height0 = (new_dst.height0 + 3) / 4; new_src.height0 = (new_src.height0 + 3) / 4; dsty /= 4; box = *src_box; box.y /= 4; box.height = (box.height + 3) / 4; src_box = &box; } if (old_src.format != new_src.format) r300_resource_set_properties(pipe->screen, src, &new_src); if (old_dst.format != new_dst.format) r300_resource_set_properties(pipe->screen, dst, &new_dst); r300_hw_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); if (old_src.format != new_src.format) r300_resource_set_properties(pipe->screen, src, &old_src); if (old_dst.format != new_dst.format) r300_resource_set_properties(pipe->screen, dst, &old_dst); }
/* Copy a block of pixels from one surface to another. */ static void r300_resource_copy_region(struct pipe_context *pipe, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct pipe_screen *screen = pipe->screen; struct r300_context *r300 = r300_context(pipe); struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; unsigned src_width0 = r300_resource(src)->tex.width0; unsigned src_height0 = r300_resource(src)->tex.height0; unsigned dst_width0 = r300_resource(dst)->tex.width0; unsigned dst_height0 = r300_resource(dst)->tex.height0; unsigned layout; struct pipe_box box; struct pipe_sampler_view src_templ, *src_view; struct pipe_surface dst_templ, *dst_view; /* Fallback for buffers. */ if ((dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) || !r300_is_blit_supported(dst->format)) { util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } /* The code below changes the texture format so that the copy can be done * on hardware. E.g. depth-stencil surfaces are copied as RGBA * colorbuffers. */ util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz, src_box); util_blitter_default_src_texture(&src_templ, src, src_level); layout = util_format_description(dst_templ.format)->layout; /* Handle non-renderable plain formats. */ if (layout == UTIL_FORMAT_LAYOUT_PLAIN && (!screen->is_format_supported(screen, src_templ.format, src->target, src->nr_samples, PIPE_BIND_SAMPLER_VIEW) || !screen->is_format_supported(screen, dst_templ.format, dst->target, dst->nr_samples, PIPE_BIND_RENDER_TARGET))) { switch (util_format_get_blocksize(dst_templ.format)) { case 1: dst_templ.format = PIPE_FORMAT_I8_UNORM; break; case 2: dst_templ.format = PIPE_FORMAT_B4G4R4A4_UNORM; break; case 4: dst_templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; break; case 8: dst_templ.format = PIPE_FORMAT_R16G16B16A16_UNORM; break; default: debug_printf("r300: copy_region: Unhandled format: %s. Falling back to software.\n" "r300: copy_region: Software fallback doesn't work for tiled textures.\n", util_format_short_name(dst_templ.format)); } src_templ.format = dst_templ.format; } /* Handle compressed formats. */ if (layout == UTIL_FORMAT_LAYOUT_S3TC || layout == UTIL_FORMAT_LAYOUT_RGTC) { assert(src_templ.format == dst_templ.format); box = *src_box; src_box = &box; dst_width0 = align(dst_width0, 4); dst_height0 = align(dst_height0, 4); src_width0 = align(src_width0, 4); src_height0 = align(src_height0, 4); box.width = align(box.width, 4); box.height = align(box.height, 4); switch (util_format_get_blocksize(dst_templ.format)) { case 8: /* one 4x4 pixel block has 8 bytes. * we set 1 pixel = 4 bytes ===> 1 block corrensponds to 2 pixels. */ dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; dst_width0 = dst_width0 / 2; src_width0 = src_width0 / 2; dstx /= 2; box.x /= 2; box.width /= 2; break; case 16: /* one 4x4 pixel block has 16 bytes. * we set 1 pixel = 4 bytes ===> 1 block corresponds to 4 pixels. */ dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; break; } src_templ.format = dst_templ.format; dst_height0 = dst_height0 / 4; src_height0 = src_height0 / 4; dsty /= 4; box.y /= 4; box.height /= 4; } /* Fallback for textures. */ if (!screen->is_format_supported(screen, dst_templ.format, dst->target, dst->nr_samples, PIPE_BIND_RENDER_TARGET) || !screen->is_format_supported(screen, src_templ.format, src->target, src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { assert(0 && "this shouldn't happen, update r300_is_blit_supported"); util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } /* Decompress ZMASK. */ if (r300->zmask_in_use && !r300->locked_zbuffer) { if (fb->zsbuf->texture == src || fb->zsbuf->texture == dst) { r300_decompress_zmask(r300); } } dst_view = r300_create_surface_custom(pipe, dst, &dst_templ, dst_width0, dst_height0); src_view = r300_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0); r300_blitter_begin(r300, R300_COPY); util_blitter_blit_generic(r300->blitter, dst_view, dstx, dsty, abs(src_box->width), abs(src_box->height), src_view, src_box, src_width0, src_height0, PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, FALSE); r300_blitter_end(r300); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); }
static void r600_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct r600_context *rctx = (struct r600_context *)ctx; struct pipe_surface *dst_view, dst_templ; struct pipe_sampler_view src_templ, *src_view; unsigned dst_width, dst_height, src_width0, src_height0, src_widthFL, src_heightFL; unsigned src_force_level = 0; struct pipe_box sbox, dstbox; /* Handle buffers first. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { if ((src->bind & PIPE_BIND_GLOBAL) || (dst->bind & PIPE_BIND_GLOBAL)) { r600_copy_global_buffer(ctx, dst, dstx, src, src_box); } else { r600_copy_buffer(ctx, dst, dstx, src, src_box); } return; } assert(u_max_sample(dst) == u_max_sample(src)); /* The driver doesn't decompress resources automatically while * u_blitter is rendering. */ if (!r600_decompress_subresource(ctx, src, src_level, src_box->z, src_box->z + src_box->depth - 1)) { return; /* error */ } dst_width = u_minify(dst->width0, dst_level); dst_height = u_minify(dst->height0, dst_level); src_width0 = src->width0; src_height0 = src->height0; src_widthFL = u_minify(src->width0, src_level); src_heightFL = u_minify(src->height0, src_level); util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); util_blitter_default_src_texture(&src_templ, src, src_level); if (util_format_is_compressed(src->format)) { unsigned blocksize = util_format_get_blocksize(src->format); if (blocksize == 8) src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */ else src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */ dst_templ.format = src_templ.format; dst_width = util_format_get_nblocksx(dst->format, dst_width); dst_height = util_format_get_nblocksy(dst->format, dst_height); src_width0 = util_format_get_nblocksx(src->format, src_width0); src_height0 = util_format_get_nblocksy(src->format, src_height0); src_widthFL = util_format_get_nblocksx(src->format, src_widthFL); src_heightFL = util_format_get_nblocksy(src->format, src_heightFL); dstx = util_format_get_nblocksx(dst->format, dstx); dsty = util_format_get_nblocksy(dst->format, dsty); sbox.x = util_format_get_nblocksx(src->format, src_box->x); sbox.y = util_format_get_nblocksy(src->format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(src->format, src_box->width); sbox.height = util_format_get_nblocksy(src->format, src_box->height); sbox.depth = src_box->depth; src_box = &sbox; src_force_level = src_level; } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src)) { if (util_format_is_subsampled_422(src->format)) { src_templ.format = PIPE_FORMAT_R8G8B8A8_UINT; dst_templ.format = PIPE_FORMAT_R8G8B8A8_UINT; dst_width = util_format_get_nblocksx(dst->format, dst_width); src_width0 = util_format_get_nblocksx(src->format, src_width0); src_widthFL = util_format_get_nblocksx(src->format, src_widthFL); dstx = util_format_get_nblocksx(dst->format, dstx); sbox = *src_box; sbox.x = util_format_get_nblocksx(src->format, src_box->x); sbox.width = util_format_get_nblocksx(src->format, src_box->width); src_box = &sbox; } else { unsigned blocksize = util_format_get_blocksize(src->format); switch (blocksize) { case 1: dst_templ.format = PIPE_FORMAT_R8_UNORM; src_templ.format = PIPE_FORMAT_R8_UNORM; break; case 2: dst_templ.format = PIPE_FORMAT_R8G8_UNORM; src_templ.format = PIPE_FORMAT_R8G8_UNORM; break; case 4: dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; src_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; break; case 8: dst_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; break; case 16: dst_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; break; default: fprintf(stderr, "Unhandled format %s with blocksize %u\n", util_format_short_name(src->format), blocksize); assert(0); } } } dst_view = r600_create_surface_custom(ctx, dst, &dst_templ, dst_width, dst_height); if (rctx->b.chip_class >= EVERGREEN) { src_view = evergreen_create_sampler_view_custom(ctx, src, &src_templ, src_width0, src_height0, src_force_level); } else { src_view = r600_create_sampler_view_custom(ctx, src, &src_templ, src_widthFL, src_heightFL); } u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), abs(src_box->depth), &dstbox); /* Copy. */ r600_blitter_begin(ctx, R600_COPY_TEXTURE); util_blitter_blit_generic(rctx->blitter, dst_view, &dstbox, src_view, src_box, src_width0, src_height0, PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); r600_blitter_end(ctx); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); }
void r600_print_texture_info(struct r600_texture *rtex, FILE *f) { int i; fprintf(f, " Info: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, " "blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, " "bpe=%u, nsamples=%u, flags=0x%x, %s\n", rtex->surface.npix_x, rtex->surface.npix_y, rtex->surface.npix_z, rtex->surface.blk_w, rtex->surface.blk_h, rtex->surface.blk_d, rtex->surface.array_size, rtex->surface.last_level, rtex->surface.bpe, rtex->surface.nsamples, rtex->surface.flags, util_format_short_name(rtex->resource.b.b.format)); fprintf(f, " Layout: size=%"PRIu64", alignment=%"PRIu64", bankw=%u, " "bankh=%u, nbanks=%u, mtilea=%u, tilesplit=%u, pipeconfig=%u, scanout=%u\n", rtex->surface.bo_size, rtex->surface.bo_alignment, rtex->surface.bankw, rtex->surface.bankh, rtex->surface.num_banks, rtex->surface.mtilea, rtex->surface.tile_split, rtex->surface.pipe_config, (rtex->surface.flags & RADEON_SURF_SCANOUT) != 0); if (rtex->fmask.size) fprintf(f, " FMask: offset=%u, size=%u, alignment=%u, pitch_in_pixels=%u, " "bankh=%u, slice_tile_max=%u, tile_mode_index=%u\n", rtex->fmask.offset, rtex->fmask.size, rtex->fmask.alignment, rtex->fmask.pitch_in_pixels, rtex->fmask.bank_height, rtex->fmask.slice_tile_max, rtex->fmask.tile_mode_index); if (rtex->cmask.size) fprintf(f, " CMask: offset=%u, size=%u, alignment=%u, pitch=%u, " "height=%u, xalign=%u, yalign=%u, slice_tile_max=%u\n", rtex->cmask.offset, rtex->cmask.size, rtex->cmask.alignment, rtex->cmask.pitch, rtex->cmask.height, rtex->cmask.xalign, rtex->cmask.yalign, rtex->cmask.slice_tile_max); if (rtex->htile_buffer) fprintf(f, " HTile: size=%u, alignment=%u, pitch=%u, height=%u, " "xalign=%u, yalign=%u\n", rtex->htile_buffer->b.b.width0, rtex->htile_buffer->buf->alignment, rtex->htile.pitch, rtex->htile.height, rtex->htile.xalign, rtex->htile.yalign); if (rtex->dcc_buffer) { fprintf(f, " DCC: size=%u, alignment=%u\n", rtex->dcc_buffer->b.b.width0, rtex->dcc_buffer->buf->alignment); for (i = 0; i <= rtex->surface.last_level; i++) fprintf(f, " DCCLevel[%i]: offset=%"PRIu64"\n", i, rtex->surface.level[i].dcc_offset); } for (i = 0; i <= rtex->surface.last_level; i++) fprintf(f, " Level[%i]: offset=%"PRIu64", slice_size=%"PRIu64", " "npix_x=%u, npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, " "nblk_z=%u, pitch_bytes=%u, mode=%u\n", i, rtex->surface.level[i].offset, rtex->surface.level[i].slice_size, u_minify(rtex->resource.b.b.width0, i), u_minify(rtex->resource.b.b.height0, i), u_minify(rtex->resource.b.b.depth0, i), rtex->surface.level[i].nblk_x, rtex->surface.level[i].nblk_y, rtex->surface.level[i].nblk_z, rtex->surface.level[i].pitch_bytes, rtex->surface.level[i].mode); if (rtex->surface.flags & RADEON_SURF_SBUFFER) { for (i = 0; i <= rtex->surface.last_level; i++) { fprintf(f, " StencilLayout: tilesplit=%u\n", rtex->surface.stencil_tile_split); fprintf(f, " StencilLevel[%i]: offset=%"PRIu64", " "slice_size=%"PRIu64", npix_x=%u, " "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, " "nblk_z=%u, pitch_bytes=%u, mode=%u\n", i, rtex->surface.stencil_level[i].offset, rtex->surface.stencil_level[i].slice_size, u_minify(rtex->resource.b.b.width0, i), u_minify(rtex->resource.b.b.height0, i), u_minify(rtex->resource.b.b.depth0, i), rtex->surface.stencil_level[i].nblk_x, rtex->surface.stencil_level[i].nblk_y, rtex->surface.stencil_level[i].nblk_z, rtex->surface.stencil_level[i].pitch_bytes, rtex->surface.stencil_level[i].mode); } } }
static void swr_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) { struct swr_context *ctx = swr_context(pipe); /* Make a copy of the const blit_info, so we can modify it */ struct pipe_blit_info info = *blit_info; if (info.render_condition_enable && !swr_check_render_cond(pipe)) return; if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1 && !util_format_is_depth_or_stencil(info.src.resource->format) && !util_format_is_pure_integer(info.src.resource->format)) { debug_printf("swr_blit: color resolve : %d -> %d\n", info.src.resource->nr_samples, info.dst.resource->nr_samples); /* Resolve is done as part of the surface store. */ swr_store_dirty_resource(pipe, info.src.resource, SWR_TILE_RESOLVED); struct pipe_resource *src_resource = info.src.resource; struct pipe_resource *resolve_target = swr_resource(src_resource)->resolve_target; /* The resolve target becomes the new source for the blit. */ info.src.resource = resolve_target; } if (util_try_blit_via_copy_region(pipe, &info)) { return; /* done */ } if (info.mask & PIPE_MASK_S) { debug_printf("swr: cannot blit stencil, skipping\n"); info.mask &= ~PIPE_MASK_S; } if (!util_blitter_is_blit_supported(ctx->blitter, &info)) { debug_printf("swr: blit unsupported %s -> %s\n", util_format_short_name(info.src.resource->format), util_format_short_name(info.dst.resource->format)); return; } if (ctx->active_queries) { ctx->api.pfnSwrEnableStatsFE(ctx->swrContext, FALSE); ctx->api.pfnSwrEnableStatsBE(ctx->swrContext, FALSE); } util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertex_buffer); util_blitter_save_vertex_elements(ctx->blitter, (void *)ctx->velems); util_blitter_save_vertex_shader(ctx->blitter, (void *)ctx->vs); util_blitter_save_geometry_shader(ctx->blitter, (void*)ctx->gs); util_blitter_save_so_targets( ctx->blitter, ctx->num_so_targets, (struct pipe_stream_output_target **)ctx->so_targets); util_blitter_save_rasterizer(ctx->blitter, (void *)ctx->rasterizer); util_blitter_save_viewport(ctx->blitter, &ctx->viewport); util_blitter_save_scissor(ctx->blitter, &ctx->scissor); util_blitter_save_fragment_shader(ctx->blitter, ctx->fs); util_blitter_save_blend(ctx->blitter, (void *)ctx->blend); util_blitter_save_depth_stencil_alpha(ctx->blitter, (void *)ctx->depth_stencil); util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref); util_blitter_save_sample_mask(ctx->blitter, ctx->sample_mask); util_blitter_save_framebuffer(ctx->blitter, &ctx->framebuffer); util_blitter_save_fragment_sampler_states( ctx->blitter, ctx->num_samplers[PIPE_SHADER_FRAGMENT], (void **)ctx->samplers[PIPE_SHADER_FRAGMENT]); util_blitter_save_fragment_sampler_views( ctx->blitter, ctx->num_sampler_views[PIPE_SHADER_FRAGMENT], ctx->sampler_views[PIPE_SHADER_FRAGMENT]); util_blitter_save_render_condition(ctx->blitter, ctx->render_cond_query, ctx->render_cond_cond, ctx->render_cond_mode); util_blitter_blit(ctx->blitter, &info); if (ctx->active_queries) { ctx->api.pfnSwrEnableStatsFE(ctx->swrContext, TRUE); ctx->api.pfnSwrEnableStatsBE(ctx->swrContext, TRUE); } }
/* Common processing for r600_texture_create and r600_texture_from_handle */ static struct r600_texture * r600_texture_create_object(struct pipe_screen *screen, const struct pipe_resource *base, unsigned pitch_in_bytes_override, struct pb_buffer *buf, struct radeon_surf *surface) { struct r600_texture *rtex; struct r600_resource *resource; struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; rtex = CALLOC_STRUCT(r600_texture); if (!rtex) return NULL; resource = &rtex->resource; resource->b.b = *base; resource->b.vtbl = &r600_texture_vtbl; pipe_reference_init(&resource->b.b.reference, 1); resource->b.b.screen = screen; /* don't include stencil-only formats which we don't support for rendering */ rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format)); rtex->surface = *surface; if (r600_setup_surface(screen, rtex, pitch_in_bytes_override)) { FREE(rtex); return NULL; } /* Tiled depth textures utilize the non-displayable tile order. * This must be done after r600_setup_surface. * Applies to R600-Cayman. */ rtex->non_disp_tiling = rtex->is_depth && rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D; if (rtex->is_depth) { if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER | R600_RESOURCE_FLAG_FLUSHED_DEPTH)) && !(rscreen->debug_flags & DBG_NO_HYPERZ)) { r600_texture_allocate_htile(rscreen, rtex); } } else { if (base->nr_samples > 1) { if (!buf) { r600_texture_allocate_fmask(rscreen, rtex); r600_texture_allocate_cmask(rscreen, rtex); rtex->cmask_buffer = &rtex->resource; } if (!rtex->fmask.size || !rtex->cmask.size) { FREE(rtex); return NULL; } } if (rtex->surface.dcc_size) vi_texture_alloc_dcc_separate(rscreen, rtex); } /* Now create the backing buffer. */ if (!buf) { if (!r600_init_resource(rscreen, resource, rtex->size, rtex->surface.bo_alignment, TRUE)) { FREE(rtex); return NULL; } } else { resource->buf = buf; resource->gpu_address = rscreen->ws->buffer_get_virtual_address(resource->buf); resource->domains = rscreen->ws->buffer_get_initial_domain(resource->buf); } if (rtex->cmask.size) { /* Initialize the cmask to 0xCC (= compressed state). */ r600_screen_clear_buffer(rscreen, &rtex->cmask_buffer->b.b, rtex->cmask.offset, rtex->cmask.size, 0xCCCCCCCC, true); } /* Initialize the CMASK base register value. */ rtex->cmask.base_address_reg = (rtex->resource.gpu_address + rtex->cmask.offset) >> 8; if (rscreen->debug_flags & DBG_VM) { fprintf(stderr, "VM start=0x%"PRIX64" end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n", rtex->resource.gpu_address, rtex->resource.gpu_address + rtex->resource.buf->size, base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1, base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format)); } if (rscreen->debug_flags & DBG_TEX) { puts("Texture:"); r600_print_texture_info(rtex, stdout); } return rtex; }
/** * Try issuing a quad blit. */ static bool try_blit(struct svga_context *svga, const struct pipe_blit_info *blit_info) { struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; struct pipe_resource *src = blit_info->src.resource; struct pipe_resource *dst = blit_info->dst.resource; struct pipe_resource *newSrc = NULL; struct pipe_resource *newDst = NULL; bool can_create_src_view; bool can_create_dst_view; bool ret = true; struct pipe_blit_info blit = *blit_info; SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_BLITBLITTER); /** * Avoid using util_blitter_blit() for these depth formats on non-vgpu10 * devices because these depth formats only support comparison mode * and not ordinary sampling. */ if (!svga_have_vgpu10(svga) && (blit.mask & PIPE_MASK_Z) && (svga_texture(dst)->key.format == SVGA3D_Z_D16 || svga_texture(dst)->key.format == SVGA3D_Z_D24X8 || svga_texture(dst)->key.format == SVGA3D_Z_D24S8)) { ret = false; goto done; } /** * If format is srgb and blend is enabled then color values need * to be converted into linear format. */ if (is_blending_enabled(svga, &blit)) { blit.src.format = util_format_linear(blit.src.format); blit.dst.format = util_format_linear(blit.dst.format); } /* Check if we can create shader resource view and * render target view for the quad blitter to work */ can_create_src_view = is_view_format_compatible(src->format, svga_texture(src)->key.format, blit.src.format); can_create_dst_view = is_view_format_compatible(dst->format, svga_texture(dst)->key.format, blit.dst.format); if ((blit.mask & PIPE_MASK_S) || ((!can_create_dst_view || !can_create_src_view) && !svga_have_vgpu10(svga))) { /* Can't do stencil blits with textured quad blitter */ debug_warn_once("using software stencil blit"); ret = false; goto done; } if (!util_blitter_is_blit_supported(svga->blitter, &blit)) { debug_printf("svga: blit unsupported %s -> %s\n", util_format_short_name(blit.src.resource->format), util_format_short_name(blit.dst.resource->format)); ret = false; goto done; } /* XXX turn off occlusion and streamout queries */ util_blitter_save_vertex_buffer_slot(svga->blitter, svga->curr.vb); util_blitter_save_vertex_elements(svga->blitter, (void*)svga->curr.velems); util_blitter_save_vertex_shader(svga->blitter, svga->curr.vs); util_blitter_save_geometry_shader(svga->blitter, svga->curr.user_gs); util_blitter_save_so_targets(svga->blitter, svga->num_so_targets, (struct pipe_stream_output_target**)svga->so_targets); util_blitter_save_rasterizer(svga->blitter, (void*)svga->curr.rast); util_blitter_save_viewport(svga->blitter, &svga->curr.viewport); util_blitter_save_scissor(svga->blitter, &svga->curr.scissor); util_blitter_save_fragment_shader(svga->blitter, svga->curr.fs); util_blitter_save_blend(svga->blitter, (void*)svga->curr.blend); util_blitter_save_depth_stencil_alpha(svga->blitter, (void*)svga->curr.depth); util_blitter_save_stencil_ref(svga->blitter, &svga->curr.stencil_ref); util_blitter_save_sample_mask(svga->blitter, svga->curr.sample_mask); util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer); util_blitter_save_fragment_sampler_states(svga->blitter, svga->curr.num_samplers[PIPE_SHADER_FRAGMENT], (void**)svga->curr.sampler[PIPE_SHADER_FRAGMENT]); util_blitter_save_fragment_sampler_views(svga->blitter, svga->curr.num_sampler_views[PIPE_SHADER_FRAGMENT], svga->curr.sampler_views[PIPE_SHADER_FRAGMENT]); if (!can_create_src_view) { struct pipe_resource template; struct pipe_blit_info copy_region_blit;
void si_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct si_context *sctx = (struct si_context *)ctx; struct pipe_surface *dst_view, dst_templ; struct pipe_sampler_view src_templ, *src_view; unsigned dst_width, dst_height, src_width0, src_height0; unsigned src_force_level = 0; struct pipe_box sbox, dstbox; /* Handle buffers first. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { si_copy_buffer(sctx, dst, src, dstx, src_box->x, src_box->width); return; } assert(u_max_sample(dst) == u_max_sample(src)); /* The driver doesn't decompress resources automatically while * u_blitter is rendering. */ si_decompress_subresource(ctx, src, PIPE_MASK_RGBAZS, src_level, src_box->z, src_box->z + src_box->depth - 1); dst_width = u_minify(dst->width0, dst_level); dst_height = u_minify(dst->height0, dst_level); src_width0 = src->width0; src_height0 = src->height0; util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); util_blitter_default_src_texture(&src_templ, src, src_level); if (util_format_is_compressed(src->format) || util_format_is_compressed(dst->format)) { unsigned blocksize = util_format_get_blocksize(src->format); if (blocksize == 8) src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */ else src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */ dst_templ.format = src_templ.format; dst_width = util_format_get_nblocksx(dst->format, dst_width); dst_height = util_format_get_nblocksy(dst->format, dst_height); src_width0 = util_format_get_nblocksx(src->format, src_width0); src_height0 = util_format_get_nblocksy(src->format, src_height0); dstx = util_format_get_nblocksx(dst->format, dstx); dsty = util_format_get_nblocksy(dst->format, dsty); sbox.x = util_format_get_nblocksx(src->format, src_box->x); sbox.y = util_format_get_nblocksy(src->format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(src->format, src_box->width); sbox.height = util_format_get_nblocksy(src->format, src_box->height); sbox.depth = src_box->depth; src_box = &sbox; src_force_level = src_level; } else if (!util_blitter_is_copy_supported(sctx->blitter, dst, src) || /* also *8_SNORM has precision issues, use UNORM instead */ util_format_is_snorm8(src->format)) { if (util_format_is_subsampled_422(src->format)) { src_templ.format = PIPE_FORMAT_R8G8B8A8_UINT; dst_templ.format = PIPE_FORMAT_R8G8B8A8_UINT; dst_width = util_format_get_nblocksx(dst->format, dst_width); src_width0 = util_format_get_nblocksx(src->format, src_width0); dstx = util_format_get_nblocksx(dst->format, dstx); sbox = *src_box; sbox.x = util_format_get_nblocksx(src->format, src_box->x); sbox.width = util_format_get_nblocksx(src->format, src_box->width); src_box = &sbox; } else { unsigned blocksize = util_format_get_blocksize(src->format); switch (blocksize) { case 1: dst_templ.format = PIPE_FORMAT_R8_UNORM; src_templ.format = PIPE_FORMAT_R8_UNORM; break; case 2: dst_templ.format = PIPE_FORMAT_R8G8_UNORM; src_templ.format = PIPE_FORMAT_R8G8_UNORM; break; case 4: dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; src_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; break; case 8: dst_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; break; case 16: dst_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; break; default: fprintf(stderr, "Unhandled format %s with blocksize %u\n", util_format_short_name(src->format), blocksize); assert(0); } } } /* Initialize the surface. */ dst_view = r600_create_surface_custom(ctx, dst, &dst_templ, dst_width, dst_height); /* Initialize the sampler view. */ src_view = si_create_sampler_view_custom(ctx, src, &src_templ, src_width0, src_height0, src_force_level); u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), abs(src_box->depth), &dstbox); /* Copy. */ si_blitter_begin(ctx, SI_COPY); util_blitter_blit_generic(sctx->blitter, dst_view, &dstbox, src_view, src_box, src_width0, src_height0, PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, FALSE); si_blitter_end(ctx); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); }
static void si_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct si_context *sctx = (struct si_context *)ctx; struct r600_texture *rdst = (struct r600_texture*)dst; struct pipe_surface *dst_view, dst_templ; struct pipe_sampler_view src_templ, *src_view; struct texture_orig_info orig_info[2]; struct pipe_box sbox, dstbox; boolean restore_orig[2]; /* Fallback for buffers. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { si_copy_buffer(sctx, dst, src, dstx, src_box->x, src_box->width); return; } memset(orig_info, 0, sizeof(orig_info)); /* The driver doesn't decompress resources automatically while * u_blitter is rendering. */ si_decompress_subresource(ctx, src, src_level, src_box->z, src_box->z + src_box->depth - 1); restore_orig[0] = restore_orig[1] = FALSE; if (util_format_is_compressed(src->format) && util_format_is_compressed(dst->format)) { si_compressed_to_blittable(src, src_level, &orig_info[0]); restore_orig[0] = TRUE; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; src_box = &sbox; si_compressed_to_blittable(dst, dst_level, &orig_info[1]); restore_orig[1] = TRUE; /* translate the dst box as well */ dstx = util_format_get_nblocksx(orig_info[1].format, dstx); dsty = util_format_get_nblocksy(orig_info[1].format, dsty); } else if (!util_blitter_is_copy_supported(sctx->blitter, dst, src)) { if (util_format_is_subsampled_422(src->format)) { /* XXX untested */ si_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8G8B8A8_UINT); si_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8G8B8A8_UINT); sbox = *src_box; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); src_box = &sbox; dstx = util_format_get_nblocksx(orig_info[1].format, dstx); restore_orig[0] = TRUE; restore_orig[1] = TRUE; } else { unsigned blocksize = util_format_get_blocksize(src->format); switch (blocksize) { case 1: si_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8_UNORM); si_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8_UNORM); break; case 2: si_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8G8_UNORM); si_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8G8_UNORM); break; case 4: si_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8G8B8A8_UNORM); si_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8G8B8A8_UNORM); break; case 8: si_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R16G16B16A16_UINT); si_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R16G16B16A16_UINT); break; case 16: si_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R32G32B32A32_UINT); si_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R32G32B32A32_UINT); break; default: fprintf(stderr, "Unhandled format %s with blocksize %u\n", util_format_short_name(src->format), blocksize); assert(0); } restore_orig[0] = TRUE; restore_orig[1] = TRUE; } } /* Initialize the surface. */ util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); dst_view = r600_create_surface_custom(ctx, dst, &dst_templ, rdst->surface.level[dst_level].npix_x, rdst->surface.level[dst_level].npix_y); /* Initialize the sampler view. */ util_blitter_default_src_texture(&src_templ, src, src_level); src_view = ctx->create_sampler_view(ctx, src, &src_templ); u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), abs(src_box->depth), &dstbox); /* Copy. */ si_blitter_begin(ctx, SI_COPY); util_blitter_blit_generic(sctx->blitter, dst_view, &dstbox, src_view, src_box, src->width0, src->height0, PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); si_blitter_end(ctx); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); if (restore_orig[0]) si_reset_blittable_to_orig(src, src_level, &orig_info[0]); if (restore_orig[1]) si_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); }
static void r600_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct r600_context *rctx = (struct r600_context *)ctx; struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; struct texture_orig_info orig_info[2]; struct pipe_box sbox; const struct pipe_box *psbox = src_box; boolean restore_orig[2]; memset(orig_info, 0, sizeof(orig_info)); /* Fallback for buffers. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box); return; } /* This must be done before entering u_blitter to avoid recursion. */ if (rsrc->is_depth && !rsrc->is_flushing_texture) { si_blit_decompress_depth_in_place(rctx, rsrc, src_level, src_level, src_box->z, src_box->z + src_box->depth - 1); } restore_orig[0] = restore_orig[1] = FALSE; if (util_format_is_compressed(src->format) && util_format_is_compressed(dst->format)) { r600_compressed_to_blittable(src, src_level, &orig_info[0]); restore_orig[0] = TRUE; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; psbox=&sbox; r600_compressed_to_blittable(dst, dst_level, &orig_info[1]); restore_orig[1] = TRUE; /* translate the dst box as well */ dstx = util_format_get_nblocksx(orig_info[1].format, dstx); dsty = util_format_get_nblocksy(orig_info[1].format, dsty); } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src, PIPE_MASK_RGBAZS)) { unsigned blocksize = util_format_get_blocksize(src->format); switch (blocksize) { case 1: r600_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8_UNORM); r600_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8_UNORM); break; case 4: r600_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8G8B8A8_UNORM); r600_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8G8B8A8_UNORM); break; default: fprintf(stderr, "Unhandled format %s with blocksize %u\n", util_format_short_name(src->format), blocksize); assert(0); } restore_orig[0] = TRUE; restore_orig[1] = TRUE; } r600_blitter_begin(ctx, R600_COPY); util_blitter_copy_texture(rctx->blitter, dst, dst_level, dstx, dsty, dstz, src, src_level, psbox, PIPE_MASK_RGBAZS, TRUE); r600_blitter_end(ctx); if (restore_orig[0]) r600_reset_blittable_to_orig(src, src_level, &orig_info[0]); if (restore_orig[1]) r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); }
/* Common processing for r600_texture_create and r600_texture_from_handle */ static struct r600_texture * r600_texture_create_object(struct pipe_screen *screen, const struct pipe_resource *base, unsigned pitch_in_bytes_override, struct pb_buffer *buf, struct radeon_surf *surface) { struct r600_texture *rtex; struct r600_resource *resource; struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; rtex = CALLOC_STRUCT(r600_texture); if (rtex == NULL) return NULL; resource = &rtex->resource; resource->b.b = *base; resource->b.vtbl = &r600_texture_vtbl; pipe_reference_init(&resource->b.b.reference, 1); resource->b.b.screen = screen; rtex->pitch_override = pitch_in_bytes_override; /* don't include stencil-only formats which we don't support for rendering */ rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format)); rtex->surface = *surface; if (r600_setup_surface(screen, rtex, pitch_in_bytes_override)) { FREE(rtex); return NULL; } /* Tiled depth textures utilize the non-displayable tile order. * This must be done after r600_setup_surface. * Applies to R600-Cayman. */ rtex->non_disp_tiling = rtex->is_depth && rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D; if (rtex->is_depth) { if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER | R600_RESOURCE_FLAG_FLUSHED_DEPTH)) && !(rscreen->debug_flags & DBG_NO_HYPERZ)) { r600_texture_allocate_htile(rscreen, rtex); } } else { if (base->nr_samples > 1) { if (!buf) { r600_texture_allocate_fmask(rscreen, rtex); r600_texture_allocate_cmask(rscreen, rtex); rtex->cmask_buffer = &rtex->resource; } if (!rtex->fmask.size || !rtex->cmask.size) { FREE(rtex); return NULL; } } } /* Now create the backing buffer. */ if (!buf) { if (!r600_init_resource(rscreen, resource, rtex->size, rtex->surface.bo_alignment, TRUE)) { FREE(rtex); return NULL; } } else { resource->buf = buf; resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf); resource->gpu_address = rscreen->ws->buffer_get_virtual_address(resource->cs_buf); resource->domains = rscreen->ws->buffer_get_initial_domain(resource->cs_buf); } if (rtex->cmask.size) { /* Initialize the cmask to 0xCC (= compressed state). */ r600_screen_clear_buffer(rscreen, &rtex->cmask_buffer->b.b, rtex->cmask.offset, rtex->cmask.size, 0xCCCCCCCC, true); } /* Initialize the CMASK base register value. */ rtex->cmask.base_address_reg = (rtex->resource.gpu_address + rtex->cmask.offset) >> 8; if (rscreen->debug_flags & DBG_VM) { fprintf(stderr, "VM start=0x%"PRIX64" end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n", rtex->resource.gpu_address, rtex->resource.gpu_address + rtex->resource.buf->size, base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1, base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format)); } if (rscreen->debug_flags & DBG_TEX || (rtex->resource.b.b.last_level > 0 && rscreen->debug_flags & DBG_TEXMIP)) { printf("Texture: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, " "blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, " "bpe=%u, nsamples=%u, flags=0x%x, %s\n", rtex->surface.npix_x, rtex->surface.npix_y, rtex->surface.npix_z, rtex->surface.blk_w, rtex->surface.blk_h, rtex->surface.blk_d, rtex->surface.array_size, rtex->surface.last_level, rtex->surface.bpe, rtex->surface.nsamples, rtex->surface.flags, util_format_short_name(base->format)); for (int i = 0; i <= rtex->surface.last_level; i++) { printf(" L %i: offset=%"PRIu64", slice_size=%"PRIu64", npix_x=%u, " "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, " "nblk_z=%u, pitch_bytes=%u, mode=%u\n", i, rtex->surface.level[i].offset, rtex->surface.level[i].slice_size, u_minify(rtex->resource.b.b.width0, i), u_minify(rtex->resource.b.b.height0, i), u_minify(rtex->resource.b.b.depth0, i), rtex->surface.level[i].nblk_x, rtex->surface.level[i].nblk_y, rtex->surface.level[i].nblk_z, rtex->surface.level[i].pitch_bytes, rtex->surface.level[i].mode); } if (rtex->surface.flags & RADEON_SURF_SBUFFER) { for (int i = 0; i <= rtex->surface.last_level; i++) { printf(" S %i: offset=%"PRIu64", slice_size=%"PRIu64", npix_x=%u, " "npix_y=%u, npix_z=%u, nblk_x=%u, nblk_y=%u, " "nblk_z=%u, pitch_bytes=%u, mode=%u\n", i, rtex->surface.stencil_level[i].offset, rtex->surface.stencil_level[i].slice_size, u_minify(rtex->resource.b.b.width0, i), u_minify(rtex->resource.b.b.height0, i), u_minify(rtex->resource.b.b.depth0, i), rtex->surface.stencil_level[i].nblk_x, rtex->surface.stencil_level[i].nblk_y, rtex->surface.stencil_level[i].nblk_z, rtex->surface.stencil_level[i].pitch_bytes, rtex->surface.stencil_level[i].mode); } } } return rtex; }
static void r600_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, const struct pipe_box *src_box) { struct r600_context *rctx = (struct r600_context *)ctx; struct r600_texture *rsrc = (struct r600_texture*)src; struct texture_orig_info orig_info[2]; struct pipe_box sbox; const struct pipe_box *psbox = src_box; boolean restore_orig[2]; unsigned last_sample, i; memset(orig_info, 0, sizeof(orig_info)); /* Handle buffers first. */ if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { r600_copy_buffer(ctx, dst, dstx, src, src_box); return; } assert(u_max_sample(dst) == u_max_sample(src)); last_sample = u_max_sample(dst); /* This must be done before entering u_blitter to avoid recursion. */ if (rsrc->is_depth && !rsrc->is_flushing_texture) { if (!r600_init_flushed_depth_texture(ctx, src, NULL)) return; /* error */ r600_blit_uncompress_depth(ctx, rsrc, NULL, src_level, src_level, src_box->z, src_box->z + src_box->depth - 1, 0, u_max_sample(src)); } restore_orig[0] = restore_orig[1] = FALSE; if (util_format_is_compressed(src->format) && util_format_is_compressed(dst->format)) { r600_compressed_to_blittable(src, src_level, &orig_info[0]); restore_orig[0] = TRUE; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y); sbox.z = src_box->z; sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; psbox = &sbox; r600_compressed_to_blittable(dst, dst_level, &orig_info[1]); restore_orig[1] = TRUE; /* translate the dst box as well */ dstx = util_format_get_nblocksx(orig_info[1].format, dstx); dsty = util_format_get_nblocksy(orig_info[1].format, dsty); } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src, PIPE_MASK_RGBAZS)) { if (util_format_is_subsampled_2x1_32bpp(src->format) && util_format_is_subsampled_2x1_32bpp(dst->format)) { r600_subsampled_2x1_32bpp_to_blittable(src, src_level, &orig_info[0]); r600_subsampled_2x1_32bpp_to_blittable(dst, dst_level, &orig_info[1]); sbox = *src_box; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); psbox = &sbox; dstx = util_format_get_nblocksx(orig_info[1].format, dstx); } else { unsigned blocksize = util_format_get_blocksize(src->format); switch (blocksize) { case 1: r600_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8_UNORM); r600_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8_UNORM); break; case 4: r600_change_format(src, src_level, &orig_info[0], PIPE_FORMAT_R8G8B8A8_UNORM); r600_change_format(dst, dst_level, &orig_info[1], PIPE_FORMAT_R8G8B8A8_UNORM); break; default: fprintf(stderr, "Unhandled format %s with blocksize %u\n", util_format_short_name(src->format), blocksize); assert(0); } } restore_orig[0] = TRUE; restore_orig[1] = TRUE; } for (i = 0; i <= last_sample; i++) { r600_blitter_begin(ctx, R600_COPY_TEXTURE); util_blitter_copy_texture(rctx->blitter, dst, dst_level, 1 << i, dstx, dsty, dstz, src, src_level, i, psbox); r600_blitter_end(ctx); } if (restore_orig[0]) r600_reset_blittable_to_orig(src, src_level, &orig_info[0]); if (restore_orig[1]) r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); }