Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (c) 2015-2017 The Khronos Group Inc.
      3  * Copyright (c) 2015-2017 Valve Corporation
      4  * Copyright (c) 2015-2017 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  * Author: Dave Houlton <daveh (at) lunarg.com>
     20  */
     21 
     22 #ifndef VKRENDERFRAMEWORK_H
     23 #define VKRENDERFRAMEWORK_H
     24 
     25 #ifdef ANDROID
     26 #include "vktestframeworkandroid.h"
     27 class VkImageObj;
     28 #else
     29 #include "vktestframework.h"
     30 #endif
     31 
     32 #include <algorithm>
     33 #include <array>
     34 #include <map>
     35 #include <vector>
     36 
     37 using namespace std;
     38 
     39 using vk_testing::MakeVkHandles;
     40 
     41 template <class Dst, class Src>
     42 std::vector<Dst *> MakeTestbindingHandles(const std::vector<Src *> &v) {
     43     std::vector<Dst *> handles;
     44     handles.reserve(v.size());
     45     std::transform(v.begin(), v.end(), std::back_inserter(handles), [](const Src *o) { return static_cast<Dst *>(o); });
     46     return handles;
     47 }
     48 
     49 class VkDeviceObj : public vk_testing::Device {
     50    public:
     51     VkDeviceObj(uint32_t id, VkPhysicalDevice obj);
     52     VkDeviceObj(uint32_t id, VkPhysicalDevice obj, std::vector<const char *> &extension_names,
     53                 VkPhysicalDeviceFeatures *features = nullptr);
     54 
     55     uint32_t QueueFamilyMatching(VkQueueFlags with, VkQueueFlags without, bool all_bits = true);
     56     uint32_t QueueFamilyWithoutCapabilities(VkQueueFlags capabilities) {
     57         // an all_bits match with 0 matches all
     58         return QueueFamilyMatching(VkQueueFlags(0), capabilities, true /* all_bits with */);
     59     }
     60 
     61     VkDevice device() { return handle(); }
     62     void get_device_queue();
     63 
     64     uint32_t id;
     65     VkPhysicalDeviceProperties props;
     66     std::vector<VkQueueFamilyProperties> queue_props;
     67 
     68     VkQueue m_queue;
     69 };
     70 
     71 class VkCommandPoolObj;
     72 class VkCommandBufferObj;
     73 class VkDepthStencilObj;
     74 
     75 class VkRenderFramework : public VkTestFramework {
     76    public:
     77     VkRenderFramework();
     78     ~VkRenderFramework();
     79 
     80     VkInstance instance() { return inst; }
     81     VkDevice device() { return m_device->device(); }
     82     VkDeviceObj *DeviceObj() const { return m_device; }
     83     VkPhysicalDevice gpu();
     84     VkRenderPass renderPass() { return m_renderPass; }
     85     const VkRenderPassCreateInfo &RenderPassInfo() const { return renderPass_info_; };
     86     VkFramebuffer framebuffer() { return m_framebuffer; }
     87     void InitViewport(float width, float height);
     88     void InitViewport();
     89     void InitRenderTarget();
     90     void InitRenderTarget(uint32_t targets);
     91     void InitRenderTarget(VkImageView *dsBinding);
     92     void InitRenderTarget(uint32_t targets, VkImageView *dsBinding);
     93     void InitFramework(PFN_vkDebugReportCallbackEXT = NULL, void *userData = NULL);
     94 
     95     void ShutdownFramework();
     96     void GetPhysicalDeviceFeatures(VkPhysicalDeviceFeatures *features);
     97     void InitState(VkPhysicalDeviceFeatures *features = nullptr, const VkCommandPoolCreateFlags flags = 0);
     98 
     99     const VkRenderPassBeginInfo &renderPassBeginInfo() const { return m_renderPassBeginInfo; }
    100 
    101     bool InstanceLayerSupported(const char *name, uint32_t specVersion = 0, uint32_t implementationVersion = 0);
    102     bool EnableDeviceProfileLayer();
    103     bool InstanceExtensionSupported(const char *name, uint32_t specVersion = 0);
    104     bool DeviceExtensionSupported(VkPhysicalDevice dev, const char *layer, const char *name, uint32_t specVersion = 0);
    105 
    106    protected:
    107     VkApplicationInfo app_info;
    108     VkInstance inst;
    109     VkPhysicalDevice objs[16];
    110     uint32_t gpu_count;
    111     VkDeviceObj *m_device;
    112     VkCommandPoolObj *m_commandPool;
    113     VkCommandBufferObj *m_commandBuffer;
    114     VkRenderPass m_renderPass;
    115     VkRenderPassCreateInfo renderPass_info_ = {};
    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     bool m_addRenderPassSelfDependency;
    130     std::vector<VkClearValue> m_renderPassClearValues;
    131     VkRenderPassBeginInfo m_renderPassBeginInfo;
    132     vector<VkImageObj *> m_renderTargets;
    133     float m_width, m_height;
    134     VkFormat m_render_target_fmt;
    135     VkFormat m_depth_stencil_fmt;
    136     VkClearColorValue m_clear_color;
    137     bool m_clear_via_load_op;
    138     float m_depth_clear_color;
    139     uint32_t m_stencil_clear_color;
    140     VkDepthStencilObj *m_depthStencil;
    141     PFN_vkCreateDebugReportCallbackEXT m_CreateDebugReportCallback;
    142     PFN_vkDestroyDebugReportCallbackEXT m_DestroyDebugReportCallback;
    143     PFN_vkDebugReportMessageEXT m_DebugReportMessage;
    144     VkDebugReportCallbackEXT m_globalMsgCallback;
    145     VkDebugReportCallbackEXT m_devMsgCallback;
    146 
    147     std::vector<const char *> m_instance_layer_names;
    148     std::vector<const char *> m_instance_extension_names;
    149     std::vector<const char *> m_device_extension_names;
    150 
    151     /*
    152      * SetUp and TearDown are called by the Google Test framework
    153      * to initialize a test framework based on this class.
    154      */
    155     virtual void SetUp() {
    156         this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    157         this->app_info.pNext = NULL;
    158         this->app_info.pApplicationName = "base";
    159         this->app_info.applicationVersion = 1;
    160         this->app_info.pEngineName = "unittest";
    161         this->app_info.engineVersion = 1;
    162         this->app_info.apiVersion = VK_API_VERSION_1_0;
    163 
    164         InitFramework();
    165     }
    166 
    167     virtual void TearDown() { ShutdownFramework(); }
    168 };
    169 
    170 class VkDescriptorSetObj;
    171 class VkConstantBufferObj;
    172 class VkPipelineObj;
    173 class VkDescriptorSetObj;
    174 
    175 class VkCommandPoolObj : public vk_testing::CommandPool {
    176    public:
    177     VkCommandPoolObj(VkDeviceObj *device, uint32_t queue_family_index, VkCommandPoolCreateFlags flags = 0);
    178 };
    179 
    180 class VkCommandBufferObj : public vk_testing::CommandBuffer {
    181    public:
    182     VkCommandBufferObj(VkDeviceObj *device, VkCommandPoolObj *pool, VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY);
    183     void PipelineBarrier(VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages, VkDependencyFlags dependencyFlags,
    184                          uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount,
    185                          const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
    186                          const VkImageMemoryBarrier *pImageMemoryBarriers);
    187     void ClearAllBuffers(const vector<VkImageObj *> &color_objs, VkClearColorValue clear_color,
    188                          VkDepthStencilObj *depth_stencil_obj, float depth_clear_value, uint32_t stencil_clear_value);
    189     void PrepareAttachments(const vector<VkImageObj *> &color_atts, VkDepthStencilObj *depth_stencil_att);
    190     void BindDescriptorSet(VkDescriptorSetObj &descriptorSet);
    191     void BindVertexBuffer(VkConstantBufferObj *vertexBuffer, VkDeviceSize offset, uint32_t binding);
    192     void BeginRenderPass(const VkRenderPassBeginInfo &info);
    193     void EndRenderPass();
    194     void FillBuffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize fill_size, uint32_t data);
    195     void Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
    196     void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
    197                      uint32_t firstInstance);
    198     void QueueCommandBuffer(bool checkSuccess = true);
    199     void QueueCommandBuffer(VkFence fence, bool checkSuccess = true);
    200     void SetViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports);
    201     void SetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference);
    202     void UpdateBuffer(VkBuffer buffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData);
    203     void CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
    204                    uint32_t regionCount, const VkImageCopy *pRegions);
    205     void ResolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
    206                       uint32_t regionCount, const VkImageResolve *pRegions);
    207     void ClearColorImage(VkImage image, VkImageLayout imageLayout, const VkClearColorValue *pColor, uint32_t rangeCount,
    208                          const VkImageSubresourceRange *pRanges);
    209     void ClearDepthStencilImage(VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue *pColor,
    210                                 uint32_t rangeCount, const VkImageSubresourceRange *pRanges);
    211 
    212    protected:
    213     VkDeviceObj *m_device;
    214 };
    215 
    216 class VkConstantBufferObj : public vk_testing::Buffer {
    217    public:
    218     VkConstantBufferObj(VkDeviceObj *device,
    219                         VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
    220     VkConstantBufferObj(VkDeviceObj *device, VkDeviceSize size, const void *data,
    221                         VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
    222 
    223     VkDescriptorBufferInfo m_descriptorBufferInfo;
    224 
    225    protected:
    226     VkDeviceObj *m_device;
    227 };
    228 
    229 class VkRenderpassObj {
    230    public:
    231     VkRenderpassObj(VkDeviceObj *device);
    232     ~VkRenderpassObj();
    233     VkRenderPass handle() { return m_renderpass; }
    234 
    235    protected:
    236     VkRenderPass m_renderpass;
    237     VkDevice device;
    238 };
    239 
    240 class VkImageObj : public vk_testing::Image {
    241    public:
    242     VkImageObj(VkDeviceObj *dev);
    243     bool IsCompatible(VkImageUsageFlags usages, VkFormatFeatureFlags features);
    244 
    245    public:
    246     void Init(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format, VkFlags const usage,
    247               VkImageTiling const tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags const reqs = 0,
    248               const std::vector<uint32_t> *queue_families = nullptr);
    249 
    250     void init(const VkImageCreateInfo *create_info);
    251 
    252     void InitNoLayout(uint32_t const width, uint32_t const height, uint32_t const mipLevels, VkFormat const format,
    253                       VkFlags const usage, VkImageTiling tiling = VK_IMAGE_TILING_LINEAR, VkMemoryPropertyFlags reqs = 0,
    254                       const std::vector<uint32_t> *queue_families = nullptr);
    255 
    256     //    void clear( CommandBuffer*, uint32_t[4] );
    257 
    258     void Layout(VkImageLayout const layout) { m_descriptorImageInfo.imageLayout = layout; }
    259 
    260     VkDeviceMemory memory() const { return Image::memory().handle(); }
    261 
    262     void *MapMemory() { return Image::memory().map(); }
    263 
    264     void UnmapMemory() { Image::memory().unmap(); }
    265 
    266     void ImageMemoryBarrier(VkCommandBufferObj *cmd, VkImageAspectFlags aspect, VkFlags output_mask, VkFlags input_mask,
    267                             VkImageLayout image_layout);
    268 
    269     VkResult CopyImage(VkImageObj &src_image);
    270 
    271     VkImage image() const { return handle(); }
    272 
    273     VkImageView targetView(VkFormat format) {
    274         if (!m_targetView.initialized()) {
    275             VkImageViewCreateInfo createView = {};
    276             createView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    277             createView.image = handle();
    278             createView.viewType = VK_IMAGE_VIEW_TYPE_2D;
    279             createView.format = format;
    280             createView.components.r = VK_COMPONENT_SWIZZLE_R;
    281             createView.components.g = VK_COMPONENT_SWIZZLE_G;
    282             createView.components.b = VK_COMPONENT_SWIZZLE_B;
    283             createView.components.a = VK_COMPONENT_SWIZZLE_A;
    284             createView.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
    285             createView.flags = 0;
    286             m_targetView.init(*m_device, createView);
    287         }
    288         return m_targetView.handle();
    289     }
    290 
    291     void SetLayout(VkCommandBufferObj *cmd_buf, VkImageAspectFlags aspect, VkImageLayout image_layout);
    292     void SetLayout(VkImageAspectFlags aspect, VkImageLayout image_layout);
    293 
    294     VkImageLayout Layout() const { return m_descriptorImageInfo.imageLayout; }
    295     uint32_t width() const { return extent().width; }
    296     uint32_t height() const { return extent().height; }
    297     VkDeviceObj *device() const { return m_device; }
    298 
    299    protected:
    300     VkDeviceObj *m_device;
    301 
    302     vk_testing::ImageView m_targetView;
    303     VkDescriptorImageInfo m_descriptorImageInfo;
    304 };
    305 
    306 class VkTextureObj : public VkImageObj {
    307    public:
    308     VkTextureObj(VkDeviceObj *device, uint32_t *colors = NULL);
    309 
    310     VkDescriptorImageInfo m_imageInfo;
    311 
    312    protected:
    313     VkDeviceObj *m_device;
    314     vk_testing::ImageView m_textureView;
    315 };
    316 
    317 class VkDepthStencilObj : public VkImageObj {
    318    public:
    319     VkDepthStencilObj(VkDeviceObj *device);
    320     void Init(VkDeviceObj *device, int32_t width, int32_t height, VkFormat format,
    321               VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
    322     bool Initialized();
    323     VkImageView *BindInfo();
    324 
    325     VkFormat Format() const;
    326 
    327    protected:
    328     VkDeviceObj *m_device;
    329     bool m_initialized;
    330     vk_testing::ImageView m_imageView;
    331     VkFormat m_depth_stencil_fmt;
    332     VkImageView m_attachmentBindInfo;
    333 };
    334 
    335 class VkSamplerObj : public vk_testing::Sampler {
    336    public:
    337     VkSamplerObj(VkDeviceObj *device);
    338 
    339    protected:
    340     VkDeviceObj *m_device;
    341 };
    342 
    343 class VkDescriptorSetLayoutObj : public vk_testing::DescriptorSetLayout {
    344    public:
    345     VkDescriptorSetLayoutObj() = default;
    346     VkDescriptorSetLayoutObj(const VkDeviceObj *device,
    347                              const std::vector<VkDescriptorSetLayoutBinding> &descriptor_set_bindings = {},
    348                              VkDescriptorSetLayoutCreateFlags flags = 0);
    349 
    350     // Move constructor and move assignment operator for Visual Studio 2013
    351     VkDescriptorSetLayoutObj(VkDescriptorSetLayoutObj &&src) : DescriptorSetLayout(std::move(src)){};
    352     VkDescriptorSetLayoutObj &operator=(VkDescriptorSetLayoutObj &&src) {
    353         DescriptorSetLayout::operator=(std::move(src));
    354         return *this;
    355     }
    356 };
    357 
    358 class VkDescriptorSetObj : public vk_testing::DescriptorPool {
    359    public:
    360     VkDescriptorSetObj(VkDeviceObj *device);
    361     ~VkDescriptorSetObj();
    362 
    363     int AppendDummy();
    364     int AppendBuffer(VkDescriptorType type, VkConstantBufferObj &constantBuffer);
    365     int AppendSamplerTexture(VkSamplerObj *sampler, VkTextureObj *texture);
    366     void CreateVKDescriptorSet(VkCommandBufferObj *commandBuffer);
    367 
    368     VkDescriptorSet GetDescriptorSetHandle() const;
    369     VkPipelineLayout GetPipelineLayout() const;
    370 
    371    protected:
    372     VkDeviceObj *m_device;
    373     std::vector<VkDescriptorSetLayoutBinding> m_layout_bindings;
    374     std::map<VkDescriptorType, int> m_type_counts;
    375     int m_nextSlot;
    376 
    377     vector<VkDescriptorImageInfo> m_imageSamplerDescriptors;
    378     vector<VkWriteDescriptorSet> m_writes;
    379 
    380     vk_testing::DescriptorSetLayout m_layout;
    381     vk_testing::PipelineLayout m_pipeline_layout;
    382     vk_testing::DescriptorSet *m_set = NULL;
    383 };
    384 
    385 class VkShaderObj : public vk_testing::ShaderModule {
    386    public:
    387     VkShaderObj(VkDeviceObj *device, const char *shaderText, VkShaderStageFlagBits stage, VkRenderFramework *framework,
    388                 char const *name = "main");
    389     VkPipelineShaderStageCreateInfo const &GetStageCreateInfo() const;
    390 
    391    protected:
    392     VkPipelineShaderStageCreateInfo m_stage_info;
    393     VkDeviceObj *m_device;
    394 };
    395 
    396 class VkPipelineLayoutObj : public vk_testing::PipelineLayout {
    397    public:
    398     VkPipelineLayoutObj() = default;
    399     VkPipelineLayoutObj(VkDeviceObj *device, const std::vector<const VkDescriptorSetLayoutObj *> &descriptor_layouts = {},
    400                         const std::vector<VkPushConstantRange> &push_constant_ranges = {});
    401 
    402     // Move constructor and move assignment operator for Visual Studio 2013
    403     VkPipelineLayoutObj(VkPipelineLayoutObj &&src) : PipelineLayout(std::move(src)) {}
    404     VkPipelineLayoutObj &operator=(VkPipelineLayoutObj &&src) {
    405         PipelineLayout::operator=(std::move(src));
    406         return *this;
    407     }
    408 
    409     void Reset();
    410 };
    411 
    412 class VkPipelineObj : public vk_testing::Pipeline {
    413    public:
    414     VkPipelineObj(VkDeviceObj *device);
    415     void AddShader(VkShaderObj *shaderObj);
    416     void AddShader(VkPipelineShaderStageCreateInfo const &createInfo);
    417     void AddVertexInputAttribs(VkVertexInputAttributeDescription *vi_attrib, uint32_t count);
    418     void AddVertexInputBindings(VkVertexInputBindingDescription *vi_binding, uint32_t count);
    419     void AddColorAttachment(uint32_t binding, const VkPipelineColorBlendAttachmentState &att);
    420     void MakeDynamic(VkDynamicState state);
    421 
    422     void AddDefaultColorAttachment(VkColorComponentFlags writeMask = 0xf /*=R|G|B|A*/) {
    423         VkPipelineColorBlendAttachmentState att = {};
    424         att.blendEnable = VK_FALSE;
    425         att.colorWriteMask = writeMask;
    426         AddColorAttachment(0, att);
    427     }
    428 
    429     void SetDepthStencil(const VkPipelineDepthStencilStateCreateInfo *);
    430     void SetMSAA(const VkPipelineMultisampleStateCreateInfo *ms_state);
    431     void SetInputAssembly(const VkPipelineInputAssemblyStateCreateInfo *ia_state);
    432     void SetRasterization(const VkPipelineRasterizationStateCreateInfo *rs_state);
    433     void SetTessellation(const VkPipelineTessellationStateCreateInfo *te_state);
    434     void SetViewport(const vector<VkViewport> viewports);
    435     void SetScissor(const vector<VkRect2D> scissors);
    436 
    437     void InitGraphicsPipelineCreateInfo(VkGraphicsPipelineCreateInfo *gp_ci);
    438 
    439     VkResult CreateVKPipeline(VkPipelineLayout layout, VkRenderPass render_pass, VkGraphicsPipelineCreateInfo *gp_ci = nullptr);
    440 
    441    protected:
    442     VkPipelineVertexInputStateCreateInfo m_vi_state;
    443     VkPipelineInputAssemblyStateCreateInfo m_ia_state;
    444     VkPipelineRasterizationStateCreateInfo m_rs_state;
    445     VkPipelineColorBlendStateCreateInfo m_cb_state;
    446     VkPipelineDepthStencilStateCreateInfo const *m_ds_state;
    447     VkPipelineViewportStateCreateInfo m_vp_state;
    448     VkPipelineMultisampleStateCreateInfo m_ms_state;
    449     VkPipelineTessellationStateCreateInfo const *m_te_state;
    450     VkPipelineDynamicStateCreateInfo m_pd_state;
    451     vector<VkDynamicState> m_dynamic_state_enables;
    452     vector<VkViewport> m_viewports;
    453     vector<VkRect2D> m_scissors;
    454     VkDeviceObj *m_device;
    455     vector<VkPipelineShaderStageCreateInfo> m_shaderStages;
    456     vector<VkPipelineColorBlendAttachmentState> m_colorAttachments;
    457 };
    458 
    459 #endif  // VKRENDERFRAMEWORK_H
    460