blob: 42a3b20e7c2c2fafb54c43a0d94cc44de3fb51cc [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");
Courtney Goeltzenleuchtereb518dc2015-06-13 21:41:00 -0600161 device_extension_names.push_back("ObjectTracker");
162 device_extension_names.push_back("Threading");
Tony Barbour30486ea2015-04-07 13:44:53 -0600163
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600164 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600165 this->app_info.pNext = NULL;
166 this->app_info.pAppName = "layer_tests";
167 this->app_info.appVersion = 1;
168 this->app_info.pEngineName = "unittest";
169 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600170 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600171
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600172 m_errorMonitor = new ErrorMonitor;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600173 InitFramework(instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
Tony Barbour30486ea2015-04-07 13:44:53 -0600174 }
175
176 virtual void TearDown() {
177 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600178 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600179 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600180 }
181};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500182
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600183VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600184{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600185 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600186
187 result = cmdBuffer.BeginCommandBuffer();
188
189 /*
190 * For render test all drawing happens in a single render pass
191 * on a single command buffer.
192 */
Chris Forbesfe133ef2015-06-16 14:05:59 +1200193 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600194 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
195 }
196
197 return result;
198}
199
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600200VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600201{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600202 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600203
Chris Forbesfe133ef2015-06-16 14:05:59 +1200204 if (renderPass()) {
205 cmdBuffer.EndRenderPass(renderPass());
206 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600207
208 result = cmdBuffer.EndCommandBuffer();
209
210 return result;
211}
212
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500213void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
214{
215 // Create identity matrix
216 int i;
217 struct vktriangle_vs_uniform data;
218
219 glm::mat4 Projection = glm::mat4(1.0f);
220 glm::mat4 View = glm::mat4(1.0f);
221 glm::mat4 Model = glm::mat4(1.0f);
222 glm::mat4 MVP = Projection * View * Model;
223 const int matrixSize = sizeof(MVP);
224 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
225
226 memcpy(&data.mvp, &MVP[0][0], matrixSize);
227
228 static const Vertex tri_data[] =
229 {
230 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
231 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
232 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
233 };
234
235 for (i=0; i<3; i++) {
236 data.position[i][0] = tri_data[i].posX;
237 data.position[i][1] = tri_data[i].posY;
238 data.position[i][2] = tri_data[i].posZ;
239 data.position[i][3] = tri_data[i].posW;
240 data.color[i][0] = tri_data[i].r;
241 data.color[i][1] = tri_data[i].g;
242 data.color[i][2] = tri_data[i].b;
243 data.color[i][3] = tri_data[i].a;
244 }
245
246 ASSERT_NO_FATAL_FAILURE(InitState());
247 ASSERT_NO_FATAL_FAILURE(InitViewport());
248
249 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
250
251 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
252 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
253
254 VkPipelineObj pipelineobj(m_device);
255 pipelineobj.AddShader(&vs);
256 pipelineobj.AddShader(&ps);
257
258 VkDescriptorSetObj descriptorSet(m_device);
259 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
260
261 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
262 VkCommandBufferObj cmdBuffer(m_device);
263 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
264
265 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
266
267 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
268
269 // render triangle
270 cmdBuffer.Draw(0, 3, 0, 1);
271
272 // finalize recording of the command buffer
273 EndCommandBuffer(cmdBuffer);
274
275 cmdBuffer.QueueCommandBuffer();
276}
277
278void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
279{
280 if (m_depthStencil->Initialized()) {
281 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
282 } else {
283 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
284 }
285
286 cmdBuffer->PrepareAttachments();
287 if ((failMask & BsoFailRaster) != BsoFailRaster) {
288 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
289 }
290 if ((failMask & BsoFailViewport) != BsoFailViewport) {
291 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
292 }
293 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
294 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
295 }
296 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
297 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
298 }
299 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
300 pipelineobj.CreateVKPipeline(descriptorSet);
301 cmdBuffer->BindPipeline(pipelineobj);
302 cmdBuffer->BindDescriptorSet(descriptorSet);
303}
304
305// ********************************************************************************************************************
306// ********************************************************************************************************************
307// ********************************************************************************************************************
308// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600309#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500310TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
311{
312 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600313 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500314 std::string msgString;
315
316 VkFenceCreateInfo fenceInfo = {};
317 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
318 fenceInfo.pNext = NULL;
319 fenceInfo.flags = 0;
320
321 ASSERT_NO_FATAL_FAILURE(InitState());
322 ASSERT_NO_FATAL_FAILURE(InitViewport());
323 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
324
325 VkCommandBufferObj cmdBuffer(m_device);
326 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
327
328 BeginCommandBuffer(cmdBuffer);
329 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
330 EndCommandBuffer(cmdBuffer);
331
332 testFence.init(*m_device, fenceInfo);
333
334 // Bypass framework since it does the waits automatically
335 VkResult err = VK_SUCCESS;
336 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
337 ASSERT_VK_SUCCESS( err );
338
339 m_errorMonitor->ClearState();
340 // Introduce failure by calling begin again before checking fence
341 vkResetCommandBuffer(cmdBuffer.obj());
342
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600343 msgFlags = m_errorMonitor->GetState(&msgString);
344 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 -0500345 if (!strstr(msgString.c_str(),"Resetting CB")) {
346 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
347 }
348}
349
350TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
351{
352 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600353 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500354 std::string msgString;
355
356 VkFenceCreateInfo fenceInfo = {};
357 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
358 fenceInfo.pNext = NULL;
359 fenceInfo.flags = 0;
360
361 ASSERT_NO_FATAL_FAILURE(InitState());
362 ASSERT_NO_FATAL_FAILURE(InitViewport());
363 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
364
365 VkCommandBufferObj cmdBuffer(m_device);
366 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
367
368 BeginCommandBuffer(cmdBuffer);
369 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
370 EndCommandBuffer(cmdBuffer);
371
372 testFence.init(*m_device, fenceInfo);
373
374 // Bypass framework since it does the waits automatically
375 VkResult err = VK_SUCCESS;
376 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
377 ASSERT_VK_SUCCESS( err );
378
379 m_errorMonitor->ClearState();
380 // Introduce failure by calling begin again before checking fence
381 BeginCommandBuffer(cmdBuffer);
382
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600383 msgFlags = m_errorMonitor->GetState(&msgString);
384 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 -0500385 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
386 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
387 }
388}
389
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500390TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
391{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600392 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500393 std::string msgString;
394 VkResult err;
395
396 ASSERT_NO_FATAL_FAILURE(InitState());
397 m_errorMonitor->ClearState();
398
399 // Create an image, allocate memory, free it, and then try to bind it
400 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500401 VkDeviceMemory mem;
402 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500403
404 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
405 const int32_t tex_width = 32;
406 const int32_t tex_height = 32;
407 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500408
409 const VkImageCreateInfo image_create_info = {
410 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
411 .pNext = NULL,
412 .imageType = VK_IMAGE_TYPE_2D,
413 .format = tex_format,
414 .extent = { tex_width, tex_height, 1 },
415 .mipLevels = 1,
416 .arraySize = 1,
417 .samples = 1,
418 .tiling = VK_IMAGE_TILING_LINEAR,
419 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
420 .flags = 0,
421 };
422 VkMemoryAllocInfo mem_alloc = {
423 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
424 .pNext = NULL,
425 .allocationSize = 0,
426 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
427 .memProps = 0,
428 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
429 };
430
431 err = vkCreateImage(m_device->device(), &image_create_info, &image);
432 ASSERT_VK_SUCCESS(err);
433
434 err = vkGetObjectInfo(m_device->device(),
435 VK_OBJECT_TYPE_IMAGE,
436 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500437 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
438 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500439 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500440 ASSERT_VK_SUCCESS(err);
441
Mark Lobodzinski23182612015-05-29 09:32:35 -0500442 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500443
444 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500445 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500446 ASSERT_VK_SUCCESS(err);
447
448 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500449 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500450 ASSERT_VK_SUCCESS(err);
451
452 // Map memory as if to initialize the image
453 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500454 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500455
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600456 msgFlags = m_errorMonitor->GetState(&msgString);
457 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 -0500458 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
459 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
460 }
461}
462
463TEST_F(VkLayerTest, BindInvalidMemory)
464{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600465 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500466 std::string msgString;
467 VkResult err;
468
469 ASSERT_NO_FATAL_FAILURE(InitState());
470 m_errorMonitor->ClearState();
471
472 // Create an image, allocate memory, free it, and then try to bind it
473 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500474 VkDeviceMemory mem;
475 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500476
477 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
478 const int32_t tex_width = 32;
479 const int32_t tex_height = 32;
480 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500481
482 const VkImageCreateInfo image_create_info = {
483 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
484 .pNext = NULL,
485 .imageType = VK_IMAGE_TYPE_2D,
486 .format = tex_format,
487 .extent = { tex_width, tex_height, 1 },
488 .mipLevels = 1,
489 .arraySize = 1,
490 .samples = 1,
491 .tiling = VK_IMAGE_TILING_LINEAR,
492 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
493 .flags = 0,
494 };
495 VkMemoryAllocInfo mem_alloc = {
496 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
497 .pNext = NULL,
498 .allocationSize = 0,
499 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
500 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
501 };
502
503 err = vkCreateImage(m_device->device(), &image_create_info, &image);
504 ASSERT_VK_SUCCESS(err);
505
506 err = vkGetObjectInfo(m_device->device(),
507 VK_OBJECT_TYPE_IMAGE,
508 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500509 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
510 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500511 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500512 ASSERT_VK_SUCCESS(err);
513
Mark Lobodzinski23182612015-05-29 09:32:35 -0500514 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500515
516 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500517 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500518 ASSERT_VK_SUCCESS(err);
519
520 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500521 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500522 ASSERT_VK_SUCCESS(err);
523
524 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500525 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500526 ASSERT_VK_SUCCESS(err);
527
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600528 msgFlags = m_errorMonitor->GetState(&msgString);
529 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 -0500530 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500531 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
532 }
533}
534
535TEST_F(VkLayerTest, FreeBoundMemory)
536{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600537 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500538 std::string msgString;
539 VkResult err;
540
541 ASSERT_NO_FATAL_FAILURE(InitState());
542 m_errorMonitor->ClearState();
543
544 // Create an image, allocate memory, free it, and then try to bind it
545 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500546 VkDeviceMemory mem;
547 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500548
549 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
550 const int32_t tex_width = 32;
551 const int32_t tex_height = 32;
552 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500553
554 const VkImageCreateInfo image_create_info = {
555 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
556 .pNext = NULL,
557 .imageType = VK_IMAGE_TYPE_2D,
558 .format = tex_format,
559 .extent = { tex_width, tex_height, 1 },
560 .mipLevels = 1,
561 .arraySize = 1,
562 .samples = 1,
563 .tiling = VK_IMAGE_TILING_LINEAR,
564 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
565 .flags = 0,
566 };
567 VkMemoryAllocInfo mem_alloc = {
568 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
569 .pNext = NULL,
570 .allocationSize = 0,
571 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
572 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
573 };
574
575 err = vkCreateImage(m_device->device(), &image_create_info, &image);
576 ASSERT_VK_SUCCESS(err);
577
578 err = vkGetObjectInfo(m_device->device(),
579 VK_OBJECT_TYPE_IMAGE,
580 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500581 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
582 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500583 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500584 ASSERT_VK_SUCCESS(err);
585
Mark Lobodzinski23182612015-05-29 09:32:35 -0500586 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500587
588 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500589 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500590 ASSERT_VK_SUCCESS(err);
591
592 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500593 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500594 ASSERT_VK_SUCCESS(err);
595
596 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500597 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500598 ASSERT_VK_SUCCESS(err);
599
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600600 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter7dc4c8b2015-06-13 21:48:47 -0600601 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 -0500602 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
603 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
604 }
605}
606
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500607TEST_F(VkLayerTest, RebindMemory)
608{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600609 VkFlags msgFlags;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500610 std::string msgString;
611 VkResult err;
612
613 ASSERT_NO_FATAL_FAILURE(InitState());
614 m_errorMonitor->ClearState();
615
616 // Create an image, allocate memory, free it, and then try to bind it
617 VkImage image;
618 VkDeviceMemory mem1;
619 VkDeviceMemory mem2;
620 VkMemoryRequirements mem_reqs;
621
622 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
623 const int32_t tex_width = 32;
624 const int32_t tex_height = 32;
625 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
626
627 const VkImageCreateInfo image_create_info = {
628 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
629 .pNext = NULL,
630 .imageType = VK_IMAGE_TYPE_2D,
631 .format = tex_format,
632 .extent = { tex_width, tex_height, 1 },
633 .mipLevels = 1,
634 .arraySize = 1,
635 .samples = 1,
636 .tiling = VK_IMAGE_TILING_LINEAR,
637 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
638 .flags = 0,
639 };
640 VkMemoryAllocInfo mem_alloc = {
641 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
642 .pNext = NULL,
643 .allocationSize = 0,
644 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
645 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
646 };
647
648 err = vkCreateImage(m_device->device(), &image_create_info, &image);
649 ASSERT_VK_SUCCESS(err);
650
651 err = vkGetObjectInfo(m_device->device(),
652 VK_OBJECT_TYPE_IMAGE,
653 image,
654 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
655 &mem_reqs_size,
656 &mem_reqs);
657 ASSERT_VK_SUCCESS(err);
658
659 mem_alloc.allocationSize = mem_reqs.size;
660
661 // allocate 2 memory objects
662 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
663 ASSERT_VK_SUCCESS(err);
664 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
665 ASSERT_VK_SUCCESS(err);
666
667 // Bind first memory object to Image object
668 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
669 ASSERT_VK_SUCCESS(err);
670
671 // Introduce validation failure, try to bind a different memory object to the same image object
672 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
673 ASSERT_VK_SUCCESS(err);
674
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600675 msgFlags = m_errorMonitor->GetState(&msgString);
676 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 -0500677 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
678 FAIL() << "Error received did not match expected message when rebinding memory to an object";
679 }
680}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500681
682TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
683{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600684 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500685 std::string msgString;
686 VkResult err;
687
688 ASSERT_NO_FATAL_FAILURE(InitState());
689 m_errorMonitor->ClearState();
690
691 // Create an image object, allocate memory, destroy the object and then try to bind it
692 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500693 VkDeviceMemory mem;
694 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500695
696 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
697 const int32_t tex_width = 32;
698 const int32_t tex_height = 32;
699 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500700
701 const VkImageCreateInfo image_create_info = {
702 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
703 .pNext = NULL,
704 .imageType = VK_IMAGE_TYPE_2D,
705 .format = tex_format,
706 .extent = { tex_width, tex_height, 1 },
707 .mipLevels = 1,
708 .arraySize = 1,
709 .samples = 1,
710 .tiling = VK_IMAGE_TILING_LINEAR,
711 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
712 .flags = 0,
713 };
714 VkMemoryAllocInfo mem_alloc = {
715 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
716 .pNext = NULL,
717 .allocationSize = 0,
718 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
719 .memPriority = VK_MEMORY_PRIORITY_NORMAL,
720 };
721
722 err = vkCreateImage(m_device->device(), &image_create_info, &image);
723 ASSERT_VK_SUCCESS(err);
724
725 err = vkGetObjectInfo(m_device->device(),
726 VK_OBJECT_TYPE_IMAGE,
727 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500728 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
729 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500730 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500731 ASSERT_VK_SUCCESS(err);
732
Mark Lobodzinski23182612015-05-29 09:32:35 -0500733 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500734
735 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500736 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500737 ASSERT_VK_SUCCESS(err);
738
739 // Introduce validation failure, destroy Image object before binding
740 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
741 ASSERT_VK_SUCCESS(err);
742
743 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500744 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500745 ASSERT_VK_SUCCESS(err);
746
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600747 msgFlags = m_errorMonitor->GetState(&msgString);
748 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 -0500749 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500750 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
751 }
752}
753
Tony Barbour8508b8e2015-04-09 10:48:04 -0600754TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600755{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600756 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600757 VkFlags msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -0600758 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600759
760 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600761 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
762 fenceInfo.pNext = NULL;
763 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600764
Tony Barbour30486ea2015-04-07 13:44:53 -0600765 ASSERT_NO_FATAL_FAILURE(InitState());
766 ASSERT_NO_FATAL_FAILURE(InitViewport());
767 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
768
Tony Barbour01999182015-04-09 12:58:51 -0600769 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600770 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
771
Tony Barbour8508b8e2015-04-09 10:48:04 -0600772 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600773 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600774 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600775
776 testFence.init(*m_device, fenceInfo);
777 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600778 cmdBuffer.QueueCommandBuffer(testFence.obj());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600779 msgFlags = m_errorMonitor->GetState(&msgString);
780 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 -0600781 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500782 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600783 }
784
785}
786
787TEST_F(VkLayerTest, ResetUnsignaledFence)
788{
789 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600790 VkFlags msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600791 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600792 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600793 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
794 fenceInfo.pNext = NULL;
795
Tony Barbour8508b8e2015-04-09 10:48:04 -0600796 ASSERT_NO_FATAL_FAILURE(InitState());
797 testFence.init(*m_device, fenceInfo);
798 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600799 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600800 vkResetFences(m_device->device(), 1, fences);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600801 msgFlags = m_errorMonitor->GetState(&msgString);
802 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 -0600803 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500804 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600805 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600806
807}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600808#endif
809#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600810
Tony Barbourdb686622015-05-06 09:35:56 -0600811TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
812{
813 VkEventCreateInfo event_info;
814 VkEvent event;
815 VkMemoryRequirements mem_req;
816 size_t data_size = sizeof(mem_req);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600817 VkFlags msgFlags;
Tony Barbourdb686622015-05-06 09:35:56 -0600818 std::string msgString;
819 VkResult err;
820
821 ASSERT_NO_FATAL_FAILURE(InitState());
822 memset(&event_info, 0, sizeof(event_info));
823 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
824
825 err = vkCreateEvent(device(), &event_info, &event);
826 ASSERT_VK_SUCCESS(err);
827 m_errorMonitor->ClearState();
828 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
829 &data_size, &mem_req);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600830 msgFlags = m_errorMonitor->GetState(&msgString);
831 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 -0600832 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500833 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600834 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500835}
Tony Barbourdb686622015-05-06 09:35:56 -0600836
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500837TEST_F(VkLayerTest, RasterStateNotBound)
838{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600839 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500840 std::string msgString;
841
842 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
843
844 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
845
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600846 msgFlags = m_errorMonitor->GetState(&msgString);
847 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 -0500848 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
849 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
850 }
851}
852
853TEST_F(VkLayerTest, ViewportStateNotBound)
854{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600855 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500856 std::string msgString;
857 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
858
859 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
860
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600861 msgFlags = m_errorMonitor->GetState(&msgString);
862 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 -0500863 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
864 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
865 }
866}
867
868TEST_F(VkLayerTest, ColorBlendStateNotBound)
869{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600870 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500871 std::string msgString;
872
873 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
874
875 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
876
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600877 msgFlags = m_errorMonitor->GetState(&msgString);
878 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 -0500879 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
880 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
881 }
882}
883
884TEST_F(VkLayerTest, DepthStencilStateNotBound)
885{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600886 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500887 std::string msgString;
888
889 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
890
891 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
892
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600893 msgFlags = m_errorMonitor->GetState(&msgString);
894 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 -0500895 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
896 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
897 }
Tony Barbourdb686622015-05-06 09:35:56 -0600898}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600899#endif
900#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600901TEST_F(VkLayerTest, PipelineNotBound)
902{
903 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600904 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600905 std::string msgString;
906
907 ASSERT_NO_FATAL_FAILURE(InitState());
908 m_errorMonitor->ClearState();
909 VkCommandBufferObj cmdBuffer(m_device);
910 BeginCommandBuffer(cmdBuffer);
911 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
912 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600913 msgFlags = m_errorMonitor->GetState(&msgString);
914 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 -0600915 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
916 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
917 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600918}
919
920TEST_F(VkLayerTest, InvalidDescriptorPool)
921{
922 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
923 // The DS check for this is after driver has been called to validate DS internal data struct
924 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600925/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600926 std::string msgString;
927 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
928 vkResetDescriptorPool(device(), badPool);
929
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600930 msgFlags = m_errorMonitor->GetState(&msgString);
931 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 -0600932 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
933 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
934 }*/
935}
936
937TEST_F(VkLayerTest, InvalidDescriptorSet)
938{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600939 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
940 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600941 // Create a valid cmd buffer
942 // call vkCmdBindDescriptorSets w/ false DS
943}
944
945TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
946{
947 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
948 // The DS check for this is after driver has been called to validate DS internal data struct
949}
950
951TEST_F(VkLayerTest, InvalidPipeline)
952{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600953 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
954 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600955 // Create a valid cmd buffer
956 // call vkCmdBindPipeline w/ false Pipeline
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600957 VkFlags msgFlags;
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600958 std::string msgString;
959
960 ASSERT_NO_FATAL_FAILURE(InitState());
961 m_errorMonitor->ClearState();
962 VkCommandBufferObj cmdBuffer(m_device);
963 BeginCommandBuffer(cmdBuffer);
964 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
965 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600966 msgFlags = m_errorMonitor->GetState(&msgString);
967 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 -0600968 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
969 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
970 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600971}
972
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600973TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600974{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600975 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600976 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600977 std::string msgString;
978 VkResult err;
979
980 ASSERT_NO_FATAL_FAILURE(InitState());
981 m_errorMonitor->ClearState();
982 VkCommandBufferObj cmdBuffer(m_device);
983 const VkDescriptorTypeCount ds_type_count = {
984 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
985 .count = 1,
986 };
987 const VkDescriptorPoolCreateInfo ds_pool_ci = {
988 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
989 .pNext = NULL,
990 .count = 1,
991 .pTypeCount = &ds_type_count,
992 };
993 VkDescriptorPool ds_pool;
994 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
995 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600996
997 const VkDescriptorSetLayoutBinding dsl_binding = {
998 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800999 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001000 .stageFlags = VK_SHADER_STAGE_ALL,
1001 .pImmutableSamplers = NULL,
1002 };
1003
1004 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1005 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1006 .pNext = NULL,
1007 .count = 1,
1008 .pBinding = &dsl_binding,
1009 };
1010 VkDescriptorSetLayout ds_layout;
1011 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1012 ASSERT_VK_SUCCESS(err);
1013
1014 VkDescriptorSet descriptorSet;
1015 uint32_t ds_count = 0;
1016 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1017 ASSERT_VK_SUCCESS(err);
1018
1019 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1020 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1021 .pNext = NULL,
1022 .descriptorSetCount = 1,
1023 .pSetLayouts = &ds_layout,
1024 };
1025
1026 VkPipelineLayout pipeline_layout;
1027 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1028 ASSERT_VK_SUCCESS(err);
1029
1030 size_t shader_len = strlen(bindStateVertShaderText);
1031 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1032 void* pCode = malloc(codeSize);
1033
1034 /* try version 0 first: VkShaderStage followed by GLSL */
1035 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1036 ((uint32_t *) pCode)[1] = 0;
1037 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1038 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1039
1040 const VkShaderCreateInfo vs_ci = {
1041 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1042 .pNext = NULL,
1043 .codeSize = codeSize,
1044 .pCode = pCode,
1045 .flags = 0,
1046 };
1047 VkShader vs;
1048 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1049 ASSERT_VK_SUCCESS(err);
1050
1051 const VkPipelineShader vs_pipe_shader = {
1052 .stage = VK_SHADER_STAGE_VERTEX,
1053 .shader = vs,
1054 .linkConstBufferCount = 0,
1055 .pLinkConstBufferInfo = NULL,
1056 .pSpecializationInfo = NULL,
1057 };
1058 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1059 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1060 .pNext = NULL,
1061 .shader = vs_pipe_shader,
1062 };
1063 const VkGraphicsPipelineCreateInfo gp_ci = {
1064 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1065 .pNext = &pipe_vs_ci,
1066 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1067 .layout = pipeline_layout,
1068 };
1069
1070 VkPipeline pipeline;
1071 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1072 ASSERT_VK_SUCCESS(err);
1073
1074 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1075 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1076
1077 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1078 m_device->get_device_queue();
1079 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1080
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001081 msgFlags = m_errorMonitor->GetState(&msgString);
1082 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 -06001083 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1084 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1085 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001086}
1087
1088TEST_F(VkLayerTest, InvalidDynamicStateObject)
1089{
1090 // Create a valid cmd buffer
1091 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001092 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1093 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001094}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001095
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001096TEST_F(VkLayerTest, VtxBufferBadIndex)
1097{
1098 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001099 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001100 std::string msgString;
1101 VkResult err;
1102
1103 ASSERT_NO_FATAL_FAILURE(InitState());
1104 m_errorMonitor->ClearState();
1105 VkCommandBufferObj cmdBuffer(m_device);
1106 const VkDescriptorTypeCount ds_type_count = {
1107 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1108 .count = 1,
1109 };
1110 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1111 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1112 .pNext = NULL,
1113 .count = 1,
1114 .pTypeCount = &ds_type_count,
1115 };
1116 VkDescriptorPool ds_pool;
1117 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1118 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001119
1120 const VkDescriptorSetLayoutBinding dsl_binding = {
1121 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001122 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001123 .stageFlags = VK_SHADER_STAGE_ALL,
1124 .pImmutableSamplers = NULL,
1125 };
1126
1127 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1128 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1129 .pNext = NULL,
1130 .count = 1,
1131 .pBinding = &dsl_binding,
1132 };
1133 VkDescriptorSetLayout ds_layout;
1134 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1135 ASSERT_VK_SUCCESS(err);
1136
1137 VkDescriptorSet descriptorSet;
1138 uint32_t ds_count = 0;
1139 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1140 ASSERT_VK_SUCCESS(err);
1141
1142 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1143 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1144 .pNext = NULL,
1145 .descriptorSetCount = 1,
1146 .pSetLayouts = &ds_layout,
1147 };
1148
1149 VkPipelineLayout pipeline_layout;
1150 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1151 ASSERT_VK_SUCCESS(err);
1152
1153 size_t shader_len = strlen(bindStateVertShaderText);
1154 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1155 void* pCode = malloc(codeSize);
1156
1157 /* try version 0 first: VkShaderStage followed by GLSL */
1158 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1159 ((uint32_t *) pCode)[1] = 0;
1160 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1161 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1162
1163 const VkShaderCreateInfo vs_ci = {
1164 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1165 .pNext = NULL,
1166 .codeSize = codeSize,
1167 .pCode = pCode,
1168 .flags = 0,
1169 };
1170 VkShader vs;
1171 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1172
1173 const VkPipelineShader vs_pipe_shader = {
1174 .stage = VK_SHADER_STAGE_VERTEX,
1175 .shader = vs,
1176 .linkConstBufferCount = 0,
1177 .pLinkConstBufferInfo = NULL,
1178 .pSpecializationInfo = NULL,
1179 };
1180 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1181 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1182 .pNext = NULL,
1183 .shader = vs_pipe_shader,
1184 };
1185 const VkGraphicsPipelineCreateInfo gp_ci = {
1186 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1187 .pNext = &pipe_vs_ci,
1188 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1189 .layout = pipeline_layout,
1190 };
1191
1192 VkPipeline pipeline;
1193 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1194 ASSERT_VK_SUCCESS(err);
1195
1196 err= cmdBuffer.BeginCommandBuffer();
1197 ASSERT_VK_SUCCESS(err);
1198 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1199 // Should error before calling to driver so don't care about actual data
1200 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1201
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001202 msgFlags = m_errorMonitor->GetState(&msgString);
1203 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 -06001204 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1205 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1206 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001207}
1208
1209TEST_F(VkLayerTest, DSTypeMismatch)
1210{
1211 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001212 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001213 std::string msgString;
1214 VkResult err;
1215
1216 ASSERT_NO_FATAL_FAILURE(InitState());
1217 m_errorMonitor->ClearState();
1218 //VkDescriptorSetObj descriptorSet(m_device);
1219 const VkDescriptorTypeCount ds_type_count = {
1220 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1221 .count = 1,
1222 };
1223 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1224 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1225 .pNext = NULL,
1226 .count = 1,
1227 .pTypeCount = &ds_type_count,
1228 };
1229 VkDescriptorPool ds_pool;
1230 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1231 ASSERT_VK_SUCCESS(err);
1232 const VkDescriptorSetLayoutBinding dsl_binding = {
1233 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001234 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001235 .stageFlags = VK_SHADER_STAGE_ALL,
1236 .pImmutableSamplers = NULL,
1237 };
1238
1239 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1240 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1241 .pNext = NULL,
1242 .count = 1,
1243 .pBinding = &dsl_binding,
1244 };
1245 VkDescriptorSetLayout ds_layout;
1246 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1247 ASSERT_VK_SUCCESS(err);
1248
1249 VkDescriptorSet descriptorSet;
1250 uint32_t ds_count = 0;
1251 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1252 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001253
1254 const VkSamplerCreateInfo sampler_ci = {
1255 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1256 .pNext = NULL,
1257 .magFilter = VK_TEX_FILTER_NEAREST,
1258 .minFilter = VK_TEX_FILTER_NEAREST,
1259 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1260 .addressU = VK_TEX_ADDRESS_CLAMP,
1261 .addressV = VK_TEX_ADDRESS_CLAMP,
1262 .addressW = VK_TEX_ADDRESS_CLAMP,
1263 .mipLodBias = 1.0,
1264 .maxAnisotropy = 1,
1265 .compareOp = VK_COMPARE_OP_NEVER,
1266 .minLod = 1.0,
1267 .maxLod = 1.0,
1268 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1269 };
1270 VkSampler sampler;
1271 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1272 ASSERT_VK_SUCCESS(err);
1273
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001274 VkDescriptorInfo descriptor_info;
1275 memset(&descriptor_info, 0, sizeof(descriptor_info));
1276 descriptor_info.sampler = sampler;
1277
1278 VkWriteDescriptorSet descriptor_write;
1279 memset(&descriptor_write, 0, sizeof(descriptor_write));
1280 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1281 descriptor_write.destSet = descriptorSet;
1282 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001283 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001284 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1285 descriptor_write.pDescriptors = &descriptor_info;
1286
1287 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1288
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001289 msgFlags = m_errorMonitor->GetState(&msgString);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001290 std::cout << msgString << "\n";
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001291 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 +08001292 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1293 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 -06001294 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001295}
1296
1297TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1298{
1299 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001300 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001301 std::string msgString;
1302 VkResult err;
1303
1304 ASSERT_NO_FATAL_FAILURE(InitState());
1305 m_errorMonitor->ClearState();
1306 //VkDescriptorSetObj descriptorSet(m_device);
1307 const VkDescriptorTypeCount ds_type_count = {
1308 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1309 .count = 1,
1310 };
1311 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1312 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1313 .pNext = NULL,
1314 .count = 1,
1315 .pTypeCount = &ds_type_count,
1316 };
1317 VkDescriptorPool ds_pool;
1318 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1319 ASSERT_VK_SUCCESS(err);
1320 const VkDescriptorSetLayoutBinding dsl_binding = {
1321 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001322 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001323 .stageFlags = VK_SHADER_STAGE_ALL,
1324 .pImmutableSamplers = NULL,
1325 };
1326
1327 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1328 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1329 .pNext = NULL,
1330 .count = 1,
1331 .pBinding = &dsl_binding,
1332 };
1333 VkDescriptorSetLayout ds_layout;
1334 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1335 ASSERT_VK_SUCCESS(err);
1336
1337 VkDescriptorSet descriptorSet;
1338 uint32_t ds_count = 0;
1339 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1340 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001341
1342 const VkSamplerCreateInfo sampler_ci = {
1343 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1344 .pNext = NULL,
1345 .magFilter = VK_TEX_FILTER_NEAREST,
1346 .minFilter = VK_TEX_FILTER_NEAREST,
1347 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1348 .addressU = VK_TEX_ADDRESS_CLAMP,
1349 .addressV = VK_TEX_ADDRESS_CLAMP,
1350 .addressW = VK_TEX_ADDRESS_CLAMP,
1351 .mipLodBias = 1.0,
1352 .maxAnisotropy = 1,
1353 .compareOp = VK_COMPARE_OP_NEVER,
1354 .minLod = 1.0,
1355 .maxLod = 1.0,
1356 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1357 };
1358 VkSampler sampler;
1359 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1360 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001361
1362 VkDescriptorInfo descriptor_info;
1363 memset(&descriptor_info, 0, sizeof(descriptor_info));
1364 descriptor_info.sampler = sampler;
1365
1366 VkWriteDescriptorSet descriptor_write;
1367 memset(&descriptor_write, 0, sizeof(descriptor_write));
1368 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1369 descriptor_write.destSet = descriptorSet;
1370 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1371 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001372 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001373 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1374 descriptor_write.pDescriptors = &descriptor_info;
1375
1376 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1377
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001378 msgFlags = m_errorMonitor->GetState(&msgString);
1379 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 +08001380 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1381 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 -06001382 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001383}
1384
1385TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1386{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001387 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001388 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001389 std::string msgString;
1390 VkResult err;
1391
1392 ASSERT_NO_FATAL_FAILURE(InitState());
1393 m_errorMonitor->ClearState();
1394 //VkDescriptorSetObj descriptorSet(m_device);
1395 const VkDescriptorTypeCount ds_type_count = {
1396 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1397 .count = 1,
1398 };
1399 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1400 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1401 .pNext = NULL,
1402 .count = 1,
1403 .pTypeCount = &ds_type_count,
1404 };
1405 VkDescriptorPool ds_pool;
1406 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1407 ASSERT_VK_SUCCESS(err);
1408 const VkDescriptorSetLayoutBinding dsl_binding = {
1409 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001410 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001411 .stageFlags = VK_SHADER_STAGE_ALL,
1412 .pImmutableSamplers = NULL,
1413 };
1414
1415 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1416 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1417 .pNext = NULL,
1418 .count = 1,
1419 .pBinding = &dsl_binding,
1420 };
1421 VkDescriptorSetLayout ds_layout;
1422 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1423 ASSERT_VK_SUCCESS(err);
1424
1425 VkDescriptorSet descriptorSet;
1426 uint32_t ds_count = 0;
1427 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1428 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001429
1430 const VkSamplerCreateInfo sampler_ci = {
1431 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1432 .pNext = NULL,
1433 .magFilter = VK_TEX_FILTER_NEAREST,
1434 .minFilter = VK_TEX_FILTER_NEAREST,
1435 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1436 .addressU = VK_TEX_ADDRESS_CLAMP,
1437 .addressV = VK_TEX_ADDRESS_CLAMP,
1438 .addressW = VK_TEX_ADDRESS_CLAMP,
1439 .mipLodBias = 1.0,
1440 .maxAnisotropy = 1,
1441 .compareOp = VK_COMPARE_OP_NEVER,
1442 .minLod = 1.0,
1443 .maxLod = 1.0,
1444 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1445 };
1446 VkSampler sampler;
1447 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1448 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001449
1450 VkDescriptorInfo descriptor_info;
1451 memset(&descriptor_info, 0, sizeof(descriptor_info));
1452 descriptor_info.sampler = sampler;
1453
1454 VkWriteDescriptorSet descriptor_write;
1455 memset(&descriptor_write, 0, sizeof(descriptor_write));
1456 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1457 descriptor_write.destSet = descriptorSet;
1458 descriptor_write.destBinding = 2;
1459 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001460 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001461 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1462 descriptor_write.pDescriptors = &descriptor_info;
1463
1464 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1465
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001466 msgFlags = m_errorMonitor->GetState(&msgString);
1467 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 -06001468 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1469 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1470 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001471}
1472
1473TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1474{
1475 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001476 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001477 std::string msgString;
1478 VkResult err;
1479
1480 ASSERT_NO_FATAL_FAILURE(InitState());
1481 m_errorMonitor->ClearState();
1482 //VkDescriptorSetObj descriptorSet(m_device);
1483 const VkDescriptorTypeCount ds_type_count = {
1484 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1485 .count = 1,
1486 };
1487 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1488 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1489 .pNext = NULL,
1490 .count = 1,
1491 .pTypeCount = &ds_type_count,
1492 };
1493 VkDescriptorPool ds_pool;
1494 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1495 ASSERT_VK_SUCCESS(err);
1496 const VkDescriptorSetLayoutBinding dsl_binding = {
1497 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001498 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001499 .stageFlags = VK_SHADER_STAGE_ALL,
1500 .pImmutableSamplers = NULL,
1501 };
1502
1503 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1504 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1505 .pNext = NULL,
1506 .count = 1,
1507 .pBinding = &dsl_binding,
1508 };
1509 VkDescriptorSetLayout ds_layout;
1510 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1511 ASSERT_VK_SUCCESS(err);
1512
1513 VkDescriptorSet descriptorSet;
1514 uint32_t ds_count = 0;
1515 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1516 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001517
1518 const VkSamplerCreateInfo sampler_ci = {
1519 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1520 .pNext = NULL,
1521 .magFilter = VK_TEX_FILTER_NEAREST,
1522 .minFilter = VK_TEX_FILTER_NEAREST,
1523 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1524 .addressU = VK_TEX_ADDRESS_CLAMP,
1525 .addressV = VK_TEX_ADDRESS_CLAMP,
1526 .addressW = VK_TEX_ADDRESS_CLAMP,
1527 .mipLodBias = 1.0,
1528 .maxAnisotropy = 1,
1529 .compareOp = VK_COMPARE_OP_NEVER,
1530 .minLod = 1.0,
1531 .maxLod = 1.0,
1532 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1533 };
1534 VkSampler sampler;
1535 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1536 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001537
1538
1539 VkDescriptorInfo descriptor_info;
1540 memset(&descriptor_info, 0, sizeof(descriptor_info));
1541 descriptor_info.sampler = sampler;
1542
1543 VkWriteDescriptorSet descriptor_write;
1544 memset(&descriptor_write, 0, sizeof(descriptor_write));
1545 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1546 descriptor_write.destSet = descriptorSet;
1547 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001548 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001549 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1550 descriptor_write.pDescriptors = &descriptor_info;
1551
1552 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1553
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001554 msgFlags = m_errorMonitor->GetState(&msgString);
1555 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 -06001556 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1557 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1558 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001559}
1560
1561TEST_F(VkLayerTest, NumSamplesMismatch)
1562{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001563 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001564 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001565 std::string msgString;
1566 VkResult err;
1567
1568 ASSERT_NO_FATAL_FAILURE(InitState());
1569 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1570 m_errorMonitor->ClearState();
1571 VkCommandBufferObj cmdBuffer(m_device);
1572 const VkDescriptorTypeCount ds_type_count = {
1573 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1574 .count = 1,
1575 };
1576 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1577 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1578 .pNext = NULL,
1579 .count = 1,
1580 .pTypeCount = &ds_type_count,
1581 };
1582 VkDescriptorPool ds_pool;
1583 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1584 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001585
1586 const VkDescriptorSetLayoutBinding dsl_binding = {
1587 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001588 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001589 .stageFlags = VK_SHADER_STAGE_ALL,
1590 .pImmutableSamplers = NULL,
1591 };
1592
1593 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1594 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1595 .pNext = NULL,
1596 .count = 1,
1597 .pBinding = &dsl_binding,
1598 };
1599 VkDescriptorSetLayout ds_layout;
1600 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1601 ASSERT_VK_SUCCESS(err);
1602
1603 VkDescriptorSet descriptorSet;
1604 uint32_t ds_count = 0;
1605 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1606 ASSERT_VK_SUCCESS(err);
1607
1608 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1609 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1610 .pNext = NULL,
Tony Barbourd1e95582015-06-03 12:30:49 -06001611 .samples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001612 .multisampleEnable = 1,
1613 .sampleShadingEnable = 0,
1614 .minSampleShading = 1.0,
1615 .sampleMask = 15,
1616 };
1617
1618 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1619 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1620 .pNext = NULL,
1621 .descriptorSetCount = 1,
1622 .pSetLayouts = &ds_layout,
1623 };
1624
1625 VkPipelineLayout pipeline_layout;
1626 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1627 ASSERT_VK_SUCCESS(err);
1628
1629 size_t shader_len = strlen(bindStateVertShaderText);
1630 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1631 void* pCode = malloc(codeSize);
1632
1633 /* try version 0 first: VkShaderStage followed by GLSL */
1634 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1635 ((uint32_t *) pCode)[1] = 0;
1636 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1637 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1638
1639 const VkShaderCreateInfo vs_ci = {
1640 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1641 .pNext = NULL,
1642 .codeSize = codeSize,
1643 .pCode = pCode,
1644 .flags = 0,
1645 };
1646 VkShader vs;
1647 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1648 ASSERT_VK_SUCCESS(err);
1649
1650 const VkPipelineShader vs_pipe_shader = {
1651 .stage = VK_SHADER_STAGE_VERTEX,
1652 .shader = vs,
1653 .linkConstBufferCount = 0,
1654 .pLinkConstBufferInfo = NULL,
1655 .pSpecializationInfo = NULL,
1656 };
1657 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1658 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1659 .pNext = &pipe_ms_state_ci,
1660 .shader = vs_pipe_shader,
1661 };
1662 const VkGraphicsPipelineCreateInfo gp_ci = {
1663 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1664 .pNext = &pipe_vs_ci,
1665 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1666 .layout = pipeline_layout,
1667 };
1668
1669 VkPipeline pipeline;
1670 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1671 ASSERT_VK_SUCCESS(err);
1672
1673 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1674 BeginCommandBuffer(cmdBuffer);
1675 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1676
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001677 msgFlags = m_errorMonitor->GetState(&msgString);
1678 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 -06001679 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1680 FAIL() << "Error received was not 'Num samples mismatch!...'";
1681 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001682}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001683#endif
1684#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001685#if GTEST_IS_THREADSAFE
1686struct thread_data_struct {
1687 VkCmdBuffer cmdBuffer;
1688 VkEvent event;
1689 bool bailout;
1690};
1691
1692extern "C" void *AddToCommandBuffer(void *arg)
1693{
1694 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1695 std::string msgString;
1696
1697 for (int i = 0; i<10000; i++) {
1698 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1699 if (data->bailout) {
1700 break;
1701 }
1702 }
1703 return NULL;
1704}
1705
1706TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1707{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001708 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06001709 std::string msgString;
1710 pthread_t thread;
1711 pthread_attr_t thread_attr;
1712
1713 ASSERT_NO_FATAL_FAILURE(InitState());
1714 ASSERT_NO_FATAL_FAILURE(InitViewport());
1715 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1716
1717 VkCommandBufferObj cmdBuffer(m_device);
1718
1719 m_errorMonitor->ClearState();
1720 pthread_attr_init(&thread_attr);
1721 BeginCommandBuffer(cmdBuffer);
1722
1723 VkEventCreateInfo event_info;
1724 VkEvent event;
1725 VkMemoryRequirements mem_req;
1726 size_t data_size = sizeof(mem_req);
1727 VkResult err;
1728
1729 memset(&event_info, 0, sizeof(event_info));
1730 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1731
1732 err = vkCreateEvent(device(), &event_info, &event);
1733 ASSERT_VK_SUCCESS(err);
1734
1735 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1736 &data_size, &mem_req);
1737 ASSERT_VK_SUCCESS(err);
1738
1739 VkMemoryAllocInfo mem_info;
1740 VkDeviceMemory event_mem;
1741
1742 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1743
1744 memset(&mem_info, 0, sizeof(mem_info));
1745 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1746 mem_info.allocationSize = mem_req.size;
1747 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1748 mem_info.memPriority = VK_MEMORY_PRIORITY_NORMAL;
1749 err = vkAllocMemory(device(), &mem_info, &event_mem);
1750 ASSERT_VK_SUCCESS(err);
1751
Mark Lobodzinski23182612015-05-29 09:32:35 -05001752 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001753 ASSERT_VK_SUCCESS(err);
1754
1755 err = vkResetEvent(device(), event);
1756 ASSERT_VK_SUCCESS(err);
1757
1758 struct thread_data_struct data;
1759 data.cmdBuffer = cmdBuffer.obj();
1760 data.event = event;
1761 data.bailout = false;
1762 m_errorMonitor->SetBailout(&data.bailout);
1763 // Add many entries to command buffer from another thread.
1764 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1765 // Add many entries to command buffer from this thread at the same time.
1766 AddToCommandBuffer(&data);
1767 pthread_join(thread, NULL);
1768 EndCommandBuffer(cmdBuffer);
1769
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001770 msgFlags = m_errorMonitor->GetState(&msgString);
1771 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 -06001772 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001773 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001774 }
1775
1776}
1777#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001778#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12001779
1780#if SHADER_CHECKER_TESTS
1781TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
1782{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001783 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12001784 std::string msgString;
1785 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001786 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001787
1788 char const *vsSource =
1789 "#version 140\n"
1790 "#extension GL_ARB_separate_shader_objects: require\n"
1791 "#extension GL_ARB_shading_language_420pack: require\n"
1792 "\n"
1793 "layout(location=0) out float x;\n"
1794 "void main(){\n"
1795 " gl_Position = vec4(1);\n"
1796 " x = 0;\n"
1797 "}\n";
1798 char const *fsSource =
1799 "#version 140\n"
1800 "#extension GL_ARB_separate_shader_objects: require\n"
1801 "#extension GL_ARB_shading_language_420pack: require\n"
1802 "\n"
1803 "layout(location=0) out vec4 color;\n"
1804 "void main(){\n"
1805 " color = vec4(1);\n"
1806 "}\n";
1807
1808 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1809 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1810
1811 VkPipelineObj pipe(m_device);
1812 pipe.AddShader(&vs);
1813 pipe.AddShader(&fs);
1814
1815 VkCommandBufferObj dummyCmd(m_device);
1816 VkDescriptorSetObj descriptorSet(m_device);
1817 descriptorSet.AppendDummy();
1818 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1819
1820 m_errorMonitor->ClearState();
1821 pipe.CreateVKPipeline(descriptorSet);
1822
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001823 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001824
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001825 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001826 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
1827 FAIL() << "Incorrect warning: " << msgString;
1828 }
1829}
Chris Forbes5af3bf22015-05-25 11:13:08 +12001830
Chris Forbes3c10b852015-05-25 11:13:13 +12001831TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
1832{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001833 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12001834 std::string msgString;
1835 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001836 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12001837
1838 char const *vsSource =
1839 "#version 140\n"
1840 "#extension GL_ARB_separate_shader_objects: require\n"
1841 "#extension GL_ARB_shading_language_420pack: require\n"
1842 "\n"
1843 "void main(){\n"
1844 " gl_Position = vec4(1);\n"
1845 "}\n";
1846 char const *fsSource =
1847 "#version 140\n"
1848 "#extension GL_ARB_separate_shader_objects: require\n"
1849 "#extension GL_ARB_shading_language_420pack: require\n"
1850 "\n"
1851 "layout(location=0) in float x;\n"
1852 "layout(location=0) out vec4 color;\n"
1853 "void main(){\n"
1854 " color = vec4(x);\n"
1855 "}\n";
1856
1857 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1858 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1859
1860 VkPipelineObj pipe(m_device);
1861 pipe.AddShader(&vs);
1862 pipe.AddShader(&fs);
1863
1864 VkCommandBufferObj dummyCmd(m_device);
1865 VkDescriptorSetObj descriptorSet(m_device);
1866 descriptorSet.AppendDummy();
1867 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1868
1869 m_errorMonitor->ClearState();
1870 pipe.CreateVKPipeline(descriptorSet);
1871
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001872 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12001873
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001874 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12001875 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
1876 FAIL() << "Incorrect error: " << msgString;
1877 }
1878}
1879
Chris Forbescc281692015-05-25 11:13:17 +12001880TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
1881{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001882 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12001883 std::string msgString;
1884 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001885 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12001886
1887 char const *vsSource =
1888 "#version 140\n"
1889 "#extension GL_ARB_separate_shader_objects: require\n"
1890 "#extension GL_ARB_shading_language_420pack: require\n"
1891 "\n"
1892 "layout(location=0) out int x;\n"
1893 "void main(){\n"
1894 " x = 0;\n"
1895 " gl_Position = vec4(1);\n"
1896 "}\n";
1897 char const *fsSource =
1898 "#version 140\n"
1899 "#extension GL_ARB_separate_shader_objects: require\n"
1900 "#extension GL_ARB_shading_language_420pack: require\n"
1901 "\n"
1902 "layout(location=0) in float x;\n" /* VS writes int */
1903 "layout(location=0) out vec4 color;\n"
1904 "void main(){\n"
1905 " color = vec4(x);\n"
1906 "}\n";
1907
1908 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1909 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1910
1911 VkPipelineObj pipe(m_device);
1912 pipe.AddShader(&vs);
1913 pipe.AddShader(&fs);
1914
1915 VkCommandBufferObj dummyCmd(m_device);
1916 VkDescriptorSetObj descriptorSet(m_device);
1917 descriptorSet.AppendDummy();
1918 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1919
1920 m_errorMonitor->ClearState();
1921 pipe.CreateVKPipeline(descriptorSet);
1922
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001923 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12001924
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001925 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12001926 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
1927 FAIL() << "Incorrect error: " << msgString;
1928 }
1929}
1930
Chris Forbes8291c052015-05-25 11:13:28 +12001931TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
1932{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001933 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12001934 std::string msgString;
1935 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001936 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12001937
1938 VkVertexInputBindingDescription input_binding;
1939 memset(&input_binding, 0, sizeof(input_binding));
1940
1941 VkVertexInputAttributeDescription input_attrib;
1942 memset(&input_attrib, 0, sizeof(input_attrib));
1943 input_attrib.format = VK_FORMAT_R32_SFLOAT;
1944
1945 char const *vsSource =
1946 "#version 140\n"
1947 "#extension GL_ARB_separate_shader_objects: require\n"
1948 "#extension GL_ARB_shading_language_420pack: require\n"
1949 "\n"
1950 "void main(){\n"
1951 " gl_Position = vec4(1);\n"
1952 "}\n";
1953 char const *fsSource =
1954 "#version 140\n"
1955 "#extension GL_ARB_separate_shader_objects: require\n"
1956 "#extension GL_ARB_shading_language_420pack: require\n"
1957 "\n"
1958 "layout(location=0) out vec4 color;\n"
1959 "void main(){\n"
1960 " color = vec4(1);\n"
1961 "}\n";
1962
1963 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1964 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1965
1966 VkPipelineObj pipe(m_device);
1967 pipe.AddShader(&vs);
1968 pipe.AddShader(&fs);
1969
1970 pipe.AddVertexInputBindings(&input_binding, 1);
1971 pipe.AddVertexInputAttribs(&input_attrib, 1);
1972
1973 VkCommandBufferObj dummyCmd(m_device);
1974 VkDescriptorSetObj descriptorSet(m_device);
1975 descriptorSet.AppendDummy();
1976 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1977
1978 m_errorMonitor->ClearState();
1979 pipe.CreateVKPipeline(descriptorSet);
1980
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001981 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes8291c052015-05-25 11:13:28 +12001982
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001983 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12001984 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
1985 FAIL() << "Incorrect warning: " << msgString;
1986 }
1987}
1988
Chris Forbes37367e62015-05-25 11:13:29 +12001989TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
1990{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001991 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12001992 std::string msgString;
1993 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001994 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12001995
1996 char const *vsSource =
1997 "#version 140\n"
1998 "#extension GL_ARB_separate_shader_objects: require\n"
1999 "#extension GL_ARB_shading_language_420pack: require\n"
2000 "\n"
2001 "layout(location=0) in vec4 x;\n" /* not provided */
2002 "void main(){\n"
2003 " gl_Position = x;\n"
2004 "}\n";
2005 char const *fsSource =
2006 "#version 140\n"
2007 "#extension GL_ARB_separate_shader_objects: require\n"
2008 "#extension GL_ARB_shading_language_420pack: require\n"
2009 "\n"
2010 "layout(location=0) out vec4 color;\n"
2011 "void main(){\n"
2012 " color = vec4(1);\n"
2013 "}\n";
2014
2015 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2016 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2017
2018 VkPipelineObj pipe(m_device);
2019 pipe.AddShader(&vs);
2020 pipe.AddShader(&fs);
2021
2022 VkCommandBufferObj dummyCmd(m_device);
2023 VkDescriptorSetObj descriptorSet(m_device);
2024 descriptorSet.AppendDummy();
2025 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2026
2027 m_errorMonitor->ClearState();
2028 pipe.CreateVKPipeline(descriptorSet);
2029
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002030 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002031
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002032 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002033 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2034 FAIL() << "Incorrect warning: " << msgString;
2035 }
2036}
2037
Chris Forbesa4b02322015-05-25 11:13:31 +12002038TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2039{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002040 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002041 std::string msgString;
2042 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002043 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002044
2045 VkVertexInputBindingDescription input_binding;
2046 memset(&input_binding, 0, sizeof(input_binding));
2047
2048 VkVertexInputAttributeDescription input_attrib;
2049 memset(&input_attrib, 0, sizeof(input_attrib));
2050 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2051
2052 char const *vsSource =
2053 "#version 140\n"
2054 "#extension GL_ARB_separate_shader_objects: require\n"
2055 "#extension GL_ARB_shading_language_420pack: require\n"
2056 "\n"
2057 "layout(location=0) in int x;\n" /* attrib provided float */
2058 "void main(){\n"
2059 " gl_Position = vec4(x);\n"
2060 "}\n";
2061 char const *fsSource =
2062 "#version 140\n"
2063 "#extension GL_ARB_separate_shader_objects: require\n"
2064 "#extension GL_ARB_shading_language_420pack: require\n"
2065 "\n"
2066 "layout(location=0) out vec4 color;\n"
2067 "void main(){\n"
2068 " color = vec4(1);\n"
2069 "}\n";
2070
2071 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2072 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2073
2074 VkPipelineObj pipe(m_device);
2075 pipe.AddShader(&vs);
2076 pipe.AddShader(&fs);
2077
2078 pipe.AddVertexInputBindings(&input_binding, 1);
2079 pipe.AddVertexInputAttribs(&input_attrib, 1);
2080
2081 VkCommandBufferObj dummyCmd(m_device);
2082 VkDescriptorSetObj descriptorSet(m_device);
2083 descriptorSet.AppendDummy();
2084 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2085
2086 m_errorMonitor->ClearState();
2087 pipe.CreateVKPipeline(descriptorSet);
2088
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002089 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002090
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002091 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002092 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2093 FAIL() << "Incorrect error: " << msgString;
2094 }
2095}
2096
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002097TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2098{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002099 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002100 std::string msgString;
2101 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002102 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002103
2104 /* Two binding descriptions for binding 0 */
2105 VkVertexInputBindingDescription input_bindings[2];
2106 memset(input_bindings, 0, sizeof(input_bindings));
2107
2108 VkVertexInputAttributeDescription input_attrib;
2109 memset(&input_attrib, 0, sizeof(input_attrib));
2110 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2111
2112 char const *vsSource =
2113 "#version 140\n"
2114 "#extension GL_ARB_separate_shader_objects: require\n"
2115 "#extension GL_ARB_shading_language_420pack: require\n"
2116 "\n"
2117 "layout(location=0) in float x;\n" /* attrib provided float */
2118 "void main(){\n"
2119 " gl_Position = vec4(x);\n"
2120 "}\n";
2121 char const *fsSource =
2122 "#version 140\n"
2123 "#extension GL_ARB_separate_shader_objects: require\n"
2124 "#extension GL_ARB_shading_language_420pack: require\n"
2125 "\n"
2126 "layout(location=0) out vec4 color;\n"
2127 "void main(){\n"
2128 " color = vec4(1);\n"
2129 "}\n";
2130
2131 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2132 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2133
2134 VkPipelineObj pipe(m_device);
2135 pipe.AddShader(&vs);
2136 pipe.AddShader(&fs);
2137
2138 pipe.AddVertexInputBindings(input_bindings, 2);
2139 pipe.AddVertexInputAttribs(&input_attrib, 1);
2140
2141 VkCommandBufferObj dummyCmd(m_device);
2142 VkDescriptorSetObj descriptorSet(m_device);
2143 descriptorSet.AppendDummy();
2144 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2145
2146 m_errorMonitor->ClearState();
2147 pipe.CreateVKPipeline(descriptorSet);
2148
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002149 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002150
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002151 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002152 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2153 FAIL() << "Incorrect error: " << msgString;
2154 }
2155}
Chris Forbes4c948702015-05-25 11:13:32 +12002156
Chris Forbesc12ef122015-05-25 11:13:40 +12002157/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2158 * rejects it. */
2159
2160TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2161{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002162 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002163 std::string msgString;
2164 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002165 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002166
2167 char const *vsSource =
2168 "#version 140\n"
2169 "#extension GL_ARB_separate_shader_objects: require\n"
2170 "#extension GL_ARB_shading_language_420pack: require\n"
2171 "\n"
2172 "void main(){\n"
2173 " gl_Position = vec4(1);\n"
2174 "}\n";
2175 char const *fsSource =
2176 "#version 140\n"
2177 "#extension GL_ARB_separate_shader_objects: require\n"
2178 "#extension GL_ARB_shading_language_420pack: require\n"
2179 "\n"
2180 "void main(){\n"
2181 "}\n";
2182
2183 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2184 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2185
2186 VkPipelineObj pipe(m_device);
2187 pipe.AddShader(&vs);
2188 pipe.AddShader(&fs);
2189
2190 /* implicit CB 0 set up by the test framework, not written */
2191
2192 VkCommandBufferObj dummyCmd(m_device);
2193 VkDescriptorSetObj descriptorSet(m_device);
2194 descriptorSet.AppendDummy();
2195 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2196
2197 m_errorMonitor->ClearState();
2198 pipe.CreateVKPipeline(descriptorSet);
2199
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002200 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002201
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002202 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002203 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2204 FAIL() << "Incorrect error: " << msgString;
2205 }
2206}
2207
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002208TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2209{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002210 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002211 std::string msgString;
2212 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002213 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002214
2215 char const *vsSource =
2216 "#version 140\n"
2217 "#extension GL_ARB_separate_shader_objects: require\n"
2218 "#extension GL_ARB_shading_language_420pack: require\n"
2219 "\n"
2220 "void main(){\n"
2221 " gl_Position = vec4(1);\n"
2222 "}\n";
2223 char const *fsSource =
2224 "#version 140\n"
2225 "#extension GL_ARB_separate_shader_objects: require\n"
2226 "#extension GL_ARB_shading_language_420pack: require\n"
2227 "\n"
2228 "layout(location=0) out vec4 x;\n"
2229 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2230 "void main(){\n"
2231 " x = vec4(1);\n"
2232 " y = vec4(1);\n"
2233 "}\n";
2234
2235 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2236 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2237
2238 VkPipelineObj pipe(m_device);
2239 pipe.AddShader(&vs);
2240 pipe.AddShader(&fs);
2241
2242 /* implicit CB 0 set up by the test framework */
2243 /* FS writes CB 1, but we don't configure it */
2244
2245 VkCommandBufferObj dummyCmd(m_device);
2246 VkDescriptorSetObj descriptorSet(m_device);
2247 descriptorSet.AppendDummy();
2248 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2249
2250 m_errorMonitor->ClearState();
2251 pipe.CreateVKPipeline(descriptorSet);
2252
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002253 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002254
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002255 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002256 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2257 FAIL() << "Incorrect warning: " << msgString;
2258 }
2259}
2260
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002261TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2262{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002263 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002264 std::string msgString;
2265 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002266 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002267
2268 char const *vsSource =
2269 "#version 140\n"
2270 "#extension GL_ARB_separate_shader_objects: require\n"
2271 "#extension GL_ARB_shading_language_420pack: require\n"
2272 "\n"
2273 "void main(){\n"
2274 " gl_Position = vec4(1);\n"
2275 "}\n";
2276 char const *fsSource =
2277 "#version 140\n"
2278 "#extension GL_ARB_separate_shader_objects: require\n"
2279 "#extension GL_ARB_shading_language_420pack: require\n"
2280 "\n"
2281 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2282 "void main(){\n"
2283 " x = ivec4(1);\n"
2284 "}\n";
2285
2286 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2287 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2288
2289 VkPipelineObj pipe(m_device);
2290 pipe.AddShader(&vs);
2291 pipe.AddShader(&fs);
2292
2293 /* implicit CB 0 set up by test framework, is UNORM. */
2294
2295 VkCommandBufferObj dummyCmd(m_device);
2296 VkDescriptorSetObj descriptorSet(m_device);
2297 descriptorSet.AppendDummy();
2298 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2299
2300 m_errorMonitor->ClearState();
2301 pipe.CreateVKPipeline(descriptorSet);
2302
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002303 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002304
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002305 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002306 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2307 FAIL() << "Incorrect error: " << msgString;
2308 }
2309}
Chris Forbesc2050732015-06-05 14:43:36 +12002310
2311TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2312{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002313 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002314 std::string msgString;
2315 ASSERT_NO_FATAL_FAILURE(InitState());
2316 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002317 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002318
2319 char const *vsSource =
2320 "#version 140\n"
2321 "#extension GL_ARB_separate_shader_objects: require\n"
2322 "#extension GL_ARB_shading_language_420pack: require\n"
2323 "\n"
2324 "void main(){\n"
2325 " gl_Position = vec4(1);\n"
2326 "}\n";
2327 char const *fsSource =
2328 "#version 140\n"
2329 "#extension GL_ARB_separate_shader_objects: require\n"
2330 "#extension GL_ARB_shading_language_420pack: require\n"
2331 "\n"
2332 "layout(location=0) out vec4 x;\n"
2333 "void main(){\n"
2334 " x = vec4(1);\n"
2335 "}\n";
2336
2337 m_errorMonitor->ClearState();
2338
2339 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2340 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2341
2342
2343 VkPipelineObj pipe(m_device);
2344 pipe.AddShader(&vs);
2345 pipe.AddShader(&fs);
2346
2347 /* implicit CB 0 set up by test framework, is UNORM. */
2348
2349 VkCommandBufferObj dummyCmd(m_device);
2350 VkDescriptorSetObj descriptorSet(m_device);
2351 descriptorSet.AppendDummy();
2352 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2353
2354 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2355 /* pipeline creation should have succeeded */
2356 ASSERT_EQ(VK_SUCCESS, res);
2357
2358 /* should have emitted a warning: the shader is not SPIRV, so we're
2359 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002360 msgFlags = m_errorMonitor->GetState(&msgString);
2361 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002362 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2363 FAIL() << "Incorrect warning: " << msgString;
2364 }
2365}
Chris Forbes01c9db72015-06-04 09:25:25 +12002366#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002367
Tony Barbour30486ea2015-04-07 13:44:53 -06002368int main(int argc, char **argv) {
2369 int result;
2370
2371 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002372 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002373
2374 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2375
2376 result = RUN_ALL_TESTS();
2377
Tony Barbour01999182015-04-09 12:58:51 -06002378 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002379 return result;
2380}