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