spirv: Implement SPV_KHR_shader_clock
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Fri, 19 Apr 2019 19:15:16 +0000 (12:15 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 7 Oct 2019 16:12:12 +0000 (09:12 -0700)
We only have the subgroup variant in NIR (equivalent to clockARB), so
only support that for now.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/compiler/shader_info.h
src/compiler/spirv/spirv_to_nir.c

index 8b0176f0438ca91883e548e10b4bc5a172d3624f..740b75b756ad669437e83a164ffbd2d8e8332064 100644 (file)
@@ -60,6 +60,7 @@ struct spirv_supported_capabilities {
    bool post_depth_coverage;
    bool runtime_descriptor_array;
    bool float_controls;
+   bool shader_clock;
    bool shader_viewport_index_layer;
    bool stencil_export;
    bool storage_8bit;
index edffcb0a53fe0fca21b5ffd1762276bfbc98f6d2..abfd8eaef70eeda5b0f9c64eba50e2e6ad58ec74 100644 (file)
@@ -3652,6 +3652,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
          spv_check_supported(demote_to_helper_invocation, cap);
          break;
 
+      case SpvCapabilityShaderClockKHR:
+         spv_check_supported(shader_clock, cap);
+         break;
+
       default:
          vtn_fail("Unhandled capability: %s (%u)",
                   spirv_capability_to_string(cap), cap);
@@ -4554,6 +4558,37 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
       break;
    }
 
+   case SpvOpReadClockKHR: {
+      assert(vtn_constant_uint(b, w[3]) == SpvScopeSubgroup);
+
+      /* Operation supports two result types: uvec2 and uint64_t.  The NIR
+       * intrinsic gives uvec2, so pack the result for the other case.
+       */
+      nir_intrinsic_instr *intrin =
+         nir_intrinsic_instr_create(b->nb.shader, nir_intrinsic_shader_clock);
+      nir_ssa_dest_init(&intrin->instr, &intrin->dest, 2, 32, NULL);
+      nir_builder_instr_insert(&b->nb, &intrin->instr);
+
+      struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
+      const struct glsl_type *dest_type = type->type;
+      nir_ssa_def *result;
+
+      if (glsl_type_is_vector(dest_type)) {
+         assert(dest_type == glsl_vector_type(GLSL_TYPE_UINT, 2));
+         result = &intrin->dest.ssa;
+      } else {
+         assert(glsl_type_is_scalar(dest_type));
+         assert(glsl_get_base_type(dest_type) == GLSL_TYPE_UINT64);
+         result = nir_pack_64_2x32(&b->nb, &intrin->dest.ssa);
+      }
+
+      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+      val->type = type;
+      val->ssa = vtn_create_ssa_value(b, dest_type);
+      val->ssa->def = result;
+      break;
+   }
+
    default:
       vtn_fail_with_opcode("Unhandled opcode", opcode);
    }