1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Intel Corporation
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Dynamic State Tests - Base Class
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktDynamicStateBaseClass.hpp"
26
27 #include "vkPrograms.hpp"
28
29 namespace vkt
30 {
31 namespace DynamicState
32 {
33
34 using namespace Draw;
35
DynamicStateBaseClass(Context & context,const char * vertexShaderName,const char * fragmentShaderName)36 DynamicStateBaseClass::DynamicStateBaseClass (Context& context, const char* vertexShaderName, const char* fragmentShaderName)
37 : TestInstance (context)
38 , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
39 , m_topology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
40 , m_vk (context.getDeviceInterface())
41 , m_vertexShaderName (vertexShaderName)
42 , m_fragmentShaderName (fragmentShaderName)
43 {
44 }
45
initialize(void)46 void DynamicStateBaseClass::initialize (void)
47 {
48 const vk::VkDevice device = m_context.getDevice();
49 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
50
51 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
52 m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
53
54 const vk::VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
55 const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, targetImageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
56 vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
57
58 m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator());
59
60 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
61 m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
62
63 RenderPassCreateInfo renderPassCreateInfo;
64 renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
65 vk::VK_SAMPLE_COUNT_1_BIT,
66 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
67 vk::VK_ATTACHMENT_STORE_OP_STORE,
68 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
69 vk::VK_ATTACHMENT_STORE_OP_STORE,
70 vk::VK_IMAGE_LAYOUT_GENERAL,
71 vk::VK_IMAGE_LAYOUT_GENERAL));
72
73 const vk::VkAttachmentReference colorAttachmentReference =
74 {
75 0,
76 vk::VK_IMAGE_LAYOUT_GENERAL
77 };
78
79 renderPassCreateInfo.addSubpass(SubpassDescription(
80 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
81 0,
82 0,
83 DE_NULL,
84 1,
85 &colorAttachmentReference,
86 DE_NULL,
87 AttachmentReference(),
88 0,
89 DE_NULL
90 )
91 );
92
93 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
94
95 std::vector<vk::VkImageView> colorAttachments(1);
96 colorAttachments[0] = *m_colorTargetView;
97
98 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
99
100 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
101
102 const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
103 {
104 0,
105 (deUint32)sizeof(tcu::Vec4) * 2,
106 vk::VK_VERTEX_INPUT_RATE_VERTEX,
107 };
108
109 const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
110 {
111 {
112 0u,
113 0u,
114 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
115 0u
116 },
117 {
118 1u,
119 0u,
120 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
121 (deUint32)(sizeof(float)* 4),
122 }
123 };
124
125 m_vertexInputState = PipelineCreateInfo::VertexInputState(
126 1,
127 &vertexInputBindingDescription,
128 2,
129 vertexInputAttributeDescriptions);
130
131 const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
132 m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
133 m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
134
135 deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
136 deMemcpy(ptr, &m_data[0], (size_t)dataSize);
137
138 vk::flushMappedMemoryRange(m_vk, device,
139 m_vertexBuffer->getBoundMemory().getMemory(),
140 m_vertexBuffer->getBoundMemory().getOffset(),
141 dataSize);
142
143 const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
144 m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
145
146 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
147 {
148 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
149 DE_NULL, // const void* pNext;
150 *m_cmdPool, // VkCommandPool commandPool;
151 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
152 1u, // deUint32 bufferCount;
153 };
154 m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, &cmdBufferAllocateInfo);
155
156 initPipeline(device);
157 }
158
initPipeline(const vk::VkDevice device)159 void DynamicStateBaseClass::initPipeline (const vk::VkDevice device)
160 {
161 const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
162 const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
163
164 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
165
166 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
167 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
168 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
169 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
170 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
171 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
172 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
173 pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
174 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
175 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
176 pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
177
178 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
179 }
180
iterate(void)181 tcu::TestStatus DynamicStateBaseClass::iterate (void)
182 {
183 DE_ASSERT(false);
184 return tcu::TestStatus::fail("Implement iterate() method!");
185 }
186
beginRenderPass(void)187 void DynamicStateBaseClass::beginRenderPass (void)
188 {
189 const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
190 beginRenderPassWithClearColor(clearColor);
191 }
192
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor)193 void DynamicStateBaseClass::beginRenderPassWithClearColor (const vk::VkClearColorValue& clearColor)
194 {
195 const CmdBufferBeginInfo beginInfo;
196 m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo);
197
198 initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL);
199
200 const ImageSubresourceRange subresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT);
201 m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
202 vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
203
204 const vk::VkMemoryBarrier memBarrier =
205 {
206 vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,
207 DE_NULL,
208 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
209 vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
210 };
211
212 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
213 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
214 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
215
216 const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } };
217 const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea);
218
219 m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_SUBPASS_CONTENTS_INLINE);
220 }
221
setDynamicViewportState(const deUint32 width,const deUint32 height)222 void DynamicStateBaseClass::setDynamicViewportState (const deUint32 width, const deUint32 height)
223 {
224 vk::VkViewport viewport;
225 viewport.x = 0;
226 viewport.y = 0;
227 viewport.width = static_cast<float>(width);
228 viewport.height = static_cast<float>(height);
229 viewport.minDepth = 0.0f;
230 viewport.maxDepth = 1.0f;
231
232 m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
233
234 vk::VkRect2D scissor;
235 scissor.offset.x = 0;
236 scissor.offset.y = 0;
237 scissor.extent.width = width;
238 scissor.extent.height = height;
239 m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
240 }
241
setDynamicViewportState(deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)242 void DynamicStateBaseClass::setDynamicViewportState (deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
243 {
244 m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
245 m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
246 }
247
setDynamicRasterizationState(const float lineWidth,const float depthBiasConstantFactor,const float depthBiasClamp,const float depthBiasSlopeFactor)248 void DynamicStateBaseClass::setDynamicRasterizationState (const float lineWidth,
249 const float depthBiasConstantFactor,
250 const float depthBiasClamp,
251 const float depthBiasSlopeFactor)
252 {
253 m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
254 m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
255 }
256
setDynamicBlendState(const float const1,const float const2,const float const3,const float const4)257 void DynamicStateBaseClass::setDynamicBlendState (const float const1, const float const2, const float const3, const float const4)
258 {
259 float blendConstantsants[4] = { const1, const2, const3, const4 };
260 m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
261 }
262
setDynamicDepthStencilState(const float minDepthBounds,const float maxDepthBounds,const deUint32 stencilFrontCompareMask,const deUint32 stencilFrontWriteMask,const deUint32 stencilFrontReference,const deUint32 stencilBackCompareMask,const deUint32 stencilBackWriteMask,const deUint32 stencilBackReference)263 void DynamicStateBaseClass::setDynamicDepthStencilState (const float minDepthBounds,
264 const float maxDepthBounds,
265 const deUint32 stencilFrontCompareMask,
266 const deUint32 stencilFrontWriteMask,
267 const deUint32 stencilFrontReference,
268 const deUint32 stencilBackCompareMask,
269 const deUint32 stencilBackWriteMask,
270 const deUint32 stencilBackReference)
271 {
272 m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
273 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
274 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
275 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
276 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
277 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
278 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
279 }
280
281 } // DynamicState
282 } // vkt
283