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