• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
device()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 
instance()61     VkInstance instance() { return inst; }
device()62     VkDevice device() { return m_device->device(); }
gpu()63     VkPhysicalDevice gpu() { return objs[0]; }
renderPass()64     VkRenderPass renderPass() { return m_renderPass; }
framebuffer()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 
renderPassBeginInfo()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      */
SetUp()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 
TearDown()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();
handle()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 
layout(VkImageLayout layout)261     void layout(VkImageLayout layout) { m_descriptorImageInfo.imageLayout = layout; }
262 
memory()263     VkDeviceMemory memory() const { return Image::memory().handle(); }
264 
MapMemory()265     void *MapMemory() { return Image::memory().map(); }
266 
UnmapMemory()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 
image()274     VkImage image() const { return handle(); }
275 
targetView(VkFormat format)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 
layout()297     VkImageLayout layout() const { return m_descriptorImageInfo.imageLayout; }
width()298     uint32_t width() const { return extent().width; }
height()299     uint32_t height() const { return extent().height; }
device()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;
GetTypeCounts()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 
AddColorAttachment()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