/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto2";

package perfetto.protos;

// next id: 22
message GpuRenderStageEvent {
  // required. Unique ID for the event.
  optional uint64 event_id = 1;

  // optional. Duration of the event in nanoseconds. If unset, this is a
  // single time point event.
  optional uint64 duration = 2;

  // required. ID to a hardware queue description in the specifications.
  // InternedGpuRenderStageSpecification
  optional uint64 hw_queue_iid = 13;

  // required. ID to a render stage description in the specifications.
  // InternedGpuRenderStageSpecification
  optional uint64 stage_iid = 14;

  // optional. Identifier for GPU in a multi-gpu device.
  optional int32 gpu_id = 11;

  // required. Graphics context for the event.
  // For OpenGL, this is the GL context.
  // For Vulkan, this is the VkDevice.
  optional uint64 context = 5;

  // optional. The render target for this event.
  // For OpenGL, this is the GL frame buffer handle.
  // For Vulkan, this is the VkFrameBuffer handle.
  optional uint64 render_target_handle = 8;

  // optional. Submission ID generated by the UMD.
  // For OpenGL, the ID should map to an API submission (e.g., glFlush,
  // glFinish, eglSwapBufffers) event.  The set of submissions to the HW due
  // to a single API submission should share the same ID.
  // For Vulkan, it should map 1:1 with a vkQueueSubmit.
  optional uint32 submission_id = 10;

  // optional. Additional data for the user. This may include attributes for
  // the event like resource ids, shaders, etc.
  message ExtraData {
    optional string name = 1;
    optional string value = 2;
  }
  repeated ExtraData extra_data = 6;

  // VULKAN SPECIFICS

  // optional. The Vulkan render pass handle.
  optional uint64 render_pass_handle = 9;

  // optional. An ID for the render pass instance. This is used to correlate
  // different events on different queues produced by the same Vulkan render
  // pass instance.
  optional uint64 render_pass_instance_id = 16;

  // optional. A bit mask representing which render subpasses contributed to
  // this render stage event.  Subpass index 0 is represented by setting the
  // LSB of the mask.  Additional mask can be added for subpass index greater
  // than 63.
  repeated uint64 render_subpass_index_mask = 15;

  // optional. The Vulkan command buffer handle.
  optional uint64 command_buffer_handle = 12;

  // optional. Custom name for this render stage event. When set, this
  // provides a name for the stage instead of using the name from the stage
  // specification.
  oneof name_field {
    string name = 17;
    // Interned event name. Refers to EventName in InternedData.
    uint64 name_iid = 20;
  }

  // Event IDs of other GpuRenderStageEvents that this event
  // had to wait on before it could run.
  repeated uint64 event_wait_ids = 18;

  // optional. ID to a compute kernel description in the interned data.
  // InternedComputeKernel
  optional uint64 kernel_iid = 19;

  // 3D unsigned integer vector for grid and workgroup dimensions.
  message Dim3 {
    optional uint32 x = 1;
    optional uint32 y = 2;
    optional uint32 z = 3;
  }

  // Typed key/value argument for extending compute kernel descriptions
  // and launch parameters with custom data.
  message ExtraComputeArg {
    oneof name_field {
      // Interned InternedComputeArgName.
      uint64 name_iid = 1;
      // Non-interned variant.
      string name = 2;
    }
    oneof value {
      int64 int_value = 3;
      uint64 uint_value = 4;
      double double_value = 5;
      string string_value = 6;
      // Interned InternedString via debug_annotation_string_values.
      uint64 string_value_iid = 7;
    }
  }

  // Compute kernel launch parameters for a single dispatch.
  message ComputeKernelLaunch {
    // Grid dimensions (number of workgroups in each dimension).
    optional Dim3 grid_size = 1;
    // Workgroup dimensions (number of threads per workgroup in each dimension).
    optional Dim3 workgroup_size = 2;
    // Additional typed launch parameters (e.g. registers_per_thread,
    // shared_mem_dynamic, shared_mem_static).
    repeated ExtraComputeArg args = 3;
  }

  // optional. Compute kernel launch parameters for this event.
  optional ComputeKernelLaunch launch = 21;

  // DEPRECATED

  // Deprecated.  Use InternedGpuRenderStageSpecification instead.
  // The first trace packet of each session should include a Specifications
  // to enumerate *all* IDs that will be used. The timestamp of this packet
  // must be earlier than all other packets. Only one packet with Specifications
  // is expected.
  message Specifications {
    message ContextSpec {
      optional uint64 context = 1;
      optional int32 pid = 2;
    }
    optional ContextSpec context_spec = 1;

    message Description {
      optional string name = 1;
      optional string description = 2;
    }

    // Labels to categorize the hw Queue this event goes on.
    repeated Description hw_queue = 2;

    // Labels to categorize render stage(binning, render, compute etc).
    repeated Description stage = 3;
  }
  // Deprecated.  Use hw_queue_iid and stage_iid to refer to
  // InternedGpuRenderStageSpecification instead.
  optional Specifications specifications = 7 [deprecated = true];

  // Deprecated. Use hw_queue_iid instead;
  optional int32 hw_queue_id = 3 [deprecated = true];

  // Deprecated. Use stage_iid instead;
  optional int32 stage_id = 4 [deprecated = true];

  // Extension for vendor's custom proto.
  extensions 100;
}

// Interned data.

// The iid is the numeric value of either the GL Context or the VkDevice
// handle.
message InternedGraphicsContext {
  optional uint64 iid = 1;
  optional int32 pid = 2;
  enum Api {
    UNDEFINED = 0;
    OPEN_GL = 1;
    VULKAN = 2;
    OPEN_CL = 3;
    CUDA = 4;
    HIP = 5;
  }
  optional Api api = 3;
}

message InternedGpuRenderStageSpecification {
  optional uint64 iid = 1;
  optional string name = 2;
  optional string description = 3;

  enum RenderStageCategory {
    OTHER = 0;
    GRAPHICS = 1;
    COMPUTE = 2;
  }
  optional RenderStageCategory category = 4;
}

message InternedComputeKernel {
  optional uint64 iid = 1;
  optional string name = 2;
  optional string demangled_name = 3;
  optional string arch = 4;
  // Additional typed kernel attributes (e.g. static resource limits).
  repeated GpuRenderStageEvent.ExtraComputeArg args = 5;
}

message InternedComputeArgName {
  optional uint64 iid = 1;
  optional string name = 2;
}
