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@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 
device()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 
device()82     VkDevice device() { return m_device->device(); }
gpu()83     VkPhysicalDevice gpu() { return objs[0]; }
renderPass()84     VkRenderPass renderPass() { return m_renderPass; }
framebuffer()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 
renderPassBeginInfo()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      */
SetUp()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 
TearDown()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 
layout(VkImageLayout layout)296     void layout(VkImageLayout layout) {
297         m_descriptorImageInfo.imageLayout = layout;
298     }
299 
memory()300     VkDeviceMemory memory() const { return Image::memory().handle(); }
301 
MapMemory()302     void *MapMemory() { return Image::memory().map(); }
303 
UnmapMemory()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 
image()312     VkImage image() const { return handle(); }
313 
targetView(VkFormat format)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 
layout()337     VkImageLayout layout() const { return m_descriptorImageInfo.imageLayout; }
width()338     uint32_t width() const { return extent().width; }
height()339     uint32_t height() const { return extent().height; }
device()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;
GetTypeCounts()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 
AddColorAttachment()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