microsoft/compiler: Support descriptor heap indexing for UBO/SSBO
authorJesse Natalie <jenatali@microsoft.com>
Mon, 27 Feb 2023 19:22:35 +0000 (11:22 -0800)
committerMarge Bot <emma+marge@anholt.net>
Thu, 23 Mar 2023 21:48:43 +0000 (21:48 +0000)
Treat load_vulkan_descriptor on an input that didn't come from
vulkan_resource_index as a descriptor heap index instead of a
binding index.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21913>

src/microsoft/compiler/nir_to_dxil.c

index 3432dee..83861b7 100644 (file)
@@ -4510,40 +4510,51 @@ static bool
 emit_load_vulkan_descriptor(struct ntd_context *ctx, nir_intrinsic_instr *intr)
 {
    nir_intrinsic_instr* index = nir_src_as_intrinsic(intr->src[0]);
-   /* We currently do not support reindex */
-   assert(index && index->intrinsic == nir_intrinsic_vulkan_resource_index);
-
-   unsigned binding = nir_intrinsic_binding(index);
-   unsigned space = nir_intrinsic_desc_set(index);
-
-   /* The descriptor_set field for variables is only 5 bits. We shouldn't have intrinsics trying to go beyond that. */
-   assert(space < 32);
-
-   nir_variable *var = nir_get_binding_variable(ctx->shader, nir_chase_binding(intr->src[0]));
-
    const struct dxil_value *handle = NULL;
-   enum dxil_resource_class resource_class;
 
+   enum dxil_resource_class resource_class;
+   enum dxil_resource_kind resource_kind;
    switch (nir_intrinsic_desc_type(intr)) {
    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
       resource_class = DXIL_RESOURCE_CLASS_CBV;
+      resource_kind = DXIL_RESOURCE_KIND_CBUFFER;
       break;
    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
-      if (var->data.access & ACCESS_NON_WRITEABLE)
-         resource_class = DXIL_RESOURCE_CLASS_SRV;
-      else
-         resource_class = DXIL_RESOURCE_CLASS_UAV;
+      resource_class = DXIL_RESOURCE_CLASS_UAV;
+      resource_kind = DXIL_RESOURCE_KIND_RAW_BUFFER;
       break;
    default:
       unreachable("unknown descriptor type");
       return false;
    }
 
-   const struct dxil_value *index_value = get_src(ctx, &intr->src[0], 0, nir_type_uint32);
-   if (!index_value)
-      return false;
+   if (index && index->intrinsic == nir_intrinsic_vulkan_resource_index) {
+      unsigned binding = nir_intrinsic_binding(index);
+      unsigned space = nir_intrinsic_desc_set(index);
+
+      /* The descriptor_set field for variables is only 5 bits. We shouldn't have intrinsics trying to go beyond that. */
+      assert(space < 32);
 
-   handle = emit_createhandle_call_dynamic(ctx, resource_class, space, binding, index_value, false);
+      nir_variable *var = nir_get_binding_variable(ctx->shader, nir_chase_binding(intr->src[0]));
+      if (resource_class == DXIL_RESOURCE_CLASS_UAV &&
+          (var->data.access & ACCESS_NON_WRITEABLE))
+         resource_class = DXIL_RESOURCE_CLASS_SRV;
+
+      const struct dxil_value *index_value = get_src(ctx, &intr->src[0], 0, nir_type_uint32);
+      if (!index_value)
+         return false;
+
+      handle = emit_createhandle_call_dynamic(ctx, resource_class, space, binding, index_value, false);
+   } else {
+      const struct dxil_value *heap_index_value = get_src(ctx, &intr->src[0], 0, nir_type_uint32);
+      if (!heap_index_value)
+         return false;
+      const struct dxil_value *unannotated_handle = emit_createhandle_heap(ctx, heap_index_value, false, true);
+      const struct dxil_value *res_props = dxil_module_get_buffer_res_props_const(&ctx->mod, resource_class, resource_kind);
+      if (!unannotated_handle || !res_props)
+         return false;
+      handle = emit_annotate_handle(ctx, unannotated_handle, res_props);
+   }
 
    store_dest_value(ctx, &intr->dest, 0, handle);
    store_dest(ctx, &intr->dest, 1, get_src(ctx, &intr->src[0], 1, nir_type_uint32), nir_type_uint32);