/*
 * Copyright © 2020 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * @file intel_measure.c
 */

#include "intel_measure.h"

#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>

#include "dev/intel_device_info.h"
#include "util/os_time.h"
#include "util/u_debug.h"
#include "util/macros.h"


static const struct debug_control debug_control[] = {
   { "draw",            INTEL_MEASURE_DRAW       },
   { "rt",              INTEL_MEASURE_RENDERPASS },
   { "shader",          INTEL_MEASURE_SHADER     },
   { "batch",           INTEL_MEASURE_BATCH      },
   { "frame",           INTEL_MEASURE_FRAME      },
   { NULL, 0 }
};
static struct intel_measure_config config;

void
intel_measure_init(struct intel_measure_device *device)
{
   static bool once = false;
   const char *env = getenv("INTEL_MEASURE");
   if (unlikely(!once)) {
      once = true;
      memset(&config, 0, sizeof(struct intel_measure_config));
      if (!env)
         return;

      char env_copy[1024];
      strncpy(env_copy, env, 1024);
      env_copy[1023] = '\0';

      config.file = stderr;
      config.flags = parse_debug_string(env_copy, debug_control);
      if (!config.flags)
         config.flags = INTEL_MEASURE_DRAW;
      config.enabled = true;
      config.event_interval = 1;
      config.control_fh = -1;

      /* Overflows of the following defaults will drop data and generate a
       * warning on the output filehandle.
       */

      /* default batch_size allows for 32k renders in a single batch */
      const int MINIMUM_BATCH_SIZE = 1024;
      const int DEFAULT_BATCH_SIZE = 64 * 1024;
      config.batch_size = DEFAULT_BATCH_SIZE;

      /* Default buffer_size allows for 64k batches per line of output in the
       * csv.  Overflow may occur for offscreen workloads or large 'interval'
       * settings.
       */
      const int MINIMUM_BUFFER_SIZE = 1024;
      const int DEFAULT_BUFFER_SIZE = 64 * 1024;
      config.buffer_size = DEFAULT_BUFFER_SIZE;

      const char *filename = strstr(env_copy, "file=");
      const char *start_frame_s = strstr(env_copy, "start=");
      const char *count_frame_s = strstr(env_copy, "count=");
      const char *control_path = strstr(env_copy, "control=");
      const char *interval_s = strstr(env_copy, "interval=");
      const char *batch_size_s = strstr(env_copy, "batch_size=");
      const char *buffer_size_s = strstr(env_copy, "buffer_size=");
      const char *cpu_s = strstr(env_copy, "cpu");
      const char *no_ogl = strstr(env_copy, "nogl");
      while (true) {
         char *sep = strrchr(env_copy, ',');
         if (sep == NULL)
            break;
         *sep = '\0';
      }

      if (no_ogl && device->type == INTEL_MEASURE_DEVICE_OGL) {
         config.enabled = false;
         return;
      }

      if (filename && __normal_user()) {
         filename += 5;
         config.deferred_create_filename = strdup(filename);
      }

      if (start_frame_s) {
         start_frame_s += 6;
         const int start_frame = atoi(start_frame_s);
         if (start_frame < 0) {
            fprintf(stderr, "INTEL_MEASURE start frame may "
                    "not be negative: %d\n", start_frame);
            abort();
         }

         config.start_frame = start_frame;
         config.enabled = false;
      }

      if (count_frame_s) {
         count_frame_s += 6;
         const int count_frame = atoi(count_frame_s);
         if (count_frame <= 0) {
            fprintf(stderr, "INTEL_MEASURE count frame must be positive: %d\n",
                    count_frame);
            abort();
         }

         config.end_frame = config.start_frame + count_frame;
      }

      if (control_path) {
         control_path += 8;
         if (mkfifoat(AT_FDCWD, control_path, O_CREAT | S_IRUSR | S_IWUSR)) {
            if (errno != EEXIST) {
               fprintf(stderr, "INTEL_MEASURE failed to create control "
                       "fifo %s: %s\n", control_path, strerror (errno));
               abort();
            }
         }

         config.control_fh = openat(AT_FDCWD, control_path,
                                    O_RDONLY | O_NONBLOCK);
         if (config.control_fh == -1) {
            fprintf(stderr, "INTEL_MEASURE failed to open control fifo "
                    "%s: %s\n", control_path, strerror (errno));
            abort();
         }

         /* when using a control fifo, do not start until the user triggers
          * capture
          */
         config.enabled = false;
      }

      if (interval_s) {
         interval_s += 9;
         const int event_interval = atoi(interval_s);
         if (event_interval < 1) {
            fprintf(stderr, "INTEL_MEASURE event_interval must be positive: "
                    "%d\n", event_interval);
            abort();
         }
         config.event_interval = event_interval;
      }

      if (batch_size_s) {
         batch_size_s += 11;
         const int batch_size = atoi(batch_size_s);
         if (batch_size < MINIMUM_BATCH_SIZE ) {
            fprintf(stderr, "INTEL_MEASURE minimum batch_size is 1k: "
                    "%d\n", batch_size);
            abort();
         }
         if (batch_size > MINIMUM_BATCH_SIZE * 4 * 1024) {
            fprintf(stderr, "INTEL_MEASURE batch_size limited to 4M: "
                    "%d\n", batch_size);
            abort();
         }

         config.batch_size = batch_size;
      }

      if (buffer_size_s) {
         buffer_size_s += 12;
         const int buffer_size = atoi(buffer_size_s);
         if (buffer_size < MINIMUM_BUFFER_SIZE) {
            fprintf(stderr, "INTEL_MEASURE minimum buffer_size is 1k: "
                    "%d\n", DEFAULT_BUFFER_SIZE);
         }
         if (buffer_size > MINIMUM_BUFFER_SIZE * 1024) {
            fprintf(stderr, "INTEL_MEASURE buffer_size limited to 1M: "
                    "%d\n", buffer_size);
         }

         config.buffer_size = buffer_size;
      }

      if (cpu_s) {
         config.cpu_measure = true;
      }
   }

   device->config = NULL;
   device->frame = 0;
   device->render_pass_count = 0;
   device->release_batch = NULL;
   pthread_mutex_init(&device->mutex, NULL);
   list_inithead(&device->queued_snapshots);

   if (env)
      device->config = &config;
}

const char *
intel_measure_snapshot_string(enum intel_measure_snapshot_type type)
{
   const char *names[] = {
      [INTEL_SNAPSHOT_UNDEFINED]           = "undefined",
      [INTEL_SNAPSHOT_BLIT]                = "blit",
      [INTEL_SNAPSHOT_CCS_AMBIGUATE]       = "ccs ambiguate",
      [INTEL_SNAPSHOT_CCS_COLOR_CLEAR]     = "ccs color clear",
      [INTEL_SNAPSHOT_CCS_PARTIAL_RESOLVE] = "ccs partial resolve",
      [INTEL_SNAPSHOT_CCS_RESOLVE]         = "ccs resolve",
      [INTEL_SNAPSHOT_COMPUTE]             = "compute",
      [INTEL_SNAPSHOT_COPY]                = "copy",
      [INTEL_SNAPSHOT_DRAW]                = "draw",
      [INTEL_SNAPSHOT_HIZ_AMBIGUATE]       = "hiz ambiguate",
      [INTEL_SNAPSHOT_HIZ_CLEAR]           = "hiz clear",
      [INTEL_SNAPSHOT_HIZ_RESOLVE]         = "hiz resolve",
      [INTEL_SNAPSHOT_MCS_AMBIGUATE]       = "mcs ambiguate",
      [INTEL_SNAPSHOT_MCS_COLOR_CLEAR]     = "mcs color clear",
      [INTEL_SNAPSHOT_MCS_PARTIAL_RESOLVE] = "mcs partial resolve",
      [INTEL_SNAPSHOT_SLOW_COLOR_CLEAR]    = "slow color clear",
      [INTEL_SNAPSHOT_SLOW_DEPTH_CLEAR]    = "slow depth clear",
      [INTEL_SNAPSHOT_SECONDARY_BATCH]     = "secondary command buffer",
      [INTEL_SNAPSHOT_END]                 = "end",
   };
   assert(type < ARRAY_SIZE(names));
   assert(names[type] != NULL);
   assert(type != INTEL_SNAPSHOT_UNDEFINED);
   return names[type];
}

/**
 * Indicate to the caller whether a new snapshot should be started.
 *
 * Callers provide rendering state to this method to determine whether the
 * current start event should be skipped. Depending on the configuration
 * flags, a new snapshot may start:
 *  - at every event
 *  - when the program changes
 *  - after a batch is submitted
 *  - at frame boundaries
 *
 * Returns true if a snapshot should be started.
 */
bool
intel_measure_state_changed(const struct intel_measure_batch *batch,
                            uint32_t vs, uint32_t tcs, uint32_t tes,
                            uint32_t gs, uint32_t fs, uint32_t cs,
                            uint32_t ms, uint32_t ts)
{
   if (batch->index == 0) {
      /* always record the first event */
      return true;
   }

   const struct intel_measure_snapshot *last_snap =
      &batch->snapshots[batch->index - 1];

   if (config.flags & INTEL_MEASURE_DRAW)
      return true;

   if (batch->index % 2 == 0) {
      /* no snapshot is running, but we have a start event */
      return true;
   }

   if (config.flags & (INTEL_MEASURE_FRAME | INTEL_MEASURE_BATCH)) {
      /* only start collection when index == 0, at the beginning of a batch */
      return false;
   }

   if (config.flags & INTEL_MEASURE_RENDERPASS) {
      bool new_renderpass = !cs && last_snap->renderpass != batch->renderpass;
      bool new_compute_block = cs && last_snap->type != INTEL_SNAPSHOT_COMPUTE;
      return new_renderpass || new_compute_block;
   }

   /* remaining comparisons check the state of the render pipeline for
    * INTEL_MEASURE_PROGRAM
    */
   assert(config.flags & INTEL_MEASURE_SHADER);

   if (!vs && !tcs && !tes && !gs && !fs && !cs && !ms && !ts) {
      /* blorp always changes program */
      return true;
   }

   return (last_snap->vs  != vs ||
           last_snap->tcs != tcs ||
           last_snap->tes != tes ||
           last_snap->gs  != gs ||
           last_snap->fs  != fs ||
           last_snap->cs  != cs ||
           last_snap->ms  != ms ||
           last_snap->ts  != ts);
}

/**
 * Notify intel_measure that a frame is about to begin.
 *
 * Configuration values and the control fifo may commence measurement at frame
 * boundaries.
 */
void
intel_measure_frame_transition(unsigned frame)
{
   if (frame == config.start_frame)
      config.enabled = true;
   else if (frame == config.end_frame)
      config.enabled = false;

   /* user commands to the control fifo will override any start/count
    * environment settings
    */
   if (config.control_fh != -1) {
      while (true) {
         const unsigned BUF_SIZE = 128;
         char buf[BUF_SIZE];
         ssize_t bytes = read(config.control_fh, buf, BUF_SIZE - 1);
         if (bytes == 0)
            break;
         if (bytes == -1) {
            fprintf(stderr, "INTEL_MEASURE failed to read control fifo: %s\n",
                    strerror(errno));
            abort();
         }

         buf[bytes] = '\0';
         char *nptr = buf, *endptr = buf;
         while (*nptr != '\0' && *endptr != '\0') {
            long fcount = strtol(nptr, &endptr, 10);
            if (nptr == endptr) {
               config.enabled = false;
               fprintf(stderr, "INTEL_MEASURE invalid frame count on "
                       "control fifo.\n");
               lseek(config.control_fh, 0, SEEK_END);
               break;
            } else if (fcount == 0) {
               config.enabled = false;
            } else {
               config.enabled = true;
               config.end_frame = frame + fcount;
            }

            nptr = endptr + 1;
         }
      }
   }
}

#define TIMESTAMP_BITS 36
static uint64_t
raw_timestamp_delta(uint64_t time0, uint64_t time1)
{
   if (time0 > time1) {
      return (1ULL << TIMESTAMP_BITS) + time1 - time0;
   } else {
      return time1 - time0;
   }
}

/**
 * Verify that rendering has completed for the batch
 *
 * Rendering is complete when the last timestamp has been written.
*/
bool
intel_measure_ready(struct intel_measure_batch *batch)
{
   assert(batch->timestamps);
   assert(batch->index > 1);
   return (batch->timestamps[batch->index - 1] != 0);
}

/**
 * Submit completed snapshots for buffering.
 *
 * Snapshot data becomes available when asynchronous rendering completes.
 * Depending on configuration, snapshot data may need to be collated before
 * writing to the output file.
 */
static void
intel_measure_push_result(struct intel_measure_device *device,
                          struct intel_measure_batch *batch)
{
   struct intel_measure_ringbuffer *rb = device->ringbuffer;

   uint64_t *timestamps = batch->timestamps;
   assert(timestamps != NULL);
   assert(batch->index == 0 || timestamps[0] != 0);

   for (int i = 0; i < batch->index; i += 2) {
      const struct intel_measure_snapshot *begin = &batch->snapshots[i];
      const struct intel_measure_snapshot *end = &batch->snapshots[i+1];

      assert (end->type == INTEL_SNAPSHOT_END);

      if (begin->type == INTEL_SNAPSHOT_SECONDARY_BATCH) {
         assert(begin->secondary != NULL);
         begin->secondary->batch_count = batch->batch_count;
         begin->secondary->batch_size = 0;
         begin->secondary->primary_renderpass = batch->renderpass;
         intel_measure_push_result(device, begin->secondary);
         continue;
      }

      const uint64_t prev_end_ts = rb->results[rb->head].end_ts;

      /* advance ring buffer */
      if (++rb->head == config.buffer_size)
         rb->head = 0;
      if (rb->head == rb->tail) {
         static bool warned = false;
         if (unlikely(!warned)) {
            fprintf(config.file,
                    "WARNING: Buffered data exceeds INTEL_MEASURE limit: %d. "
                    "Data has been dropped. "
                    "Increase setting with INTEL_MEASURE=buffer_size={count}\n",
                    config.buffer_size);
            warned = true;
         }
         break;
      }

      struct intel_measure_buffered_result *buffered_result =
         &rb->results[rb->head];

      memset(buffered_result, 0, sizeof(*buffered_result));
      memcpy(&buffered_result->snapshot, begin,
             sizeof(struct intel_measure_snapshot));
      buffered_result->start_ts = timestamps[i];
      buffered_result->end_ts = timestamps[i+1];
      buffered_result->idle_duration =
         raw_timestamp_delta(prev_end_ts, buffered_result->start_ts);
      buffered_result->frame = batch->frame;
      buffered_result->batch_count = batch->batch_count;
      buffered_result->batch_size = batch->batch_size;
      buffered_result->primary_renderpass = batch->primary_renderpass;
      buffered_result->event_index = i / 2;
      buffered_result->snapshot.event_count = end->event_count;
   }
}

static unsigned
ringbuffer_size(const struct intel_measure_ringbuffer *rb)
{
   unsigned head = rb->head;
   if (head < rb->tail)
      head += config.buffer_size;
   return head - rb->tail;
}

static const struct intel_measure_buffered_result *
ringbuffer_pop(struct intel_measure_ringbuffer *rb)
{
   if (rb->tail == rb->head) {
      /* encountered ringbuffer overflow while processing events */
      return NULL;
   }

   if (++rb->tail == config.buffer_size)
      rb->tail = 0;
   return &rb->results[rb->tail];
}

static const struct intel_measure_buffered_result *
ringbuffer_peek(const struct intel_measure_ringbuffer *rb, unsigned index)
{
   int result_offset = rb->tail + index + 1;
   if (result_offset >= config.buffer_size)
      result_offset -= config.buffer_size;
   return &rb->results[result_offset];
}


/**
 * Determine the number of buffered events that must be combined for the next
 * line of csv output. Returns 0 if more events are needed.
 */
static unsigned
buffered_event_count(struct intel_measure_device *device)
{
   const struct intel_measure_ringbuffer *rb = device->ringbuffer;
   const unsigned buffered_event_count = ringbuffer_size(rb);
   if (buffered_event_count == 0) {
      /* no events to collect */
      return 0;
   }

   /* count the number of buffered events required to meet the configuration */
   if (config.flags & (INTEL_MEASURE_DRAW |
                       INTEL_MEASURE_RENDERPASS |
                       INTEL_MEASURE_SHADER)) {
      /* For these flags, every buffered event represents a line in the
       * output.  None of these events span batches.  If the event interval
       * crosses a batch boundary, then the next interval starts with the new
       * batch.
       */
      return 1;
   }

   const unsigned start_frame = ringbuffer_peek(rb, 0)->frame;
   if (config.flags & INTEL_MEASURE_BATCH) {
      /* each buffered event is a command buffer.  The number of events to
       * process is the same as the interval, unless the interval crosses a
       * frame boundary
       */
      if (buffered_event_count < config.event_interval) {
         /* not enough events */
         return 0;
      }

      /* Imperfect frame tracking requires us to allow for *older* frames */
      if (ringbuffer_peek(rb, config.event_interval - 1)->frame <= start_frame) {
         /* No frame transition.  The next {interval} events should be combined. */
         return config.event_interval;
      }

      /* Else a frame transition occurs within the interval.  Find the
       * transition, so the following line of output begins with the batch
       * that starts the new frame.
       */
      for (int event_index = 1;
           event_index <= config.event_interval;
           ++event_index) {
         if (ringbuffer_peek(rb, event_index)->frame > start_frame)
            return event_index;
      }

      assert(false);
   }

   /* Else we need to search buffered events to find the matching frame
    * transition for our interval.
    */
   assert(config.flags & INTEL_MEASURE_FRAME);
   for (int event_index = 1;
        event_index < buffered_event_count;
        ++event_index) {
      const int latest_frame = ringbuffer_peek(rb, event_index)->frame;
      if (latest_frame - start_frame >= config.event_interval)
         return event_index;
   }

   return 0;
}

/**
 * Take result_count events from the ringbuffer and output them as a single
 * line.
 */
static void
print_combined_results(struct intel_measure_device *measure_device,
                       int result_count,
                       const struct intel_device_info *info)
{
   if (result_count == 0)
      return;

   struct intel_measure_ringbuffer *result_rb = measure_device->ringbuffer;
   assert(ringbuffer_size(result_rb) >= result_count);
   const struct intel_measure_buffered_result* start_result =
      ringbuffer_pop(result_rb);
   const struct intel_measure_buffered_result* current_result = start_result;

   if (start_result == NULL)
      return;
   --result_count;

   uint64_t duration_ts = raw_timestamp_delta(start_result->start_ts,
                                              current_result->end_ts);
   unsigned event_count = start_result->snapshot.event_count;
   while (result_count-- > 0) {
      assert(ringbuffer_size(result_rb) > 0);
      current_result = ringbuffer_pop(result_rb);
      if (current_result == NULL)
         return;
      duration_ts += raw_timestamp_delta(current_result->start_ts,
                                         current_result->end_ts);
      event_count += current_result->snapshot.event_count;
   }

   uint64_t duration_idle_ns =
      intel_device_info_timebase_scale(info, start_result->idle_duration);
   uint64_t duration_time_ns =
      intel_device_info_timebase_scale(info, duration_ts);
   const struct intel_measure_snapshot *begin = &start_result->snapshot;
   uint32_t renderpass = (start_result->primary_renderpass)
      ? start_result->primary_renderpass : begin->renderpass;
   fprintf(config.file, "%"PRIu64",%"PRIu64",%u,%u,%"PRIu64",%u,%u,%u,%s,%u,"
           "0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,%.3lf,%.3lf\n",
           start_result->start_ts, current_result->end_ts,
           start_result->frame,
           start_result->batch_count, start_result->batch_size,
           renderpass, start_result->event_index, event_count,
           begin->event_name, begin->count,
           begin->vs, begin->tcs, begin->tes, begin->gs,
           begin->fs, begin->cs, begin->ms, begin->ts,
           (double)duration_idle_ns / 1000.0,
           (double)duration_time_ns / 1000.0);
}

/**
 * Write data for a cpu event.
 */
void
intel_measure_print_cpu_result(unsigned int frame,
                               unsigned int batch_count,
                               uint64_t batch_size,
                               unsigned int event_index,
                               unsigned int event_count,
                               unsigned int count,
                               const char* event_name)
{
   assert(config.cpu_measure);
   uint64_t start_ns = os_time_get_nano();

   fprintf(config.file, "%"PRIu64",%u,%3u,%"PRIu64",%3u,%u,%s,%u\n",
           start_ns, frame, batch_count, batch_size,
           event_index, event_count, event_name, count);
}

/**
 * Empty the ringbuffer of events that can be printed.
 */
static void
intel_measure_print(struct intel_measure_device *device,
                    const struct intel_device_info *info)
{
   if (unlikely(config.deferred_create_filename)) {
      config.file = fopen(config.deferred_create_filename, "w");
      if (!config.file) {
         fprintf(stderr, "INTEL_MEASURE failed to open output file %s: %s\n",
                  config.deferred_create_filename, strerror(errno));
         abort();
      }
      free(config.deferred_create_filename);
      config.deferred_create_filename = NULL;

      if (!config.cpu_measure)
         fputs("draw_start,draw_end,frame,batch,batch_size,renderpass,"
               "event_index,event_count,type,count,vs,tcs,tes,"
               "gs,fs,cs,ms,ts,idle_us,time_us\n",
               config.file);
      else
         fputs("draw_start,frame,batch,batch_size,event_index,event_count,"
               "type,count\n",
               config.file);
   }

   while (true) {
      const int events_to_combine = buffered_event_count(device);
      if (events_to_combine == 0)
         break;
      print_combined_results(device, events_to_combine, info);
   }
}

/**
 * Collect snapshots from completed command buffers and submit them to
 * intel_measure for printing.
 */
void
intel_measure_gather(struct intel_measure_device *measure_device,
                     const struct intel_device_info *info)
{
   pthread_mutex_lock(&measure_device->mutex);

   /* Iterate snapshots and collect if ready.  Each snapshot queue will be
    * in-order, but we must determine which queue has the oldest batch.
    */
   /* iterate snapshots and collect if ready */
   while (!list_is_empty(&measure_device->queued_snapshots)) {
      struct intel_measure_batch *batch =
         list_first_entry(&measure_device->queued_snapshots,
                          struct intel_measure_batch, link);

      if (!intel_measure_ready(batch)) {
         /* command buffer has begun execution on the gpu, but has not
          * completed.
          */
         break;
      }

      list_del(&batch->link);
      assert(batch->index % 2 == 0);

      intel_measure_push_result(measure_device, batch);

      batch->index = 0;
      batch->frame = 0;
      if (measure_device->release_batch)
         measure_device->release_batch(batch);
   }

   intel_measure_print(measure_device, info);
   pthread_mutex_unlock(&measure_device->mutex);
}
