185 lines
9.3 KiB
C++

//=====================================================================
// Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 GPU_Vulkan.h
//
// Vulkan Example - Texture loading (and display) example (including mip maps)
//
// Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
//=====================================================================
#ifndef H_GPU_VULKAN
#define H_GPU_VULKAN
#include "vulkanswapchain.hpp"
#include "vulkandebug.h"
#include <gpu_decodebase.h>
#include <vulkan/vulkan.h>
#include <glm/gtc/matrix_transform.hpp>
#include <assert.h>
#include <string>
#include <array>
#define FENCE_TIMEOUT 100000000
//---------------------------------------------------------------------------------
namespace GPU_Decode {
// Macro to check and display Vulkan return results
#define VK_CHECK_RESULT(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) \
{ \
std::cout << "Fatal : VkResult is \"" << vkTools::errorString(res) << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \
return; \
} \
}
// Macro to check and display Vulkan return results
#define VK_CHECK_RESULT_ERR_PTR(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) \
{ \
std::cout << "Fatal : VkResult is \"" << vkTools::errorString(res) << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \
return NULL; \
} \
}
class GPU_Vulkan : public RenderWindow {
public:
GPU_Vulkan(std::uint32_t Width, std::uint32_t Height, WNDPROC callback);
~GPU_Vulkan();
virtual CMP_ERROR WINAPI Decompress(
const CMP_Texture* pSourceTexture,
CMP_Texture* pDestTexture
);
private:
void VkRender();
VkFormat MIP2VK_Format(const CMP_Texture* pSourceTexture);
// Set to true if want to enable validation layers
bool m_tenableValidation = false;
bool m_prepared = false;
float m_zoom = -2.0f;
uint32_t m_width;
uint32_t m_height;
bool m_initOk;
const CMP_Texture* m_pSourceTexture = nullptr;
VulkanSwapChain swapChain;
vkTools::UniformData uniformDataVS;
// Active frame buffer index
uint32_t currentBuffer = 0;
// Handle to the device graphics queue that command buffers are submitted to
VkQueue queue;
// Depth format is selected during Vulkan initialization
VkFormat depthFormat;
// number of vulkan devices
uint32_t gpuCount = 0;
// List of available vulkan devices
std::vector<VkPhysicalDevice> physicalDevices;
// Physical device (GPU) that Vulkan will use
VkPhysicalDevice physicalDevice;
// Stores all available memory (type) properties for the physical device
VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
// Logical device, application's view of the physical device (GPU)
VkDevice device;
// Vulkan instance, stores all per-application states
VkInstance instance;
// Command buffer pool
VkCommandPool cmdPool;
// Command buffer used for setup
VkCommandBuffer setupCmdBuffer = VK_NULL_HANDLE;
// Command buffer for submitting a post present image barrier
VkCommandBuffer postPresentCmdBuffer = VK_NULL_HANDLE;
// Command buffer for submitting a pre present image barrier
VkCommandBuffer prePresentCmdBuffer = VK_NULL_HANDLE;
// Pipeline stage flags for the submit info structure
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
// Contains command buffers and semaphores to be presented to the queue
VkSubmitInfo submitInfo;
// Pipeline cache object
VkPipelineCache pipelineCache;
// Global render pass for frame buffer writes
VkRenderPass renderPass;
// Pipeline layout and descriptors
VkPipelineLayout pipelineLayout;
VkDescriptorSet descriptorSet;
VkDescriptorSetLayout descriptorSetLayout;
// List of available frame buffers (same as number of swap chain images)
std::vector<VkFramebuffer>frameBuffers;
// Command buffers used for rendering
std::vector<VkCommandBuffer> drawCmdBuffers;
// Descriptor set pool
VkDescriptorPool m_descriptorPool;
// List of shader modules created (stored for cleanup)
std::vector<VkShaderModule> shaderModules;
// List of functions used for loading compressed texture and decode view in compressonator gui
VkResult createInstance(bool enableValidation);
VkResult createDevice(VkDeviceQueueCreateInfo requestedQueues, bool enableValidation);
bool initVulkan(bool enableValidation);
bool isSupportASTC();
bool isSupportVersion();
void submitPostPresentBarrier(VkImage image);
void submitPrePresentBarrier(VkImage image);
void draw();
void createCommandPool();
void createSetupCommandBuffer();
void createCommandBuffers();
VkBool32 getMemoryType(uint32_t typeBits, VkFlags properties, uint32_t * typeIndex);
void setupDepthStencil();
void setupRenderPass();
void createPipelineCache();
void setupFrameBuffer();
void flushSetupCommandBuffer();
VkBool32 createBuffer(VkBufferUsageFlags usage, VkDeviceSize size, void * data, VkBuffer *buffer, VkDeviceMemory *memory);
VkBool32 createBuffer(VkBufferUsageFlags usage, VkDeviceSize size, void * data, VkBuffer * buffer, VkDeviceMemory * memory, VkDescriptorBufferInfo * descriptor);
void updateUniformBuffers();
void setImageLayout(VkImage image, VkImageAspectFlags aspectMask, VkImageLayout oldImageLayout, VkImageLayout newImageLayout);
void setImageLayout(VkCommandBuffer cmdBuffer, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout oldImageLayout, VkImageLayout newImageLayout, VkImageSubresourceRange subresourceRange);
CMP_ERROR loadTexture(const CMP_Texture* pSourceTexture);
VkPipelineShaderStageCreateInfo loadShader(const char * fileName, VkShaderStageFlagBits stage);
CMP_ERROR prepare(const CMP_Texture* pSourceTexture);
void destroyCommandBuffers();
void clean();
bool memory_type_from_properties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex);
void set_image_layout(VkImage image, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout, VkImageLayout new_image_layout);
void write(const CMP_Texture* pDestTexture);
//=====================================================
VkCommandBuffer createCommandBuffer(VkCommandBufferLevel level, bool begin);
void flushCommandBuffer(VkCommandBuffer commandBuffer, VkQueue queue, bool free);
};
}
#endif