// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_VULKAN_VULKAN_COMMAND_BUFFER_H_
#define GPU_VULKAN_VULKAN_COMMAND_BUFFER_H_

#include <vulkan/vulkan.h>

#include "base/logging.h"
#include "base/macros.h"
#include "gpu/vulkan/vulkan_export.h"

namespace gpu {

class VulkanCommandPool;
class VulkanDeviceQueue;

class VULKAN_EXPORT VulkanCommandBuffer {
 public:
  VulkanCommandBuffer(VulkanDeviceQueue* device_queue,
                      VulkanCommandPool* command_pool,
                      bool primary);
  ~VulkanCommandBuffer();

  bool Initialize();
  void Destroy();

  // Submit primary command buffer to the queue.
  bool Submit(uint32_t num_wait_semaphores,
              VkSemaphore* wait_semaphores,
              uint32_t num_signal_semaphores,
              VkSemaphore* signal_semaphores);

  // Enqueue secondary command buffer within a primary command buffer.
  void Enqueue(VkCommandBuffer primary_command_buffer);

  void Clear();

  // This blocks until the commands from the previous submit are done.
  void Wait(uint64_t timeout);

  // This simply tests asynchronously if the commands from the previous submit
  // is finished.
  bool SubmissionFinished();

 private:
  friend class CommandBufferRecorderBase;

  enum RecordType {
    // Nothing has been recorded yet.
    RECORD_TYPE_EMPTY,

    // Recorded for single use, will be reset upon submission.
    RECORD_TYPE_SINGLE_USE,

    // Recording for multi use, once submitted it can't be modified until reset.
    RECORD_TYPE_MULTI_USE,

    // Recorded for multi-use, can no longer be modified unless reset.
    RECORD_TYPE_RECORDED,

    // Dirty, should be cleared before use. This assumes its externally
    // synchronized and the command buffer is no longer in use.
    RECORD_TYPE_DIRTY,
  };

  void PostExecution();
  void ResetIfDirty();

  const bool primary_;
  bool recording_ = false;
  RecordType record_type_ = RECORD_TYPE_EMPTY;
  VulkanDeviceQueue* device_queue_;
  VulkanCommandPool* command_pool_;
  VkCommandBuffer command_buffer_ = VK_NULL_HANDLE;
  VkFence submission_fence_ = VK_NULL_HANDLE;

  DISALLOW_COPY_AND_ASSIGN(VulkanCommandBuffer);
};

class VULKAN_EXPORT CommandBufferRecorderBase {
 public:
  VkCommandBuffer handle() const { return handle_; }

 protected:
  CommandBufferRecorderBase(VulkanCommandBuffer& command_buffer)
      : handle_(command_buffer.command_buffer_) {
    command_buffer.ResetIfDirty();
  }

  virtual ~CommandBufferRecorderBase();

  void ValidateSingleUse(VulkanCommandBuffer& command_buffer) {
    DCHECK((VulkanCommandBuffer::RECORD_TYPE_SINGLE_USE ==
            command_buffer.record_type_) ||
           (VulkanCommandBuffer::RECORD_TYPE_EMPTY ==
            command_buffer.record_type_));
    command_buffer.record_type_ = VulkanCommandBuffer::RECORD_TYPE_SINGLE_USE;
  }

  void ValidateMultiUse(VulkanCommandBuffer& command_buffer) {
    DCHECK((VulkanCommandBuffer::RECORD_TYPE_MULTI_USE ==
            command_buffer.record_type_) ||
           (VulkanCommandBuffer::RECORD_TYPE_EMPTY ==
            command_buffer.record_type_));
    command_buffer.record_type_ = VulkanCommandBuffer::RECORD_TYPE_MULTI_USE;
  }

  VkCommandBuffer handle_;
};

class VULKAN_EXPORT ScopedMultiUseCommandBufferRecorder
    : public CommandBufferRecorderBase {
 public:
  ScopedMultiUseCommandBufferRecorder(VulkanCommandBuffer& command_buffer);
  ~ScopedMultiUseCommandBufferRecorder() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ScopedMultiUseCommandBufferRecorder);
};

class VULKAN_EXPORT ScopedSingleUseCommandBufferRecorder
    : public CommandBufferRecorderBase {
 public:
  ScopedSingleUseCommandBufferRecorder(VulkanCommandBuffer& command_buffer);
  ~ScopedSingleUseCommandBufferRecorder() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ScopedSingleUseCommandBufferRecorder);
};

}  // namespace gpu

#endif  // GPU_VULKAN_VULKAN_COMMAND_BUFFER_H_
