blob: 688bb713581279927da261ee154263c0ed633a1a [file] [log] [blame]
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001#include <vulkan.h>
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002#include "vk_debug_report_lunarg.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06003#include "gtest-1.7.0/include/gtest/gtest.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06004#include "vkrenderframework.h"
Mark Lobodzinskia910dc82015-05-14 14:30:48 -05005#include "layers_config.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06006
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05007#define GLM_FORCE_RADIANS
8#include "glm/glm.hpp"
9#include <glm/gtc/matrix_transform.hpp>
10
Tobin Ehlis57e6a612015-05-26 16:11:58 -060011#define MEM_TRACKER_TESTS 1
12#define OBJ_TRACKER_TESTS 1
13#define DRAW_STATE_TESTS 1
14#define THREADING_TESTS 1
Chris Forbes5af3bf22015-05-25 11:13:08 +120015#define SHADER_CHECKER_TESTS 1
Tobin Ehlis57e6a612015-05-26 16:11:58 -060016
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050017//--------------------------------------------------------------------------------------
18// Mesh and VertexFormat Data
19//--------------------------------------------------------------------------------------
20struct Vertex
21{
22 float posX, posY, posZ, posW; // Position data
23 float r, g, b, a; // Color
24};
25
26#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
27
28typedef enum _BsoFailSelect {
29 BsoFailNone = 0x00000000,
30 BsoFailRaster = 0x00000001,
31 BsoFailViewport = 0x00000002,
32 BsoFailColorBlend = 0x00000004,
33 BsoFailDepthStencil = 0x00000008,
34} BsoFailSelect;
35
36struct vktriangle_vs_uniform {
37 // Must start with MVP
38 float mvp[4][4];
39 float position[3][4];
40 float color[3][4];
41};
42
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050043static const char bindStateVertShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050044 "#version 130\n"
45 "vec2 vertices[3];\n"
46 "void main() {\n"
47 " vertices[0] = vec2(-1.0, -1.0);\n"
48 " vertices[1] = vec2( 1.0, -1.0);\n"
49 " vertices[2] = vec2( 0.0, 1.0);\n"
50 " gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
51 "}\n";
52
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050053static const char bindStateFragShaderText[] =
Cody Northrop74a2d2c2015-06-16 17:32:04 -060054 "#version 140\n"
55 "#extension GL_ARB_separate_shader_objects: require\n"
56 "#extension GL_ARB_shading_language_420pack: require\n"
57 "\n"
58 "layout(location = 0) out vec4 uFragColor;\n"
59 "void main(){\n"
60 " uFragColor = vec4(0,1,0,1);\n"
61 "}\n";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050062
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060063static void myDbgFunc(
64 VkFlags msgFlags,
65 VkObjectType objType,
66 VkObject srcObject,
67 size_t location,
68 int32_t msgCode,
69 const char* pLayerPrefix,
70 const char* pMsg,
71 void* pUserData);
Tony Barbour30486ea2015-04-07 13:44:53 -060072
73class ErrorMonitor {
74public:
Tony Barbour0c1bdc62015-04-29 17:34:29 -060075 ErrorMonitor()
Tony Barbour30486ea2015-04-07 13:44:53 -060076 {
Mike Stroyan09aae812015-05-12 16:00:45 -060077 pthread_mutexattr_t attr;
78 pthread_mutexattr_init(&attr);
79 pthread_mutex_init(&m_mutex, &attr);
80 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060081 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Mike Stroyan09aae812015-05-12 16:00:45 -060082 m_bailout = NULL;
83 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060084 }
85 void ClearState()
86 {
Mike Stroyan09aae812015-05-12 16:00:45 -060087 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060088 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -060089 m_msgString.clear();
Mike Stroyan09aae812015-05-12 16:00:45 -060090 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060091 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060092 VkFlags GetState(std::string *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060093 {
Mike Stroyan09aae812015-05-12 16:00:45 -060094 pthread_mutex_lock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060095 *msgString = m_msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -060096 pthread_mutex_unlock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060097 return m_msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -060098 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060099 void SetState(VkFlags msgFlags, const char *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -0600100 {
Mike Stroyan09aae812015-05-12 16:00:45 -0600101 pthread_mutex_lock(&m_mutex);
102 if (m_bailout != NULL) {
103 *m_bailout = true;
104 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600105 m_msgFlags = msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600106 m_msgString.reserve(strlen(msgString));
107 m_msgString = msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -0600108 pthread_mutex_unlock(&m_mutex);
109 }
110 void SetBailout(bool *bailout)
111 {
112 m_bailout = bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600113 }
114
115private:
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600116 VkFlags m_msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -0600117 std::string m_msgString;
118 pthread_mutex_t m_mutex;
119 bool* m_bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600120};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500121
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600122static void myDbgFunc(
123 VkFlags msgFlags,
124 VkObjectType objType,
125 VkObject srcObject,
126 size_t location,
127 int32_t msgCode,
128 const char* pLayerPrefix,
129 const char* pMsg,
130 void* pUserData)
Tony Barbour30486ea2015-04-07 13:44:53 -0600131{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600132 if (msgFlags & (VK_DBG_REPORT_WARN_BIT | VK_DBG_REPORT_ERROR_BIT)) {
Tony Barbour8508b8e2015-04-09 10:48:04 -0600133 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600134 errMonitor->SetState(msgFlags, pMsg);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600135 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600136}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500137
Tony Barbour01999182015-04-09 12:58:51 -0600138class VkLayerTest : public VkRenderFramework
Tony Barbour30486ea2015-04-07 13:44:53 -0600139{
140public:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600141 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
142 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500143 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
144 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour30486ea2015-04-07 13:44:53 -0600145
146protected:
Tony Barbour01999182015-04-09 12:58:51 -0600147 VkMemoryRefManager m_memoryRefManager;
148 ErrorMonitor *m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600149
150 virtual void SetUp() {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600151 std::vector<const char *> instance_extension_names;
152 std::vector<const char *> device_extension_names;
Tony Barbour950ebc02015-04-23 12:55:36 -0600153
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600154 instance_extension_names.push_back(DEBUG_REPORT_EXTENSION_NAME);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600155 instance_extension_names.push_back("MemTracker");
Courtney Goeltzenleuchtereb518dc2015-06-13 21:41:00 -0600156 instance_extension_names.push_back("DrawState");
157 instance_extension_names.push_back("ObjectTracker");
158 instance_extension_names.push_back("Threading");
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600159
160 device_extension_names.push_back("MemTracker");
Jon Ashburn64716542015-06-15 12:21:02 -0600161 device_extension_names.push_back("DrawState");
Courtney Goeltzenleuchtereb518dc2015-06-13 21:41:00 -0600162 device_extension_names.push_back("ObjectTracker");
163 device_extension_names.push_back("Threading");
Tony Barbour30486ea2015-04-07 13:44:53 -0600164
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600165 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600166 this->app_info.pNext = NULL;
167 this->app_info.pAppName = "layer_tests";
168 this->app_info.appVersion = 1;
169 this->app_info.pEngineName = "unittest";
170 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600171 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600172
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600173 m_errorMonitor = new ErrorMonitor;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600174 InitFramework(instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
Tony Barbour30486ea2015-04-07 13:44:53 -0600175 }
176
177 virtual void TearDown() {
178 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600179 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600180 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600181 }
182};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500183
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600184VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600185{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600186 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600187
188 result = cmdBuffer.BeginCommandBuffer();
189
190 /*
191 * For render test all drawing happens in a single render pass
192 * on a single command buffer.
193 */
Chris Forbesfe133ef2015-06-16 14:05:59 +1200194 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600195 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
196 }
197
198 return result;
199}
200
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600201VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600202{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600203 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600204
Chris Forbesfe133ef2015-06-16 14:05:59 +1200205 if (renderPass()) {
206 cmdBuffer.EndRenderPass(renderPass());
207 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600208
209 result = cmdBuffer.EndCommandBuffer();
210
211 return result;
212}
213
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500214void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
215{
216 // Create identity matrix
217 int i;
218 struct vktriangle_vs_uniform data;
219
220 glm::mat4 Projection = glm::mat4(1.0f);
221 glm::mat4 View = glm::mat4(1.0f);
222 glm::mat4 Model = glm::mat4(1.0f);
223 glm::mat4 MVP = Projection * View * Model;
224 const int matrixSize = sizeof(MVP);
225 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
226
227 memcpy(&data.mvp, &MVP[0][0], matrixSize);
228
229 static const Vertex tri_data[] =
230 {
231 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
232 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
233 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
234 };
235
236 for (i=0; i<3; i++) {
237 data.position[i][0] = tri_data[i].posX;
238 data.position[i][1] = tri_data[i].posY;
239 data.position[i][2] = tri_data[i].posZ;
240 data.position[i][3] = tri_data[i].posW;
241 data.color[i][0] = tri_data[i].r;
242 data.color[i][1] = tri_data[i].g;
243 data.color[i][2] = tri_data[i].b;
244 data.color[i][3] = tri_data[i].a;
245 }
246
247 ASSERT_NO_FATAL_FAILURE(InitState());
248 ASSERT_NO_FATAL_FAILURE(InitViewport());
249
250 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
251
252 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
253 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
254
255 VkPipelineObj pipelineobj(m_device);
256 pipelineobj.AddShader(&vs);
257 pipelineobj.AddShader(&ps);
258
259 VkDescriptorSetObj descriptorSet(m_device);
260 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
261
262 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
263 VkCommandBufferObj cmdBuffer(m_device);
264 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
265
266 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
267
268 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
269
270 // render triangle
271 cmdBuffer.Draw(0, 3, 0, 1);
272
273 // finalize recording of the command buffer
274 EndCommandBuffer(cmdBuffer);
275
276 cmdBuffer.QueueCommandBuffer();
277}
278
279void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
280{
281 if (m_depthStencil->Initialized()) {
282 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
283 } else {
284 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
285 }
286
287 cmdBuffer->PrepareAttachments();
288 if ((failMask & BsoFailRaster) != BsoFailRaster) {
289 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
290 }
291 if ((failMask & BsoFailViewport) != BsoFailViewport) {
292 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
293 }
294 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
295 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
296 }
297 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
298 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
299 }
300 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
301 pipelineobj.CreateVKPipeline(descriptorSet);
302 cmdBuffer->BindPipeline(pipelineobj);
303 cmdBuffer->BindDescriptorSet(descriptorSet);
304}
305
306// ********************************************************************************************************************
307// ********************************************************************************************************************
308// ********************************************************************************************************************
309// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600310#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500311TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
312{
313 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600314 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500315 std::string msgString;
316
317 VkFenceCreateInfo fenceInfo = {};
318 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
319 fenceInfo.pNext = NULL;
320 fenceInfo.flags = 0;
321
322 ASSERT_NO_FATAL_FAILURE(InitState());
323 ASSERT_NO_FATAL_FAILURE(InitViewport());
324 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
325
326 VkCommandBufferObj cmdBuffer(m_device);
327 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
328
329 BeginCommandBuffer(cmdBuffer);
330 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
331 EndCommandBuffer(cmdBuffer);
332
333 testFence.init(*m_device, fenceInfo);
334
335 // Bypass framework since it does the waits automatically
336 VkResult err = VK_SUCCESS;
337 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
338 ASSERT_VK_SUCCESS( err );
339
340 m_errorMonitor->ClearState();
341 // Introduce failure by calling begin again before checking fence
342 vkResetCommandBuffer(cmdBuffer.obj());
343
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600344 msgFlags = m_errorMonitor->GetState(&msgString);
345 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err after calling ResetCommandBuffer on an active Command Buffer";
Mark Lobodzinski81078192015-05-19 10:28:29 -0500346 if (!strstr(msgString.c_str(),"Resetting CB")) {
347 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
348 }
349}
350
351TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
352{
353 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600354 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500355 std::string msgString;
356
357 VkFenceCreateInfo fenceInfo = {};
358 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
359 fenceInfo.pNext = NULL;
360 fenceInfo.flags = 0;
361
362 ASSERT_NO_FATAL_FAILURE(InitState());
363 ASSERT_NO_FATAL_FAILURE(InitViewport());
364 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
365
366 VkCommandBufferObj cmdBuffer(m_device);
367 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
368
369 BeginCommandBuffer(cmdBuffer);
370 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
371 EndCommandBuffer(cmdBuffer);
372
373 testFence.init(*m_device, fenceInfo);
374
375 // Bypass framework since it does the waits automatically
376 VkResult err = VK_SUCCESS;
377 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
378 ASSERT_VK_SUCCESS( err );
379
380 m_errorMonitor->ClearState();
381 // Introduce failure by calling begin again before checking fence
382 BeginCommandBuffer(cmdBuffer);
383
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600384 msgFlags = m_errorMonitor->GetState(&msgString);
385 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err after calling BeginCommandBuffer on an active Command Buffer";
Mark Lobodzinski81078192015-05-19 10:28:29 -0500386 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
387 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
388 }
389}
390
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500391TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
392{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600393 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500394 std::string msgString;
395 VkResult err;
396
397 ASSERT_NO_FATAL_FAILURE(InitState());
398 m_errorMonitor->ClearState();
399
400 // Create an image, allocate memory, free it, and then try to bind it
401 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500402 VkDeviceMemory mem;
403 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500404
405 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
406 const int32_t tex_width = 32;
407 const int32_t tex_height = 32;
408 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500409
410 const VkImageCreateInfo image_create_info = {
411 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
412 .pNext = NULL,
413 .imageType = VK_IMAGE_TYPE_2D,
414 .format = tex_format,
415 .extent = { tex_width, tex_height, 1 },
416 .mipLevels = 1,
417 .arraySize = 1,
418 .samples = 1,
419 .tiling = VK_IMAGE_TILING_LINEAR,
420 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
421 .flags = 0,
422 };
423 VkMemoryAllocInfo mem_alloc = {
424 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
425 .pNext = NULL,
426 .allocationSize = 0,
427 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
428 .memProps = 0,
429 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
430 };
431
432 err = vkCreateImage(m_device->device(), &image_create_info, &image);
433 ASSERT_VK_SUCCESS(err);
434
435 err = vkGetObjectInfo(m_device->device(),
436 VK_OBJECT_TYPE_IMAGE,
437 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500438 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
439 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500440 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500441 ASSERT_VK_SUCCESS(err);
442
Mark Lobodzinski23182612015-05-29 09:32:35 -0500443 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500444
445 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500446 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500447 ASSERT_VK_SUCCESS(err);
448
449 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500450 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500451 ASSERT_VK_SUCCESS(err);
452
453 // Map memory as if to initialize the image
454 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500455 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500456
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600457 msgFlags = m_errorMonitor->GetState(&msgString);
458 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to map memory not visible to CPU";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500459 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
460 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
461 }
462}
463
464TEST_F(VkLayerTest, BindInvalidMemory)
465{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600466 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500467 std::string msgString;
468 VkResult err;
469
470 ASSERT_NO_FATAL_FAILURE(InitState());
471 m_errorMonitor->ClearState();
472
473 // Create an image, allocate memory, free it, and then try to bind it
474 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500475 VkDeviceMemory mem;
476 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500477
478 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
479 const int32_t tex_width = 32;
480 const int32_t tex_height = 32;
481 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500482
483 const VkImageCreateInfo image_create_info = {
484 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
485 .pNext = NULL,
486 .imageType = VK_IMAGE_TYPE_2D,
487 .format = tex_format,
488 .extent = { tex_width, tex_height, 1 },
489 .mipLevels = 1,
490 .arraySize = 1,
491 .samples = 1,
492 .tiling = VK_IMAGE_TILING_LINEAR,
493 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
494 .flags = 0,
495 };
496 VkMemoryAllocInfo mem_alloc = {
497 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
498 .pNext = NULL,
499 .allocationSize = 0,
500 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
501 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
502 };
503
504 err = vkCreateImage(m_device->device(), &image_create_info, &image);
505 ASSERT_VK_SUCCESS(err);
506
507 err = vkGetObjectInfo(m_device->device(),
508 VK_OBJECT_TYPE_IMAGE,
509 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500510 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
511 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500512 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500513 ASSERT_VK_SUCCESS(err);
514
Mark Lobodzinski23182612015-05-29 09:32:35 -0500515 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500516
517 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500518 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500519 ASSERT_VK_SUCCESS(err);
520
521 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500522 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500523 ASSERT_VK_SUCCESS(err);
524
525 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500526 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500527 ASSERT_VK_SUCCESS(err);
528
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600529 msgFlags = m_errorMonitor->GetState(&msgString);
530 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to bind a freed memory object";
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500531 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500532 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
533 }
534}
535
536TEST_F(VkLayerTest, FreeBoundMemory)
537{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600538 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500539 std::string msgString;
540 VkResult err;
541
542 ASSERT_NO_FATAL_FAILURE(InitState());
543 m_errorMonitor->ClearState();
544
545 // Create an image, allocate memory, free it, and then try to bind it
546 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500547 VkDeviceMemory mem;
548 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500549
550 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
551 const int32_t tex_width = 32;
552 const int32_t tex_height = 32;
553 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500554
555 const VkImageCreateInfo image_create_info = {
556 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
557 .pNext = NULL,
558 .imageType = VK_IMAGE_TYPE_2D,
559 .format = tex_format,
560 .extent = { tex_width, tex_height, 1 },
561 .mipLevels = 1,
562 .arraySize = 1,
563 .samples = 1,
564 .tiling = VK_IMAGE_TILING_LINEAR,
565 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
566 .flags = 0,
567 };
568 VkMemoryAllocInfo mem_alloc = {
569 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
570 .pNext = NULL,
571 .allocationSize = 0,
572 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
573 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
574 };
575
576 err = vkCreateImage(m_device->device(), &image_create_info, &image);
577 ASSERT_VK_SUCCESS(err);
578
579 err = vkGetObjectInfo(m_device->device(),
580 VK_OBJECT_TYPE_IMAGE,
581 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500582 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
583 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500584 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500585 ASSERT_VK_SUCCESS(err);
586
Mark Lobodzinski23182612015-05-29 09:32:35 -0500587 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500588
589 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500590 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500591 ASSERT_VK_SUCCESS(err);
592
593 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500594 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500595 ASSERT_VK_SUCCESS(err);
596
597 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500598 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500599 ASSERT_VK_SUCCESS(err);
600
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600601 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter7dc4c8b2015-06-13 21:48:47 -0600602 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an warning while tring to free bound memory";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500603 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
604 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
605 }
606}
607
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500608TEST_F(VkLayerTest, RebindMemory)
609{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600610 VkFlags msgFlags;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500611 std::string msgString;
612 VkResult err;
613
614 ASSERT_NO_FATAL_FAILURE(InitState());
615 m_errorMonitor->ClearState();
616
617 // Create an image, allocate memory, free it, and then try to bind it
618 VkImage image;
619 VkDeviceMemory mem1;
620 VkDeviceMemory mem2;
621 VkMemoryRequirements mem_reqs;
622
623 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
624 const int32_t tex_width = 32;
625 const int32_t tex_height = 32;
626 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
627
628 const VkImageCreateInfo image_create_info = {
629 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
630 .pNext = NULL,
631 .imageType = VK_IMAGE_TYPE_2D,
632 .format = tex_format,
633 .extent = { tex_width, tex_height, 1 },
634 .mipLevels = 1,
635 .arraySize = 1,
636 .samples = 1,
637 .tiling = VK_IMAGE_TILING_LINEAR,
638 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
639 .flags = 0,
640 };
641 VkMemoryAllocInfo mem_alloc = {
642 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
643 .pNext = NULL,
644 .allocationSize = 0,
645 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
646 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
647 };
648
649 err = vkCreateImage(m_device->device(), &image_create_info, &image);
650 ASSERT_VK_SUCCESS(err);
651
652 err = vkGetObjectInfo(m_device->device(),
653 VK_OBJECT_TYPE_IMAGE,
654 image,
655 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
656 &mem_reqs_size,
657 &mem_reqs);
658 ASSERT_VK_SUCCESS(err);
659
660 mem_alloc.allocationSize = mem_reqs.size;
661
662 // allocate 2 memory objects
663 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
664 ASSERT_VK_SUCCESS(err);
665 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
666 ASSERT_VK_SUCCESS(err);
667
668 // Bind first memory object to Image object
669 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
670 ASSERT_VK_SUCCESS(err);
671
672 // Introduce validation failure, try to bind a different memory object to the same image object
673 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
674 ASSERT_VK_SUCCESS(err);
675
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600676 msgFlags = m_errorMonitor->GetState(&msgString);
677 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while tring to rebind an object";
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500678 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
679 FAIL() << "Error received did not match expected message when rebinding memory to an object";
680 }
681}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500682
683TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
684{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600685 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500686 std::string msgString;
687 VkResult err;
688
689 ASSERT_NO_FATAL_FAILURE(InitState());
690 m_errorMonitor->ClearState();
691
692 // Create an image object, allocate memory, destroy the object and then try to bind it
693 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500694 VkDeviceMemory mem;
695 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500696
697 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
698 const int32_t tex_width = 32;
699 const int32_t tex_height = 32;
700 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500701
702 const VkImageCreateInfo image_create_info = {
703 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
704 .pNext = NULL,
705 .imageType = VK_IMAGE_TYPE_2D,
706 .format = tex_format,
707 .extent = { tex_width, tex_height, 1 },
708 .mipLevels = 1,
709 .arraySize = 1,
710 .samples = 1,
711 .tiling = VK_IMAGE_TILING_LINEAR,
712 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
713 .flags = 0,
714 };
715 VkMemoryAllocInfo mem_alloc = {
716 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
717 .pNext = NULL,
718 .allocationSize = 0,
719 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
720 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
721 };
722
723 err = vkCreateImage(m_device->device(), &image_create_info, &image);
724 ASSERT_VK_SUCCESS(err);
725
726 err = vkGetObjectInfo(m_device->device(),
727 VK_OBJECT_TYPE_IMAGE,
728 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500729 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
730 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500731 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500732 ASSERT_VK_SUCCESS(err);
733
Mark Lobodzinski23182612015-05-29 09:32:35 -0500734 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500735
736 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500737 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500738 ASSERT_VK_SUCCESS(err);
739
740 // Introduce validation failure, destroy Image object before binding
741 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
742 ASSERT_VK_SUCCESS(err);
743
744 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500745 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500746 ASSERT_VK_SUCCESS(err);
747
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600748 msgFlags = m_errorMonitor->GetState(&msgString);
749 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error while binding memory to a destroyed object";
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500750 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500751 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
752 }
753}
754
Tony Barbour8508b8e2015-04-09 10:48:04 -0600755TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600756{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600757 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600758 VkFlags msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -0600759 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600760
761 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600762 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
763 fenceInfo.pNext = NULL;
764 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600765
Tony Barbour30486ea2015-04-07 13:44:53 -0600766 ASSERT_NO_FATAL_FAILURE(InitState());
767 ASSERT_NO_FATAL_FAILURE(InitViewport());
768 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
769
Tony Barbour01999182015-04-09 12:58:51 -0600770 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600771 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
772
Tony Barbour8508b8e2015-04-09 10:48:04 -0600773 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600774 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600775 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600776
777 testFence.init(*m_device, fenceInfo);
778 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600779 cmdBuffer.QueueCommandBuffer(testFence.obj());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600780 msgFlags = m_errorMonitor->GetState(&msgString);
781 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err from using a fence in SIGNALED state in call to vkQueueSubmit";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600782 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500783 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600784 }
785
786}
787
788TEST_F(VkLayerTest, ResetUnsignaledFence)
789{
790 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600791 VkFlags msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600792 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600793 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600794 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
795 fenceInfo.pNext = NULL;
796
Tony Barbour8508b8e2015-04-09 10:48:04 -0600797 ASSERT_NO_FATAL_FAILURE(InitState());
798 testFence.init(*m_device, fenceInfo);
799 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600800 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600801 vkResetFences(m_device->device(), 1, fences);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600802 msgFlags = m_errorMonitor->GetState(&msgString);
803 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from submitting fence with UNSIGNALED state to vkResetFences";
Tony Barbour01999182015-04-09 12:58:51 -0600804 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500805 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600806 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600807
808}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600809#endif
810#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600811
Tony Barbourdb686622015-05-06 09:35:56 -0600812TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
813{
814 VkEventCreateInfo event_info;
815 VkEvent event;
816 VkMemoryRequirements mem_req;
817 size_t data_size = sizeof(mem_req);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600818 VkFlags msgFlags;
Tony Barbourdb686622015-05-06 09:35:56 -0600819 std::string msgString;
820 VkResult err;
821
822 ASSERT_NO_FATAL_FAILURE(InitState());
823 memset(&event_info, 0, sizeof(event_info));
824 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
825
826 err = vkCreateEvent(device(), &event_info, &event);
827 ASSERT_VK_SUCCESS(err);
828 m_errorMonitor->ClearState();
829 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
830 &data_size, &mem_req);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600831 msgFlags = m_errorMonitor->GetState(&msgString);
832 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from mismatched types in vkGetObjectInfo";
Tony Barbourdb686622015-05-06 09:35:56 -0600833 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500834 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600835 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500836}
Tony Barbourdb686622015-05-06 09:35:56 -0600837
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500838TEST_F(VkLayerTest, RasterStateNotBound)
839{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600840 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500841 std::string msgString;
842
843 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
844
845 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
846
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600847 msgFlags = m_errorMonitor->GetState(&msgString);
848 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Raster State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500849 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
850 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
851 }
852}
853
854TEST_F(VkLayerTest, ViewportStateNotBound)
855{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600856 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500857 std::string msgString;
858 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
859
860 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
861
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600862 msgFlags = m_errorMonitor->GetState(&msgString);
863 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a Viewport State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500864 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
865 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
866 }
867}
868
869TEST_F(VkLayerTest, ColorBlendStateNotBound)
870{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600871 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500872 std::string msgString;
873
874 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
875
876 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
877
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600878 msgFlags = m_errorMonitor->GetState(&msgString);
879 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a ColorBlend State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500880 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
881 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
882 }
883}
884
885TEST_F(VkLayerTest, DepthStencilStateNotBound)
886{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600887 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500888 std::string msgString;
889
890 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
891
892 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
893
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600894 msgFlags = m_errorMonitor->GetState(&msgString);
895 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Not Binding a DepthStencil State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500896 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
897 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
898 }
Tony Barbourdb686622015-05-06 09:35:56 -0600899}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600900#endif
901#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600902TEST_F(VkLayerTest, PipelineNotBound)
903{
904 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600905 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600906 std::string msgString;
907
908 ASSERT_NO_FATAL_FAILURE(InitState());
909 m_errorMonitor->ClearState();
910 VkCommandBufferObj cmdBuffer(m_device);
911 BeginCommandBuffer(cmdBuffer);
912 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
913 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600914 msgFlags = m_errorMonitor->GetState(&msgString);
915 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600916 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
917 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
918 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600919}
920
921TEST_F(VkLayerTest, InvalidDescriptorPool)
922{
923 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
924 // The DS check for this is after driver has been called to validate DS internal data struct
925 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600926/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600927 std::string msgString;
928 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
929 vkResetDescriptorPool(device(), badPool);
930
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600931 msgFlags = m_errorMonitor->GetState(&msgString);
932 ASSERT_EQ(msgFlags, VK_DBG_MSG_ERROR) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600933 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
934 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
935 }*/
936}
937
938TEST_F(VkLayerTest, InvalidDescriptorSet)
939{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600940 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
941 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600942 // Create a valid cmd buffer
943 // call vkCmdBindDescriptorSets w/ false DS
944}
945
946TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
947{
948 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
949 // The DS check for this is after driver has been called to validate DS internal data struct
950}
951
952TEST_F(VkLayerTest, InvalidPipeline)
953{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600954 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
955 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600956 // Create a valid cmd buffer
957 // call vkCmdBindPipeline w/ false Pipeline
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600958 VkFlags msgFlags;
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600959 std::string msgString;
960
961 ASSERT_NO_FATAL_FAILURE(InitState());
962 m_errorMonitor->ClearState();
963 VkCommandBufferObj cmdBuffer(m_device);
964 BeginCommandBuffer(cmdBuffer);
965 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
966 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600967 msgFlags = m_errorMonitor->GetState(&msgString);
968 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600969 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
970 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
971 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600972}
973
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600974TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600975{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600976 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600977 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600978 std::string msgString;
979 VkResult err;
980
981 ASSERT_NO_FATAL_FAILURE(InitState());
982 m_errorMonitor->ClearState();
983 VkCommandBufferObj cmdBuffer(m_device);
984 const VkDescriptorTypeCount ds_type_count = {
985 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
986 .count = 1,
987 };
988 const VkDescriptorPoolCreateInfo ds_pool_ci = {
989 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
990 .pNext = NULL,
991 .count = 1,
992 .pTypeCount = &ds_type_count,
993 };
994 VkDescriptorPool ds_pool;
995 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
996 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600997
998 const VkDescriptorSetLayoutBinding dsl_binding = {
999 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001000 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001001 .stageFlags = VK_SHADER_STAGE_ALL,
1002 .pImmutableSamplers = NULL,
1003 };
1004
1005 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1006 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1007 .pNext = NULL,
1008 .count = 1,
1009 .pBinding = &dsl_binding,
1010 };
1011 VkDescriptorSetLayout ds_layout;
1012 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1013 ASSERT_VK_SUCCESS(err);
1014
1015 VkDescriptorSet descriptorSet;
1016 uint32_t ds_count = 0;
1017 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1018 ASSERT_VK_SUCCESS(err);
1019
1020 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1021 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1022 .pNext = NULL,
1023 .descriptorSetCount = 1,
1024 .pSetLayouts = &ds_layout,
1025 };
1026
1027 VkPipelineLayout pipeline_layout;
1028 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1029 ASSERT_VK_SUCCESS(err);
1030
1031 size_t shader_len = strlen(bindStateVertShaderText);
1032 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1033 void* pCode = malloc(codeSize);
1034
1035 /* try version 0 first: VkShaderStage followed by GLSL */
1036 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1037 ((uint32_t *) pCode)[1] = 0;
1038 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1039 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1040
1041 const VkShaderCreateInfo vs_ci = {
1042 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1043 .pNext = NULL,
1044 .codeSize = codeSize,
1045 .pCode = pCode,
1046 .flags = 0,
1047 };
1048 VkShader vs;
1049 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1050 ASSERT_VK_SUCCESS(err);
1051
1052 const VkPipelineShader vs_pipe_shader = {
1053 .stage = VK_SHADER_STAGE_VERTEX,
1054 .shader = vs,
1055 .linkConstBufferCount = 0,
1056 .pLinkConstBufferInfo = NULL,
1057 .pSpecializationInfo = NULL,
1058 };
1059 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1060 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1061 .pNext = NULL,
1062 .shader = vs_pipe_shader,
1063 };
1064 const VkGraphicsPipelineCreateInfo gp_ci = {
1065 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1066 .pNext = &pipe_vs_ci,
1067 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1068 .layout = pipeline_layout,
1069 };
1070
1071 VkPipeline pipeline;
1072 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1073 ASSERT_VK_SUCCESS(err);
1074
1075 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1076 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1077
1078 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1079 m_device->get_device_queue();
1080 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1081
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001082 msgFlags = m_errorMonitor->GetState(&msgString);
1083 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001084 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1085 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1086 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001087}
1088
1089TEST_F(VkLayerTest, InvalidDynamicStateObject)
1090{
1091 // Create a valid cmd buffer
1092 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001093 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1094 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001095}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001096
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001097TEST_F(VkLayerTest, VtxBufferBadIndex)
1098{
1099 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001100 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001101 std::string msgString;
1102 VkResult err;
1103
1104 ASSERT_NO_FATAL_FAILURE(InitState());
1105 m_errorMonitor->ClearState();
1106 VkCommandBufferObj cmdBuffer(m_device);
1107 const VkDescriptorTypeCount ds_type_count = {
1108 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1109 .count = 1,
1110 };
1111 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1112 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1113 .pNext = NULL,
1114 .count = 1,
1115 .pTypeCount = &ds_type_count,
1116 };
1117 VkDescriptorPool ds_pool;
1118 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1119 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001120
1121 const VkDescriptorSetLayoutBinding dsl_binding = {
1122 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001123 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001124 .stageFlags = VK_SHADER_STAGE_ALL,
1125 .pImmutableSamplers = NULL,
1126 };
1127
1128 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1129 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1130 .pNext = NULL,
1131 .count = 1,
1132 .pBinding = &dsl_binding,
1133 };
1134 VkDescriptorSetLayout ds_layout;
1135 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1136 ASSERT_VK_SUCCESS(err);
1137
1138 VkDescriptorSet descriptorSet;
1139 uint32_t ds_count = 0;
1140 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1141 ASSERT_VK_SUCCESS(err);
1142
1143 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1144 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1145 .pNext = NULL,
1146 .descriptorSetCount = 1,
1147 .pSetLayouts = &ds_layout,
1148 };
1149
1150 VkPipelineLayout pipeline_layout;
1151 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1152 ASSERT_VK_SUCCESS(err);
1153
1154 size_t shader_len = strlen(bindStateVertShaderText);
1155 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1156 void* pCode = malloc(codeSize);
1157
1158 /* try version 0 first: VkShaderStage followed by GLSL */
1159 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1160 ((uint32_t *) pCode)[1] = 0;
1161 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1162 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1163
1164 const VkShaderCreateInfo vs_ci = {
1165 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1166 .pNext = NULL,
1167 .codeSize = codeSize,
1168 .pCode = pCode,
1169 .flags = 0,
1170 };
1171 VkShader vs;
1172 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1173
1174 const VkPipelineShader vs_pipe_shader = {
1175 .stage = VK_SHADER_STAGE_VERTEX,
1176 .shader = vs,
1177 .linkConstBufferCount = 0,
1178 .pLinkConstBufferInfo = NULL,
1179 .pSpecializationInfo = NULL,
1180 };
1181 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1182 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1183 .pNext = NULL,
1184 .shader = vs_pipe_shader,
1185 };
1186 const VkGraphicsPipelineCreateInfo gp_ci = {
1187 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1188 .pNext = &pipe_vs_ci,
1189 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1190 .layout = pipeline_layout,
1191 };
1192
1193 VkPipeline pipeline;
1194 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1195 ASSERT_VK_SUCCESS(err);
1196
1197 err= cmdBuffer.BeginCommandBuffer();
1198 ASSERT_VK_SUCCESS(err);
1199 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1200 // Should error before calling to driver so don't care about actual data
1201 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1202
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001203 msgFlags = m_errorMonitor->GetState(&msgString);
1204 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o any Vtx Inputs in PSO.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001205 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1206 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1207 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001208}
1209
1210TEST_F(VkLayerTest, DSTypeMismatch)
1211{
1212 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001213 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001214 std::string msgString;
1215 VkResult err;
1216
1217 ASSERT_NO_FATAL_FAILURE(InitState());
1218 m_errorMonitor->ClearState();
1219 //VkDescriptorSetObj descriptorSet(m_device);
1220 const VkDescriptorTypeCount ds_type_count = {
1221 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1222 .count = 1,
1223 };
1224 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1225 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1226 .pNext = NULL,
1227 .count = 1,
1228 .pTypeCount = &ds_type_count,
1229 };
1230 VkDescriptorPool ds_pool;
1231 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1232 ASSERT_VK_SUCCESS(err);
1233 const VkDescriptorSetLayoutBinding dsl_binding = {
1234 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001235 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001236 .stageFlags = VK_SHADER_STAGE_ALL,
1237 .pImmutableSamplers = NULL,
1238 };
1239
1240 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1241 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1242 .pNext = NULL,
1243 .count = 1,
1244 .pBinding = &dsl_binding,
1245 };
1246 VkDescriptorSetLayout ds_layout;
1247 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1248 ASSERT_VK_SUCCESS(err);
1249
1250 VkDescriptorSet descriptorSet;
1251 uint32_t ds_count = 0;
1252 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1253 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001254
1255 const VkSamplerCreateInfo sampler_ci = {
1256 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1257 .pNext = NULL,
1258 .magFilter = VK_TEX_FILTER_NEAREST,
1259 .minFilter = VK_TEX_FILTER_NEAREST,
1260 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1261 .addressU = VK_TEX_ADDRESS_CLAMP,
1262 .addressV = VK_TEX_ADDRESS_CLAMP,
1263 .addressW = VK_TEX_ADDRESS_CLAMP,
1264 .mipLodBias = 1.0,
1265 .maxAnisotropy = 1,
1266 .compareOp = VK_COMPARE_OP_NEVER,
1267 .minLod = 1.0,
1268 .maxLod = 1.0,
1269 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1270 };
1271 VkSampler sampler;
1272 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1273 ASSERT_VK_SUCCESS(err);
1274
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001275 VkDescriptorInfo descriptor_info;
1276 memset(&descriptor_info, 0, sizeof(descriptor_info));
1277 descriptor_info.sampler = sampler;
1278
1279 VkWriteDescriptorSet descriptor_write;
1280 memset(&descriptor_write, 0, sizeof(descriptor_write));
1281 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1282 descriptor_write.destSet = descriptorSet;
1283 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001284 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001285 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1286 descriptor_write.pDescriptors = &descriptor_info;
1287
1288 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1289
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001290 msgFlags = m_errorMonitor->GetState(&msgString);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001291 std::cout << msgString << "\n";
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001292 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001293 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1294 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match overlapping binding type!'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001295 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001296}
1297
1298TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1299{
1300 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001301 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001302 std::string msgString;
1303 VkResult err;
1304
1305 ASSERT_NO_FATAL_FAILURE(InitState());
1306 m_errorMonitor->ClearState();
1307 //VkDescriptorSetObj descriptorSet(m_device);
1308 const VkDescriptorTypeCount ds_type_count = {
1309 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1310 .count = 1,
1311 };
1312 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1313 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1314 .pNext = NULL,
1315 .count = 1,
1316 .pTypeCount = &ds_type_count,
1317 };
1318 VkDescriptorPool ds_pool;
1319 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1320 ASSERT_VK_SUCCESS(err);
1321 const VkDescriptorSetLayoutBinding dsl_binding = {
1322 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001323 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001324 .stageFlags = VK_SHADER_STAGE_ALL,
1325 .pImmutableSamplers = NULL,
1326 };
1327
1328 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1329 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1330 .pNext = NULL,
1331 .count = 1,
1332 .pBinding = &dsl_binding,
1333 };
1334 VkDescriptorSetLayout ds_layout;
1335 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1336 ASSERT_VK_SUCCESS(err);
1337
1338 VkDescriptorSet descriptorSet;
1339 uint32_t ds_count = 0;
1340 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1341 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001342
1343 const VkSamplerCreateInfo sampler_ci = {
1344 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1345 .pNext = NULL,
1346 .magFilter = VK_TEX_FILTER_NEAREST,
1347 .minFilter = VK_TEX_FILTER_NEAREST,
1348 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1349 .addressU = VK_TEX_ADDRESS_CLAMP,
1350 .addressV = VK_TEX_ADDRESS_CLAMP,
1351 .addressW = VK_TEX_ADDRESS_CLAMP,
1352 .mipLodBias = 1.0,
1353 .maxAnisotropy = 1,
1354 .compareOp = VK_COMPARE_OP_NEVER,
1355 .minLod = 1.0,
1356 .maxLod = 1.0,
1357 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1358 };
1359 VkSampler sampler;
1360 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1361 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001362
1363 VkDescriptorInfo descriptor_info;
1364 memset(&descriptor_info, 0, sizeof(descriptor_info));
1365 descriptor_info.sampler = sampler;
1366
1367 VkWriteDescriptorSet descriptor_write;
1368 memset(&descriptor_write, 0, sizeof(descriptor_write));
1369 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1370 descriptor_write.destSet = descriptorSet;
1371 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1372 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001373 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001374 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1375 descriptor_write.pDescriptors = &descriptor_info;
1376
1377 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1378
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001379 msgFlags = m_errorMonitor->GetState(&msgString);
1380 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ index out of bounds.";
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001381 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1382 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding...'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001383 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001384}
1385
1386TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1387{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001388 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001389 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001390 std::string msgString;
1391 VkResult err;
1392
1393 ASSERT_NO_FATAL_FAILURE(InitState());
1394 m_errorMonitor->ClearState();
1395 //VkDescriptorSetObj descriptorSet(m_device);
1396 const VkDescriptorTypeCount ds_type_count = {
1397 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1398 .count = 1,
1399 };
1400 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1401 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1402 .pNext = NULL,
1403 .count = 1,
1404 .pTypeCount = &ds_type_count,
1405 };
1406 VkDescriptorPool ds_pool;
1407 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1408 ASSERT_VK_SUCCESS(err);
1409 const VkDescriptorSetLayoutBinding dsl_binding = {
1410 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001411 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001412 .stageFlags = VK_SHADER_STAGE_ALL,
1413 .pImmutableSamplers = NULL,
1414 };
1415
1416 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1417 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1418 .pNext = NULL,
1419 .count = 1,
1420 .pBinding = &dsl_binding,
1421 };
1422 VkDescriptorSetLayout ds_layout;
1423 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1424 ASSERT_VK_SUCCESS(err);
1425
1426 VkDescriptorSet descriptorSet;
1427 uint32_t ds_count = 0;
1428 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1429 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001430
1431 const VkSamplerCreateInfo sampler_ci = {
1432 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1433 .pNext = NULL,
1434 .magFilter = VK_TEX_FILTER_NEAREST,
1435 .minFilter = VK_TEX_FILTER_NEAREST,
1436 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1437 .addressU = VK_TEX_ADDRESS_CLAMP,
1438 .addressV = VK_TEX_ADDRESS_CLAMP,
1439 .addressW = VK_TEX_ADDRESS_CLAMP,
1440 .mipLodBias = 1.0,
1441 .maxAnisotropy = 1,
1442 .compareOp = VK_COMPARE_OP_NEVER,
1443 .minLod = 1.0,
1444 .maxLod = 1.0,
1445 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1446 };
1447 VkSampler sampler;
1448 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1449 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001450
1451 VkDescriptorInfo descriptor_info;
1452 memset(&descriptor_info, 0, sizeof(descriptor_info));
1453 descriptor_info.sampler = sampler;
1454
1455 VkWriteDescriptorSet descriptor_write;
1456 memset(&descriptor_write, 0, sizeof(descriptor_write));
1457 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1458 descriptor_write.destSet = descriptorSet;
1459 descriptor_write.destBinding = 2;
1460 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001461 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001462 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1463 descriptor_write.pDescriptors = &descriptor_info;
1464
1465 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1466
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001467 msgFlags = m_errorMonitor->GetState(&msgString);
1468 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ count too large for layout.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001469 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1470 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1471 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001472}
1473
1474TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1475{
1476 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001477 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001478 std::string msgString;
1479 VkResult err;
1480
1481 ASSERT_NO_FATAL_FAILURE(InitState());
1482 m_errorMonitor->ClearState();
1483 //VkDescriptorSetObj descriptorSet(m_device);
1484 const VkDescriptorTypeCount ds_type_count = {
1485 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1486 .count = 1,
1487 };
1488 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1489 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1490 .pNext = NULL,
1491 .count = 1,
1492 .pTypeCount = &ds_type_count,
1493 };
1494 VkDescriptorPool ds_pool;
1495 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1496 ASSERT_VK_SUCCESS(err);
1497 const VkDescriptorSetLayoutBinding dsl_binding = {
1498 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001499 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001500 .stageFlags = VK_SHADER_STAGE_ALL,
1501 .pImmutableSamplers = NULL,
1502 };
1503
1504 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1505 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1506 .pNext = NULL,
1507 .count = 1,
1508 .pBinding = &dsl_binding,
1509 };
1510 VkDescriptorSetLayout ds_layout;
1511 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1512 ASSERT_VK_SUCCESS(err);
1513
1514 VkDescriptorSet descriptorSet;
1515 uint32_t ds_count = 0;
1516 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1517 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001518
1519 const VkSamplerCreateInfo sampler_ci = {
1520 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1521 .pNext = NULL,
1522 .magFilter = VK_TEX_FILTER_NEAREST,
1523 .minFilter = VK_TEX_FILTER_NEAREST,
1524 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1525 .addressU = VK_TEX_ADDRESS_CLAMP,
1526 .addressV = VK_TEX_ADDRESS_CLAMP,
1527 .addressW = VK_TEX_ADDRESS_CLAMP,
1528 .mipLodBias = 1.0,
1529 .maxAnisotropy = 1,
1530 .compareOp = VK_COMPARE_OP_NEVER,
1531 .minLod = 1.0,
1532 .maxLod = 1.0,
1533 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1534 };
1535 VkSampler sampler;
1536 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1537 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001538
1539
1540 VkDescriptorInfo descriptor_info;
1541 memset(&descriptor_info, 0, sizeof(descriptor_info));
1542 descriptor_info.sampler = sampler;
1543
1544 VkWriteDescriptorSet descriptor_write;
1545 memset(&descriptor_write, 0, sizeof(descriptor_write));
1546 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1547 descriptor_write.destSet = descriptorSet;
1548 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001549 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001550 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1551 descriptor_write.pDescriptors = &descriptor_info;
1552
1553 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1554
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001555 msgFlags = m_errorMonitor->GetState(&msgString);
1556 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ invalid struct type.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001557 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1558 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1559 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001560}
1561
1562TEST_F(VkLayerTest, NumSamplesMismatch)
1563{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001564 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001565 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001566 std::string msgString;
1567 VkResult err;
1568
1569 ASSERT_NO_FATAL_FAILURE(InitState());
1570 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1571 m_errorMonitor->ClearState();
1572 VkCommandBufferObj cmdBuffer(m_device);
1573 const VkDescriptorTypeCount ds_type_count = {
1574 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1575 .count = 1,
1576 };
1577 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1578 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1579 .pNext = NULL,
1580 .count = 1,
1581 .pTypeCount = &ds_type_count,
1582 };
1583 VkDescriptorPool ds_pool;
1584 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1585 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001586
1587 const VkDescriptorSetLayoutBinding dsl_binding = {
1588 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001589 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001590 .stageFlags = VK_SHADER_STAGE_ALL,
1591 .pImmutableSamplers = NULL,
1592 };
1593
1594 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1595 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1596 .pNext = NULL,
1597 .count = 1,
1598 .pBinding = &dsl_binding,
1599 };
1600 VkDescriptorSetLayout ds_layout;
1601 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1602 ASSERT_VK_SUCCESS(err);
1603
1604 VkDescriptorSet descriptorSet;
1605 uint32_t ds_count = 0;
1606 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1607 ASSERT_VK_SUCCESS(err);
1608
1609 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1610 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1611 .pNext = NULL,
Tony Barbourd1e95582015-06-03 12:30:49 -06001612 .samples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001613 .multisampleEnable = 1,
1614 .sampleShadingEnable = 0,
1615 .minSampleShading = 1.0,
1616 .sampleMask = 15,
1617 };
1618
1619 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1620 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1621 .pNext = NULL,
1622 .descriptorSetCount = 1,
1623 .pSetLayouts = &ds_layout,
1624 };
1625
1626 VkPipelineLayout pipeline_layout;
1627 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1628 ASSERT_VK_SUCCESS(err);
1629
1630 size_t shader_len = strlen(bindStateVertShaderText);
1631 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1632 void* pCode = malloc(codeSize);
1633
1634 /* try version 0 first: VkShaderStage followed by GLSL */
1635 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1636 ((uint32_t *) pCode)[1] = 0;
1637 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1638 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1639
1640 const VkShaderCreateInfo vs_ci = {
1641 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1642 .pNext = NULL,
1643 .codeSize = codeSize,
1644 .pCode = pCode,
1645 .flags = 0,
1646 };
1647 VkShader vs;
1648 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1649 ASSERT_VK_SUCCESS(err);
1650
1651 const VkPipelineShader vs_pipe_shader = {
1652 .stage = VK_SHADER_STAGE_VERTEX,
1653 .shader = vs,
1654 .linkConstBufferCount = 0,
1655 .pLinkConstBufferInfo = NULL,
1656 .pSpecializationInfo = NULL,
1657 };
1658 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1659 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1660 .pNext = &pipe_ms_state_ci,
1661 .shader = vs_pipe_shader,
1662 };
1663 const VkGraphicsPipelineCreateInfo gp_ci = {
1664 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1665 .pNext = &pipe_vs_ci,
1666 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1667 .layout = pipeline_layout,
1668 };
1669
1670 VkPipeline pipeline;
1671 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1672 ASSERT_VK_SUCCESS(err);
1673
1674 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1675 BeginCommandBuffer(cmdBuffer);
1676 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1677
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001678 msgFlags = m_errorMonitor->GetState(&msgString);
1679 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding RenderPass w/ mismatched MSAA from PSO.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001680 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1681 FAIL() << "Error received was not 'Num samples mismatch!...'";
1682 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001683}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001684#endif
1685#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001686#if GTEST_IS_THREADSAFE
1687struct thread_data_struct {
1688 VkCmdBuffer cmdBuffer;
1689 VkEvent event;
1690 bool bailout;
1691};
1692
1693extern "C" void *AddToCommandBuffer(void *arg)
1694{
1695 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1696 std::string msgString;
1697
1698 for (int i = 0; i<10000; i++) {
1699 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1700 if (data->bailout) {
1701 break;
1702 }
1703 }
1704 return NULL;
1705}
1706
1707TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1708{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001709 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06001710 std::string msgString;
1711 pthread_t thread;
1712 pthread_attr_t thread_attr;
1713
1714 ASSERT_NO_FATAL_FAILURE(InitState());
1715 ASSERT_NO_FATAL_FAILURE(InitViewport());
1716 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1717
1718 VkCommandBufferObj cmdBuffer(m_device);
1719
1720 m_errorMonitor->ClearState();
1721 pthread_attr_init(&thread_attr);
1722 BeginCommandBuffer(cmdBuffer);
1723
1724 VkEventCreateInfo event_info;
1725 VkEvent event;
1726 VkMemoryRequirements mem_req;
1727 size_t data_size = sizeof(mem_req);
1728 VkResult err;
1729
1730 memset(&event_info, 0, sizeof(event_info));
1731 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1732
1733 err = vkCreateEvent(device(), &event_info, &event);
1734 ASSERT_VK_SUCCESS(err);
1735
1736 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1737 &data_size, &mem_req);
1738 ASSERT_VK_SUCCESS(err);
1739
1740 VkMemoryAllocInfo mem_info;
1741 VkDeviceMemory event_mem;
1742
1743 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1744
1745 memset(&mem_info, 0, sizeof(mem_info));
1746 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1747 mem_info.allocationSize = mem_req.size;
1748 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1749 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1750 err = vkAllocMemory(device(), &mem_info, &event_mem);
1751 ASSERT_VK_SUCCESS(err);
1752
Mark Lobodzinski23182612015-05-29 09:32:35 -05001753 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001754 ASSERT_VK_SUCCESS(err);
1755
1756 err = vkResetEvent(device(), event);
1757 ASSERT_VK_SUCCESS(err);
1758
1759 struct thread_data_struct data;
1760 data.cmdBuffer = cmdBuffer.obj();
1761 data.event = event;
1762 data.bailout = false;
1763 m_errorMonitor->SetBailout(&data.bailout);
1764 // Add many entries to command buffer from another thread.
1765 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1766 // Add many entries to command buffer from this thread at the same time.
1767 AddToCommandBuffer(&data);
1768 pthread_join(thread, NULL);
1769 EndCommandBuffer(cmdBuffer);
1770
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001771 msgFlags = m_errorMonitor->GetState(&msgString);
1772 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_INFO_BIT) << "Did not receive an err from using one VkCommandBufferObj in two threads";
Mike Stroyan09aae812015-05-12 16:00:45 -06001773 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001774 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001775 }
1776
1777}
1778#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001779#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12001780
1781#if SHADER_CHECKER_TESTS
1782TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
1783{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001784 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12001785 std::string msgString;
1786 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001787 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001788
1789 char const *vsSource =
1790 "#version 140\n"
1791 "#extension GL_ARB_separate_shader_objects: require\n"
1792 "#extension GL_ARB_shading_language_420pack: require\n"
1793 "\n"
1794 "layout(location=0) out float x;\n"
1795 "void main(){\n"
1796 " gl_Position = vec4(1);\n"
1797 " x = 0;\n"
1798 "}\n";
1799 char const *fsSource =
1800 "#version 140\n"
1801 "#extension GL_ARB_separate_shader_objects: require\n"
1802 "#extension GL_ARB_shading_language_420pack: require\n"
1803 "\n"
1804 "layout(location=0) out vec4 color;\n"
1805 "void main(){\n"
1806 " color = vec4(1);\n"
1807 "}\n";
1808
1809 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1810 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1811
1812 VkPipelineObj pipe(m_device);
1813 pipe.AddShader(&vs);
1814 pipe.AddShader(&fs);
1815
1816 VkCommandBufferObj dummyCmd(m_device);
1817 VkDescriptorSetObj descriptorSet(m_device);
1818 descriptorSet.AppendDummy();
1819 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1820
1821 m_errorMonitor->ClearState();
1822 pipe.CreateVKPipeline(descriptorSet);
1823
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001824 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001825
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001826 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001827 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
1828 FAIL() << "Incorrect warning: " << msgString;
1829 }
1830}
Chris Forbes5af3bf22015-05-25 11:13:08 +12001831
Chris Forbes3c10b852015-05-25 11:13:13 +12001832TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
1833{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001834 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12001835 std::string msgString;
1836 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001837 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12001838
1839 char const *vsSource =
1840 "#version 140\n"
1841 "#extension GL_ARB_separate_shader_objects: require\n"
1842 "#extension GL_ARB_shading_language_420pack: require\n"
1843 "\n"
1844 "void main(){\n"
1845 " gl_Position = vec4(1);\n"
1846 "}\n";
1847 char const *fsSource =
1848 "#version 140\n"
1849 "#extension GL_ARB_separate_shader_objects: require\n"
1850 "#extension GL_ARB_shading_language_420pack: require\n"
1851 "\n"
1852 "layout(location=0) in float x;\n"
1853 "layout(location=0) out vec4 color;\n"
1854 "void main(){\n"
1855 " color = vec4(x);\n"
1856 "}\n";
1857
1858 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1859 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1860
1861 VkPipelineObj pipe(m_device);
1862 pipe.AddShader(&vs);
1863 pipe.AddShader(&fs);
1864
1865 VkCommandBufferObj dummyCmd(m_device);
1866 VkDescriptorSetObj descriptorSet(m_device);
1867 descriptorSet.AppendDummy();
1868 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1869
1870 m_errorMonitor->ClearState();
1871 pipe.CreateVKPipeline(descriptorSet);
1872
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001873 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12001874
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001875 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12001876 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
1877 FAIL() << "Incorrect error: " << msgString;
1878 }
1879}
1880
Chris Forbescc281692015-05-25 11:13:17 +12001881TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
1882{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001883 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12001884 std::string msgString;
1885 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001886 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12001887
1888 char const *vsSource =
1889 "#version 140\n"
1890 "#extension GL_ARB_separate_shader_objects: require\n"
1891 "#extension GL_ARB_shading_language_420pack: require\n"
1892 "\n"
1893 "layout(location=0) out int x;\n"
1894 "void main(){\n"
1895 " x = 0;\n"
1896 " gl_Position = vec4(1);\n"
1897 "}\n";
1898 char const *fsSource =
1899 "#version 140\n"
1900 "#extension GL_ARB_separate_shader_objects: require\n"
1901 "#extension GL_ARB_shading_language_420pack: require\n"
1902 "\n"
1903 "layout(location=0) in float x;\n" /* VS writes int */
1904 "layout(location=0) out vec4 color;\n"
1905 "void main(){\n"
1906 " color = vec4(x);\n"
1907 "}\n";
1908
1909 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1910 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1911
1912 VkPipelineObj pipe(m_device);
1913 pipe.AddShader(&vs);
1914 pipe.AddShader(&fs);
1915
1916 VkCommandBufferObj dummyCmd(m_device);
1917 VkDescriptorSetObj descriptorSet(m_device);
1918 descriptorSet.AppendDummy();
1919 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1920
1921 m_errorMonitor->ClearState();
1922 pipe.CreateVKPipeline(descriptorSet);
1923
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001924 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12001925
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001926 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12001927 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
1928 FAIL() << "Incorrect error: " << msgString;
1929 }
1930}
1931
Chris Forbes8291c052015-05-25 11:13:28 +12001932TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
1933{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001934 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12001935 std::string msgString;
1936 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001937 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12001938
1939 VkVertexInputBindingDescription input_binding;
1940 memset(&input_binding, 0, sizeof(input_binding));
1941
1942 VkVertexInputAttributeDescription input_attrib;
1943 memset(&input_attrib, 0, sizeof(input_attrib));
1944 input_attrib.format = VK_FORMAT_R32_SFLOAT;
1945
1946 char const *vsSource =
1947 "#version 140\n"
1948 "#extension GL_ARB_separate_shader_objects: require\n"
1949 "#extension GL_ARB_shading_language_420pack: require\n"
1950 "\n"
1951 "void main(){\n"
1952 " gl_Position = vec4(1);\n"
1953 "}\n";
1954 char const *fsSource =
1955 "#version 140\n"
1956 "#extension GL_ARB_separate_shader_objects: require\n"
1957 "#extension GL_ARB_shading_language_420pack: require\n"
1958 "\n"
1959 "layout(location=0) out vec4 color;\n"
1960 "void main(){\n"
1961 " color = vec4(1);\n"
1962 "}\n";
1963
1964 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1965 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1966
1967 VkPipelineObj pipe(m_device);
1968 pipe.AddShader(&vs);
1969 pipe.AddShader(&fs);
1970
1971 pipe.AddVertexInputBindings(&input_binding, 1);
1972 pipe.AddVertexInputAttribs(&input_attrib, 1);
1973
1974 VkCommandBufferObj dummyCmd(m_device);
1975 VkDescriptorSetObj descriptorSet(m_device);
1976 descriptorSet.AppendDummy();
1977 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1978
1979 m_errorMonitor->ClearState();
1980 pipe.CreateVKPipeline(descriptorSet);
1981
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001982 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes8291c052015-05-25 11:13:28 +12001983
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001984 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12001985 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
1986 FAIL() << "Incorrect warning: " << msgString;
1987 }
1988}
1989
Chris Forbes37367e62015-05-25 11:13:29 +12001990TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
1991{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001992 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12001993 std::string msgString;
1994 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001995 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12001996
1997 char const *vsSource =
1998 "#version 140\n"
1999 "#extension GL_ARB_separate_shader_objects: require\n"
2000 "#extension GL_ARB_shading_language_420pack: require\n"
2001 "\n"
2002 "layout(location=0) in vec4 x;\n" /* not provided */
2003 "void main(){\n"
2004 " gl_Position = x;\n"
2005 "}\n";
2006 char const *fsSource =
2007 "#version 140\n"
2008 "#extension GL_ARB_separate_shader_objects: require\n"
2009 "#extension GL_ARB_shading_language_420pack: require\n"
2010 "\n"
2011 "layout(location=0) out vec4 color;\n"
2012 "void main(){\n"
2013 " color = vec4(1);\n"
2014 "}\n";
2015
2016 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2017 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2018
2019 VkPipelineObj pipe(m_device);
2020 pipe.AddShader(&vs);
2021 pipe.AddShader(&fs);
2022
2023 VkCommandBufferObj dummyCmd(m_device);
2024 VkDescriptorSetObj descriptorSet(m_device);
2025 descriptorSet.AppendDummy();
2026 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2027
2028 m_errorMonitor->ClearState();
2029 pipe.CreateVKPipeline(descriptorSet);
2030
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002031 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002032
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002033 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002034 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2035 FAIL() << "Incorrect warning: " << msgString;
2036 }
2037}
2038
Chris Forbesa4b02322015-05-25 11:13:31 +12002039TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2040{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002041 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002042 std::string msgString;
2043 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002044 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002045
2046 VkVertexInputBindingDescription input_binding;
2047 memset(&input_binding, 0, sizeof(input_binding));
2048
2049 VkVertexInputAttributeDescription input_attrib;
2050 memset(&input_attrib, 0, sizeof(input_attrib));
2051 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2052
2053 char const *vsSource =
2054 "#version 140\n"
2055 "#extension GL_ARB_separate_shader_objects: require\n"
2056 "#extension GL_ARB_shading_language_420pack: require\n"
2057 "\n"
2058 "layout(location=0) in int x;\n" /* attrib provided float */
2059 "void main(){\n"
2060 " gl_Position = vec4(x);\n"
2061 "}\n";
2062 char const *fsSource =
2063 "#version 140\n"
2064 "#extension GL_ARB_separate_shader_objects: require\n"
2065 "#extension GL_ARB_shading_language_420pack: require\n"
2066 "\n"
2067 "layout(location=0) out vec4 color;\n"
2068 "void main(){\n"
2069 " color = vec4(1);\n"
2070 "}\n";
2071
2072 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2073 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2074
2075 VkPipelineObj pipe(m_device);
2076 pipe.AddShader(&vs);
2077 pipe.AddShader(&fs);
2078
2079 pipe.AddVertexInputBindings(&input_binding, 1);
2080 pipe.AddVertexInputAttribs(&input_attrib, 1);
2081
2082 VkCommandBufferObj dummyCmd(m_device);
2083 VkDescriptorSetObj descriptorSet(m_device);
2084 descriptorSet.AppendDummy();
2085 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2086
2087 m_errorMonitor->ClearState();
2088 pipe.CreateVKPipeline(descriptorSet);
2089
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002090 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002091
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002092 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002093 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2094 FAIL() << "Incorrect error: " << msgString;
2095 }
2096}
2097
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002098TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2099{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002100 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002101 std::string msgString;
2102 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002103 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002104
2105 /* Two binding descriptions for binding 0 */
2106 VkVertexInputBindingDescription input_bindings[2];
2107 memset(input_bindings, 0, sizeof(input_bindings));
2108
2109 VkVertexInputAttributeDescription input_attrib;
2110 memset(&input_attrib, 0, sizeof(input_attrib));
2111 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2112
2113 char const *vsSource =
2114 "#version 140\n"
2115 "#extension GL_ARB_separate_shader_objects: require\n"
2116 "#extension GL_ARB_shading_language_420pack: require\n"
2117 "\n"
2118 "layout(location=0) in float x;\n" /* attrib provided float */
2119 "void main(){\n"
2120 " gl_Position = vec4(x);\n"
2121 "}\n";
2122 char const *fsSource =
2123 "#version 140\n"
2124 "#extension GL_ARB_separate_shader_objects: require\n"
2125 "#extension GL_ARB_shading_language_420pack: require\n"
2126 "\n"
2127 "layout(location=0) out vec4 color;\n"
2128 "void main(){\n"
2129 " color = vec4(1);\n"
2130 "}\n";
2131
2132 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2133 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2134
2135 VkPipelineObj pipe(m_device);
2136 pipe.AddShader(&vs);
2137 pipe.AddShader(&fs);
2138
2139 pipe.AddVertexInputBindings(input_bindings, 2);
2140 pipe.AddVertexInputAttribs(&input_attrib, 1);
2141
2142 VkCommandBufferObj dummyCmd(m_device);
2143 VkDescriptorSetObj descriptorSet(m_device);
2144 descriptorSet.AppendDummy();
2145 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2146
2147 m_errorMonitor->ClearState();
2148 pipe.CreateVKPipeline(descriptorSet);
2149
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002150 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002151
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002152 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002153 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2154 FAIL() << "Incorrect error: " << msgString;
2155 }
2156}
Chris Forbes4c948702015-05-25 11:13:32 +12002157
Chris Forbesc12ef122015-05-25 11:13:40 +12002158/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2159 * rejects it. */
2160
2161TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2162{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002163 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002164 std::string msgString;
2165 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002166 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002167
2168 char const *vsSource =
2169 "#version 140\n"
2170 "#extension GL_ARB_separate_shader_objects: require\n"
2171 "#extension GL_ARB_shading_language_420pack: require\n"
2172 "\n"
2173 "void main(){\n"
2174 " gl_Position = vec4(1);\n"
2175 "}\n";
2176 char const *fsSource =
2177 "#version 140\n"
2178 "#extension GL_ARB_separate_shader_objects: require\n"
2179 "#extension GL_ARB_shading_language_420pack: require\n"
2180 "\n"
2181 "void main(){\n"
2182 "}\n";
2183
2184 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2185 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2186
2187 VkPipelineObj pipe(m_device);
2188 pipe.AddShader(&vs);
2189 pipe.AddShader(&fs);
2190
2191 /* implicit CB 0 set up by the test framework, not written */
2192
2193 VkCommandBufferObj dummyCmd(m_device);
2194 VkDescriptorSetObj descriptorSet(m_device);
2195 descriptorSet.AppendDummy();
2196 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2197
2198 m_errorMonitor->ClearState();
2199 pipe.CreateVKPipeline(descriptorSet);
2200
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002201 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002202
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002203 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002204 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2205 FAIL() << "Incorrect error: " << msgString;
2206 }
2207}
2208
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002209TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2210{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002211 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002212 std::string msgString;
2213 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002214 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002215
2216 char const *vsSource =
2217 "#version 140\n"
2218 "#extension GL_ARB_separate_shader_objects: require\n"
2219 "#extension GL_ARB_shading_language_420pack: require\n"
2220 "\n"
2221 "void main(){\n"
2222 " gl_Position = vec4(1);\n"
2223 "}\n";
2224 char const *fsSource =
2225 "#version 140\n"
2226 "#extension GL_ARB_separate_shader_objects: require\n"
2227 "#extension GL_ARB_shading_language_420pack: require\n"
2228 "\n"
2229 "layout(location=0) out vec4 x;\n"
2230 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2231 "void main(){\n"
2232 " x = vec4(1);\n"
2233 " y = vec4(1);\n"
2234 "}\n";
2235
2236 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2237 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2238
2239 VkPipelineObj pipe(m_device);
2240 pipe.AddShader(&vs);
2241 pipe.AddShader(&fs);
2242
2243 /* implicit CB 0 set up by the test framework */
2244 /* FS writes CB 1, but we don't configure it */
2245
2246 VkCommandBufferObj dummyCmd(m_device);
2247 VkDescriptorSetObj descriptorSet(m_device);
2248 descriptorSet.AppendDummy();
2249 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2250
2251 m_errorMonitor->ClearState();
2252 pipe.CreateVKPipeline(descriptorSet);
2253
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002254 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002255
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002256 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002257 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2258 FAIL() << "Incorrect warning: " << msgString;
2259 }
2260}
2261
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002262TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2263{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002264 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002265 std::string msgString;
2266 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002267 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002268
2269 char const *vsSource =
2270 "#version 140\n"
2271 "#extension GL_ARB_separate_shader_objects: require\n"
2272 "#extension GL_ARB_shading_language_420pack: require\n"
2273 "\n"
2274 "void main(){\n"
2275 " gl_Position = vec4(1);\n"
2276 "}\n";
2277 char const *fsSource =
2278 "#version 140\n"
2279 "#extension GL_ARB_separate_shader_objects: require\n"
2280 "#extension GL_ARB_shading_language_420pack: require\n"
2281 "\n"
2282 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2283 "void main(){\n"
2284 " x = ivec4(1);\n"
2285 "}\n";
2286
2287 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2288 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2289
2290 VkPipelineObj pipe(m_device);
2291 pipe.AddShader(&vs);
2292 pipe.AddShader(&fs);
2293
2294 /* implicit CB 0 set up by test framework, is UNORM. */
2295
2296 VkCommandBufferObj dummyCmd(m_device);
2297 VkDescriptorSetObj descriptorSet(m_device);
2298 descriptorSet.AppendDummy();
2299 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2300
2301 m_errorMonitor->ClearState();
2302 pipe.CreateVKPipeline(descriptorSet);
2303
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002304 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002305
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002306 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002307 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2308 FAIL() << "Incorrect error: " << msgString;
2309 }
2310}
Chris Forbesc2050732015-06-05 14:43:36 +12002311
2312TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2313{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002314 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002315 std::string msgString;
2316 ASSERT_NO_FATAL_FAILURE(InitState());
2317 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002318 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002319
2320 char const *vsSource =
2321 "#version 140\n"
2322 "#extension GL_ARB_separate_shader_objects: require\n"
2323 "#extension GL_ARB_shading_language_420pack: require\n"
2324 "\n"
2325 "void main(){\n"
2326 " gl_Position = vec4(1);\n"
2327 "}\n";
2328 char const *fsSource =
2329 "#version 140\n"
2330 "#extension GL_ARB_separate_shader_objects: require\n"
2331 "#extension GL_ARB_shading_language_420pack: require\n"
2332 "\n"
2333 "layout(location=0) out vec4 x;\n"
2334 "void main(){\n"
2335 " x = vec4(1);\n"
2336 "}\n";
2337
2338 m_errorMonitor->ClearState();
2339
2340 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2341 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2342
2343
2344 VkPipelineObj pipe(m_device);
2345 pipe.AddShader(&vs);
2346 pipe.AddShader(&fs);
2347
2348 /* implicit CB 0 set up by test framework, is UNORM. */
2349
2350 VkCommandBufferObj dummyCmd(m_device);
2351 VkDescriptorSetObj descriptorSet(m_device);
2352 descriptorSet.AppendDummy();
2353 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2354
2355 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2356 /* pipeline creation should have succeeded */
2357 ASSERT_EQ(VK_SUCCESS, res);
2358
2359 /* should have emitted a warning: the shader is not SPIRV, so we're
2360 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002361 msgFlags = m_errorMonitor->GetState(&msgString);
2362 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002363 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2364 FAIL() << "Incorrect warning: " << msgString;
2365 }
2366}
Chris Forbes01c9db72015-06-04 09:25:25 +12002367#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002368
Tony Barbour30486ea2015-04-07 13:44:53 -06002369int main(int argc, char **argv) {
2370 int result;
2371
2372 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002373 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002374
2375 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2376
2377 result = RUN_ALL_TESTS();
2378
Tony Barbour01999182015-04-09 12:58:51 -06002379 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002380 return result;
2381}