anv/apply_pipeline_layout: Prepare for multi-planar images
[mesa.git] / src / intel / vulkan / anv_private.h
index f9537c2b2450c43cba6d0d4bbe4a79353961aae4..ff1b1cc8a80cb478fa79148482bdba52727d46fc 100644 (file)
@@ -61,6 +61,8 @@ typedef uint32_t xcb_window_t;
 struct anv_buffer;
 struct anv_buffer_view;
 struct anv_image_view;
+struct anv_instance;
+struct anv_debug_report_callback;
 
 struct gen_l3_config;
 
@@ -195,20 +197,127 @@ vk_to_isl_color(VkClearColorValue color)
    memcpy((dest), (src), (count) * sizeof(*(src))); \
 })
 
+/* Mapping from anv object to VkDebugReportObjectTypeEXT. New types need
+ * to be added here in order to utilize mapping in debug/error/perf macros.
+ */
+#define REPORT_OBJECT_TYPE(o)                                                      \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_instance*),              \
+   VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,                                       \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_physical_device*),       \
+   VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,                                \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_device*),                \
+   VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,                                         \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), const struct anv_device*),          \
+   VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,                                         \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_queue*),                 \
+   VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,                                          \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_semaphore*),             \
+   VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,                                      \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_cmd_buffer*),            \
+   VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,                                 \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_fence*),                 \
+   VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT,                                          \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_device_memory*),         \
+   VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,                                  \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_buffer*),                \
+   VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,                                         \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_image*),                 \
+   VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,                                          \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), const struct anv_image*),           \
+   VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,                                          \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_event*),                 \
+   VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,                                          \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_query_pool*),            \
+   VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT,                                     \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_buffer_view*),           \
+   VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT,                                    \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_image_view*),            \
+   VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT,                                     \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_shader_module*),         \
+   VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,                                  \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_pipeline_cache*),        \
+   VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT,                                 \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_pipeline_layout*),       \
+   VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT,                                \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_render_pass*),           \
+   VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,                                    \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_pipeline*),              \
+   VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,                                       \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_descriptor_set_layout*), \
+   VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT,                          \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_sampler*),               \
+   VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT,                                        \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_descriptor_pool*),       \
+   VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,                                \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_descriptor_set*),        \
+   VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,                                 \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_framebuffer*),           \
+   VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT,                                    \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_cmd_pool*),              \
+   VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT,                                   \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_surface*),               \
+   VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT,                                    \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct wsi_swapchain*),             \
+   VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,                                  \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), struct anv_debug_callback*),        \
+   VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT,                      \
+   __builtin_choose_expr (                                                         \
+   __builtin_types_compatible_p (__typeof (o), void*),                             \
+   VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,                                        \
+   /* The void expression results in a compile-time error                          \
+      when assigning the result to something.  */                                  \
+   (void)0)))))))))))))))))))))))))))))))
+
 /* Whenever we generate an error, pass it through this function. Useful for
  * debugging, where we can break on it. Only call at error site, not when
  * propagating errors. Might be useful to plug in a stack trace here.
  */
 
-VkResult __vk_errorf(VkResult error, const char *file, int line, const char *format, ...);
+VkResult __vk_errorf(struct anv_instance *instance, const void *object,
+                     VkDebugReportObjectTypeEXT type, VkResult error,
+                     const char *file, int line, const char *format, ...);
 
 #ifdef DEBUG
-#define vk_error(error) __vk_errorf(error, __FILE__, __LINE__, NULL);
-#define vk_errorf(error, format, ...) __vk_errorf(error, __FILE__, __LINE__, format, ## __VA_ARGS__);
+#define vk_error(error) __vk_errorf(NULL, NULL,\
+                                    VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,\
+                                    error, __FILE__, __LINE__, NULL);
+#define vk_errorf(instance, obj, error, format, ...)\
+    __vk_errorf(instance, obj, REPORT_OBJECT_TYPE(obj), error,\
+                __FILE__, __LINE__, format, ## __VA_ARGS__);
 #define anv_debug(format, ...) fprintf(stderr, "debug: " format, ##__VA_ARGS__)
 #else
 #define vk_error(error) error
-#define vk_errorf(error, format, ...) error
+#define vk_errorf(instance, obj, error, format, ...) error
 #define anv_debug(format, ...)
 #endif
 
@@ -228,15 +337,26 @@ VkResult __vk_errorf(VkResult error, const char *file, int line, const char *for
  *    defined by extensions supported by that component.
  */
 #define anv_debug_ignored_stype(sType) \
-   anv_debug("debug: %s: ignored VkStructureType %u\n", __func__, (sType))
+   anv_debug("%s: ignored VkStructureType %u\n", __func__, (sType))
 
 void __anv_finishme(const char *file, int line, const char *format, ...)
    anv_printflike(3, 4);
-void __anv_perf_warn(const char *file, int line, const char *format, ...)
-   anv_printflike(3, 4);
+void __anv_perf_warn(struct anv_instance *instance, const void *object,
+                     VkDebugReportObjectTypeEXT type, const char *file,
+                     int line, const char *format, ...)
+   anv_printflike(6, 7);
 void anv_loge(const char *format, ...) anv_printflike(1, 2);
 void anv_loge_v(const char *format, va_list va);
 
+void anv_debug_report(struct anv_instance *instance,
+                      VkDebugReportFlagsEXT flags,
+                      VkDebugReportObjectTypeEXT object_type,
+                      uint64_t handle,
+                      size_t location,
+                      int32_t messageCode,
+                      const char* pLayerPrefix,
+                      const char *pMessage);
+
 /**
  * Print a FINISHME message, including its source location.
  */
@@ -252,11 +372,12 @@ void anv_loge_v(const char *format, va_list va);
 /**
  * Print a perf warning message.  Set INTEL_DEBUG=perf to see these.
  */
-#define anv_perf_warn(format, ...) \
+#define anv_perf_warn(instance, obj, format, ...) \
    do { \
       static bool reported = false; \
       if (!reported && unlikely(INTEL_DEBUG & DEBUG_PERF)) { \
-         __anv_perf_warn(__FILE__, __LINE__, format, ##__VA_ARGS__); \
+         __anv_perf_warn(instance, obj, REPORT_OBJECT_TYPE(obj), __FILE__, __LINE__,\
+                         format, ##__VA_ARGS__); \
          reported = true; \
       } \
    } while (0)
@@ -666,6 +787,14 @@ struct anv_physical_device {
     int                                         local_fd;
 };
 
+struct anv_debug_report_callback {
+   /* Link in the 'callbacks' list in anv_instance struct. */
+   struct list_head                             link;
+   VkDebugReportFlagsEXT                        flags;
+   PFN_vkDebugReportCallbackEXT                 callback;
+   void *                                       data;
+};
+
 struct anv_instance {
     VK_LOADER_DATA                              _loader_data;
 
@@ -674,6 +803,11 @@ struct anv_instance {
     uint32_t                                    apiVersion;
     int                                         physicalDeviceCount;
     struct anv_physical_device                  physicalDevice;
+
+    /* VK_EXT_debug_report debug callbacks */
+    pthread_mutex_t                             callbacks_mutex;
+    struct list_head                            callbacks;
+    struct anv_debug_report_callback            destroy_debug_cb;
 };
 
 VkResult anv_init_wsi(struct anv_physical_device *physical_device);
@@ -810,6 +944,10 @@ uint32_t anv_gem_syncobj_create(struct anv_device *device, uint32_t flags);
 void anv_gem_syncobj_destroy(struct anv_device *device, uint32_t handle);
 int anv_gem_syncobj_handle_to_fd(struct anv_device *device, uint32_t handle);
 uint32_t anv_gem_syncobj_fd_to_handle(struct anv_device *device, int fd);
+int anv_gem_syncobj_export_sync_file(struct anv_device *device,
+                                     uint32_t handle);
+int anv_gem_syncobj_import_sync_file(struct anv_device *device,
+                                     uint32_t handle, int fd);
 void anv_gem_syncobj_reset(struct anv_device *device, uint32_t handle);
 bool anv_gem_supports_syncobj_wait(int fd);
 int anv_gem_syncobj_wait(struct anv_device *device,
@@ -1185,6 +1323,9 @@ struct anv_descriptor_update_template {
    struct anv_descriptor_template_entry entries[0];
 };
 
+size_t
+anv_descriptor_set_binding_layout_get_hw_size(const struct anv_descriptor_set_binding_layout *binding);
+
 size_t
 anv_descriptor_set_layout_size(const struct anv_descriptor_set_layout *layout);
 
@@ -1242,10 +1383,13 @@ struct anv_pipeline_binding {
    uint8_t set;
 
    /* Binding in the descriptor set */
-   uint8_t binding;
+   uint32_t binding;
 
    /* Index in the binding */
-   uint8_t index;
+   uint32_t index;
+
+   /* Plane in the binding index */
+   uint8_t plane;
 
    /* Input attachment index (relative to the subpass) */
    uint8_t input_attachment_index;
@@ -1422,13 +1566,6 @@ struct anv_push_constants {
    /* Push constant data provided by the client through vkPushConstants */
    uint8_t client_data[MAX_PUSH_CONSTANTS_SIZE];
 
-   /* Our hardware only provides zero-based vertex and instance id so, in
-    * order to satisfy the vulkan requirements, we may have to push one or
-    * both of these into the shader.
-    */
-   uint32_t base_vertex;
-   uint32_t base_instance;
-
    /* Image data for image_load_store on pre-SKL */
    struct brw_image_param images[MAX_IMAGES];
 };
@@ -1481,6 +1618,23 @@ void anv_dynamic_state_copy(struct anv_dynamic_state *dest,
                             const struct anv_dynamic_state *src,
                             uint32_t copy_mask);
 
+struct anv_surface_state {
+   struct anv_state state;
+   /** Address of the surface referred to by this state
+    *
+    * This address is relative to the start of the BO.
+    */
+   uint64_t address;
+   /* Address of the aux surface, if any
+    *
+    * This field is 0 if and only if no aux surface exists.
+    *
+    * This address is relative to the start of the BO.  On gen7, the bottom 12
+    * bits of this address include extra aux information.
+    */
+   uint64_t aux_address;
+};
+
 /**
  * Attachment state when recording a renderpass instance.
  *
@@ -1489,8 +1643,8 @@ void anv_dynamic_state_copy(struct anv_dynamic_state *dest,
 struct anv_attachment_state {
    enum isl_aux_usage                           aux_usage;
    enum isl_aux_usage                           input_aux_usage;
-   struct anv_state                             color_rt_state;
-   struct anv_state                             input_att_state;
+   struct anv_surface_state                     color;
+   struct anv_surface_state                     input;
 
    VkImageLayout                                current_layout;
    VkImageAspectFlags                           pending_clear_aspects;
@@ -1757,7 +1911,7 @@ struct anv_fence_impl {
 struct anv_fence {
    /* Permanent fence state.  Every fence has some form of permanent state
     * (type != ANV_SEMAPHORE_TYPE_NONE).  This may be a BO to fence on (for
-    * cross-process fences0 or it could just be a dummy for use internally.
+    * cross-process fences) or it could just be a dummy for use internally.
     */
    struct anv_fence_impl permanent;
 
@@ -1795,13 +1949,13 @@ struct anv_semaphore_impl {
        */
       struct anv_bo *bo;
 
-      /* The sync file descriptor when type == AKV_SEMAPHORE_TYPE_SYNC_FILE.
+      /* The sync file descriptor when type == ANV_SEMAPHORE_TYPE_SYNC_FILE.
        * If the semaphore is in the unsignaled state due to either just being
        * created or because it has been used for a wait, fd will be -1.
        */
       int fd;
 
-      /* Sync object handle when type == AKV_SEMAPHORE_TYPE_DRM_SYNCOBJ.
+      /* Sync object handle when type == ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ.
        * Unlike GEM BOs, DRM sync objects aren't deduplicated by the kernel on
        * import so we don't need to bother with a userspace cache.
        */
@@ -2021,20 +2175,69 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
                         const char *entrypoint,
                         const VkSpecializationInfo *spec_info);
 
-struct anv_format {
+struct anv_format_plane {
    enum isl_format isl_format:16;
    struct isl_swizzle swizzle;
+
+   /* Whether this plane contains chroma channels */
+   bool has_chroma;
+
+   /* For downscaling of YUV planes */
+   uint8_t denominator_scales[2];
+
+   /* How to map sampled ycbcr planes to a single 4 component element. */
+   struct isl_swizzle ycbcr_swizzle;
 };
 
-struct anv_format
-anv_get_format(const struct gen_device_info *devinfo, VkFormat format,
-               VkImageAspectFlags aspect, VkImageTiling tiling);
+
+struct anv_format {
+   struct anv_format_plane planes[3];
+   uint8_t n_planes;
+   bool can_ycbcr;
+};
+
+static inline uint32_t
+anv_image_aspect_to_plane(VkImageAspectFlags image_aspects,
+                          VkImageAspectFlags aspect_mask)
+{
+   switch (aspect_mask) {
+   case VK_IMAGE_ASPECT_COLOR_BIT:
+   case VK_IMAGE_ASPECT_DEPTH_BIT:
+   case VK_IMAGE_ASPECT_PLANE_0_BIT_KHR:
+      return 0;
+   case VK_IMAGE_ASPECT_STENCIL_BIT:
+      if ((image_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) == 0)
+         return 0;
+      /* Fall-through */
+   case VK_IMAGE_ASPECT_PLANE_1_BIT_KHR:
+      return 1;
+   case VK_IMAGE_ASPECT_PLANE_2_BIT_KHR:
+      return 2;
+   default:
+      unreachable("invalid image aspect");
+   }
+}
+
+const struct anv_format *
+anv_get_format(VkFormat format);
+
+static inline uint32_t
+anv_get_format_planes(VkFormat vk_format)
+{
+   const struct anv_format *format = anv_get_format(vk_format);
+
+   return format != NULL ? format->n_planes : 0;
+}
+
+struct anv_format_plane
+anv_get_format_plane(const struct gen_device_info *devinfo, VkFormat vk_format,
+                     VkImageAspectFlags aspect, VkImageTiling tiling);
 
 static inline enum isl_format
 anv_get_isl_format(const struct gen_device_info *devinfo, VkFormat vk_format,
                    VkImageAspectFlags aspect, VkImageTiling tiling)
 {
-   return anv_get_format(devinfo, vk_format, aspect, tiling).isl_format;
+   return anv_get_format_plane(devinfo, vk_format, aspect, tiling).isl_format;
 }
 
 static inline struct isl_swizzle
@@ -2110,6 +2313,13 @@ struct anv_image {
       };
    };
 
+   /**
+    * A surface which shadows the main surface and may have different tiling.
+    * This is used for sampling using a tiling that isn't supported for other
+    * operations.
+    */
+   struct anv_surface shadow_surface;
+
    /**
     * For color images, this is the aux usage for this image when not used as a
     * color attachment.
@@ -2197,6 +2407,13 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,
                      const uint32_t base_level, const uint32_t level_count,
                      const uint32_t base_layer, uint32_t layer_count);
 
+void
+anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer,
+                         const struct anv_image *image,
+                         VkImageAspectFlagBits aspect,
+                         uint32_t base_level, uint32_t level_count,
+                         uint32_t base_layer, uint32_t layer_count);
+
 enum isl_aux_usage
 anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
                         const struct anv_image *image,
@@ -2221,8 +2438,6 @@ anv_get_levelCount(const struct anv_image *image,
 
 struct anv_image_view {
    const struct anv_image *image; /**< VkImageViewCreateInfo::image */
-   struct anv_bo *bo;
-   uint32_t offset; /**< Offset into bo. */
 
    struct isl_view isl;
 
@@ -2234,27 +2449,41 @@ struct anv_image_view {
     * RENDER_SURFACE_STATE when using image as a sampler surface with an image
     * layout of SHADER_READ_ONLY_OPTIMAL or DEPTH_STENCIL_READ_ONLY_OPTIMAL.
     */
-   enum isl_aux_usage optimal_sampler_aux_usage;
-   struct anv_state optimal_sampler_surface_state;
+   struct anv_surface_state optimal_sampler_surface_state;
 
    /**
     * RENDER_SURFACE_STATE when using image as a sampler surface with an image
     * layout of GENERAL.
     */
-   enum isl_aux_usage general_sampler_aux_usage;
-   struct anv_state general_sampler_surface_state;
+   struct anv_surface_state general_sampler_surface_state;
 
    /**
     * RENDER_SURFACE_STATE when using image as a storage image. Separate states
     * for write-only and readable, using the real format for write-only and the
     * lowered format for readable.
     */
-   struct anv_state storage_surface_state;
-   struct anv_state writeonly_storage_surface_state;
+   struct anv_surface_state storage_surface_state;
+   struct anv_surface_state writeonly_storage_surface_state;
 
    struct brw_image_param storage_image_param;
 };
 
+enum anv_image_view_state_flags {
+   ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY   = (1 << 0),
+   ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL      = (1 << 1),
+};
+
+void anv_image_fill_surface_state(struct anv_device *device,
+                                  const struct anv_image *image,
+                                  VkImageAspectFlagBits aspect,
+                                  const struct isl_view *view,
+                                  isl_surf_usage_flags_t view_usage,
+                                  enum isl_aux_usage aux_usage,
+                                  const union isl_color_value *clear_color,
+                                  enum anv_image_view_state_flags flags,
+                                  struct anv_surface_state *state_inout,
+                                  struct brw_image_param *image_param_out);
+
 struct anv_image_create_info {
    const VkImageCreateInfo *vk_info;
 
@@ -2317,6 +2546,7 @@ void anv_fill_buffer_surface_state(struct anv_device *device,
 
 struct anv_sampler {
    uint32_t state[4];
+   uint32_t n_planes;
 };
 
 struct anv_framebuffer {
@@ -2489,6 +2719,7 @@ ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_render_pass, VkRenderPass)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_sampler, VkSampler)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_semaphore, VkSemaphore)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_shader_module, VkShaderModule)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_debug_report_callback, VkDebugReportCallbackEXT)
 
 /* Gen-specific function declarations */
 #ifdef genX