blob: 6597e7e6f20734de37547b0685f572be092524ca [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 Goeltzenleuchterde53c5b2015-06-16 15:59:11 -0600155 /*
156 * Since CreateDbgMsgCallback is an instance level extension call
157 * any extension / layer that utilizes that feature also needs
158 * to be enabled at create instance time.
159 */
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600160 instance_extension_names.push_back("MemTracker");
Courtney Goeltzenleuchtereb518dc2015-06-13 21:41:00 -0600161 instance_extension_names.push_back("DrawState");
162 instance_extension_names.push_back("ObjectTracker");
163 instance_extension_names.push_back("Threading");
Courtney Goeltzenleuchterde53c5b2015-06-16 15:59:11 -0600164 instance_extension_names.push_back("ShaderChecker");
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600165
166 device_extension_names.push_back("MemTracker");
Jon Ashburn64716542015-06-15 12:21:02 -0600167 device_extension_names.push_back("DrawState");
Courtney Goeltzenleuchtereb518dc2015-06-13 21:41:00 -0600168 device_extension_names.push_back("ObjectTracker");
169 device_extension_names.push_back("Threading");
Courtney Goeltzenleuchterde53c5b2015-06-16 15:59:11 -0600170 device_extension_names.push_back("ShaderChecker");
Tony Barbour30486ea2015-04-07 13:44:53 -0600171
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600172 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600173 this->app_info.pNext = NULL;
174 this->app_info.pAppName = "layer_tests";
175 this->app_info.appVersion = 1;
176 this->app_info.pEngineName = "unittest";
177 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600178 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600179
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600180 m_errorMonitor = new ErrorMonitor;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600181 InitFramework(instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
Tony Barbour30486ea2015-04-07 13:44:53 -0600182 }
183
184 virtual void TearDown() {
185 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600186 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600187 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600188 }
189};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500190
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600191VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600192{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600193 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600194
195 result = cmdBuffer.BeginCommandBuffer();
196
197 /*
198 * For render test all drawing happens in a single render pass
199 * on a single command buffer.
200 */
Chris Forbesfe133ef2015-06-16 14:05:59 +1200201 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600202 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
203 }
204
205 return result;
206}
207
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600208VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600209{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600210 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600211
Chris Forbesfe133ef2015-06-16 14:05:59 +1200212 if (renderPass()) {
213 cmdBuffer.EndRenderPass(renderPass());
214 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600215
216 result = cmdBuffer.EndCommandBuffer();
217
218 return result;
219}
220
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500221void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
222{
223 // Create identity matrix
224 int i;
225 struct vktriangle_vs_uniform data;
226
227 glm::mat4 Projection = glm::mat4(1.0f);
228 glm::mat4 View = glm::mat4(1.0f);
229 glm::mat4 Model = glm::mat4(1.0f);
230 glm::mat4 MVP = Projection * View * Model;
231 const int matrixSize = sizeof(MVP);
232 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
233
234 memcpy(&data.mvp, &MVP[0][0], matrixSize);
235
236 static const Vertex tri_data[] =
237 {
238 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
239 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
240 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
241 };
242
243 for (i=0; i<3; i++) {
244 data.position[i][0] = tri_data[i].posX;
245 data.position[i][1] = tri_data[i].posY;
246 data.position[i][2] = tri_data[i].posZ;
247 data.position[i][3] = tri_data[i].posW;
248 data.color[i][0] = tri_data[i].r;
249 data.color[i][1] = tri_data[i].g;
250 data.color[i][2] = tri_data[i].b;
251 data.color[i][3] = tri_data[i].a;
252 }
253
254 ASSERT_NO_FATAL_FAILURE(InitState());
255 ASSERT_NO_FATAL_FAILURE(InitViewport());
256
257 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
258
259 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
260 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
261
262 VkPipelineObj pipelineobj(m_device);
263 pipelineobj.AddShader(&vs);
264 pipelineobj.AddShader(&ps);
265
266 VkDescriptorSetObj descriptorSet(m_device);
267 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
268
269 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
270 VkCommandBufferObj cmdBuffer(m_device);
271 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
272
273 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
274
275 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
276
277 // render triangle
278 cmdBuffer.Draw(0, 3, 0, 1);
279
280 // finalize recording of the command buffer
281 EndCommandBuffer(cmdBuffer);
282
283 cmdBuffer.QueueCommandBuffer();
284}
285
286void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
287{
288 if (m_depthStencil->Initialized()) {
289 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
290 } else {
291 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
292 }
293
294 cmdBuffer->PrepareAttachments();
295 if ((failMask & BsoFailRaster) != BsoFailRaster) {
296 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
297 }
298 if ((failMask & BsoFailViewport) != BsoFailViewport) {
299 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
300 }
301 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
302 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
303 }
304 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
305 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
306 }
307 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
308 pipelineobj.CreateVKPipeline(descriptorSet);
309 cmdBuffer->BindPipeline(pipelineobj);
310 cmdBuffer->BindDescriptorSet(descriptorSet);
311}
312
313// ********************************************************************************************************************
314// ********************************************************************************************************************
315// ********************************************************************************************************************
316// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600317#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500318TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
319{
320 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600321 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500322 std::string msgString;
323
324 VkFenceCreateInfo fenceInfo = {};
325 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
326 fenceInfo.pNext = NULL;
327 fenceInfo.flags = 0;
328
329 ASSERT_NO_FATAL_FAILURE(InitState());
330 ASSERT_NO_FATAL_FAILURE(InitViewport());
331 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
332
333 VkCommandBufferObj cmdBuffer(m_device);
334 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
335
336 BeginCommandBuffer(cmdBuffer);
337 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
338 EndCommandBuffer(cmdBuffer);
339
340 testFence.init(*m_device, fenceInfo);
341
342 // Bypass framework since it does the waits automatically
343 VkResult err = VK_SUCCESS;
344 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
345 ASSERT_VK_SUCCESS( err );
346
347 m_errorMonitor->ClearState();
348 // Introduce failure by calling begin again before checking fence
349 vkResetCommandBuffer(cmdBuffer.obj());
350
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600351 msgFlags = m_errorMonitor->GetState(&msgString);
352 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 -0500353 if (!strstr(msgString.c_str(),"Resetting CB")) {
354 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
355 }
356}
357
358TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
359{
360 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600361 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500362 std::string msgString;
363
364 VkFenceCreateInfo fenceInfo = {};
365 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
366 fenceInfo.pNext = NULL;
367 fenceInfo.flags = 0;
368
369 ASSERT_NO_FATAL_FAILURE(InitState());
370 ASSERT_NO_FATAL_FAILURE(InitViewport());
371 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
372
373 VkCommandBufferObj cmdBuffer(m_device);
374 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
375
376 BeginCommandBuffer(cmdBuffer);
377 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
378 EndCommandBuffer(cmdBuffer);
379
380 testFence.init(*m_device, fenceInfo);
381
382 // Bypass framework since it does the waits automatically
383 VkResult err = VK_SUCCESS;
384 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
385 ASSERT_VK_SUCCESS( err );
386
387 m_errorMonitor->ClearState();
388 // Introduce failure by calling begin again before checking fence
389 BeginCommandBuffer(cmdBuffer);
390
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600391 msgFlags = m_errorMonitor->GetState(&msgString);
392 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 -0500393 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
394 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
395 }
396}
397
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500398TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
399{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600400 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500401 std::string msgString;
402 VkResult err;
403
404 ASSERT_NO_FATAL_FAILURE(InitState());
405 m_errorMonitor->ClearState();
406
407 // Create an image, allocate memory, free it, and then try to bind it
408 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500409 VkDeviceMemory mem;
410 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500411
412 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
413 const int32_t tex_width = 32;
414 const int32_t tex_height = 32;
415 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500416
417 const VkImageCreateInfo image_create_info = {
418 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
419 .pNext = NULL,
420 .imageType = VK_IMAGE_TYPE_2D,
421 .format = tex_format,
422 .extent = { tex_width, tex_height, 1 },
423 .mipLevels = 1,
424 .arraySize = 1,
425 .samples = 1,
426 .tiling = VK_IMAGE_TILING_LINEAR,
427 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
428 .flags = 0,
429 };
430 VkMemoryAllocInfo mem_alloc = {
431 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
432 .pNext = NULL,
433 .allocationSize = 0,
434 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
435 .memProps = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500436 };
437
438 err = vkCreateImage(m_device->device(), &image_create_info, &image);
439 ASSERT_VK_SUCCESS(err);
440
441 err = vkGetObjectInfo(m_device->device(),
442 VK_OBJECT_TYPE_IMAGE,
443 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500444 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
445 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500446 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500447 ASSERT_VK_SUCCESS(err);
448
Mark Lobodzinski23182612015-05-29 09:32:35 -0500449 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500450
451 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500452 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500453 ASSERT_VK_SUCCESS(err);
454
455 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500456 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500457 ASSERT_VK_SUCCESS(err);
458
459 // Map memory as if to initialize the image
460 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500461 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500462
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600463 msgFlags = m_errorMonitor->GetState(&msgString);
464 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 -0500465 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
466 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
467 }
468}
469
470TEST_F(VkLayerTest, BindInvalidMemory)
471{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600472 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500473 std::string msgString;
474 VkResult err;
475
476 ASSERT_NO_FATAL_FAILURE(InitState());
477 m_errorMonitor->ClearState();
478
479 // Create an image, allocate memory, free it, and then try to bind it
480 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500481 VkDeviceMemory mem;
482 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500483
484 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
485 const int32_t tex_width = 32;
486 const int32_t tex_height = 32;
487 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500488
489 const VkImageCreateInfo image_create_info = {
490 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
491 .pNext = NULL,
492 .imageType = VK_IMAGE_TYPE_2D,
493 .format = tex_format,
494 .extent = { tex_width, tex_height, 1 },
495 .mipLevels = 1,
496 .arraySize = 1,
497 .samples = 1,
498 .tiling = VK_IMAGE_TILING_LINEAR,
499 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
500 .flags = 0,
501 };
502 VkMemoryAllocInfo mem_alloc = {
503 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
504 .pNext = NULL,
505 .allocationSize = 0,
506 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500507 };
508
509 err = vkCreateImage(m_device->device(), &image_create_info, &image);
510 ASSERT_VK_SUCCESS(err);
511
512 err = vkGetObjectInfo(m_device->device(),
513 VK_OBJECT_TYPE_IMAGE,
514 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500515 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
516 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500517 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500518 ASSERT_VK_SUCCESS(err);
519
Mark Lobodzinski23182612015-05-29 09:32:35 -0500520 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500521
522 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500523 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500524 ASSERT_VK_SUCCESS(err);
525
526 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500527 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500528 ASSERT_VK_SUCCESS(err);
529
530 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500531 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500532 ASSERT_VK_SUCCESS(err);
533
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600534 msgFlags = m_errorMonitor->GetState(&msgString);
535 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 -0500536 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500537 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
538 }
539}
540
541TEST_F(VkLayerTest, FreeBoundMemory)
542{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600543 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500544 std::string msgString;
545 VkResult err;
546
547 ASSERT_NO_FATAL_FAILURE(InitState());
548 m_errorMonitor->ClearState();
549
550 // Create an image, allocate memory, free it, and then try to bind it
551 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500552 VkDeviceMemory mem;
553 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500554
555 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
556 const int32_t tex_width = 32;
557 const int32_t tex_height = 32;
558 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500559
560 const VkImageCreateInfo image_create_info = {
561 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
562 .pNext = NULL,
563 .imageType = VK_IMAGE_TYPE_2D,
564 .format = tex_format,
565 .extent = { tex_width, tex_height, 1 },
566 .mipLevels = 1,
567 .arraySize = 1,
568 .samples = 1,
569 .tiling = VK_IMAGE_TILING_LINEAR,
570 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
571 .flags = 0,
572 };
573 VkMemoryAllocInfo mem_alloc = {
574 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
575 .pNext = NULL,
576 .allocationSize = 0,
577 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500578 };
579
580 err = vkCreateImage(m_device->device(), &image_create_info, &image);
581 ASSERT_VK_SUCCESS(err);
582
583 err = vkGetObjectInfo(m_device->device(),
584 VK_OBJECT_TYPE_IMAGE,
585 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500586 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
587 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500588 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500589 ASSERT_VK_SUCCESS(err);
590
Mark Lobodzinski23182612015-05-29 09:32:35 -0500591 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500592
593 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500594 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500595 ASSERT_VK_SUCCESS(err);
596
597 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500598 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500599 ASSERT_VK_SUCCESS(err);
600
601 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500602 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500603 ASSERT_VK_SUCCESS(err);
604
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600605 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter7dc4c8b2015-06-13 21:48:47 -0600606 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 -0500607 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
608 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
609 }
610}
611
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500612TEST_F(VkLayerTest, RebindMemory)
613{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600614 VkFlags msgFlags;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500615 std::string msgString;
616 VkResult err;
617
618 ASSERT_NO_FATAL_FAILURE(InitState());
619 m_errorMonitor->ClearState();
620
621 // Create an image, allocate memory, free it, and then try to bind it
622 VkImage image;
623 VkDeviceMemory mem1;
624 VkDeviceMemory mem2;
625 VkMemoryRequirements mem_reqs;
626
627 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
628 const int32_t tex_width = 32;
629 const int32_t tex_height = 32;
630 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
631
632 const VkImageCreateInfo image_create_info = {
633 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
634 .pNext = NULL,
635 .imageType = VK_IMAGE_TYPE_2D,
636 .format = tex_format,
637 .extent = { tex_width, tex_height, 1 },
638 .mipLevels = 1,
639 .arraySize = 1,
640 .samples = 1,
641 .tiling = VK_IMAGE_TILING_LINEAR,
642 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
643 .flags = 0,
644 };
645 VkMemoryAllocInfo mem_alloc = {
646 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
647 .pNext = NULL,
648 .allocationSize = 0,
649 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500650 };
651
652 err = vkCreateImage(m_device->device(), &image_create_info, &image);
653 ASSERT_VK_SUCCESS(err);
654
655 err = vkGetObjectInfo(m_device->device(),
656 VK_OBJECT_TYPE_IMAGE,
657 image,
658 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
659 &mem_reqs_size,
660 &mem_reqs);
661 ASSERT_VK_SUCCESS(err);
662
663 mem_alloc.allocationSize = mem_reqs.size;
664
665 // allocate 2 memory objects
666 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
667 ASSERT_VK_SUCCESS(err);
668 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
669 ASSERT_VK_SUCCESS(err);
670
671 // Bind first memory object to Image object
672 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
673 ASSERT_VK_SUCCESS(err);
674
675 // Introduce validation failure, try to bind a different memory object to the same image object
676 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
677 ASSERT_VK_SUCCESS(err);
678
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600679 msgFlags = m_errorMonitor->GetState(&msgString);
680 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 -0500681 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
682 FAIL() << "Error received did not match expected message when rebinding memory to an object";
683 }
684}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500685
686TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
687{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600688 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500689 std::string msgString;
690 VkResult err;
691
692 ASSERT_NO_FATAL_FAILURE(InitState());
693 m_errorMonitor->ClearState();
694
695 // Create an image object, allocate memory, destroy the object and then try to bind it
696 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500697 VkDeviceMemory mem;
698 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500699
700 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
701 const int32_t tex_width = 32;
702 const int32_t tex_height = 32;
703 size_t mem_reqs_size = sizeof(VkMemoryRequirements);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500704
705 const VkImageCreateInfo image_create_info = {
706 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
707 .pNext = NULL,
708 .imageType = VK_IMAGE_TYPE_2D,
709 .format = tex_format,
710 .extent = { tex_width, tex_height, 1 },
711 .mipLevels = 1,
712 .arraySize = 1,
713 .samples = 1,
714 .tiling = VK_IMAGE_TILING_LINEAR,
715 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
716 .flags = 0,
717 };
718 VkMemoryAllocInfo mem_alloc = {
719 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
720 .pNext = NULL,
721 .allocationSize = 0,
722 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500723 };
724
725 err = vkCreateImage(m_device->device(), &image_create_info, &image);
726 ASSERT_VK_SUCCESS(err);
727
728 err = vkGetObjectInfo(m_device->device(),
729 VK_OBJECT_TYPE_IMAGE,
730 image,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500731 VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
732 &mem_reqs_size,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500733 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500734 ASSERT_VK_SUCCESS(err);
735
Mark Lobodzinski23182612015-05-29 09:32:35 -0500736 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500737
738 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500739 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500740 ASSERT_VK_SUCCESS(err);
741
742 // Introduce validation failure, destroy Image object before binding
743 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
744 ASSERT_VK_SUCCESS(err);
745
746 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500747 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500748 ASSERT_VK_SUCCESS(err);
749
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600750 msgFlags = m_errorMonitor->GetState(&msgString);
751 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 -0500752 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500753 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
754 }
755}
756
Tony Barbour8508b8e2015-04-09 10:48:04 -0600757TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600758{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600759 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600760 VkFlags msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -0600761 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600762
763 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600764 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
765 fenceInfo.pNext = NULL;
766 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600767
Tony Barbour30486ea2015-04-07 13:44:53 -0600768 ASSERT_NO_FATAL_FAILURE(InitState());
769 ASSERT_NO_FATAL_FAILURE(InitViewport());
770 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
771
Tony Barbour01999182015-04-09 12:58:51 -0600772 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600773 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
774
Tony Barbour8508b8e2015-04-09 10:48:04 -0600775 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600776 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600777 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600778
779 testFence.init(*m_device, fenceInfo);
780 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600781 cmdBuffer.QueueCommandBuffer(testFence.obj());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600782 msgFlags = m_errorMonitor->GetState(&msgString);
783 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 -0600784 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500785 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600786 }
787
788}
789
790TEST_F(VkLayerTest, ResetUnsignaledFence)
791{
792 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600793 VkFlags msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600794 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600795 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600796 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
797 fenceInfo.pNext = NULL;
798
Tony Barbour8508b8e2015-04-09 10:48:04 -0600799 ASSERT_NO_FATAL_FAILURE(InitState());
800 testFence.init(*m_device, fenceInfo);
801 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600802 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600803 vkResetFences(m_device->device(), 1, fences);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600804 msgFlags = m_errorMonitor->GetState(&msgString);
805 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 -0600806 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500807 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600808 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600809
810}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600811#endif
812#if OBJECT_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600813
Tony Barbourdb686622015-05-06 09:35:56 -0600814TEST_F(VkLayerTest, GetObjectInfoMismatchedType)
815{
816 VkEventCreateInfo event_info;
817 VkEvent event;
818 VkMemoryRequirements mem_req;
819 size_t data_size = sizeof(mem_req);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600820 VkFlags msgFlags;
Tony Barbourdb686622015-05-06 09:35:56 -0600821 std::string msgString;
822 VkResult err;
823
824 ASSERT_NO_FATAL_FAILURE(InitState());
825 memset(&event_info, 0, sizeof(event_info));
826 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
827
828 err = vkCreateEvent(device(), &event_info, &event);
829 ASSERT_VK_SUCCESS(err);
830 m_errorMonitor->ClearState();
831 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_IMAGE, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
832 &data_size, &mem_req);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600833 msgFlags = m_errorMonitor->GetState(&msgString);
834 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 -0600835 if (!strstr(msgString.c_str(),"does not match designated type")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500836 FAIL() << "Error received was not 'does not match designated type'";
Tony Barbourdb686622015-05-06 09:35:56 -0600837 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500838}
Tony Barbourdb686622015-05-06 09:35:56 -0600839
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500840TEST_F(VkLayerTest, RasterStateNotBound)
841{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600842 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500843 std::string msgString;
844
845 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
846
847 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
848
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600849 msgFlags = m_errorMonitor->GetState(&msgString);
850 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 -0500851 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
852 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
853 }
854}
855
856TEST_F(VkLayerTest, ViewportStateNotBound)
857{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600858 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500859 std::string msgString;
860 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
861
862 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
863
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600864 msgFlags = m_errorMonitor->GetState(&msgString);
865 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 -0500866 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
867 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
868 }
869}
870
871TEST_F(VkLayerTest, ColorBlendStateNotBound)
872{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600873 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500874 std::string msgString;
875
876 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
877
878 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
879
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600880 msgFlags = m_errorMonitor->GetState(&msgString);
881 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 -0500882 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
883 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
884 }
885}
886
887TEST_F(VkLayerTest, DepthStencilStateNotBound)
888{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600889 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500890 std::string msgString;
891
892 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
893
894 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
895
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600896 msgFlags = m_errorMonitor->GetState(&msgString);
897 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 -0500898 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
899 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
900 }
Tony Barbourdb686622015-05-06 09:35:56 -0600901}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600902#endif
903#if DRAW_STATE_TESTS
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600904TEST_F(VkLayerTest, PipelineNotBound)
905{
906 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600907 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600908 std::string msgString;
909
910 ASSERT_NO_FATAL_FAILURE(InitState());
911 m_errorMonitor->ClearState();
912 VkCommandBufferObj cmdBuffer(m_device);
913 BeginCommandBuffer(cmdBuffer);
914 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
915 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600916 msgFlags = m_errorMonitor->GetState(&msgString);
917 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 -0600918 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
919 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
920 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600921}
922
923TEST_F(VkLayerTest, InvalidDescriptorPool)
924{
925 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
926 // The DS check for this is after driver has been called to validate DS internal data struct
927 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600928/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600929 std::string msgString;
930 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
931 vkResetDescriptorPool(device(), badPool);
932
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600933 msgFlags = m_errorMonitor->GetState(&msgString);
934 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 -0600935 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
936 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
937 }*/
938}
939
940TEST_F(VkLayerTest, InvalidDescriptorSet)
941{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600942 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
943 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600944 // Create a valid cmd buffer
945 // call vkCmdBindDescriptorSets w/ false DS
946}
947
948TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
949{
950 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
951 // The DS check for this is after driver has been called to validate DS internal data struct
952}
953
954TEST_F(VkLayerTest, InvalidPipeline)
955{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600956 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
957 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600958 // Create a valid cmd buffer
959 // call vkCmdBindPipeline w/ false Pipeline
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600960 VkFlags msgFlags;
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600961 std::string msgString;
962
963 ASSERT_NO_FATAL_FAILURE(InitState());
964 m_errorMonitor->ClearState();
965 VkCommandBufferObj cmdBuffer(m_device);
966 BeginCommandBuffer(cmdBuffer);
967 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
968 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600969 msgFlags = m_errorMonitor->GetState(&msgString);
970 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 -0600971 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
972 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
973 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600974}
975
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600976TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600977{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600978 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600979 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600980 std::string msgString;
981 VkResult err;
982
983 ASSERT_NO_FATAL_FAILURE(InitState());
984 m_errorMonitor->ClearState();
985 VkCommandBufferObj cmdBuffer(m_device);
986 const VkDescriptorTypeCount ds_type_count = {
987 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
988 .count = 1,
989 };
990 const VkDescriptorPoolCreateInfo ds_pool_ci = {
991 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
992 .pNext = NULL,
993 .count = 1,
994 .pTypeCount = &ds_type_count,
995 };
996 VkDescriptorPool ds_pool;
997 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
998 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600999
1000 const VkDescriptorSetLayoutBinding dsl_binding = {
1001 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001002 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001003 .stageFlags = VK_SHADER_STAGE_ALL,
1004 .pImmutableSamplers = NULL,
1005 };
1006
1007 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1008 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1009 .pNext = NULL,
1010 .count = 1,
1011 .pBinding = &dsl_binding,
1012 };
1013 VkDescriptorSetLayout ds_layout;
1014 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1015 ASSERT_VK_SUCCESS(err);
1016
1017 VkDescriptorSet descriptorSet;
1018 uint32_t ds_count = 0;
1019 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1020 ASSERT_VK_SUCCESS(err);
1021
1022 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1023 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1024 .pNext = NULL,
1025 .descriptorSetCount = 1,
1026 .pSetLayouts = &ds_layout,
1027 };
1028
1029 VkPipelineLayout pipeline_layout;
1030 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1031 ASSERT_VK_SUCCESS(err);
1032
1033 size_t shader_len = strlen(bindStateVertShaderText);
1034 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1035 void* pCode = malloc(codeSize);
1036
1037 /* try version 0 first: VkShaderStage followed by GLSL */
1038 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1039 ((uint32_t *) pCode)[1] = 0;
1040 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1041 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1042
1043 const VkShaderCreateInfo vs_ci = {
1044 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1045 .pNext = NULL,
1046 .codeSize = codeSize,
1047 .pCode = pCode,
1048 .flags = 0,
1049 };
1050 VkShader vs;
1051 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1052 ASSERT_VK_SUCCESS(err);
1053
1054 const VkPipelineShader vs_pipe_shader = {
1055 .stage = VK_SHADER_STAGE_VERTEX,
1056 .shader = vs,
1057 .linkConstBufferCount = 0,
1058 .pLinkConstBufferInfo = NULL,
1059 .pSpecializationInfo = NULL,
1060 };
1061 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1062 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1063 .pNext = NULL,
1064 .shader = vs_pipe_shader,
1065 };
1066 const VkGraphicsPipelineCreateInfo gp_ci = {
1067 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1068 .pNext = &pipe_vs_ci,
1069 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1070 .layout = pipeline_layout,
1071 };
1072
1073 VkPipeline pipeline;
1074 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1075 ASSERT_VK_SUCCESS(err);
1076
1077 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1078 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 1, &descriptorSet, 0, NULL);
1079
1080 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1081 m_device->get_device_queue();
1082 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1083
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001084 msgFlags = m_errorMonitor->GetState(&msgString);
1085 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 -06001086 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1087 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1088 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001089}
1090
1091TEST_F(VkLayerTest, InvalidDynamicStateObject)
1092{
1093 // Create a valid cmd buffer
1094 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001095 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1096 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001097}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001098
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001099TEST_F(VkLayerTest, VtxBufferBadIndex)
1100{
1101 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001102 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001103 std::string msgString;
1104 VkResult err;
1105
1106 ASSERT_NO_FATAL_FAILURE(InitState());
1107 m_errorMonitor->ClearState();
1108 VkCommandBufferObj cmdBuffer(m_device);
1109 const VkDescriptorTypeCount ds_type_count = {
1110 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1111 .count = 1,
1112 };
1113 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1114 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1115 .pNext = NULL,
1116 .count = 1,
1117 .pTypeCount = &ds_type_count,
1118 };
1119 VkDescriptorPool ds_pool;
1120 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1121 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001122
1123 const VkDescriptorSetLayoutBinding dsl_binding = {
1124 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001125 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001126 .stageFlags = VK_SHADER_STAGE_ALL,
1127 .pImmutableSamplers = NULL,
1128 };
1129
1130 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1131 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1132 .pNext = NULL,
1133 .count = 1,
1134 .pBinding = &dsl_binding,
1135 };
1136 VkDescriptorSetLayout ds_layout;
1137 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1138 ASSERT_VK_SUCCESS(err);
1139
1140 VkDescriptorSet descriptorSet;
1141 uint32_t ds_count = 0;
1142 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1143 ASSERT_VK_SUCCESS(err);
1144
1145 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1146 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1147 .pNext = NULL,
1148 .descriptorSetCount = 1,
1149 .pSetLayouts = &ds_layout,
1150 };
1151
1152 VkPipelineLayout pipeline_layout;
1153 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1154 ASSERT_VK_SUCCESS(err);
1155
1156 size_t shader_len = strlen(bindStateVertShaderText);
1157 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1158 void* pCode = malloc(codeSize);
1159
1160 /* try version 0 first: VkShaderStage followed by GLSL */
1161 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1162 ((uint32_t *) pCode)[1] = 0;
1163 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1164 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1165
1166 const VkShaderCreateInfo vs_ci = {
1167 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1168 .pNext = NULL,
1169 .codeSize = codeSize,
1170 .pCode = pCode,
1171 .flags = 0,
1172 };
1173 VkShader vs;
1174 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1175
1176 const VkPipelineShader vs_pipe_shader = {
1177 .stage = VK_SHADER_STAGE_VERTEX,
1178 .shader = vs,
1179 .linkConstBufferCount = 0,
1180 .pLinkConstBufferInfo = NULL,
1181 .pSpecializationInfo = NULL,
1182 };
1183 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1184 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1185 .pNext = NULL,
1186 .shader = vs_pipe_shader,
1187 };
1188 const VkGraphicsPipelineCreateInfo gp_ci = {
1189 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1190 .pNext = &pipe_vs_ci,
1191 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1192 .layout = pipeline_layout,
1193 };
1194
1195 VkPipeline pipeline;
1196 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1197 ASSERT_VK_SUCCESS(err);
1198
1199 err= cmdBuffer.BeginCommandBuffer();
1200 ASSERT_VK_SUCCESS(err);
1201 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1202 // Should error before calling to driver so don't care about actual data
1203 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1204
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001205 msgFlags = m_errorMonitor->GetState(&msgString);
1206 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 -06001207 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1208 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1209 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001210}
1211
1212TEST_F(VkLayerTest, DSTypeMismatch)
1213{
1214 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001215 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001216 std::string msgString;
1217 VkResult err;
1218
1219 ASSERT_NO_FATAL_FAILURE(InitState());
1220 m_errorMonitor->ClearState();
1221 //VkDescriptorSetObj descriptorSet(m_device);
1222 const VkDescriptorTypeCount ds_type_count = {
1223 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1224 .count = 1,
1225 };
1226 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1227 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1228 .pNext = NULL,
1229 .count = 1,
1230 .pTypeCount = &ds_type_count,
1231 };
1232 VkDescriptorPool ds_pool;
1233 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1234 ASSERT_VK_SUCCESS(err);
1235 const VkDescriptorSetLayoutBinding dsl_binding = {
1236 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001237 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001238 .stageFlags = VK_SHADER_STAGE_ALL,
1239 .pImmutableSamplers = NULL,
1240 };
1241
1242 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1243 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1244 .pNext = NULL,
1245 .count = 1,
1246 .pBinding = &dsl_binding,
1247 };
1248 VkDescriptorSetLayout ds_layout;
1249 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1250 ASSERT_VK_SUCCESS(err);
1251
1252 VkDescriptorSet descriptorSet;
1253 uint32_t ds_count = 0;
1254 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1255 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001256
1257 const VkSamplerCreateInfo sampler_ci = {
1258 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1259 .pNext = NULL,
1260 .magFilter = VK_TEX_FILTER_NEAREST,
1261 .minFilter = VK_TEX_FILTER_NEAREST,
1262 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1263 .addressU = VK_TEX_ADDRESS_CLAMP,
1264 .addressV = VK_TEX_ADDRESS_CLAMP,
1265 .addressW = VK_TEX_ADDRESS_CLAMP,
1266 .mipLodBias = 1.0,
1267 .maxAnisotropy = 1,
1268 .compareOp = VK_COMPARE_OP_NEVER,
1269 .minLod = 1.0,
1270 .maxLod = 1.0,
1271 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1272 };
1273 VkSampler sampler;
1274 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1275 ASSERT_VK_SUCCESS(err);
1276
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001277 VkDescriptorInfo descriptor_info;
1278 memset(&descriptor_info, 0, sizeof(descriptor_info));
1279 descriptor_info.sampler = sampler;
1280
1281 VkWriteDescriptorSet descriptor_write;
1282 memset(&descriptor_write, 0, sizeof(descriptor_write));
1283 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1284 descriptor_write.destSet = descriptorSet;
1285 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001286 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001287 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1288 descriptor_write.pDescriptors = &descriptor_info;
1289
1290 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1291
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001292 msgFlags = m_errorMonitor->GetState(&msgString);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001293 std::cout << msgString << "\n";
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001294 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 +08001295 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1296 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 -06001297 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001298}
1299
1300TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1301{
1302 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001303 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001304 std::string msgString;
1305 VkResult err;
1306
1307 ASSERT_NO_FATAL_FAILURE(InitState());
1308 m_errorMonitor->ClearState();
1309 //VkDescriptorSetObj descriptorSet(m_device);
1310 const VkDescriptorTypeCount ds_type_count = {
1311 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1312 .count = 1,
1313 };
1314 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1315 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1316 .pNext = NULL,
1317 .count = 1,
1318 .pTypeCount = &ds_type_count,
1319 };
1320 VkDescriptorPool ds_pool;
1321 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1322 ASSERT_VK_SUCCESS(err);
1323 const VkDescriptorSetLayoutBinding dsl_binding = {
1324 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001325 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001326 .stageFlags = VK_SHADER_STAGE_ALL,
1327 .pImmutableSamplers = NULL,
1328 };
1329
1330 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1331 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1332 .pNext = NULL,
1333 .count = 1,
1334 .pBinding = &dsl_binding,
1335 };
1336 VkDescriptorSetLayout ds_layout;
1337 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1338 ASSERT_VK_SUCCESS(err);
1339
1340 VkDescriptorSet descriptorSet;
1341 uint32_t ds_count = 0;
1342 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1343 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001344
1345 const VkSamplerCreateInfo sampler_ci = {
1346 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1347 .pNext = NULL,
1348 .magFilter = VK_TEX_FILTER_NEAREST,
1349 .minFilter = VK_TEX_FILTER_NEAREST,
1350 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1351 .addressU = VK_TEX_ADDRESS_CLAMP,
1352 .addressV = VK_TEX_ADDRESS_CLAMP,
1353 .addressW = VK_TEX_ADDRESS_CLAMP,
1354 .mipLodBias = 1.0,
1355 .maxAnisotropy = 1,
1356 .compareOp = VK_COMPARE_OP_NEVER,
1357 .minLod = 1.0,
1358 .maxLod = 1.0,
1359 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1360 };
1361 VkSampler sampler;
1362 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1363 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001364
1365 VkDescriptorInfo descriptor_info;
1366 memset(&descriptor_info, 0, sizeof(descriptor_info));
1367 descriptor_info.sampler = sampler;
1368
1369 VkWriteDescriptorSet descriptor_write;
1370 memset(&descriptor_write, 0, sizeof(descriptor_write));
1371 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1372 descriptor_write.destSet = descriptorSet;
1373 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1374 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001375 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001376 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1377 descriptor_write.pDescriptors = &descriptor_info;
1378
1379 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1380
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001381 msgFlags = m_errorMonitor->GetState(&msgString);
1382 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 +08001383 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1384 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 -06001385 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001386}
1387
1388TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1389{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001390 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001391 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001392 std::string msgString;
1393 VkResult err;
1394
1395 ASSERT_NO_FATAL_FAILURE(InitState());
1396 m_errorMonitor->ClearState();
1397 //VkDescriptorSetObj descriptorSet(m_device);
1398 const VkDescriptorTypeCount ds_type_count = {
1399 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1400 .count = 1,
1401 };
1402 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1403 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1404 .pNext = NULL,
1405 .count = 1,
1406 .pTypeCount = &ds_type_count,
1407 };
1408 VkDescriptorPool ds_pool;
1409 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1410 ASSERT_VK_SUCCESS(err);
1411 const VkDescriptorSetLayoutBinding dsl_binding = {
1412 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001413 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001414 .stageFlags = VK_SHADER_STAGE_ALL,
1415 .pImmutableSamplers = NULL,
1416 };
1417
1418 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1419 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1420 .pNext = NULL,
1421 .count = 1,
1422 .pBinding = &dsl_binding,
1423 };
1424 VkDescriptorSetLayout ds_layout;
1425 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1426 ASSERT_VK_SUCCESS(err);
1427
1428 VkDescriptorSet descriptorSet;
1429 uint32_t ds_count = 0;
1430 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1431 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001432
1433 const VkSamplerCreateInfo sampler_ci = {
1434 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1435 .pNext = NULL,
1436 .magFilter = VK_TEX_FILTER_NEAREST,
1437 .minFilter = VK_TEX_FILTER_NEAREST,
1438 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1439 .addressU = VK_TEX_ADDRESS_CLAMP,
1440 .addressV = VK_TEX_ADDRESS_CLAMP,
1441 .addressW = VK_TEX_ADDRESS_CLAMP,
1442 .mipLodBias = 1.0,
1443 .maxAnisotropy = 1,
1444 .compareOp = VK_COMPARE_OP_NEVER,
1445 .minLod = 1.0,
1446 .maxLod = 1.0,
1447 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1448 };
1449 VkSampler sampler;
1450 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1451 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001452
1453 VkDescriptorInfo descriptor_info;
1454 memset(&descriptor_info, 0, sizeof(descriptor_info));
1455 descriptor_info.sampler = sampler;
1456
1457 VkWriteDescriptorSet descriptor_write;
1458 memset(&descriptor_write, 0, sizeof(descriptor_write));
1459 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1460 descriptor_write.destSet = descriptorSet;
1461 descriptor_write.destBinding = 2;
1462 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001463 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001464 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1465 descriptor_write.pDescriptors = &descriptor_info;
1466
1467 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1468
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001469 msgFlags = m_errorMonitor->GetState(&msgString);
1470 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 -06001471 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1472 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1473 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001474}
1475
1476TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1477{
1478 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001479 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001480 std::string msgString;
1481 VkResult err;
1482
1483 ASSERT_NO_FATAL_FAILURE(InitState());
1484 m_errorMonitor->ClearState();
1485 //VkDescriptorSetObj descriptorSet(m_device);
1486 const VkDescriptorTypeCount ds_type_count = {
1487 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1488 .count = 1,
1489 };
1490 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1491 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1492 .pNext = NULL,
1493 .count = 1,
1494 .pTypeCount = &ds_type_count,
1495 };
1496 VkDescriptorPool ds_pool;
1497 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1498 ASSERT_VK_SUCCESS(err);
1499 const VkDescriptorSetLayoutBinding dsl_binding = {
1500 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001501 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001502 .stageFlags = VK_SHADER_STAGE_ALL,
1503 .pImmutableSamplers = NULL,
1504 };
1505
1506 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1507 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1508 .pNext = NULL,
1509 .count = 1,
1510 .pBinding = &dsl_binding,
1511 };
1512 VkDescriptorSetLayout ds_layout;
1513 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1514 ASSERT_VK_SUCCESS(err);
1515
1516 VkDescriptorSet descriptorSet;
1517 uint32_t ds_count = 0;
1518 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1519 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001520
1521 const VkSamplerCreateInfo sampler_ci = {
1522 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1523 .pNext = NULL,
1524 .magFilter = VK_TEX_FILTER_NEAREST,
1525 .minFilter = VK_TEX_FILTER_NEAREST,
1526 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1527 .addressU = VK_TEX_ADDRESS_CLAMP,
1528 .addressV = VK_TEX_ADDRESS_CLAMP,
1529 .addressW = VK_TEX_ADDRESS_CLAMP,
1530 .mipLodBias = 1.0,
1531 .maxAnisotropy = 1,
1532 .compareOp = VK_COMPARE_OP_NEVER,
1533 .minLod = 1.0,
1534 .maxLod = 1.0,
1535 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1536 };
1537 VkSampler sampler;
1538 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1539 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001540
1541
1542 VkDescriptorInfo descriptor_info;
1543 memset(&descriptor_info, 0, sizeof(descriptor_info));
1544 descriptor_info.sampler = sampler;
1545
1546 VkWriteDescriptorSet descriptor_write;
1547 memset(&descriptor_write, 0, sizeof(descriptor_write));
1548 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1549 descriptor_write.destSet = descriptorSet;
1550 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001551 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001552 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1553 descriptor_write.pDescriptors = &descriptor_info;
1554
1555 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1556
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001557 msgFlags = m_errorMonitor->GetState(&msgString);
1558 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 -06001559 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1560 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1561 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001562}
1563
1564TEST_F(VkLayerTest, NumSamplesMismatch)
1565{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001566 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001567 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001568 std::string msgString;
1569 VkResult err;
1570
1571 ASSERT_NO_FATAL_FAILURE(InitState());
1572 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1573 m_errorMonitor->ClearState();
1574 VkCommandBufferObj cmdBuffer(m_device);
1575 const VkDescriptorTypeCount ds_type_count = {
1576 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1577 .count = 1,
1578 };
1579 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1580 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1581 .pNext = NULL,
1582 .count = 1,
1583 .pTypeCount = &ds_type_count,
1584 };
1585 VkDescriptorPool ds_pool;
1586 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1587 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001588
1589 const VkDescriptorSetLayoutBinding dsl_binding = {
1590 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001591 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001592 .stageFlags = VK_SHADER_STAGE_ALL,
1593 .pImmutableSamplers = NULL,
1594 };
1595
1596 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1597 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1598 .pNext = NULL,
1599 .count = 1,
1600 .pBinding = &dsl_binding,
1601 };
1602 VkDescriptorSetLayout ds_layout;
1603 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1604 ASSERT_VK_SUCCESS(err);
1605
1606 VkDescriptorSet descriptorSet;
1607 uint32_t ds_count = 0;
1608 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1609 ASSERT_VK_SUCCESS(err);
1610
1611 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1612 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1613 .pNext = NULL,
Tony Barbourd1e95582015-06-03 12:30:49 -06001614 .samples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001615 .multisampleEnable = 1,
1616 .sampleShadingEnable = 0,
1617 .minSampleShading = 1.0,
1618 .sampleMask = 15,
1619 };
1620
1621 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1622 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1623 .pNext = NULL,
1624 .descriptorSetCount = 1,
1625 .pSetLayouts = &ds_layout,
1626 };
1627
1628 VkPipelineLayout pipeline_layout;
1629 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1630 ASSERT_VK_SUCCESS(err);
1631
1632 size_t shader_len = strlen(bindStateVertShaderText);
1633 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1634 void* pCode = malloc(codeSize);
1635
1636 /* try version 0 first: VkShaderStage followed by GLSL */
1637 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1638 ((uint32_t *) pCode)[1] = 0;
1639 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1640 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1641
1642 const VkShaderCreateInfo vs_ci = {
1643 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1644 .pNext = NULL,
1645 .codeSize = codeSize,
1646 .pCode = pCode,
1647 .flags = 0,
1648 };
1649 VkShader vs;
1650 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1651 ASSERT_VK_SUCCESS(err);
1652
1653 const VkPipelineShader vs_pipe_shader = {
1654 .stage = VK_SHADER_STAGE_VERTEX,
1655 .shader = vs,
1656 .linkConstBufferCount = 0,
1657 .pLinkConstBufferInfo = NULL,
1658 .pSpecializationInfo = NULL,
1659 };
1660 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1661 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1662 .pNext = &pipe_ms_state_ci,
1663 .shader = vs_pipe_shader,
1664 };
1665 const VkGraphicsPipelineCreateInfo gp_ci = {
1666 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1667 .pNext = &pipe_vs_ci,
1668 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1669 .layout = pipeline_layout,
1670 };
1671
1672 VkPipeline pipeline;
1673 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1674 ASSERT_VK_SUCCESS(err);
1675
1676 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1677 BeginCommandBuffer(cmdBuffer);
1678 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1679
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001680 msgFlags = m_errorMonitor->GetState(&msgString);
1681 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 -06001682 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1683 FAIL() << "Error received was not 'Num samples mismatch!...'";
1684 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001685}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001686#endif
1687#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001688#if GTEST_IS_THREADSAFE
1689struct thread_data_struct {
1690 VkCmdBuffer cmdBuffer;
1691 VkEvent event;
1692 bool bailout;
1693};
1694
1695extern "C" void *AddToCommandBuffer(void *arg)
1696{
1697 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1698 std::string msgString;
1699
1700 for (int i = 0; i<10000; i++) {
1701 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1702 if (data->bailout) {
1703 break;
1704 }
1705 }
1706 return NULL;
1707}
1708
1709TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1710{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001711 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06001712 std::string msgString;
1713 pthread_t thread;
1714 pthread_attr_t thread_attr;
1715
1716 ASSERT_NO_FATAL_FAILURE(InitState());
1717 ASSERT_NO_FATAL_FAILURE(InitViewport());
1718 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1719
1720 VkCommandBufferObj cmdBuffer(m_device);
1721
1722 m_errorMonitor->ClearState();
1723 pthread_attr_init(&thread_attr);
1724 BeginCommandBuffer(cmdBuffer);
1725
1726 VkEventCreateInfo event_info;
1727 VkEvent event;
1728 VkMemoryRequirements mem_req;
1729 size_t data_size = sizeof(mem_req);
1730 VkResult err;
1731
1732 memset(&event_info, 0, sizeof(event_info));
1733 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1734
1735 err = vkCreateEvent(device(), &event_info, &event);
1736 ASSERT_VK_SUCCESS(err);
1737
1738 err = vkGetObjectInfo(device(), VK_OBJECT_TYPE_EVENT, event, VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS,
1739 &data_size, &mem_req);
1740 ASSERT_VK_SUCCESS(err);
1741
1742 VkMemoryAllocInfo mem_info;
1743 VkDeviceMemory event_mem;
1744
1745 ASSERT_NE(0, mem_req.size) << "vkGetObjectInfo (Event): Failed - expect events to require memory";
1746
1747 memset(&mem_info, 0, sizeof(mem_info));
1748 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1749 mem_info.allocationSize = mem_req.size;
1750 mem_info.memProps = VK_MEMORY_PROPERTY_SHAREABLE_BIT;
Mike Stroyan09aae812015-05-12 16:00:45 -06001751 err = vkAllocMemory(device(), &mem_info, &event_mem);
1752 ASSERT_VK_SUCCESS(err);
1753
Mark Lobodzinski23182612015-05-29 09:32:35 -05001754 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001755 ASSERT_VK_SUCCESS(err);
1756
1757 err = vkResetEvent(device(), event);
1758 ASSERT_VK_SUCCESS(err);
1759
1760 struct thread_data_struct data;
1761 data.cmdBuffer = cmdBuffer.obj();
1762 data.event = event;
1763 data.bailout = false;
1764 m_errorMonitor->SetBailout(&data.bailout);
1765 // Add many entries to command buffer from another thread.
1766 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1767 // Add many entries to command buffer from this thread at the same time.
1768 AddToCommandBuffer(&data);
1769 pthread_join(thread, NULL);
1770 EndCommandBuffer(cmdBuffer);
1771
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001772 msgFlags = m_errorMonitor->GetState(&msgString);
1773 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 -06001774 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001775 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06001776 }
1777
1778}
1779#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001780#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12001781
1782#if SHADER_CHECKER_TESTS
1783TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
1784{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001785 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12001786 std::string msgString;
1787 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001788 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001789
1790 char const *vsSource =
1791 "#version 140\n"
1792 "#extension GL_ARB_separate_shader_objects: require\n"
1793 "#extension GL_ARB_shading_language_420pack: require\n"
1794 "\n"
1795 "layout(location=0) out float x;\n"
1796 "void main(){\n"
1797 " gl_Position = vec4(1);\n"
1798 " x = 0;\n"
1799 "}\n";
1800 char const *fsSource =
1801 "#version 140\n"
1802 "#extension GL_ARB_separate_shader_objects: require\n"
1803 "#extension GL_ARB_shading_language_420pack: require\n"
1804 "\n"
1805 "layout(location=0) out vec4 color;\n"
1806 "void main(){\n"
1807 " color = vec4(1);\n"
1808 "}\n";
1809
1810 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1811 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1812
1813 VkPipelineObj pipe(m_device);
1814 pipe.AddShader(&vs);
1815 pipe.AddShader(&fs);
1816
1817 VkCommandBufferObj dummyCmd(m_device);
1818 VkDescriptorSetObj descriptorSet(m_device);
1819 descriptorSet.AppendDummy();
1820 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1821
1822 m_errorMonitor->ClearState();
1823 pipe.CreateVKPipeline(descriptorSet);
1824
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001825 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001826
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001827 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12001828 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
1829 FAIL() << "Incorrect warning: " << msgString;
1830 }
1831}
Chris Forbes5af3bf22015-05-25 11:13:08 +12001832
Chris Forbes3c10b852015-05-25 11:13:13 +12001833TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
1834{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001835 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12001836 std::string msgString;
1837 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001838 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12001839
1840 char const *vsSource =
1841 "#version 140\n"
1842 "#extension GL_ARB_separate_shader_objects: require\n"
1843 "#extension GL_ARB_shading_language_420pack: require\n"
1844 "\n"
1845 "void main(){\n"
1846 " gl_Position = vec4(1);\n"
1847 "}\n";
1848 char const *fsSource =
1849 "#version 140\n"
1850 "#extension GL_ARB_separate_shader_objects: require\n"
1851 "#extension GL_ARB_shading_language_420pack: require\n"
1852 "\n"
1853 "layout(location=0) in float x;\n"
1854 "layout(location=0) out vec4 color;\n"
1855 "void main(){\n"
1856 " color = vec4(x);\n"
1857 "}\n";
1858
1859 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1860 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1861
1862 VkPipelineObj pipe(m_device);
1863 pipe.AddShader(&vs);
1864 pipe.AddShader(&fs);
1865
1866 VkCommandBufferObj dummyCmd(m_device);
1867 VkDescriptorSetObj descriptorSet(m_device);
1868 descriptorSet.AppendDummy();
1869 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1870
1871 m_errorMonitor->ClearState();
1872 pipe.CreateVKPipeline(descriptorSet);
1873
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001874 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12001875
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001876 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12001877 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
1878 FAIL() << "Incorrect error: " << msgString;
1879 }
1880}
1881
Chris Forbescc281692015-05-25 11:13:17 +12001882TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
1883{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001884 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12001885 std::string msgString;
1886 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001887 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12001888
1889 char const *vsSource =
1890 "#version 140\n"
1891 "#extension GL_ARB_separate_shader_objects: require\n"
1892 "#extension GL_ARB_shading_language_420pack: require\n"
1893 "\n"
1894 "layout(location=0) out int x;\n"
1895 "void main(){\n"
1896 " x = 0;\n"
1897 " gl_Position = vec4(1);\n"
1898 "}\n";
1899 char const *fsSource =
1900 "#version 140\n"
1901 "#extension GL_ARB_separate_shader_objects: require\n"
1902 "#extension GL_ARB_shading_language_420pack: require\n"
1903 "\n"
1904 "layout(location=0) in float x;\n" /* VS writes int */
1905 "layout(location=0) out vec4 color;\n"
1906 "void main(){\n"
1907 " color = vec4(x);\n"
1908 "}\n";
1909
1910 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1911 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1912
1913 VkPipelineObj pipe(m_device);
1914 pipe.AddShader(&vs);
1915 pipe.AddShader(&fs);
1916
1917 VkCommandBufferObj dummyCmd(m_device);
1918 VkDescriptorSetObj descriptorSet(m_device);
1919 descriptorSet.AppendDummy();
1920 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1921
1922 m_errorMonitor->ClearState();
1923 pipe.CreateVKPipeline(descriptorSet);
1924
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001925 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12001926
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001927 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12001928 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
1929 FAIL() << "Incorrect error: " << msgString;
1930 }
1931}
1932
Chris Forbes8291c052015-05-25 11:13:28 +12001933TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
1934{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001935 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12001936 std::string msgString;
1937 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001938 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12001939
1940 VkVertexInputBindingDescription input_binding;
1941 memset(&input_binding, 0, sizeof(input_binding));
1942
1943 VkVertexInputAttributeDescription input_attrib;
1944 memset(&input_attrib, 0, sizeof(input_attrib));
1945 input_attrib.format = VK_FORMAT_R32_SFLOAT;
1946
1947 char const *vsSource =
1948 "#version 140\n"
1949 "#extension GL_ARB_separate_shader_objects: require\n"
1950 "#extension GL_ARB_shading_language_420pack: require\n"
1951 "\n"
1952 "void main(){\n"
1953 " gl_Position = vec4(1);\n"
1954 "}\n";
1955 char const *fsSource =
1956 "#version 140\n"
1957 "#extension GL_ARB_separate_shader_objects: require\n"
1958 "#extension GL_ARB_shading_language_420pack: require\n"
1959 "\n"
1960 "layout(location=0) out vec4 color;\n"
1961 "void main(){\n"
1962 " color = vec4(1);\n"
1963 "}\n";
1964
1965 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
1966 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
1967
1968 VkPipelineObj pipe(m_device);
1969 pipe.AddShader(&vs);
1970 pipe.AddShader(&fs);
1971
1972 pipe.AddVertexInputBindings(&input_binding, 1);
1973 pipe.AddVertexInputAttribs(&input_attrib, 1);
1974
1975 VkCommandBufferObj dummyCmd(m_device);
1976 VkDescriptorSetObj descriptorSet(m_device);
1977 descriptorSet.AppendDummy();
1978 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
1979
1980 m_errorMonitor->ClearState();
1981 pipe.CreateVKPipeline(descriptorSet);
1982
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001983 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes8291c052015-05-25 11:13:28 +12001984
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001985 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12001986 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
1987 FAIL() << "Incorrect warning: " << msgString;
1988 }
1989}
1990
Chris Forbes37367e62015-05-25 11:13:29 +12001991TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
1992{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001993 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12001994 std::string msgString;
1995 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06001996 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12001997
1998 char const *vsSource =
1999 "#version 140\n"
2000 "#extension GL_ARB_separate_shader_objects: require\n"
2001 "#extension GL_ARB_shading_language_420pack: require\n"
2002 "\n"
2003 "layout(location=0) in vec4 x;\n" /* not provided */
2004 "void main(){\n"
2005 " gl_Position = x;\n"
2006 "}\n";
2007 char const *fsSource =
2008 "#version 140\n"
2009 "#extension GL_ARB_separate_shader_objects: require\n"
2010 "#extension GL_ARB_shading_language_420pack: require\n"
2011 "\n"
2012 "layout(location=0) out vec4 color;\n"
2013 "void main(){\n"
2014 " color = vec4(1);\n"
2015 "}\n";
2016
2017 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2018 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2019
2020 VkPipelineObj pipe(m_device);
2021 pipe.AddShader(&vs);
2022 pipe.AddShader(&fs);
2023
2024 VkCommandBufferObj dummyCmd(m_device);
2025 VkDescriptorSetObj descriptorSet(m_device);
2026 descriptorSet.AppendDummy();
2027 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2028
2029 m_errorMonitor->ClearState();
2030 pipe.CreateVKPipeline(descriptorSet);
2031
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002032 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002033
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002034 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002035 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2036 FAIL() << "Incorrect warning: " << msgString;
2037 }
2038}
2039
Chris Forbesa4b02322015-05-25 11:13:31 +12002040TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2041{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002042 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002043 std::string msgString;
2044 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002045 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002046
2047 VkVertexInputBindingDescription input_binding;
2048 memset(&input_binding, 0, sizeof(input_binding));
2049
2050 VkVertexInputAttributeDescription input_attrib;
2051 memset(&input_attrib, 0, sizeof(input_attrib));
2052 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2053
2054 char const *vsSource =
2055 "#version 140\n"
2056 "#extension GL_ARB_separate_shader_objects: require\n"
2057 "#extension GL_ARB_shading_language_420pack: require\n"
2058 "\n"
2059 "layout(location=0) in int x;\n" /* attrib provided float */
2060 "void main(){\n"
2061 " gl_Position = vec4(x);\n"
2062 "}\n";
2063 char const *fsSource =
2064 "#version 140\n"
2065 "#extension GL_ARB_separate_shader_objects: require\n"
2066 "#extension GL_ARB_shading_language_420pack: require\n"
2067 "\n"
2068 "layout(location=0) out vec4 color;\n"
2069 "void main(){\n"
2070 " color = vec4(1);\n"
2071 "}\n";
2072
2073 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2074 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2075
2076 VkPipelineObj pipe(m_device);
2077 pipe.AddShader(&vs);
2078 pipe.AddShader(&fs);
2079
2080 pipe.AddVertexInputBindings(&input_binding, 1);
2081 pipe.AddVertexInputAttribs(&input_attrib, 1);
2082
2083 VkCommandBufferObj dummyCmd(m_device);
2084 VkDescriptorSetObj descriptorSet(m_device);
2085 descriptorSet.AppendDummy();
2086 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2087
2088 m_errorMonitor->ClearState();
2089 pipe.CreateVKPipeline(descriptorSet);
2090
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002091 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002092
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002093 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002094 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2095 FAIL() << "Incorrect error: " << msgString;
2096 }
2097}
2098
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002099TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2100{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002101 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002102 std::string msgString;
2103 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002104 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002105
2106 /* Two binding descriptions for binding 0 */
2107 VkVertexInputBindingDescription input_bindings[2];
2108 memset(input_bindings, 0, sizeof(input_bindings));
2109
2110 VkVertexInputAttributeDescription input_attrib;
2111 memset(&input_attrib, 0, sizeof(input_attrib));
2112 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2113
2114 char const *vsSource =
2115 "#version 140\n"
2116 "#extension GL_ARB_separate_shader_objects: require\n"
2117 "#extension GL_ARB_shading_language_420pack: require\n"
2118 "\n"
2119 "layout(location=0) in float x;\n" /* attrib provided float */
2120 "void main(){\n"
2121 " gl_Position = vec4(x);\n"
2122 "}\n";
2123 char const *fsSource =
2124 "#version 140\n"
2125 "#extension GL_ARB_separate_shader_objects: require\n"
2126 "#extension GL_ARB_shading_language_420pack: require\n"
2127 "\n"
2128 "layout(location=0) out vec4 color;\n"
2129 "void main(){\n"
2130 " color = vec4(1);\n"
2131 "}\n";
2132
2133 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2134 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2135
2136 VkPipelineObj pipe(m_device);
2137 pipe.AddShader(&vs);
2138 pipe.AddShader(&fs);
2139
2140 pipe.AddVertexInputBindings(input_bindings, 2);
2141 pipe.AddVertexInputAttribs(&input_attrib, 1);
2142
2143 VkCommandBufferObj dummyCmd(m_device);
2144 VkDescriptorSetObj descriptorSet(m_device);
2145 descriptorSet.AppendDummy();
2146 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2147
2148 m_errorMonitor->ClearState();
2149 pipe.CreateVKPipeline(descriptorSet);
2150
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002151 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002152
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002153 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002154 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2155 FAIL() << "Incorrect error: " << msgString;
2156 }
2157}
Chris Forbes4c948702015-05-25 11:13:32 +12002158
Chris Forbesc12ef122015-05-25 11:13:40 +12002159/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2160 * rejects it. */
2161
2162TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2163{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002164 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002165 std::string msgString;
2166 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002167 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002168
2169 char const *vsSource =
2170 "#version 140\n"
2171 "#extension GL_ARB_separate_shader_objects: require\n"
2172 "#extension GL_ARB_shading_language_420pack: require\n"
2173 "\n"
2174 "void main(){\n"
2175 " gl_Position = vec4(1);\n"
2176 "}\n";
2177 char const *fsSource =
2178 "#version 140\n"
2179 "#extension GL_ARB_separate_shader_objects: require\n"
2180 "#extension GL_ARB_shading_language_420pack: require\n"
2181 "\n"
2182 "void main(){\n"
2183 "}\n";
2184
2185 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2186 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2187
2188 VkPipelineObj pipe(m_device);
2189 pipe.AddShader(&vs);
2190 pipe.AddShader(&fs);
2191
2192 /* implicit CB 0 set up by the test framework, not written */
2193
2194 VkCommandBufferObj dummyCmd(m_device);
2195 VkDescriptorSetObj descriptorSet(m_device);
2196 descriptorSet.AppendDummy();
2197 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2198
2199 m_errorMonitor->ClearState();
2200 pipe.CreateVKPipeline(descriptorSet);
2201
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002202 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002203
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002204 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002205 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2206 FAIL() << "Incorrect error: " << msgString;
2207 }
2208}
2209
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002210TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2211{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002212 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002213 std::string msgString;
2214 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002215 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002216
2217 char const *vsSource =
2218 "#version 140\n"
2219 "#extension GL_ARB_separate_shader_objects: require\n"
2220 "#extension GL_ARB_shading_language_420pack: require\n"
2221 "\n"
2222 "void main(){\n"
2223 " gl_Position = vec4(1);\n"
2224 "}\n";
2225 char const *fsSource =
2226 "#version 140\n"
2227 "#extension GL_ARB_separate_shader_objects: require\n"
2228 "#extension GL_ARB_shading_language_420pack: require\n"
2229 "\n"
2230 "layout(location=0) out vec4 x;\n"
2231 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2232 "void main(){\n"
2233 " x = vec4(1);\n"
2234 " y = vec4(1);\n"
2235 "}\n";
2236
2237 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2238 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2239
2240 VkPipelineObj pipe(m_device);
2241 pipe.AddShader(&vs);
2242 pipe.AddShader(&fs);
2243
2244 /* implicit CB 0 set up by the test framework */
2245 /* FS writes CB 1, but we don't configure it */
2246
2247 VkCommandBufferObj dummyCmd(m_device);
2248 VkDescriptorSetObj descriptorSet(m_device);
2249 descriptorSet.AppendDummy();
2250 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2251
2252 m_errorMonitor->ClearState();
2253 pipe.CreateVKPipeline(descriptorSet);
2254
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002255 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002256
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002257 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002258 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2259 FAIL() << "Incorrect warning: " << msgString;
2260 }
2261}
2262
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002263TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2264{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002265 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002266 std::string msgString;
2267 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002268 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002269
2270 char const *vsSource =
2271 "#version 140\n"
2272 "#extension GL_ARB_separate_shader_objects: require\n"
2273 "#extension GL_ARB_shading_language_420pack: require\n"
2274 "\n"
2275 "void main(){\n"
2276 " gl_Position = vec4(1);\n"
2277 "}\n";
2278 char const *fsSource =
2279 "#version 140\n"
2280 "#extension GL_ARB_separate_shader_objects: require\n"
2281 "#extension GL_ARB_shading_language_420pack: require\n"
2282 "\n"
2283 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2284 "void main(){\n"
2285 " x = ivec4(1);\n"
2286 "}\n";
2287
2288 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2289 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2290
2291 VkPipelineObj pipe(m_device);
2292 pipe.AddShader(&vs);
2293 pipe.AddShader(&fs);
2294
2295 /* implicit CB 0 set up by test framework, is UNORM. */
2296
2297 VkCommandBufferObj dummyCmd(m_device);
2298 VkDescriptorSetObj descriptorSet(m_device);
2299 descriptorSet.AppendDummy();
2300 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2301
2302 m_errorMonitor->ClearState();
2303 pipe.CreateVKPipeline(descriptorSet);
2304
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002305 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002306
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002307 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002308 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2309 FAIL() << "Incorrect error: " << msgString;
2310 }
2311}
Chris Forbesc2050732015-06-05 14:43:36 +12002312
2313TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2314{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002315 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002316 std::string msgString;
2317 ASSERT_NO_FATAL_FAILURE(InitState());
2318 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002319 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002320
2321 char const *vsSource =
2322 "#version 140\n"
2323 "#extension GL_ARB_separate_shader_objects: require\n"
2324 "#extension GL_ARB_shading_language_420pack: require\n"
2325 "\n"
2326 "void main(){\n"
2327 " gl_Position = vec4(1);\n"
2328 "}\n";
2329 char const *fsSource =
2330 "#version 140\n"
2331 "#extension GL_ARB_separate_shader_objects: require\n"
2332 "#extension GL_ARB_shading_language_420pack: require\n"
2333 "\n"
2334 "layout(location=0) out vec4 x;\n"
2335 "void main(){\n"
2336 " x = vec4(1);\n"
2337 "}\n";
2338
2339 m_errorMonitor->ClearState();
2340
2341 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2342 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2343
2344
2345 VkPipelineObj pipe(m_device);
2346 pipe.AddShader(&vs);
2347 pipe.AddShader(&fs);
2348
2349 /* implicit CB 0 set up by test framework, is UNORM. */
2350
2351 VkCommandBufferObj dummyCmd(m_device);
2352 VkDescriptorSetObj descriptorSet(m_device);
2353 descriptorSet.AppendDummy();
2354 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2355
2356 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2357 /* pipeline creation should have succeeded */
2358 ASSERT_EQ(VK_SUCCESS, res);
2359
2360 /* should have emitted a warning: the shader is not SPIRV, so we're
2361 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002362 msgFlags = m_errorMonitor->GetState(&msgString);
2363 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002364 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2365 FAIL() << "Incorrect warning: " << msgString;
2366 }
2367}
Chris Forbes01c9db72015-06-04 09:25:25 +12002368#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002369
Tony Barbour30486ea2015-04-07 13:44:53 -06002370int main(int argc, char **argv) {
2371 int result;
2372
2373 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002374 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002375
2376 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2377
2378 result = RUN_ALL_TESTS();
2379
Tony Barbour01999182015-04-09 12:58:51 -06002380 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002381 return result;
2382}