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 Depth Stencil Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktDynamicStateDSTests.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktDynamicStateTestCaseUtil.hpp"
29 #include "vktDynamicStateBaseClass.hpp"
30
31 #include "tcuTestLog.hpp"
32 #include "tcuResource.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuCommandLine.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuRGBA.hpp"
37
38 #include "vkRefUtil.hpp"
39 #include "vkImageUtil.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkCmdUtil.hpp"
42
43 #include "vktDrawCreateInfoUtil.hpp"
44 #include "vktDrawImageObjectUtil.hpp"
45 #include "vktDrawBufferObjectUtil.hpp"
46 #include "vkPrograms.hpp"
47
48 namespace vkt
49 {
50 namespace DynamicState
51 {
52
53 using namespace Draw;
54
55 namespace
56 {
57
58 class DepthStencilBaseCase : public TestInstance
59 {
60 public:
DepthStencilBaseCase(Context & context,const char * vertexShaderName,const char * fragmentShaderName)61 DepthStencilBaseCase (Context& context, const char* vertexShaderName, const char* fragmentShaderName)
62 : TestInstance (context)
63 , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
64 , m_topology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
65 , m_vk (context.getDeviceInterface())
66 , m_vertexShaderName (vertexShaderName)
67 , m_fragmentShaderName (fragmentShaderName)
68 {
69 }
70
71 protected:
72
73 enum
74 {
75 WIDTH = 128,
76 HEIGHT = 128
77 };
78
79 vk::VkFormat m_colorAttachmentFormat;
80 vk::VkFormat m_depthStencilAttachmentFormat;
81
82 vk::VkPrimitiveTopology m_topology;
83
84 const vk::DeviceInterface& m_vk;
85
86 vk::Move<vk::VkPipeline> m_pipeline_1;
87 vk::Move<vk::VkPipeline> m_pipeline_2;
88 vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
89
90 de::SharedPtr<Image> m_colorTargetImage;
91 vk::Move<vk::VkImageView> m_colorTargetView;
92
93 de::SharedPtr<Image> m_depthStencilImage;
94 vk::Move<vk::VkImageView> m_attachmentView;
95
96 PipelineCreateInfo::VertexInputState m_vertexInputState;
97 de::SharedPtr<Buffer> m_vertexBuffer;
98
99 vk::Move<vk::VkCommandPool> m_cmdPool;
100 vk::Move<vk::VkCommandBuffer> m_cmdBuffer;
101
102 vk::Move<vk::VkFramebuffer> m_framebuffer;
103 vk::Move<vk::VkRenderPass> m_renderPass;
104
105 const std::string m_vertexShaderName;
106 const std::string m_fragmentShaderName;
107
108 std::vector<PositionColorVertex> m_data;
109
110 PipelineCreateInfo::DepthStencilState m_depthStencilState_1;
111 PipelineCreateInfo::DepthStencilState m_depthStencilState_2;
112
initialize(void)113 void initialize (void)
114 {
115 const vk::VkDevice device = m_context.getDevice();
116
117 vk::VkFormatProperties formatProperties;
118 // check for VK_FORMAT_D24_UNORM_S8_UINT support
119 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties);
120 if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
121 {
122 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT;
123 }
124 else
125 {
126 // check for VK_FORMAT_D32_SFLOAT_S8_UINT support
127 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties);
128 if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
129 {
130 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT;
131 }
132 else
133 throw tcu::NotSupportedError("No valid depth stencil attachment available");
134 }
135
136 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
137 m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
138
139 const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
140 const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
141
142 const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 };
143 const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
144 vk::VK_IMAGE_TILING_OPTIMAL,
145 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
146 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
147 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
148
149 m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
150
151 const ImageCreateInfo depthStencilImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent,
152 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
153 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
154 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
155
156 m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
157
158 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat);
159 m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
160
161 const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat);
162 m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo);
163
164 RenderPassCreateInfo renderPassCreateInfo;
165 renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
166 vk::VK_SAMPLE_COUNT_1_BIT,
167 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
168 vk::VK_ATTACHMENT_STORE_OP_STORE,
169 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
170 vk::VK_ATTACHMENT_STORE_OP_STORE,
171 vk::VK_IMAGE_LAYOUT_GENERAL,
172 vk::VK_IMAGE_LAYOUT_GENERAL));
173
174 renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat,
175 vk::VK_SAMPLE_COUNT_1_BIT,
176 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
177 vk::VK_ATTACHMENT_STORE_OP_STORE,
178 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
179 vk::VK_ATTACHMENT_STORE_OP_STORE,
180 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
181 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
182
183 const vk::VkAttachmentReference colorAttachmentReference =
184 {
185 0,
186 vk::VK_IMAGE_LAYOUT_GENERAL
187 };
188
189 const vk::VkAttachmentReference depthAttachmentReference =
190 {
191 1,
192 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
193 };
194
195 renderPassCreateInfo.addSubpass(SubpassDescription(
196 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
197 0,
198 0,
199 DE_NULL,
200 1,
201 &colorAttachmentReference,
202 DE_NULL,
203 depthAttachmentReference,
204 0,
205 DE_NULL));
206
207 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
208
209 const vk::VkVertexInputBindingDescription vertexInputBindingDescription =
210 {
211 0,
212 (deUint32)sizeof(tcu::Vec4) * 2,
213 vk::VK_VERTEX_INPUT_RATE_VERTEX,
214 };
215
216 const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
217 {
218 {
219 0u,
220 0u,
221 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
222 0u
223 },
224 {
225 1u,
226 0u,
227 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
228 (deUint32)(sizeof(float)* 4),
229 }
230 };
231
232 m_vertexInputState = PipelineCreateInfo::VertexInputState(
233 1,
234 &vertexInputBindingDescription,
235 2,
236 vertexInputAttributeDescriptions);
237
238 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
239
240 PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
241 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
242 pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
243 pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
244 pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
245 pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
246 pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
247 pipelineCreateInfo_1.addState(m_depthStencilState_1);
248 pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
249 pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
250 pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
251
252 PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
253 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
254 pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
255 pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
256 pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
257 pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
258 pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
259 pipelineCreateInfo_2.addState(m_depthStencilState_2);
260 pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
261 pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
262 pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
263
264 m_pipeline_1 = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
265 m_pipeline_2 = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
266
267 std::vector<vk::VkImageView> attachments(2);
268 attachments[0] = *m_colorTargetView;
269 attachments[1] = *m_attachmentView;
270
271 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
272
273 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
274
275 const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex);
276 m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
277 m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
278
279 deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr());
280 deMemcpy(ptr, &m_data[0], (size_t)dataSize);
281
282 vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
283
284 const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
285 m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
286 m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
287 }
288
iterate(void)289 virtual tcu::TestStatus iterate (void)
290 {
291 DE_ASSERT(false);
292 return tcu::TestStatus::fail("Implement iterate() method!");
293 }
294
beginRenderPass(void)295 void beginRenderPass (void)
296 {
297 const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } };
298 beginRenderPassWithClearColor(clearColor);
299 }
300
beginRenderPassWithClearColor(const vk::VkClearColorValue & clearColor)301 void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor)
302 {
303 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
304
305 initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
306 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
307 initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
308 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
309
310 const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT);
311 m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(),
312 vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage);
313
314 const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 };
315
316 const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT };
317 m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(),
318 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil);
319
320 vk::VkMemoryBarrier memBarrier;
321 memBarrier.sType = vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER;
322 memBarrier.pNext = NULL;
323 memBarrier.srcAccessMask = vk::VK_ACCESS_TRANSFER_WRITE_BIT;
324 memBarrier.dstAccessMask = vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
325 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
326
327 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
328 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
329 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
330 0, 1, &memBarrier, 0, NULL, 0, NULL);
331
332 transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT,
333 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
334 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
335 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
336
337 vk::beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, vk::makeRect2D(0, 0, WIDTH, HEIGHT));
338 }
339
setDynamicViewportState(const deUint32 width,const deUint32 height)340 void setDynamicViewportState (const deUint32 width, const deUint32 height)
341 {
342 vk::VkViewport viewport = vk::makeViewport(tcu::UVec2(width, height));
343 m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport);
344
345 vk::VkRect2D scissor = vk::makeRect2D(tcu::UVec2(width, height));
346 m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor);
347 }
348
setDynamicViewportState(const deUint32 viewportCount,const vk::VkViewport * pViewports,const vk::VkRect2D * pScissors)349 void setDynamicViewportState(const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors)
350 {
351 m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports);
352 m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors);
353 }
354
setDynamicRasterizationState(const float lineWidth=1.0f,const float depthBiasConstantFactor=0.0f,const float depthBiasClamp=0.0f,const float depthBiasSlopeFactor=0.0f)355 void setDynamicRasterizationState(const float lineWidth = 1.0f,
356 const float depthBiasConstantFactor = 0.0f,
357 const float depthBiasClamp = 0.0f,
358 const float depthBiasSlopeFactor = 0.0f)
359 {
360 m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth);
361 m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
362 }
363
setDynamicBlendState(const float const1=0.0f,const float const2=0.0f,const float const3=0.0f,const float const4=0.0f)364 void setDynamicBlendState(const float const1 = 0.0f, const float const2 = 0.0f,
365 const float const3 = 0.0f, const float const4 = 0.0f)
366 {
367 float blendConstantsants[4] = { const1, const2, const3, const4 };
368 m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants);
369 }
370
setDynamicDepthStencilState(const float minDepthBounds=-1.0f,const float maxDepthBounds=1.0f,const deUint32 stencilFrontCompareMask=0xffffffffu,const deUint32 stencilFrontWriteMask=0xffffffffu,const deUint32 stencilFrontReference=0,const deUint32 stencilBackCompareMask=0xffffffffu,const deUint32 stencilBackWriteMask=0xffffffffu,const deUint32 stencilBackReference=0)371 void setDynamicDepthStencilState(const float minDepthBounds = -1.0f,
372 const float maxDepthBounds = 1.0f,
373 const deUint32 stencilFrontCompareMask = 0xffffffffu,
374 const deUint32 stencilFrontWriteMask = 0xffffffffu,
375 const deUint32 stencilFrontReference = 0,
376 const deUint32 stencilBackCompareMask = 0xffffffffu,
377 const deUint32 stencilBackWriteMask = 0xffffffffu,
378 const deUint32 stencilBackReference = 0)
379 {
380 m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds);
381 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask);
382 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask);
383 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference);
384 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask);
385 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask);
386 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference);
387 }
388 };
389
390 class DepthBoundsParamTestInstance : public DepthStencilBaseCase
391 {
392 public:
DepthBoundsParamTestInstance(Context & context,ShaderMap shaders)393 DepthBoundsParamTestInstance (Context &context, ShaderMap shaders)
394 : DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
395 {
396 // Check if depth bounds test is supported
397 {
398 const vk::VkPhysicalDeviceFeatures& deviceFeatures = m_context.getDeviceFeatures();
399
400 if (!deviceFeatures.depthBounds)
401 throw tcu::NotSupportedError("Depth bounds test is unsupported");
402 }
403
404 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
405 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
406 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
407 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.375f, 1.0f), tcu::RGBA::green().toVec()));
408
409 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
410 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
411 m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
412 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.625f, 1.0f), tcu::RGBA::green().toVec()));
413
414 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
415 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
416 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
417 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
418
419 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
420 VK_TRUE, VK_TRUE, vk::VK_COMPARE_OP_ALWAYS, VK_FALSE);
421
422 // enable depth bounds test
423 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
424 VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_TRUE);
425
426 DepthStencilBaseCase::initialize();
427 }
428
iterate(void)429 virtual tcu::TestStatus iterate (void)
430 {
431 tcu::TestLog& log = m_context.getTestContext().getLog();
432 const vk::VkQueue queue = m_context.getUniversalQueue();
433 const vk::VkDevice device = m_context.getDevice();
434
435 beginRenderPass();
436
437 // set states here
438 setDynamicViewportState(WIDTH, HEIGHT);
439 setDynamicRasterizationState();
440 setDynamicBlendState();
441 setDynamicDepthStencilState(0.5f, 0.75f);
442
443 const vk::VkDeviceSize vertexBufferOffset = 0;
444 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
445 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
446
447 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
448 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
449 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
450
451 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
452 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0);
453
454 endRenderPass(m_vk, *m_cmdBuffer);
455 endCommandBuffer(m_vk, *m_cmdBuffer);
456
457 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
458
459 // validation
460 {
461 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
462 referenceFrame.allocLevel(0);
463
464 const deInt32 frameWidth = referenceFrame.getWidth();
465 const deInt32 frameHeight = referenceFrame.getHeight();
466
467 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
468
469 for (int y = 0; y < frameHeight; y++)
470 {
471 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
472
473 for (int x = 0; x < frameWidth; x++)
474 {
475 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
476
477 if (xCoord >= 0.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
478 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
479 else
480 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
481 }
482 }
483
484 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
485 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
486 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
487
488 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
489 referenceFrame.getLevel(0), renderedFrame, 0.05f,
490 tcu::COMPARE_LOG_RESULT))
491 {
492 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
493 }
494
495 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
496 }
497 }
498 };
499
500 class DepthBoundsTestInstance : public DynamicStateBaseClass
501 {
502 public:
503 enum
504 {
505 DEPTH_BOUNDS_MIN = 0,
506 DEPTH_BOUNDS_MAX = 1,
507 DEPTH_BOUNDS_COUNT = 2
508 };
509 static const float depthBounds[DEPTH_BOUNDS_COUNT];
510
511 DepthBoundsTestInstance (Context& context,
512 ShaderMap shaders);
513 virtual void initRenderPass (const vk::VkDevice device);
514 virtual void initFramebuffer (const vk::VkDevice device);
515 virtual void initPipeline (const vk::VkDevice device);
516 virtual tcu::TestStatus iterate (void);
517 private:
518 const vk::VkFormat m_depthAttachmentFormat;
519
520 de::SharedPtr<Draw::Image> m_depthImage;
521 vk::Move<vk::VkImageView> m_depthView;
522 };
523
524 const float DepthBoundsTestInstance::depthBounds[DEPTH_BOUNDS_COUNT] =
525 {
526 0.3f,
527 0.9f
528 };
529
DepthBoundsTestInstance(Context & context,ShaderMap shaders)530 DepthBoundsTestInstance::DepthBoundsTestInstance(Context& context, ShaderMap shaders)
531 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
532 , m_depthAttachmentFormat (vk::VK_FORMAT_D16_UNORM)
533 {
534 // Check depthBounds support
535 if (!context.getDeviceFeatures().depthBounds)
536 TCU_THROW(NotSupportedError, "depthBounds feature is not supported");
537
538 const vk::VkDevice device = m_context.getDevice();
539
540 const vk::VkExtent3D depthImageExtent = { WIDTH, HEIGHT, 1 };
541 const ImageCreateInfo depthImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthAttachmentFormat, depthImageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
542 vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
543
544 m_depthImage = Image::createAndAlloc(m_vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
545
546 const ImageViewCreateInfo depthViewInfo(m_depthImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthAttachmentFormat);
547 m_depthView = vk::createImageView(m_vk, device, &depthViewInfo);
548
549 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
550
551 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
552 m_data.push_back(PositionColorVertex(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
553 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
554 m_data.push_back(PositionColorVertex(tcu::Vec4( 1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
555
556 DynamicStateBaseClass::initialize();
557 }
558
559
initRenderPass(const vk::VkDevice device)560 void DepthBoundsTestInstance::initRenderPass (const vk::VkDevice device)
561 {
562 RenderPassCreateInfo renderPassCreateInfo;
563 renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat,
564 vk::VK_SAMPLE_COUNT_1_BIT,
565 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
566 vk::VK_ATTACHMENT_STORE_OP_STORE,
567 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
568 vk::VK_ATTACHMENT_STORE_OP_STORE,
569 vk::VK_IMAGE_LAYOUT_GENERAL,
570 vk::VK_IMAGE_LAYOUT_GENERAL));
571 renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthAttachmentFormat,
572 vk::VK_SAMPLE_COUNT_1_BIT,
573 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
574 vk::VK_ATTACHMENT_STORE_OP_STORE,
575 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
576 vk::VK_ATTACHMENT_STORE_OP_STORE,
577 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
578 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL));
579
580 const vk::VkAttachmentReference colorAttachmentReference =
581 {
582 0,
583 vk::VK_IMAGE_LAYOUT_GENERAL
584 };
585
586 const vk::VkAttachmentReference depthAttachmentReference =
587 {
588 1,
589 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
590 };
591
592 renderPassCreateInfo.addSubpass(SubpassDescription(
593 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
594 0,
595 0,
596 DE_NULL,
597 1,
598 &colorAttachmentReference,
599 DE_NULL,
600 depthAttachmentReference,
601 0,
602 DE_NULL
603 )
604 );
605
606 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
607 }
608
initFramebuffer(const vk::VkDevice device)609 void DepthBoundsTestInstance::initFramebuffer (const vk::VkDevice device)
610 {
611 std::vector<vk::VkImageView> attachments(2);
612 attachments[0] = *m_colorTargetView;
613 attachments[1] = *m_depthView;
614
615 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
616
617 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
618 }
619
initPipeline(const vk::VkDevice device)620 void DepthBoundsTestInstance::initPipeline (const vk::VkDevice device)
621 {
622 const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
623 const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
624
625 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
626
627 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
628 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
629 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
630 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
631 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
632 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
633 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1));
634 pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState(false, false, vk::VK_COMPARE_OP_NEVER, true));
635 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
636 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
637 pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState());
638
639 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
640 }
641
642
iterate(void)643 tcu::TestStatus DepthBoundsTestInstance::iterate (void)
644 {
645 tcu::TestLog &log = m_context.getTestContext().getLog();
646 const vk::VkQueue queue = m_context.getUniversalQueue();
647 const vk::VkDevice device = m_context.getDevice();
648
649 // Prepare depth image
650 tcu::Texture2D depthData(vk::mapVkFormat(m_depthAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
651 depthData.allocLevel(0);
652
653 const deInt32 depthDataWidth = depthData.getWidth();
654 const deInt32 depthDataHeight = depthData.getHeight();
655
656 for (int y = 0; y < depthDataHeight; ++y)
657 for (int x = 0; x < depthDataWidth; ++x)
658 depthData.getLevel(0).setPixDepth((float)(y * depthDataWidth + x % 11) / 10, x, y);
659
660 const vk::VkDeviceSize dataSize = depthData.getLevel(0).getWidth() * depthData.getLevel(0).getHeight()
661 * tcu::getPixelSize(mapVkFormat(m_depthAttachmentFormat));
662 de::SharedPtr<Draw::Buffer> stageBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
663 m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
664
665 deUint8* ptr = reinterpret_cast<unsigned char *>(stageBuffer->getBoundMemory().getHostPtr());
666 deMemcpy(ptr, depthData.getLevel(0).getDataPtr(), (size_t)dataSize);
667
668 vk::flushAlloc(m_vk, device, stageBuffer->getBoundMemory());
669
670 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
671
672 initialTransitionDepth2DImage(m_vk, *m_cmdBuffer, m_depthImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
673 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
674
675 const vk::VkBufferImageCopy bufferImageCopy =
676 {
677 (vk::VkDeviceSize)0, // VkDeviceSize bufferOffset;
678 0u, // deUint32 bufferRowLength;
679 0u, // deUint32 bufferImageHeight;
680 vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u), // VkImageSubresourceLayers imageSubresource;
681 vk::makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
682 vk::makeExtent3D(WIDTH, HEIGHT, 1u) // VkExtent3D imageExtent;
683 };
684 m_vk.cmdCopyBufferToImage(*m_cmdBuffer, stageBuffer->object(), m_depthImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopy);
685
686 transition2DImage(m_vk, *m_cmdBuffer, m_depthImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
687 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
688 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
689
690 const vk::VkClearColorValue clearColor = { { 1.0f, 1.0f, 1.0f, 1.0f } };
691 beginRenderPassWithClearColor(clearColor, true);
692
693 // Bind states
694 setDynamicViewportState(WIDTH, HEIGHT);
695 setDynamicRasterizationState();
696 setDynamicBlendState();
697 setDynamicDepthStencilState(depthBounds[DEPTH_BOUNDS_MIN], depthBounds[DEPTH_BOUNDS_MAX]);
698
699 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
700
701 const vk::VkDeviceSize vertexBufferOffset = 0;
702 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
703 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
704
705 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
706
707 endRenderPass(m_vk, *m_cmdBuffer);
708 endCommandBuffer(m_vk, *m_cmdBuffer);
709
710 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
711
712 // Validation
713 {
714 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
715 referenceFrame.allocLevel(0);
716
717 const deInt32 frameWidth = referenceFrame.getWidth();
718 const deInt32 frameHeight = referenceFrame.getHeight();
719
720 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
721
722 for (int y = 0; y < frameHeight; ++y)
723 for (int x = 0; x < frameWidth; ++x)
724 if (depthData.getLevel(0).getPixDepth(x, y) >= depthBounds[DEPTH_BOUNDS_MIN]
725 && depthData.getLevel(0).getPixDepth(x, y) <= depthBounds[DEPTH_BOUNDS_MAX])
726 referenceFrame.getLevel(0).setPixel(tcu::RGBA::green().toVec(), x, y);
727
728 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
729 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
730 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
731
732 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
733 referenceFrame.getLevel(0), renderedFrame, 0.05f,
734 tcu::COMPARE_LOG_RESULT))
735 {
736 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
737 }
738
739 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
740 }
741 }
742
743 class StencilParamsBasicTestInstance : public DepthStencilBaseCase
744 {
745 protected:
746 deUint32 m_writeMask;
747 deUint32 m_readMask;
748 deUint32 m_expectedValue;
749 tcu::Vec4 m_expectedColor;
750
751 public:
StencilParamsBasicTestInstance(Context & context,const char * vertexShaderName,const char * fragmentShaderName,const deUint32 writeMask,const deUint32 readMask,const deUint32 expectedValue,const tcu::Vec4 expectedColor)752 StencilParamsBasicTestInstance (Context& context, const char* vertexShaderName, const char* fragmentShaderName,
753 const deUint32 writeMask, const deUint32 readMask,
754 const deUint32 expectedValue, const tcu::Vec4 expectedColor)
755 : DepthStencilBaseCase (context, vertexShaderName, fragmentShaderName)
756 , m_expectedColor (1.0f, 1.0f, 1.0f, 1.0f)
757 {
758 m_writeMask = writeMask;
759 m_readMask = readMask;
760 m_expectedValue = expectedValue;
761 m_expectedColor = expectedColor;
762
763 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
764 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
765 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
766 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
767
768 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
769 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
770 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
771 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
772
773 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
774 PipelineCreateInfo::DepthStencilState::StencilOpState(
775 vk::VK_STENCIL_OP_REPLACE,
776 vk::VK_STENCIL_OP_REPLACE,
777 vk::VK_STENCIL_OP_REPLACE,
778 vk::VK_COMPARE_OP_ALWAYS);
779
780 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
781 PipelineCreateInfo::DepthStencilState::StencilOpState(
782 vk::VK_STENCIL_OP_REPLACE,
783 vk::VK_STENCIL_OP_REPLACE,
784 vk::VK_STENCIL_OP_REPLACE,
785 vk::VK_COMPARE_OP_ALWAYS);
786
787 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
788 PipelineCreateInfo::DepthStencilState::StencilOpState(
789 vk::VK_STENCIL_OP_REPLACE,
790 vk::VK_STENCIL_OP_REPLACE,
791 vk::VK_STENCIL_OP_REPLACE,
792 vk::VK_COMPARE_OP_EQUAL);
793
794 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
795 PipelineCreateInfo::DepthStencilState::StencilOpState(
796 vk::VK_STENCIL_OP_REPLACE,
797 vk::VK_STENCIL_OP_REPLACE,
798 vk::VK_STENCIL_OP_REPLACE,
799 vk::VK_COMPARE_OP_EQUAL);
800
801 // enable stencil test
802 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
803 VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_1, backState_1);
804
805 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
806 VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_2, backState_2);
807
808 DepthStencilBaseCase::initialize();
809 }
810
iterate(void)811 virtual tcu::TestStatus iterate (void)
812 {
813 tcu::TestLog& log = m_context.getTestContext().getLog();
814 const vk::VkQueue queue = m_context.getUniversalQueue();
815 const vk::VkDevice device = m_context.getDevice();
816
817 beginRenderPass();
818
819 // set states here
820 setDynamicViewportState(WIDTH, HEIGHT);
821 setDynamicRasterizationState();
822 setDynamicBlendState();
823
824 const vk::VkDeviceSize vertexBufferOffset = 0;
825 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
826 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
827
828 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
829 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, m_writeMask, 0x0F, 0xFF, m_writeMask, 0x0F);
830 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
831
832 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
833 setDynamicDepthStencilState(-1.0f, 1.0f, m_readMask, 0xFF, m_expectedValue, m_readMask, 0xFF, m_expectedValue);
834 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
835
836 endRenderPass(m_vk, *m_cmdBuffer);
837 endCommandBuffer(m_vk, *m_cmdBuffer);
838
839 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
840
841 // validation
842 {
843 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
844 referenceFrame.allocLevel(0);
845
846 const deInt32 frameWidth = referenceFrame.getWidth();
847 const deInt32 frameHeight = referenceFrame.getHeight();
848
849 for (int y = 0; y < frameHeight; y++)
850 {
851 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
852
853 for (int x = 0; x < frameWidth; x++)
854 {
855 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
856
857 if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -1.0f && yCoord <= 1.0f)
858 referenceFrame.getLevel(0).setPixel(m_expectedColor, x, y);
859 }
860 }
861
862 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
863 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
864 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
865
866 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
867 referenceFrame.getLevel(0), renderedFrame, 0.05f,
868 tcu::COMPARE_LOG_RESULT))
869 {
870 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
871 }
872
873 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
874 }
875 }
876 };
877
878 class StencilParamsBasicTestCase : public TestCase
879 {
880 protected:
createInstance(Context & context) const881 TestInstance* createInstance(Context& context) const
882 {
883 return new StencilParamsBasicTestInstance(context, "VertexFetch.vert", "VertexFetch.frag",
884 m_writeMask, m_readMask, m_expectedValue, m_expectedColor);
885 }
886
initPrograms(vk::SourceCollections & programCollection) const887 virtual void initPrograms(vk::SourceCollections& programCollection) const
888 {
889 programCollection.glslSources.add("VertexFetch.vert") <<
890 glu::VertexSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.vert"));
891
892 programCollection.glslSources.add("VertexFetch.frag") <<
893 glu::FragmentSource(ShaderSourceProvider::getSource(m_testCtx.getArchive(), "vulkan/dynamic_state/VertexFetch.frag"));
894 }
895
896 deUint32 m_writeMask;
897 deUint32 m_readMask;
898 deUint32 m_expectedValue;
899 tcu::Vec4 m_expectedColor;
900
901 public:
StencilParamsBasicTestCase(tcu::TestContext & context,const char * name,const char * description,const deUint32 writeMask,const deUint32 readMask,const deUint32 expectedValue,const tcu::Vec4 expectedColor)902 StencilParamsBasicTestCase (tcu::TestContext& context, const char *name, const char *description,
903 const deUint32 writeMask, const deUint32 readMask,
904 const deUint32 expectedValue, const tcu::Vec4 expectedColor)
905 : TestCase (context, name, description)
906 , m_writeMask (writeMask)
907 , m_readMask (readMask)
908 , m_expectedValue (expectedValue)
909 , m_expectedColor (expectedColor)
910 {
911 }
912 };
913
914 class StencilParamsAdvancedTestInstance : public DepthStencilBaseCase
915 {
916 public:
StencilParamsAdvancedTestInstance(Context & context,ShaderMap shaders)917 StencilParamsAdvancedTestInstance (Context& context, ShaderMap shaders)
918 : DepthStencilBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
919 {
920 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
921 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
922 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
923 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
924
925 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
926 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
927 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
928 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
929
930 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_1 =
931 PipelineCreateInfo::DepthStencilState::StencilOpState(
932 vk::VK_STENCIL_OP_REPLACE,
933 vk::VK_STENCIL_OP_REPLACE,
934 vk::VK_STENCIL_OP_REPLACE,
935 vk::VK_COMPARE_OP_ALWAYS);
936
937 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_1 =
938 PipelineCreateInfo::DepthStencilState::StencilOpState(
939 vk::VK_STENCIL_OP_REPLACE,
940 vk::VK_STENCIL_OP_REPLACE,
941 vk::VK_STENCIL_OP_REPLACE,
942 vk::VK_COMPARE_OP_ALWAYS);
943
944 const PipelineCreateInfo::DepthStencilState::StencilOpState frontState_2 =
945 PipelineCreateInfo::DepthStencilState::StencilOpState(
946 vk::VK_STENCIL_OP_REPLACE,
947 vk::VK_STENCIL_OP_REPLACE,
948 vk::VK_STENCIL_OP_REPLACE,
949 vk::VK_COMPARE_OP_NOT_EQUAL);
950
951 const PipelineCreateInfo::DepthStencilState::StencilOpState backState_2 =
952 PipelineCreateInfo::DepthStencilState::StencilOpState(
953 vk::VK_STENCIL_OP_REPLACE,
954 vk::VK_STENCIL_OP_REPLACE,
955 vk::VK_STENCIL_OP_REPLACE,
956 vk::VK_COMPARE_OP_NOT_EQUAL);
957
958 // enable stencil test
959 m_depthStencilState_1 = PipelineCreateInfo::DepthStencilState(
960 VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_1, backState_1);
961
962 m_depthStencilState_2 = PipelineCreateInfo::DepthStencilState(
963 VK_FALSE, VK_FALSE, vk::VK_COMPARE_OP_NEVER, VK_FALSE, VK_TRUE, frontState_2, backState_2);
964
965 DepthStencilBaseCase::initialize();
966 }
967
iterate(void)968 virtual tcu::TestStatus iterate (void)
969 {
970 tcu::TestLog& log = m_context.getTestContext().getLog();
971 const vk::VkQueue queue = m_context.getUniversalQueue();
972 const vk::VkDevice device = m_context.getDevice();
973
974 beginRenderPass();
975
976 // set states here
977 setDynamicViewportState(WIDTH, HEIGHT);
978 setDynamicRasterizationState();
979 setDynamicBlendState();
980
981 const vk::VkDeviceSize vertexBufferOffset = 0;
982 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
983 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
984
985 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_1);
986 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0x0E, 0x0F, 0xFF, 0x0E, 0x0F);
987 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
988
989 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline_2);
990 setDynamicDepthStencilState(-1.0f, 1.0f, 0xFF, 0xFF, 0x0E, 0xFF, 0xFF, 0x0E);
991 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0);
992
993 endRenderPass(m_vk, *m_cmdBuffer);
994 endCommandBuffer(m_vk, *m_cmdBuffer);
995
996 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
997
998 // validation
999 {
1000 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
1001 referenceFrame.allocLevel(0);
1002
1003 const deInt32 frameWidth = referenceFrame.getWidth();
1004 const deInt32 frameHeight = referenceFrame.getHeight();
1005
1006 for (int y = 0; y < frameHeight; y++)
1007 {
1008 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
1009
1010 for (int x = 0; x < frameWidth; x++)
1011 {
1012 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
1013
1014 if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f)
1015 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
1016 else
1017 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
1018 }
1019 }
1020
1021 const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
1022 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
1023 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
1024
1025 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
1026 referenceFrame.getLevel(0), renderedFrame, 0.05f,
1027 tcu::COMPARE_LOG_RESULT))
1028 {
1029 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
1030 }
1031
1032 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
1033 }
1034 }
1035 };
1036
1037 } //anonymous
1038
DynamicStateDSTests(tcu::TestContext & testCtx)1039 DynamicStateDSTests::DynamicStateDSTests (tcu::TestContext& testCtx)
1040 : TestCaseGroup (testCtx, "ds_state", "Tests for depth stencil state")
1041 {
1042 /* Left blank on purpose */
1043 }
1044
~DynamicStateDSTests()1045 DynamicStateDSTests::~DynamicStateDSTests ()
1046 {
1047 }
1048
init(void)1049 void DynamicStateDSTests::init (void)
1050 {
1051 ShaderMap shaderPaths;
1052 shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
1053 shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
1054
1055 addChild(new InstanceFactory<DepthBoundsParamTestInstance>(m_testCtx, "depth_bounds_1", "Perform depth bounds test 1", shaderPaths));
1056 addChild(new InstanceFactory<DepthBoundsTestInstance>(m_testCtx, "depth_bounds_2", "Perform depth bounds test 1", shaderPaths));
1057 addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_1", "Perform basic stencil test 1", 0x0D, 0x06, 0x05, tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f)));
1058 addChild(new StencilParamsBasicTestCase(m_testCtx, "stencil_params_basic_2", "Perform basic stencil test 2", 0x06, 0x02, 0x05, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)));
1059 addChild(new InstanceFactory<StencilParamsAdvancedTestInstance>(m_testCtx, "stencil_params_advanced", "Perform advanced stencil test", shaderPaths));
1060 }
1061
1062 } // DynamicState
1063 } // vkt
1064