"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/zink/zink_blit.c" (16 Sep 2020, 8531 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "zink_blit.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    1 #include "zink_context.h"
    2 #include "zink_helpers.h"
    3 #include "zink_resource.h"
    4 #include "zink_screen.h"
    5 
    6 #include "util/u_blitter.h"
    7 #include "util/format/u_format.h"
    8 
    9 static bool
   10 blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info)
   11 {
   12    if (util_format_get_mask(info->dst.format) != info->mask ||
   13        util_format_get_mask(info->src.format) != info->mask ||
   14        info->scissor_enable ||
   15        info->alpha_blend)
   16       return false;
   17 
   18    struct zink_resource *src = zink_resource(info->src.resource);
   19    struct zink_resource *dst = zink_resource(info->dst.resource);
   20 
   21    struct zink_screen *screen = zink_screen(ctx->base.screen);
   22    if (src->format != zink_get_format(screen, info->src.format) ||
   23        dst->format != zink_get_format(screen, info->dst.format))
   24       return false;
   25 
   26    struct zink_batch *batch = zink_batch_no_rp(ctx);
   27 
   28    zink_batch_reference_resoure(batch, src);
   29    zink_batch_reference_resoure(batch, dst);
   30 
   31    if (src->layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
   32       zink_resource_barrier(batch->cmdbuf, src, src->aspect,
   33                             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
   34 
   35    if (dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
   36       zink_resource_barrier(batch->cmdbuf, dst, dst->aspect,
   37                             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
   38 
   39    VkImageResolve region = {};
   40 
   41    region.srcSubresource.aspectMask = src->aspect;
   42    region.srcSubresource.mipLevel = info->src.level;
   43    region.srcSubresource.baseArrayLayer = 0; // no clue
   44    region.srcSubresource.layerCount = 1; // no clue
   45    region.srcOffset.x = info->src.box.x;
   46    region.srcOffset.y = info->src.box.y;
   47    region.srcOffset.z = info->src.box.z;
   48 
   49    region.dstSubresource.aspectMask = dst->aspect;
   50    region.dstSubresource.mipLevel = info->dst.level;
   51    region.dstSubresource.baseArrayLayer = 0; // no clue
   52    region.dstSubresource.layerCount = 1; // no clue
   53    region.dstOffset.x = info->dst.box.x;
   54    region.dstOffset.y = info->dst.box.y;
   55    region.dstOffset.z = info->dst.box.z;
   56 
   57    region.extent.width = info->dst.box.width;
   58    region.extent.height = info->dst.box.height;
   59    region.extent.depth = info->dst.box.depth;
   60    vkCmdResolveImage(batch->cmdbuf, src->image, src->layout,
   61                      dst->image, dst->layout,
   62                      1, &region);
   63 
   64    return true;
   65 }
   66 
   67 static bool
   68 blit_native(struct zink_context *ctx, const struct pipe_blit_info *info)
   69 {
   70    if (util_format_get_mask(info->dst.format) != info->mask ||
   71        util_format_get_mask(info->src.format) != info->mask ||
   72        info->scissor_enable ||
   73        info->alpha_blend)
   74       return false;
   75 
   76    if (util_format_is_depth_or_stencil(info->dst.format) &&
   77        info->dst.format != info->src.format)
   78       return false;
   79 
   80    struct zink_resource *src = zink_resource(info->src.resource);
   81    struct zink_resource *dst = zink_resource(info->dst.resource);
   82 
   83    struct zink_screen *screen = zink_screen(ctx->base.screen);
   84    if (src->format != zink_get_format(screen, info->src.format) ||
   85        dst->format != zink_get_format(screen, info->dst.format))
   86       return false;
   87 
   88    struct zink_batch *batch = zink_batch_no_rp(ctx);
   89    zink_batch_reference_resoure(batch, src);
   90    zink_batch_reference_resoure(batch, dst);
   91 
   92    if (src == dst) {
   93       /* The Vulkan 1.1 specification says the following about valid usage
   94        * of vkCmdBlitImage:
   95        *
   96        * "srcImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR,
   97        *  VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL"
   98        *
   99        * and:
  100        *
  101        * "dstImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR,
  102        *  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL"
  103        *
  104        * Since we cant have the same image in two states at the same time,
  105        * we're effectively left with VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or
  106        * VK_IMAGE_LAYOUT_GENERAL. And since this isn't a present-related
  107        * operation, VK_IMAGE_LAYOUT_GENERAL seems most appropriate.
  108        */
  109       if (src->layout != VK_IMAGE_LAYOUT_GENERAL)
  110          zink_resource_barrier(batch->cmdbuf, src, src->aspect,
  111                                VK_IMAGE_LAYOUT_GENERAL);
  112    } else {
  113       if (src->layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
  114          zink_resource_barrier(batch->cmdbuf, src, src->aspect,
  115                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
  116 
  117       if (dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
  118          zink_resource_barrier(batch->cmdbuf, dst, dst->aspect,
  119                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
  120    }
  121 
  122    VkImageBlit region = {};
  123    region.srcSubresource.aspectMask = src->aspect;
  124    region.srcSubresource.mipLevel = info->src.level;
  125    region.srcOffsets[0].x = info->src.box.x;
  126    region.srcOffsets[0].y = info->src.box.y;
  127    region.srcOffsets[1].x = info->src.box.x + info->src.box.width;
  128    region.srcOffsets[1].y = info->src.box.y + info->src.box.height;
  129 
  130    if (src->base.array_size > 1) {
  131       region.srcOffsets[0].z = 0;
  132       region.srcOffsets[1].z = 1;
  133       region.srcSubresource.baseArrayLayer = info->src.box.z;
  134       region.srcSubresource.layerCount = info->src.box.depth;
  135    } else {
  136       region.srcOffsets[0].z = info->src.box.z;
  137       region.srcOffsets[1].z = info->src.box.z + info->src.box.depth;
  138       region.srcSubresource.baseArrayLayer = 0;
  139       region.srcSubresource.layerCount = 1;
  140    }
  141 
  142    region.dstSubresource.aspectMask = dst->aspect;
  143    region.dstSubresource.mipLevel = info->dst.level;
  144    region.dstOffsets[0].x = info->dst.box.x;
  145    region.dstOffsets[0].y = info->dst.box.y;
  146    region.dstOffsets[1].x = info->dst.box.x + info->dst.box.width;
  147    region.dstOffsets[1].y = info->dst.box.y + info->dst.box.height;
  148 
  149    if (dst->base.array_size > 1) {
  150       region.dstOffsets[0].z = 0;
  151       region.dstOffsets[1].z = 1;
  152       region.dstSubresource.baseArrayLayer = info->dst.box.z;
  153       region.dstSubresource.layerCount = info->dst.box.depth;
  154    } else {
  155       region.dstOffsets[0].z = info->dst.box.z;
  156       region.dstOffsets[1].z = info->dst.box.z + info->dst.box.depth;
  157       region.dstSubresource.baseArrayLayer = 0;
  158       region.dstSubresource.layerCount = 1;
  159    }
  160 
  161    vkCmdBlitImage(batch->cmdbuf, src->image, src->layout,
  162                   dst->image, dst->layout,
  163                   1, &region,
  164                   zink_filter(info->filter));
  165 
  166    return true;
  167 }
  168 
  169 void
  170 zink_blit(struct pipe_context *pctx,
  171           const struct pipe_blit_info *info)
  172 {
  173    struct zink_context *ctx = zink_context(pctx);
  174    if (info->src.resource->nr_samples > 1 &&
  175        info->dst.resource->nr_samples <= 1) {
  176       if (blit_resolve(ctx, info))
  177          return;
  178    } else {
  179       if (blit_native(ctx, info))
  180          return;
  181    }
  182 
  183    if (!util_blitter_is_blit_supported(ctx->blitter, info)) {
  184       debug_printf("blit unsupported %s -> %s\n",
  185               util_format_short_name(info->src.resource->format),
  186               util_format_short_name(info->dst.resource->format));
  187       return;
  188    }
  189 
  190    util_blitter_save_blend(ctx->blitter, ctx->gfx_pipeline_state.blend_state);
  191    util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->gfx_pipeline_state.depth_stencil_alpha_state);
  192    util_blitter_save_vertex_elements(ctx->blitter, ctx->element_state);
  193    util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref);
  194    util_blitter_save_rasterizer(ctx->blitter, ctx->rast_state);
  195    util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]);
  196    util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]);
  197    util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
  198    util_blitter_save_viewport(ctx->blitter, ctx->viewport_states);
  199    util_blitter_save_scissor(ctx->blitter, ctx->scissor_states);
  200    util_blitter_save_fragment_sampler_states(ctx->blitter,
  201                                              ctx->num_samplers[PIPE_SHADER_FRAGMENT],
  202                                              ctx->sampler_states[PIPE_SHADER_FRAGMENT]);
  203    util_blitter_save_fragment_sampler_views(ctx->blitter,
  204                                             ctx->num_image_views[PIPE_SHADER_FRAGMENT],
  205                                             ctx->image_views[PIPE_SHADER_FRAGMENT]);
  206    util_blitter_save_fragment_constant_buffer_slot(ctx->blitter, ctx->ubos[PIPE_SHADER_FRAGMENT]);
  207    util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->buffers);
  208    util_blitter_save_sample_mask(ctx->blitter, ctx->gfx_pipeline_state.sample_mask);
  209 
  210    util_blitter_blit(ctx->blitter, info);
  211 }