Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (c) 2015-2016 The Khronos Group Inc.
      3  * Copyright (c) 2015-2016 Valve Corporation
      4  * Copyright (c) 2015-2016 LunarG, Inc.
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  *
     18  * Author: Courtney Goeltzenleuchter <courtney (at) LunarG.com>
     19  */
     20 
     21 #ifndef VKRENDERFRAMEWORK_H
     22 #define VKRENDERFRAMEWORK_H
     23 
     24 #ifdef ANDROID
     25 #include "vktestframeworkandroid.h"
     26 class VkImageObj;
     27 #else
     28 #include "vktestframework.h"
     29 #endif
     30 
     31 #include <array>
     32 #include <map>
     33 #include <vector>
     34 
     35 using namespace std;
     36 
     37 class VkDeviceObj : public vk_testing::Device {
     38   public:
     39     VkDeviceObj(uint32_t id, VkPhysicalDevice obj);
     40     VkDeviceObj(uint32_t id, VkPhysicalDevice obj, std::vector<const char *> &extension_names,
     41                 VkPhysicalDeviceFeatures *features = nullptr);
     42 
     43     VkDevice device() { return handle(); }
     44     void get_device_queue();
     45 
     46     uint32_t id;
     47     VkPhysicalDeviceProperties props;
     48     std::vector<VkQueueFamilyProperties> queue_props;
     49 
     50     VkQueue m_queue;
     51 };
     52 
     53 class VkCommandBufferObj;
     54 class VkDepthStencilObj;
     55 
     56 class VkRenderFramework : public VkTestFramework {
     57   public:
     58     VkRenderFramework();
     59     ~VkRenderFramework();
     60 
     61     VkInstance instance() { return inst; }
     62     VkDevice device() { return m_device->device(); }
     63     VkPhysicalDevice gpu() { return objs[0]; }
     64     VkRenderPass renderPass() { return m_renderPass; }
     65     VkFramebuffer framebuffer() { return m_framebuffer; }
     66     void InitViewport(float width, float height);
     67     void InitViewport();
     68     void InitRenderTarget();
     69     void InitRenderTarget(uint32_t targets);
     70     void InitRenderTarget(VkImageView *dsBinding);
     71     void InitRenderTarget(uint32_t targets, VkImageView *dsBinding);
     72     void InitFramework();
     73     void InitFramework(std::vector<const char *> instance_layer_names, std::vector<const char *> instance_extension_names,
     74                        std::vector<const char *> device_extension_names, PFN_vkDebugReportCallbackEXT = NULL,
     75                        void *userData = NULL);
     76 
     77     void ShutdownFramework();
     78     void InitState(VkPhysicalDeviceFeatures *features = nullptr);
     79 
     80     const VkRenderPassBeginInfo &renderPassBeginInfo() const { return m_renderPassBeginInfo; }
     81 
     82   protected:
     83     VkApplicationInfo app_info;
     84     VkInstance inst;
     85     VkPhysicalDevice objs[16];
     86     uint32_t gpu_count;
     87     VkDeviceObj *m_device;
     88     VkCommandPool m_commandPool;
     89     VkCommandBufferObj *m_commandBuffer;
     90     VkRenderPass m_renderPass;
     91     VkFramebuffer m_framebuffer;
     92     std::vector<VkViewport> m_viewports;
     93     std::vector<VkRect2D> m_scissors;
     94     float m_lineWidth;
     95     float m_depthBiasConstantFactor;
     96     float m_depthBiasClamp;
     97     float m_depthBiasSlopeFactor;
     98     float m_blendConstants[4];
     99     float m_minDepthBounds;
    100     float m_maxDepthBounds;
    101     uint32_t m_compareMask;
    102     uint32_t m_writeMask;
    103     uint32_t m_reference;
    104     std::vector<VkClearValue> m_renderPassClearValues;
    105     VkRenderPassBeginInfo m_renderPassBeginInfo;
    106     vector<VkImageObj *> m_renderTargets;
    107     float m_width, m_height;
    108     VkFormat m_render_target_fmt;
    109     VkFormat m_depth_stencil_fmt;
    110     VkClearColorValue m_clear_color;
    111     bool m_clear_via_load_op;
    112     float m_depth_clear_color;
    113     uint32_t m_stencil_clear_color;
    114     VkDepthStencilObj *m_depthStencil;
    115     PFN_vkCreateDebugReportCallbackEXT m_CreateDebugReportCallback;
    116     PFN_vkDestroyDebugReportCallbackEXT m_DestroyDebugReportCallback;
    117     PFN_vkDebugReportMessageEXT m_DebugReportMessage;
    118     VkDebugReportCallbackEXT m_globalMsgCallback;
    119     VkDebugReportCallbackEXT m_devMsgCallback;
    120     std::vector<const char *> device_extension_names;
    121 
    122     /*
    123      * SetUp and TearDown are called by the Google Test framework
    124      * to initialize a test framework based on this class.
    125      */
    126     virtual void SetUp() {
    127         this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    128         this->app_info.pNext = NULL;
    129         this->app_info.pApplicationName = "base";
    130         this->app_info.applicationVersion = 1;
    131         this->app_info.pEngineName = "unittest";
    132         this->app_info.engineVersion = 1;
    133         this->app_info.apiVersion = VK_API_VERSION_1_0;
    134 
    135         InitFramework();
    136     }
    137 
    138     virtual void TearDown() { ShutdownFramework(); }
    139 };
    140 
    141 class VkDescriptorSetObj;
    142 class VkIndexBufferObj;
    143 class VkConstantBufferObj;
    144 class VkPipelineObj;
    145 class VkDescriptorSetObj;
    146 
    147 class VkCommandBufferObj : public vk_testing::CommandBuffer {
    148   public:
    149     VkCommandBufferObj(VkDeviceObj *device, VkCommandPool pool);
    150     VkCommandBuffer GetBufferHandle();
    151     VkResult BeginCommandBuffer();
    152     VkResult BeginCommandBuffer(VkCommandBufferBeginInfo *pInfo);
    153     VkResult EndCommandBuffer();
    154     void PipelineBarrier(VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages, VkDependencyFlags dependencyFlags,
    155                          uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
    156                          const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
    157                          const VkImageMemoryBarrier *pImageMemoryBarriers);
    158     void AddRenderTarget(VkImageObj *renderTarget);
    159     void AddDepthStencil();
    160     void ClearAllBuffers(VkClearColorValue clear_color, float depth_clear_color, uint32_t stencil_clear_color,
    161                          VkDepthStencilObj *depthStencilObj);
    162     void PrepareAttachments();
    163     void BindPipeline(VkPipelineObj &pipeline);
    164     void BindDescriptorSet(VkDescriptorSetObj &descriptorSet);
    165     void BindVertexBuffer(VkConstantBufferObj *vertexBuffer, VkDeviceSize offset, uint32_t binding);
    166     void BindIndexBuffer(VkIndexBufferObj *indexBuffer, VkDeviceSize offset);
    167     void BeginRenderPass(const VkRenderPassBeginInfo &info);
    168     void EndRenderPass();
    169     void FillBuffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize fill_size, uint32_t data);
    170     void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
    171     void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
    172                      uint32_t firstInstance);
    173     void QueueCommandBuffer(bool checkSuccess = true);
    174     void QueueCommandBuffer(VkFence fence, bool checkSuccess = true);
    175     void SetViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports);
    176     void SetScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors);
    177     void SetLineWidth(float lineWidth);
    178     void SetDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor);
    179     void SetBlendConstants(const float blendConstants[4]);
    180     void SetDepthBounds(float minDepthBounds, float maxDepthBounds);
    181     void SetStencilReadMask(VkStencilFaceFlags faceMask, uint32_t compareMask);
    182     void SetStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask);
    183     void SetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference);
    184     void UpdateBuffer(VkBuffer buffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData);
    185     void CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
    186                    uint32_t regionCount, const VkImageCopy *pRegions);
    187     void ResolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
    188                       uint32_t regionCount, const VkImageResolve *pRegions);
    189 
    190   protected:
    191     VkDeviceObj *m_device;
    192     vector<VkImageObj *> m_renderTargets;
    193 };
    194 
    195 class VkConstantBufferObj : public vk_testing::Buffer {
    196   public:
    197     VkConstantBufferObj(VkDeviceObj *device,
    198                         VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
    199     VkConstantBufferObj(VkDeviceObj *device, int constantCount, int constantSize, const void *data,
    200                         VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
    201     ~VkConstantBufferObj();
    202     void BufferMemoryBarrier(VkFlags srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT |
    203                                                      VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
    204                                                      VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
    205                              VkFlags dstAccessMask = VK_ACCESS_HOST_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
    206                                                      VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
    207                                                      VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT |
    208                                                      VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
    209                                                      VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_MEMORY_READ_BIT);
    210 
    211     void Bind(VkCommandBuffer commandBuffer, VkDeviceSize offset, uint32_t binding);
    212 
    213     VkDescriptorBufferInfo m_descriptorBufferInfo;
    214 
    215   protected:
    216     VkDeviceObj *m_device;
    217     vk_testing::BufferView m_bufferView;
    218     int m_numVertices;
    219     int m_stride;
    220     vk_testing::CommandPool *m_commandPool;
    221     VkCommandBufferObj *m_commandBuffer;
    222     vk_testing::Fence m_fence;
    223 };
    224 
    225 class VkIndexBufferObj : public VkConstantBufferObj {
    226   public:
    227     VkIndexBufferObj(VkDeviceObj *device);
    228     void CreateAndInitBuffer(int numIndexes, VkIndexType dataFormat, const void *data);
    229     void Bind(VkCommandBuffer commandBuffer, VkDeviceSize offset);
    230     VkIndexType GetIndexType();
    231 
    232   protected:
    233     VkIndexType m_indexType;
    234 };
    235 
    236 class VkRenderpassObj {
    237   public:
    238     VkRenderpassObj(VkDeviceObj *device);
    239     ~VkRenderpassObj();
    240     VkRenderPass handle() { return m_renderpass; }
    241 
    242   protected:
    243     VkRenderPass m_renderpass;
    244     VkDevice device;
    245 };
    246 
    247 class VkImageObj : public vk_testing::Image {
    248   public:
    249     VkImageObj(VkDeviceObj *dev);
    250     bool IsCompatible(VkFlags usage, VkFlags features);
    251 
    252   public:
    253     void init(uint32_t w, uint32_t h, VkFormat fmt, VkFlags usage, VkImageTiling tiling = VK_IMAGE_TILING_LINEAR,
    254               VkMemoryPropertyFlags reqs = 0);
    255 
    256     void init_no_layout(uint32_t w, uint32_t h, VkFormat fmt, VkFlags usage, VkImageTiling tiling = VK_IMAGE_TILING_LINEAR,
    257                         VkMemoryPropertyFlags reqs = 0);
    258 
    259     //    void clear( CommandBuffer*, uint32_t[4] );
    260 
    261     void layout(VkImageLayout layout) { m_descriptorImageInfo.imageLayout = layout; }
    262 
    263     VkDeviceMemory memory() const { return Image::memory().handle(); }
    264 
    265     void *MapMemory() { return Image::memory().map(); }
    266 
    267     void UnmapMemory() { Image::memory().unmap(); }
    268 
    269     void ImageMemoryBarrier(VkCommandBufferObj *cmd, VkImageAspectFlags aspect, VkFlags output_mask, VkFlags input_mask,
    270                             VkImageLayout image_layout);
    271 
    272     VkResult CopyImage(VkImageObj &src_image);
    273 
    274     VkImage image() const { return handle(); }
    275 
    276     VkImageView targetView(VkFormat format) {
    277         if (!m_targetView.initialized()) {
    278             VkImageViewCreateInfo createView = {};
    279             createView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    280             createView.image = handle();
    281             createView.viewType = VK_IMAGE_VIEW_TYPE_2D;
    282             createView.format = format;
    283             createView.components.r = VK_COMPONENT_SWIZZLE_R;
    284             createView.components.g = VK_COMPONENT_SWIZZLE_G;
    285             createView.components.b = VK_COMPONENT_SWIZZLE_B;
    286             createView.components.a = VK_COMPONENT_SWIZZLE_A;
    287             createView.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
    288             createView.flags = 0;
    289             m_targetView.init(*m_device, createView);
    290         }
    291         return m_targetView.handle();
    292     }
    293 
    294     void SetLayout(VkCommandBufferObj *cmd_buf, VkImageAspectFlags aspect, VkImageLayout image_layout);
    295     void SetLayout(VkImageAspectFlags aspect, VkImageLayout image_layout);
    296 
    297     VkImageLayout layout() const { return m_descriptorImageInfo.imageLayout; }
    298     uint32_t width() const { return extent().width; }
    299     uint32_t height() const { return extent().height; }
    300     VkDeviceObj *device() const { return m_device; }
    301 
    302   protected:
    303     VkDeviceObj *m_device;
    304 
    305     vk_testing::ImageView m_targetView;
    306     VkDescriptorImageInfo m_descriptorImageInfo;
    307 };
    308 
    309 class VkTextureObj : public VkImageObj {
    310   public:
    311     VkTextureObj(VkDeviceObj *device, uint32_t *colors = NULL);
    312 
    313     VkDescriptorImageInfo m_imageInfo;
    314 
    315   protected:
    316     VkDeviceObj *m_device;
    317     vk_testing::ImageView m_textureView;
    318     VkDeviceSize m_rowPitch;
    319 };
    320 
    321 class VkDepthStencilObj : public VkImageObj {
    322   public:
    323     VkDepthStencilObj(VkDeviceObj *device);
    324     void Init(VkDeviceObj *device, int32_t width, int32_t height, VkFormat format,
    325               VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
    326     bool Initialized();
    327     VkImageView *BindInfo();
    328 
    329   protected:
    330     VkDeviceObj *m_device;
    331     bool m_initialized;
    332     vk_testing::ImageView m_imageView;
    333     VkFormat m_depth_stencil_fmt;
    334     VkImageView m_attachmentBindInfo;
    335 };
    336 
    337 class VkSamplerObj : public vk_testing::Sampler {
    338   public:
    339     VkSamplerObj(VkDeviceObj *device);
    340 
    341   protected:
    342     VkDeviceObj *m_device;
    343 };
    344 
    345 class VkDescriptorSetObj : public vk_testing::DescriptorPool {
    346   public:
    347     VkDescriptorSetObj(VkDeviceObj *device);
    348     ~VkDescriptorSetObj();
    349 
    350     int AppendDummy();
    351     int AppendBuffer(VkDescriptorType type, VkConstantBufferObj &constantBuffer);
    352     int AppendSamplerTexture(VkSamplerObj *sampler, VkTextureObj *texture);
    353     void CreateVKDescriptorSet(VkCommandBufferObj *commandBuffer);
    354 
    355     VkDescriptorSet GetDescriptorSetHandle() const;
    356     VkPipelineLayout GetPipelineLayout() const;
    357     int GetTypeCounts() { return m_type_counts.size(); }
    358 
    359   protected:
    360     VkDeviceObj *m_device;
    361     std::vector<VkDescriptorSetLayoutBinding> m_layout_bindings;
    362     std::map<VkDescriptorType, int> m_type_counts;
    363     int m_nextSlot;
    364 
    365     vector<VkDescriptorImageInfo> m_imageSamplerDescriptors;
    366     vector<VkWriteDescriptorSet> m_writes;
    367 
    368     vk_testing::DescriptorSetLayout m_layout;
    369     vk_testing::PipelineLayout m_pipeline_layout;
    370     vk_testing::DescriptorSet *m_set = NULL;
    371 };
    372 
    373 class VkShaderObj : public vk_testing::ShaderModule {
    374   public:
    375     VkShaderObj(VkDeviceObj *device, const char *shaderText, VkShaderStageFlagBits stage, VkRenderFramework *framework,
    376                 char const *name = "main");
    377     VkPipelineShaderStageCreateInfo GetStageCreateInfo() const;
    378 
    379   protected:
    380     VkPipelineShaderStageCreateInfo stage_info;
    381     VkShaderStageFlagBits m_stage;
    382     char const *m_name;
    383     VkDeviceObj *m_device;
    384 };
    385 
    386 class VkPipelineObj : public vk_testing::Pipeline {
    387   public:
    388     VkPipelineObj(VkDeviceObj *device);
    389     void AddShader(VkShaderObj *shaderObj);
    390     void AddVertexInputAttribs(VkVertexInputAttributeDescription *vi_attrib, uint32_t count);
    391     void AddVertexInputBindings(VkVertexInputBindingDescription *vi_binding, uint32_t count);
    392     void AddColorAttachment(uint32_t binding, const VkPipelineColorBlendAttachmentState *att);
    393     void MakeDynamic(VkDynamicState state);
    394 
    395     void AddColorAttachment() {
    396         VkPipelineColorBlendAttachmentState att = {};
    397         att.blendEnable = VK_FALSE;
    398         att.colorWriteMask = 0xf;
    399         AddColorAttachment(0, &att);
    400     }
    401 
    402     void SetDepthStencil(const VkPipelineDepthStencilStateCreateInfo *);
    403     void SetMSAA(const VkPipelineMultisampleStateCreateInfo *ms_state);
    404     void SetInputAssembly(const VkPipelineInputAssemblyStateCreateInfo *ia_state);
    405     void SetRasterization(const VkPipelineRasterizationStateCreateInfo *rs_state);
    406     void SetTessellation(const VkPipelineTessellationStateCreateInfo *te_state);
    407     void SetViewport(const vector<VkViewport> viewports);
    408     void SetScissor(const vector<VkRect2D> scissors);
    409     VkResult CreateVKPipeline(VkPipelineLayout layout, VkRenderPass render_pass);
    410 
    411   protected:
    412     VkPipelineVertexInputStateCreateInfo m_vi_state;
    413     VkPipelineInputAssemblyStateCreateInfo m_ia_state;
    414     VkPipelineRasterizationStateCreateInfo m_rs_state;
    415     VkPipelineColorBlendStateCreateInfo m_cb_state;
    416     VkPipelineDepthStencilStateCreateInfo const *m_ds_state;
    417     VkPipelineViewportStateCreateInfo m_vp_state;
    418     VkPipelineMultisampleStateCreateInfo m_ms_state;
    419     VkPipelineTessellationStateCreateInfo m_te_state;
    420     vector<VkDynamicState> m_dynamic_state_enables;
    421     vector<VkViewport> m_viewports;
    422     vector<VkRect2D> m_scissors;
    423     VkDeviceObj *m_device;
    424     vector<VkShaderObj *> m_shaderObjs;
    425     vector<int> m_vertexBufferBindings;
    426     vector<VkPipelineColorBlendAttachmentState> m_colorAttachments;
    427     int m_vertexBufferCount;
    428 };
    429 #endif // VKRENDERFRAMEWORK_H
    430