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