Mesa (main): llvmpipe: implement FB fetch for depth/stencil

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 22 05:02:10 UTC 2022


Module: Mesa
Branch: main
Commit: ccaa7920ef6534b6ce1cff7a48d5f84369cfc398
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ccaa7920ef6534b6ce1cff7a48d5f84369cfc398

Author: Pavel Asyutchenko <sventeam at yandex.ru>
Date:   Sun Jun 19 21:16:26 2022 +0300

llvmpipe: implement FB fetch for depth/stencil

Signed-off-by: Pavel Asyutchenko <sventeam at yandex.ru>
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13979>

---

 src/gallium/drivers/llvmpipe/lp_state_fs.c | 80 +++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index cff9fd8e016..506be8dd2e5 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -427,6 +427,9 @@ struct lp_build_fs_llvm_iface {
    LLVMValueRef color_ptr_ptr;
    LLVMValueRef color_stride_ptr;
    LLVMValueRef color_sample_stride_ptr;
+   LLVMValueRef zs_base_ptr;
+   LLVMValueRef zs_stride;
+   LLVMValueRef zs_sample_stride;
    const struct lp_fragment_shader_variant_key *key;
 };
 
@@ -452,6 +455,29 @@ fs_interp(const struct lp_build_fs_iface *iface,
                               attrib, chan, loc, attrib_indir, offsets);
 }
 
+/* Convert depth-stencil format to a single component one, returning
+ * PIPE_FORMAT_NONE if it doesn't contain the required component. */
+static enum pipe_format
+select_zs_component_format(enum pipe_format format,
+                           bool fetch_stencil)
+{
+   const struct util_format_description* desc = util_format_description(format);
+   if (fetch_stencil && !util_format_has_stencil(desc))
+      return PIPE_FORMAT_NONE;
+   if (!fetch_stencil && !util_format_has_depth(desc))
+      return PIPE_FORMAT_NONE;
+
+   switch (format) {
+   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+      return fetch_stencil ? PIPE_FORMAT_X24S8_UINT : PIPE_FORMAT_Z24X8_UNORM;
+   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
+      return fetch_stencil ? PIPE_FORMAT_S8X24_UINT : PIPE_FORMAT_X8Z24_UNORM;
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      return fetch_stencil ? PIPE_FORMAT_X32_S8X24_UINT : format;
+   default:
+      return format;
+   }
+}
 
 static void
 fs_fb_fetch(const struct lp_build_fs_iface *iface,
@@ -459,19 +485,33 @@ fs_fb_fetch(const struct lp_build_fs_iface *iface,
             int location,
             LLVMValueRef result[4])
 {
-   assert(location >= FRAG_RESULT_DATA0 && location <= FRAG_RESULT_DATA7);
-   const int cbuf = location - FRAG_RESULT_DATA0;
-
    struct lp_build_fs_llvm_iface *fs_iface = (struct lp_build_fs_llvm_iface *)iface;
    struct gallivm_state *gallivm = bld->gallivm;
    LLVMBuilderRef builder = gallivm->builder;
    const struct lp_fragment_shader_variant_key *key = fs_iface->key;
-   LLVMValueRef index = lp_build_const_int32(gallivm, cbuf);
-   LLVMValueRef color_ptr = LLVMBuildLoad(builder, LLVMBuildGEP(builder, fs_iface->color_ptr_ptr, &index, 1, ""), "");
-   LLVMValueRef stride = LLVMBuildLoad(builder, LLVMBuildGEP(builder, fs_iface->color_stride_ptr, &index, 1, ""), "");
 
-   enum pipe_format cbuf_format = key->cbuf_format[cbuf];
-   const struct util_format_description* out_format_desc = util_format_description(cbuf_format);
+   LLVMValueRef buf_ptr;
+   LLVMValueRef stride;
+   enum pipe_format buf_format;
+
+   const bool fetch_stencil = location == FRAG_RESULT_STENCIL;
+   const bool fetch_zs = fetch_stencil || location == FRAG_RESULT_DEPTH;
+   if (fetch_zs) {
+      buf_ptr = fs_iface->zs_base_ptr;
+      stride = fs_iface->zs_stride;
+      buf_format = select_zs_component_format(key->zsbuf_format, fetch_stencil);
+   }
+   else {
+      assert(location >= FRAG_RESULT_DATA0 && location <= FRAG_RESULT_DATA7);
+      const int cbuf = location - FRAG_RESULT_DATA0;
+      LLVMValueRef index = lp_build_const_int32(gallivm, cbuf);
+
+      buf_ptr = LLVMBuildLoad(builder, LLVMBuildGEP(builder, fs_iface->color_ptr_ptr, &index, 1, ""), "");
+      stride = LLVMBuildLoad(builder, LLVMBuildGEP(builder, fs_iface->color_stride_ptr, &index, 1, ""), "");
+      buf_format = key->cbuf_format[cbuf];
+   }
+
+   const struct util_format_description* out_format_desc = util_format_description(buf_format);
    if (out_format_desc->format == PIPE_FORMAT_NONE) {
       result[0] = result[1] = result[2] = result[3] = bld->undef;
       return;
@@ -482,11 +522,20 @@ fs_fb_fetch(const struct lp_build_fs_iface *iface,
    unsigned block_width = block_size / block_height;
 
    if (key->multisample) {
-      LLVMValueRef sample_stride = LLVMBuildLoad(builder,
-                                                 LLVMBuildGEP(builder, fs_iface->color_sample_stride_ptr,
-                                                              &index, 1, ""), "");
+      LLVMValueRef sample_stride;
+
+      if (fetch_zs) {
+         sample_stride = fs_iface->zs_sample_stride;
+      }
+      else {
+         LLVMValueRef index = lp_build_const_int32(gallivm, location - FRAG_RESULT_DATA0);
+         sample_stride = LLVMBuildLoad(builder,
+                                       LLVMBuildGEP(builder, fs_iface->color_sample_stride_ptr,
+                                                    &index, 1, ""), "");
+      }
+
       LLVMValueRef sample_offset = LLVMBuildMul(builder, sample_stride, fs_iface->sample_id, "");
-      color_ptr = LLVMBuildGEP(builder, color_ptr, &sample_offset, 1, "");
+      buf_ptr = LLVMBuildGEP(builder, buf_ptr, &sample_offset, 1, "");
    }
 
    /* fragment shader executes on 4x4 blocks. depending on vector width it can
@@ -544,10 +593,12 @@ fs_fb_fetch(const struct lp_build_fs_iface *iface,
       else if (out_format_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) {
          texel_type = lp_type_uint_vec(bld->type.width, bld->type.width * bld->type.length);
       }
+   } else if (fetch_stencil) {
+      texel_type = lp_type_uint_vec(bld->type.width, bld->type.width * bld->type.length);
    }
 
    lp_build_fetch_rgba_soa(gallivm, out_format_desc, texel_type,
-                           true, color_ptr, offset,
+                           true, buf_ptr, offset,
                            NULL, NULL, NULL, result);
 }
 
@@ -955,6 +1006,9 @@ generate_fs_loop(struct gallivm_state *gallivm,
      .color_ptr_ptr = color_ptr_ptr,
      .color_stride_ptr = color_stride_ptr,
      .color_sample_stride_ptr = color_sample_stride_ptr,
+     .zs_base_ptr = depth_base_ptr,
+     .zs_stride = depth_stride,
+     .zs_sample_stride = depth_sample_stride,
      .key = key,
    };
 



More information about the mesa-commit mailing list