blob: de740d9e26aa93844d5a94bd6e9804224388a8c9 [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"
Tobin Ehlis56d204a2015-07-03 10:15:26 -06005#include "vk_layer_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 */
Mike Stroyaned254572015-06-17 16:32:06 -0600160 // Use Threading layer first to protect others from ThreadCmdBufferCollision test
161 instance_extension_names.push_back("Threading");
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600162 instance_extension_names.push_back("ObjectTracker");
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600163 instance_extension_names.push_back("MemTracker");
Courtney Goeltzenleuchtereb518dc2015-06-13 21:41:00 -0600164 instance_extension_names.push_back("DrawState");
Courtney Goeltzenleuchterde53c5b2015-06-16 15:59:11 -0600165 instance_extension_names.push_back("ShaderChecker");
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600166
Mike Stroyaned254572015-06-17 16:32:06 -0600167 device_extension_names.push_back("Threading");
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600168 device_extension_names.push_back("ObjectTracker");
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600169 device_extension_names.push_back("MemTracker");
Jon Ashburn64716542015-06-15 12:21:02 -0600170 device_extension_names.push_back("DrawState");
Courtney Goeltzenleuchterde53c5b2015-06-16 15:59:11 -0600171 device_extension_names.push_back("ShaderChecker");
Tony Barbour30486ea2015-04-07 13:44:53 -0600172
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600173 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600174 this->app_info.pNext = NULL;
175 this->app_info.pAppName = "layer_tests";
176 this->app_info.appVersion = 1;
177 this->app_info.pEngineName = "unittest";
178 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600179 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600180
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600181 m_errorMonitor = new ErrorMonitor;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600182 InitFramework(instance_extension_names, device_extension_names, myDbgFunc, m_errorMonitor);
Tony Barbour30486ea2015-04-07 13:44:53 -0600183 }
184
185 virtual void TearDown() {
186 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600187 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600188 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600189 }
190};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500191
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600192VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600193{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600194 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600195
196 result = cmdBuffer.BeginCommandBuffer();
197
198 /*
199 * For render test all drawing happens in a single render pass
200 * on a single command buffer.
201 */
Chris Forbesfe133ef2015-06-16 14:05:59 +1200202 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600203 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
204 }
205
206 return result;
207}
208
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600209VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600210{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600211 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600212
Chris Forbesfe133ef2015-06-16 14:05:59 +1200213 if (renderPass()) {
Chia-I Wu88eaa3b2015-06-26 15:34:39 +0800214 cmdBuffer.EndRenderPass();
Chris Forbesfe133ef2015-06-16 14:05:59 +1200215 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600216
217 result = cmdBuffer.EndCommandBuffer();
218
219 return result;
220}
221
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500222void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
223{
224 // Create identity matrix
225 int i;
226 struct vktriangle_vs_uniform data;
227
228 glm::mat4 Projection = glm::mat4(1.0f);
229 glm::mat4 View = glm::mat4(1.0f);
230 glm::mat4 Model = glm::mat4(1.0f);
231 glm::mat4 MVP = Projection * View * Model;
232 const int matrixSize = sizeof(MVP);
233 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
234
235 memcpy(&data.mvp, &MVP[0][0], matrixSize);
236
237 static const Vertex tri_data[] =
238 {
239 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
240 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
241 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
242 };
243
244 for (i=0; i<3; i++) {
245 data.position[i][0] = tri_data[i].posX;
246 data.position[i][1] = tri_data[i].posY;
247 data.position[i][2] = tri_data[i].posZ;
248 data.position[i][3] = tri_data[i].posW;
249 data.color[i][0] = tri_data[i].r;
250 data.color[i][1] = tri_data[i].g;
251 data.color[i][2] = tri_data[i].b;
252 data.color[i][3] = tri_data[i].a;
253 }
254
255 ASSERT_NO_FATAL_FAILURE(InitState());
256 ASSERT_NO_FATAL_FAILURE(InitViewport());
257
258 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
259
260 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
261 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
262
263 VkPipelineObj pipelineobj(m_device);
264 pipelineobj.AddShader(&vs);
265 pipelineobj.AddShader(&ps);
266
267 VkDescriptorSetObj descriptorSet(m_device);
268 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
269
270 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
271 VkCommandBufferObj cmdBuffer(m_device);
272 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
273
274 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
275
276 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
277
278 // render triangle
279 cmdBuffer.Draw(0, 3, 0, 1);
280
281 // finalize recording of the command buffer
282 EndCommandBuffer(cmdBuffer);
283
284 cmdBuffer.QueueCommandBuffer();
285}
286
287void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
288{
289 if (m_depthStencil->Initialized()) {
290 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
291 } else {
292 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
293 }
294
295 cmdBuffer->PrepareAttachments();
296 if ((failMask & BsoFailRaster) != BsoFailRaster) {
297 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
298 }
299 if ((failMask & BsoFailViewport) != BsoFailViewport) {
300 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
301 }
302 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
303 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
304 }
305 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
306 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
307 }
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600308 // Make sure depthWriteEnable is set so that DepthStencil fail test will work correctly
309 VkStencilOpState stencil = {
310 .stencilFailOp = VK_STENCIL_OP_KEEP,
311 .stencilPassOp = VK_STENCIL_OP_KEEP,
312 .stencilDepthFailOp = VK_STENCIL_OP_KEEP,
313 .stencilCompareOp = VK_COMPARE_OP_NEVER
314 };
315 VkPipelineDsStateCreateInfo ds_ci = {
316 .sType = VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO,
317 .pNext = NULL,
318 .format = VK_FORMAT_D24_UNORM_S8_UINT,
319 .depthTestEnable = VK_FALSE,
320 .depthWriteEnable = VK_TRUE,
321 .depthCompareOp = VK_COMPARE_OP_NEVER,
322 .depthBoundsEnable = VK_FALSE,
323 .stencilTestEnable = VK_FALSE,
324 .front = stencil,
325 .back = stencil
326 };
327 pipelineobj.SetDepthStencil(&ds_ci);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500328 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
329 pipelineobj.CreateVKPipeline(descriptorSet);
330 cmdBuffer->BindPipeline(pipelineobj);
331 cmdBuffer->BindDescriptorSet(descriptorSet);
332}
333
334// ********************************************************************************************************************
335// ********************************************************************************************************************
336// ********************************************************************************************************************
337// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600338#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500339TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
340{
341 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600342 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500343 std::string msgString;
344
345 VkFenceCreateInfo fenceInfo = {};
346 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
347 fenceInfo.pNext = NULL;
348 fenceInfo.flags = 0;
349
350 ASSERT_NO_FATAL_FAILURE(InitState());
351 ASSERT_NO_FATAL_FAILURE(InitViewport());
352 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
353
354 VkCommandBufferObj cmdBuffer(m_device);
355 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
356
357 BeginCommandBuffer(cmdBuffer);
358 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
359 EndCommandBuffer(cmdBuffer);
360
361 testFence.init(*m_device, fenceInfo);
362
363 // Bypass framework since it does the waits automatically
364 VkResult err = VK_SUCCESS;
365 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
366 ASSERT_VK_SUCCESS( err );
367
368 m_errorMonitor->ClearState();
369 // Introduce failure by calling begin again before checking fence
370 vkResetCommandBuffer(cmdBuffer.obj());
371
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600372 msgFlags = m_errorMonitor->GetState(&msgString);
373 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 -0500374 if (!strstr(msgString.c_str(),"Resetting CB")) {
375 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
376 }
377}
378
379TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
380{
381 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600382 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500383 std::string msgString;
384
385 VkFenceCreateInfo fenceInfo = {};
386 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
387 fenceInfo.pNext = NULL;
388 fenceInfo.flags = 0;
389
390 ASSERT_NO_FATAL_FAILURE(InitState());
391 ASSERT_NO_FATAL_FAILURE(InitViewport());
392 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
393
394 VkCommandBufferObj cmdBuffer(m_device);
395 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
396
397 BeginCommandBuffer(cmdBuffer);
398 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
399 EndCommandBuffer(cmdBuffer);
400
401 testFence.init(*m_device, fenceInfo);
402
403 // Bypass framework since it does the waits automatically
404 VkResult err = VK_SUCCESS;
405 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
406 ASSERT_VK_SUCCESS( err );
407
408 m_errorMonitor->ClearState();
409 // Introduce failure by calling begin again before checking fence
410 BeginCommandBuffer(cmdBuffer);
411
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600412 msgFlags = m_errorMonitor->GetState(&msgString);
413 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 -0500414 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
415 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
416 }
417}
418
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500419TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
420{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600421 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500422 std::string msgString;
423 VkResult err;
424
425 ASSERT_NO_FATAL_FAILURE(InitState());
426 m_errorMonitor->ClearState();
427
428 // Create an image, allocate memory, free it, and then try to bind it
429 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500430 VkDeviceMemory mem;
431 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500432
433 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
434 const int32_t tex_width = 32;
435 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500436
437 const VkImageCreateInfo image_create_info = {
438 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
439 .pNext = NULL,
440 .imageType = VK_IMAGE_TYPE_2D,
441 .format = tex_format,
442 .extent = { tex_width, tex_height, 1 },
443 .mipLevels = 1,
444 .arraySize = 1,
445 .samples = 1,
446 .tiling = VK_IMAGE_TILING_LINEAR,
447 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
448 .flags = 0,
449 };
450 VkMemoryAllocInfo mem_alloc = {
451 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
452 .pNext = NULL,
453 .allocationSize = 0,
454 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
Mark Lobodzinski72346292015-07-02 16:49:40 -0600455 .memoryTypeIndex = 1,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500456 };
457
458 err = vkCreateImage(m_device->device(), &image_create_info, &image);
459 ASSERT_VK_SUCCESS(err);
460
Tony Barbour426b9052015-06-24 16:06:58 -0600461 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500462 VK_OBJECT_TYPE_IMAGE,
463 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500464 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500465 ASSERT_VK_SUCCESS(err);
466
Mark Lobodzinski23182612015-05-29 09:32:35 -0500467 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500468
469 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500470 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500471 ASSERT_VK_SUCCESS(err);
472
473 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500474 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500475 ASSERT_VK_SUCCESS(err);
476
477 // Map memory as if to initialize the image
478 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500479 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500480
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600481 msgFlags = m_errorMonitor->GetState(&msgString);
482 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 -0500483 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
484 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
485 }
486}
487
488TEST_F(VkLayerTest, BindInvalidMemory)
489{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600490 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500491 std::string msgString;
492 VkResult err;
493
494 ASSERT_NO_FATAL_FAILURE(InitState());
495 m_errorMonitor->ClearState();
496
497 // Create an image, allocate memory, free it, and then try to bind it
498 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500499 VkDeviceMemory mem;
500 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500501
502 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
503 const int32_t tex_width = 32;
504 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500505
506 const VkImageCreateInfo image_create_info = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600507 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
508 .pNext = NULL,
509 .imageType = VK_IMAGE_TYPE_2D,
510 .format = tex_format,
511 .extent = { tex_width, tex_height, 1 },
512 .mipLevels = 1,
513 .arraySize = 1,
514 .samples = 1,
515 .tiling = VK_IMAGE_TILING_LINEAR,
516 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
517 .flags = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500518 };
519 VkMemoryAllocInfo mem_alloc = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600520 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
521 .pNext = NULL,
522 .allocationSize = 0,
523 .memoryTypeIndex = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500524 };
525
526 err = vkCreateImage(m_device->device(), &image_create_info, &image);
527 ASSERT_VK_SUCCESS(err);
528
Tony Barbour426b9052015-06-24 16:06:58 -0600529 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500530 VK_OBJECT_TYPE_IMAGE,
531 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500532 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500533 ASSERT_VK_SUCCESS(err);
534
Mark Lobodzinski23182612015-05-29 09:32:35 -0500535 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500536
Mark Lobodzinski72346292015-07-02 16:49:40 -0600537 err = m_device->gpu().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
538 ASSERT_VK_SUCCESS(err);
539
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500540 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500541 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500542 ASSERT_VK_SUCCESS(err);
543
544 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500545 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500546 ASSERT_VK_SUCCESS(err);
547
548 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500549 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500550 ASSERT_VK_SUCCESS(err);
551
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600552 msgFlags = m_errorMonitor->GetState(&msgString);
553 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 -0500554 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500555 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
556 }
557}
558
559TEST_F(VkLayerTest, FreeBoundMemory)
560{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600561 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500562 std::string msgString;
563 VkResult err;
564
565 ASSERT_NO_FATAL_FAILURE(InitState());
566 m_errorMonitor->ClearState();
567
568 // Create an image, allocate memory, free it, and then try to bind it
569 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500570 VkDeviceMemory mem;
571 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500572
573 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
574 const int32_t tex_width = 32;
575 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500576
577 const VkImageCreateInfo image_create_info = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600578 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
579 .pNext = NULL,
580 .imageType = VK_IMAGE_TYPE_2D,
581 .format = tex_format,
582 .extent = { tex_width, tex_height, 1 },
583 .mipLevels = 1,
584 .arraySize = 1,
585 .samples = 1,
586 .tiling = VK_IMAGE_TILING_LINEAR,
587 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
588 .flags = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500589 };
590 VkMemoryAllocInfo mem_alloc = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600591 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
592 .pNext = NULL,
593 .allocationSize = 0,
594 .memoryTypeIndex = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500595 };
596
597 err = vkCreateImage(m_device->device(), &image_create_info, &image);
598 ASSERT_VK_SUCCESS(err);
599
Tony Barbour426b9052015-06-24 16:06:58 -0600600 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500601 VK_OBJECT_TYPE_IMAGE,
602 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500603 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500604 ASSERT_VK_SUCCESS(err);
605
Mark Lobodzinski23182612015-05-29 09:32:35 -0500606 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500607
Mark Lobodzinski72346292015-07-02 16:49:40 -0600608 err = m_device->gpu().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
609 ASSERT_VK_SUCCESS(err);
610
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500611 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500612 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500613 ASSERT_VK_SUCCESS(err);
614
615 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500616 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500617 ASSERT_VK_SUCCESS(err);
618
619 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500620 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500621 ASSERT_VK_SUCCESS(err);
622
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600623 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter7dc4c8b2015-06-13 21:48:47 -0600624 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 -0500625 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
626 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
627 }
628}
629
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500630TEST_F(VkLayerTest, RebindMemory)
631{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600632 VkFlags msgFlags;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500633 std::string msgString;
634 VkResult err;
635
636 ASSERT_NO_FATAL_FAILURE(InitState());
637 m_errorMonitor->ClearState();
638
639 // Create an image, allocate memory, free it, and then try to bind it
640 VkImage image;
641 VkDeviceMemory mem1;
642 VkDeviceMemory mem2;
643 VkMemoryRequirements mem_reqs;
644
645 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
646 const int32_t tex_width = 32;
647 const int32_t tex_height = 32;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500648
649 const VkImageCreateInfo image_create_info = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600650 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
651 .pNext = NULL,
652 .imageType = VK_IMAGE_TYPE_2D,
653 .format = tex_format,
654 .extent = { tex_width, tex_height, 1 },
655 .mipLevels = 1,
656 .arraySize = 1,
657 .samples = 1,
658 .tiling = VK_IMAGE_TILING_LINEAR,
659 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
660 .flags = 0,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500661 };
662 VkMemoryAllocInfo mem_alloc = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600663 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
664 .pNext = NULL,
665 .allocationSize = 0,
666 .memoryTypeIndex = 0,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500667 };
668
669 err = vkCreateImage(m_device->device(), &image_create_info, &image);
670 ASSERT_VK_SUCCESS(err);
671
Tony Barbour426b9052015-06-24 16:06:58 -0600672 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500673 VK_OBJECT_TYPE_IMAGE,
674 image,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500675 &mem_reqs);
676 ASSERT_VK_SUCCESS(err);
677
678 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski72346292015-07-02 16:49:40 -0600679 err = m_device->gpu().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
680 ASSERT_VK_SUCCESS(err);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500681
682 // allocate 2 memory objects
683 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
684 ASSERT_VK_SUCCESS(err);
685 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
686 ASSERT_VK_SUCCESS(err);
687
688 // Bind first memory object to Image object
689 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
690 ASSERT_VK_SUCCESS(err);
691
692 // Introduce validation failure, try to bind a different memory object to the same image object
693 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
694 ASSERT_VK_SUCCESS(err);
695
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600696 msgFlags = m_errorMonitor->GetState(&msgString);
697 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 -0500698 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
699 FAIL() << "Error received did not match expected message when rebinding memory to an object";
700 }
701}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500702
703TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
704{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600705 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500706 std::string msgString;
707 VkResult err;
708
709 ASSERT_NO_FATAL_FAILURE(InitState());
710 m_errorMonitor->ClearState();
711
712 // Create an image object, allocate memory, destroy the object and then try to bind it
713 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500714 VkDeviceMemory mem;
715 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500716
717 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
718 const int32_t tex_width = 32;
719 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500720
721 const VkImageCreateInfo image_create_info = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600722 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
723 .pNext = NULL,
724 .imageType = VK_IMAGE_TYPE_2D,
725 .format = tex_format,
726 .extent = { tex_width, tex_height, 1 },
727 .mipLevels = 1,
728 .arraySize = 1,
729 .samples = 1,
730 .tiling = VK_IMAGE_TILING_LINEAR,
731 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
732 .flags = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500733 };
734 VkMemoryAllocInfo mem_alloc = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600735 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
736 .pNext = NULL,
737 .allocationSize = 0,
738 .memoryTypeIndex = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500739 };
740
741 err = vkCreateImage(m_device->device(), &image_create_info, &image);
742 ASSERT_VK_SUCCESS(err);
743
Tony Barbour426b9052015-06-24 16:06:58 -0600744 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500745 VK_OBJECT_TYPE_IMAGE,
746 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500747 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500748 ASSERT_VK_SUCCESS(err);
749
Mark Lobodzinski23182612015-05-29 09:32:35 -0500750 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski72346292015-07-02 16:49:40 -0600751 err = m_device->gpu().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
752 ASSERT_VK_SUCCESS(err);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500753
754 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500755 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500756 ASSERT_VK_SUCCESS(err);
757
758 // Introduce validation failure, destroy Image object before binding
759 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
760 ASSERT_VK_SUCCESS(err);
761
762 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500763 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500764 ASSERT_VK_SUCCESS(err);
765
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600766 msgFlags = m_errorMonitor->GetState(&msgString);
767 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 -0500768 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500769 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
770 }
771}
772
Tony Barbour8508b8e2015-04-09 10:48:04 -0600773TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600774{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600775 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600776 VkFlags msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -0600777 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600778
779 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600780 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
781 fenceInfo.pNext = NULL;
782 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600783
Tony Barbour30486ea2015-04-07 13:44:53 -0600784 ASSERT_NO_FATAL_FAILURE(InitState());
785 ASSERT_NO_FATAL_FAILURE(InitViewport());
786 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
787
Tony Barbour01999182015-04-09 12:58:51 -0600788 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600789 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
790
Tony Barbour8508b8e2015-04-09 10:48:04 -0600791 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600792 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600793 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600794
795 testFence.init(*m_device, fenceInfo);
796 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600797 cmdBuffer.QueueCommandBuffer(testFence.obj());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600798 msgFlags = m_errorMonitor->GetState(&msgString);
799 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 -0600800 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500801 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600802 }
803
804}
805
806TEST_F(VkLayerTest, ResetUnsignaledFence)
807{
808 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600809 VkFlags msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600810 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600811 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600812 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
813 fenceInfo.pNext = NULL;
814
Tony Barbour8508b8e2015-04-09 10:48:04 -0600815 ASSERT_NO_FATAL_FAILURE(InitState());
816 testFence.init(*m_device, fenceInfo);
817 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600818 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600819 vkResetFences(m_device->device(), 1, fences);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600820 msgFlags = m_errorMonitor->GetState(&msgString);
821 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 -0600822 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500823 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600824 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600825
826}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600827#endif
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600828#if OBJ_TRACKER_TESTS
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500829TEST_F(VkLayerTest, RasterStateNotBound)
830{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600831 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500832 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600833 ASSERT_NO_FATAL_FAILURE(InitState());
834 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500835 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
836
837 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
838
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600839 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600840 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from Not Binding a Raster State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500841 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
842 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
843 }
844}
845
846TEST_F(VkLayerTest, ViewportStateNotBound)
847{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600848 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500849 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600850 ASSERT_NO_FATAL_FAILURE(InitState());
851 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500852 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
853
854 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
855
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600856 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600857 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from Not Binding a Viewport State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500858 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
859 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
860 }
861}
862
863TEST_F(VkLayerTest, ColorBlendStateNotBound)
864{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600865 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500866 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600867 ASSERT_NO_FATAL_FAILURE(InitState());
868 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500869 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
870
871 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
872
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600873 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600874 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from Not Binding a ColorBlend State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500875 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
876 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
877 }
878}
879
880TEST_F(VkLayerTest, DepthStencilStateNotBound)
881{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600882 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500883 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600884 ASSERT_NO_FATAL_FAILURE(InitState());
885 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500886 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
887
888 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
889
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600890 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600891 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from Not Binding a DepthStencil State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500892 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
893 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
894 }
Tony Barbourdb686622015-05-06 09:35:56 -0600895}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600896#endif
897#if DRAW_STATE_TESTS
Tobin Ehlise4076782015-06-24 15:53:07 -0600898TEST_F(VkLayerTest, BindPipelineNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600899{
900 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600901 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600902 std::string msgString;
903
904 ASSERT_NO_FATAL_FAILURE(InitState());
905 m_errorMonitor->ClearState();
906 VkCommandBufferObj cmdBuffer(m_device);
907 BeginCommandBuffer(cmdBuffer);
908 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
909 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600910 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -0600911 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding pipeline to CmdBuffer w/o active RenderPass";
912 if (!strstr(msgString.c_str(),"Incorrectly binding graphics pipeline ")) {
913 FAIL() << "Error received was not 'Incorrectly binding graphics pipeline (0xbaadb1be) without an active RenderPass'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600914 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600915}
916
917TEST_F(VkLayerTest, InvalidDescriptorPool)
918{
919 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
920 // The DS check for this is after driver has been called to validate DS internal data struct
921 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600922/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600923 std::string msgString;
924 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
925 vkResetDescriptorPool(device(), badPool);
926
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600927 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600928 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from Resetting an invalid DescriptorPool Object";
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600929 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
930 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
931 }*/
932}
933
934TEST_F(VkLayerTest, InvalidDescriptorSet)
935{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600936 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
937 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600938 // Create a valid cmd buffer
939 // call vkCmdBindDescriptorSets w/ false DS
940}
941
942TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
943{
944 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
945 // The DS check for this is after driver has been called to validate DS internal data struct
946}
947
948TEST_F(VkLayerTest, InvalidPipeline)
949{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600950 // 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
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600952 // Create a valid cmd buffer
953 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlise4076782015-06-24 15:53:07 -0600954// VkFlags msgFlags;
955// std::string msgString;
956//
957// ASSERT_NO_FATAL_FAILURE(InitState());
958// m_errorMonitor->ClearState();
959// VkCommandBufferObj cmdBuffer(m_device);
960// BeginCommandBuffer(cmdBuffer);
961// VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
962// vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
963// msgFlags = m_errorMonitor->GetState(&msgString);
964// ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
965// if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
966// FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
967// }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600968}
969
Tobin Ehlis254eca02015-06-25 15:46:59 -0600970TEST_F(VkLayerTest, DescriptorSetNotUpdated)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600971{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600972 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600973 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600974 std::string msgString;
975 VkResult err;
976
977 ASSERT_NO_FATAL_FAILURE(InitState());
978 m_errorMonitor->ClearState();
979 VkCommandBufferObj cmdBuffer(m_device);
980 const VkDescriptorTypeCount ds_type_count = {
981 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
982 .count = 1,
983 };
984 const VkDescriptorPoolCreateInfo ds_pool_ci = {
985 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
986 .pNext = NULL,
987 .count = 1,
988 .pTypeCount = &ds_type_count,
989 };
990 VkDescriptorPool ds_pool;
991 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
992 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600993
994 const VkDescriptorSetLayoutBinding dsl_binding = {
995 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800996 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600997 .stageFlags = VK_SHADER_STAGE_ALL,
998 .pImmutableSamplers = NULL,
999 };
1000
1001 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1002 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1003 .pNext = NULL,
1004 .count = 1,
1005 .pBinding = &dsl_binding,
1006 };
1007 VkDescriptorSetLayout ds_layout;
1008 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1009 ASSERT_VK_SUCCESS(err);
1010
1011 VkDescriptorSet descriptorSet;
1012 uint32_t ds_count = 0;
1013 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1014 ASSERT_VK_SUCCESS(err);
1015
1016 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1017 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1018 .pNext = NULL,
1019 .descriptorSetCount = 1,
1020 .pSetLayouts = &ds_layout,
1021 };
1022
1023 VkPipelineLayout pipeline_layout;
1024 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1025 ASSERT_VK_SUCCESS(err);
1026
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001027 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001028
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001029 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1030 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1031 .pNext = NULL,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001032 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001033 .shader = vs.obj(),
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001034 .linkConstBufferCount = 0,
1035 .pLinkConstBufferInfo = NULL,
1036 .pSpecializationInfo = NULL,
1037 };
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001038 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001039 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1040 .pNext = NULL,
1041 .stageCount = 1,
1042 .pStages = &pipe_vs_ci,
1043 .pVertexInputState = NULL,
1044 .pIaState = NULL,
1045 .pTessState = NULL,
1046 .pVpState = NULL,
1047 .pRsState = NULL,
1048 .pMsState = NULL,
1049 .pDsState = NULL,
1050 .pCbState = NULL,
1051 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1052 .layout = pipeline_layout,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001053 };
1054
1055 VkPipeline pipeline;
1056 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1057 ASSERT_VK_SUCCESS(err);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001058 ASSERT_NO_FATAL_FAILURE(InitState());
1059 ASSERT_NO_FATAL_FAILURE(InitViewport());
1060 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1061 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1062 BeginCommandBuffer(cmdBuffer);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001063 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06001064 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptorSet, 0, NULL);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001065
Tobin Ehlis254eca02015-06-25 15:46:59 -06001066 msgFlags = m_errorMonitor->GetState(&msgString);
1067 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT) << "Did not warn after binding a DescriptorSet that was never updated.";
1068 if (!strstr(msgString.c_str()," bound but it was never updated. ")) {
1069 FAIL() << "Error received was not 'DS <blah> bound but it was never updated. You may want to either update it or not bind it.'";
1070 }
1071}
1072
1073TEST_F(VkLayerTest, NoBeginCmdBuffer)
1074{
1075 VkFlags msgFlags;
1076 std::string msgString;
1077
1078 ASSERT_NO_FATAL_FAILURE(InitState());
1079 m_errorMonitor->ClearState();
1080 VkCommandBufferObj cmdBuffer(m_device);
1081 // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
1082 vkEndCommandBuffer(cmdBuffer.GetBufferHandle());
1083 msgFlags = m_errorMonitor->GetState(&msgString);
1084 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after ending a CmdBuffer w/o calling BeginCommandBuffer()";
1085 if (!strstr(msgString.c_str(),"You must call vkBeginCommandBuffer() before this call to ")) {
1086 FAIL() << "Error received was not 'You must call vkBeginCommandBuffer() before this call to vkEndCommandBuffer()'";
1087 }
1088}
1089
1090TEST_F(VkLayerTest, InvalidPipelineCreateState)
1091{
1092 // Attempt to Create Gfx Pipeline w/o a VS
1093 VkFlags msgFlags;
1094 std::string msgString;
1095 VkResult err;
1096
1097 ASSERT_NO_FATAL_FAILURE(InitState());
1098 m_errorMonitor->ClearState();
1099 VkCommandBufferObj cmdBuffer(m_device);
1100 const VkDescriptorTypeCount ds_type_count = {
1101 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1102 .count = 1,
1103 };
1104 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1105 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1106 .pNext = NULL,
1107 .count = 1,
1108 .pTypeCount = &ds_type_count,
1109 };
1110 VkDescriptorPool ds_pool;
1111 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1112 ASSERT_VK_SUCCESS(err);
1113
1114 const VkDescriptorSetLayoutBinding dsl_binding = {
1115 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1116 .arraySize = 1,
1117 .stageFlags = VK_SHADER_STAGE_ALL,
1118 .pImmutableSamplers = NULL,
1119 };
1120
1121 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1122 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1123 .pNext = NULL,
1124 .count = 1,
1125 .pBinding = &dsl_binding,
1126 };
1127 VkDescriptorSetLayout ds_layout;
1128 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1129 ASSERT_VK_SUCCESS(err);
1130
1131 VkDescriptorSet descriptorSet;
1132 uint32_t ds_count = 0;
1133 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1134 ASSERT_VK_SUCCESS(err);
1135
1136 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1137 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1138 .pNext = NULL,
1139 .descriptorSetCount = 1,
1140 .pSetLayouts = &ds_layout,
1141 };
1142
1143 VkPipelineLayout pipeline_layout;
1144 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1145 ASSERT_VK_SUCCESS(err);
1146
1147 const VkGraphicsPipelineCreateInfo gp_ci = {
1148 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1149 .pNext = NULL,
1150 .stageCount = 0,
1151 .pStages = NULL, // Creating Gfx Pipeline w/o VS is a violation
1152 .pVertexInputState = NULL,
1153 .pIaState = NULL,
1154 .pTessState = NULL,
1155 .pVpState = NULL,
1156 .pRsState = NULL,
1157 .pMsState = NULL,
1158 .pDsState = NULL,
1159 .pCbState = NULL,
1160 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1161 .layout = pipeline_layout,
1162 };
1163
1164 VkPipeline pipeline;
1165 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001166
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001167 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001168 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after creating Gfx Pipeline w/o VS.";
1169 if (!strstr(msgString.c_str(),"Invalid Pipeline CreateInfo State: Vtx Shader required")) {
1170 FAIL() << "Error received was not 'Invalid Pipeline CreateInfo State: Vtx Shader required'";
1171 }
1172}
1173
Tobin Ehlisb8b06b52015-06-25 16:27:19 -06001174TEST_F(VkLayerTest, NullRenderPass)
1175{
1176 // Bind a NULL RenderPass
1177 VkFlags msgFlags;
1178 std::string msgString;
1179
1180 ASSERT_NO_FATAL_FAILURE(InitState());
1181 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1182 m_errorMonitor->ClearState();
1183 VkCommandBufferObj cmdBuffer(m_device);
1184
1185 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1186 BeginCommandBuffer(cmdBuffer);
1187 // Don't care about RenderPass handle b/c error should be flagged before that
1188 vkCmdBeginRenderPass(cmdBuffer.GetBufferHandle(), NULL);
1189
1190 msgFlags = m_errorMonitor->GetState(&msgString);
1191 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding NULL RenderPass.";
1192 if (!strstr(msgString.c_str(),"You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()")) {
1193 FAIL() << "Error received was not 'You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()'";
1194 }
1195}
1196
Tobin Ehlis254eca02015-06-25 15:46:59 -06001197TEST_F(VkLayerTest, RenderPassWithinRenderPass)
1198{
1199 // Bind a BeginRenderPass within an active RenderPass
1200 VkFlags msgFlags;
1201 std::string msgString;
1202
1203 ASSERT_NO_FATAL_FAILURE(InitState());
1204 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1205 m_errorMonitor->ClearState();
1206 VkCommandBufferObj cmdBuffer(m_device);
1207
1208 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1209 BeginCommandBuffer(cmdBuffer);
Tobin Ehlisb8b06b52015-06-25 16:27:19 -06001210 // Just create a dummy Renderpass that's non-NULL so we can get to the proper error
1211 const VkRenderPassBegin rp_begin = {
1212 .renderPass = (VkRenderPass) 0xc001d00d,
1213 .framebuffer = NULL
1214 };
1215 vkCmdBeginRenderPass(cmdBuffer.GetBufferHandle(), &rp_begin);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001216
1217 msgFlags = m_errorMonitor->GetState(&msgString);
1218 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding RenderPass w/i an active RenderPass.";
1219 if (!strstr(msgString.c_str(),"Cannot call vkCmdBeginRenderPass() during an active RenderPass ")) {
1220 FAIL() << "Error received was not 'Cannot call vkCmdBeginRenderPass() during an active RenderPass...'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001221 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001222}
1223
1224TEST_F(VkLayerTest, InvalidDynamicStateObject)
1225{
1226 // Create a valid cmd buffer
1227 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001228 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1229 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001230}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001231
Tobin Ehlise4076782015-06-24 15:53:07 -06001232TEST_F(VkLayerTest, VtxBufferNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001233{
1234 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001235 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001236 std::string msgString;
1237 VkResult err;
1238
1239 ASSERT_NO_FATAL_FAILURE(InitState());
1240 m_errorMonitor->ClearState();
1241 VkCommandBufferObj cmdBuffer(m_device);
1242 const VkDescriptorTypeCount ds_type_count = {
1243 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1244 .count = 1,
1245 };
1246 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1247 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1248 .pNext = NULL,
1249 .count = 1,
1250 .pTypeCount = &ds_type_count,
1251 };
1252 VkDescriptorPool ds_pool;
1253 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1254 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001255
1256 const VkDescriptorSetLayoutBinding dsl_binding = {
1257 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001258 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001259 .stageFlags = VK_SHADER_STAGE_ALL,
1260 .pImmutableSamplers = NULL,
1261 };
1262
1263 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1264 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1265 .pNext = NULL,
1266 .count = 1,
1267 .pBinding = &dsl_binding,
1268 };
1269 VkDescriptorSetLayout ds_layout;
1270 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1271 ASSERT_VK_SUCCESS(err);
1272
1273 VkDescriptorSet descriptorSet;
1274 uint32_t ds_count = 0;
1275 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1276 ASSERT_VK_SUCCESS(err);
1277
1278 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1279 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1280 .pNext = NULL,
1281 .descriptorSetCount = 1,
1282 .pSetLayouts = &ds_layout,
1283 };
1284
1285 VkPipelineLayout pipeline_layout;
1286 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1287 ASSERT_VK_SUCCESS(err);
1288
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001289 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001290
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001291 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1292 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1293 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001294 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001295 .shader = vs.obj(),
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001296 .linkConstBufferCount = 0,
1297 .pLinkConstBufferInfo = NULL,
1298 .pSpecializationInfo = NULL,
1299 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001300 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001301 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1302 .pNext = NULL,
1303 .stageCount = 1,
1304 .pStages = &pipe_vs_ci,
1305 .pVertexInputState = NULL,
1306 .pIaState = NULL,
1307 .pTessState = NULL,
1308 .pVpState = NULL,
1309 .pRsState = NULL,
1310 .pMsState = NULL,
1311 .pDsState = NULL,
1312 .pCbState = NULL,
1313 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1314 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001315 };
1316
1317 VkPipeline pipeline;
1318 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1319 ASSERT_VK_SUCCESS(err);
1320
1321 err= cmdBuffer.BeginCommandBuffer();
1322 ASSERT_VK_SUCCESS(err);
1323 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1324 // Should error before calling to driver so don't care about actual data
1325 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1326
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001327 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -06001328 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o active RenderPass.";
1329 if (!strstr(msgString.c_str(),"Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.")) {
1330 FAIL() << "Error received was not 'Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001331 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001332}
1333
1334TEST_F(VkLayerTest, DSTypeMismatch)
1335{
1336 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001337 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001338 std::string msgString;
1339 VkResult err;
1340
1341 ASSERT_NO_FATAL_FAILURE(InitState());
1342 m_errorMonitor->ClearState();
1343 //VkDescriptorSetObj descriptorSet(m_device);
1344 const VkDescriptorTypeCount ds_type_count = {
1345 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1346 .count = 1,
1347 };
1348 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1349 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1350 .pNext = NULL,
1351 .count = 1,
1352 .pTypeCount = &ds_type_count,
1353 };
1354 VkDescriptorPool ds_pool;
1355 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1356 ASSERT_VK_SUCCESS(err);
1357 const VkDescriptorSetLayoutBinding dsl_binding = {
1358 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001359 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001360 .stageFlags = VK_SHADER_STAGE_ALL,
1361 .pImmutableSamplers = NULL,
1362 };
1363
1364 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1365 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1366 .pNext = NULL,
1367 .count = 1,
1368 .pBinding = &dsl_binding,
1369 };
1370 VkDescriptorSetLayout ds_layout;
1371 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1372 ASSERT_VK_SUCCESS(err);
1373
1374 VkDescriptorSet descriptorSet;
1375 uint32_t ds_count = 0;
1376 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1377 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001378
1379 const VkSamplerCreateInfo sampler_ci = {
1380 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1381 .pNext = NULL,
1382 .magFilter = VK_TEX_FILTER_NEAREST,
1383 .minFilter = VK_TEX_FILTER_NEAREST,
1384 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1385 .addressU = VK_TEX_ADDRESS_CLAMP,
1386 .addressV = VK_TEX_ADDRESS_CLAMP,
1387 .addressW = VK_TEX_ADDRESS_CLAMP,
1388 .mipLodBias = 1.0,
1389 .maxAnisotropy = 1,
1390 .compareOp = VK_COMPARE_OP_NEVER,
1391 .minLod = 1.0,
1392 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001393 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001394 };
1395 VkSampler sampler;
1396 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1397 ASSERT_VK_SUCCESS(err);
1398
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001399 VkDescriptorInfo descriptor_info;
1400 memset(&descriptor_info, 0, sizeof(descriptor_info));
1401 descriptor_info.sampler = sampler;
1402
1403 VkWriteDescriptorSet descriptor_write;
1404 memset(&descriptor_write, 0, sizeof(descriptor_write));
1405 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1406 descriptor_write.destSet = descriptorSet;
1407 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001408 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001409 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1410 descriptor_write.pDescriptors = &descriptor_info;
1411
1412 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1413
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001414 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001415 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 +08001416 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1417 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 -06001418 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001419}
1420
1421TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1422{
1423 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001424 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001425 std::string msgString;
1426 VkResult err;
1427
1428 ASSERT_NO_FATAL_FAILURE(InitState());
1429 m_errorMonitor->ClearState();
1430 //VkDescriptorSetObj descriptorSet(m_device);
1431 const VkDescriptorTypeCount ds_type_count = {
1432 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1433 .count = 1,
1434 };
1435 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1436 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1437 .pNext = NULL,
1438 .count = 1,
1439 .pTypeCount = &ds_type_count,
1440 };
1441 VkDescriptorPool ds_pool;
1442 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1443 ASSERT_VK_SUCCESS(err);
1444 const VkDescriptorSetLayoutBinding dsl_binding = {
1445 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001446 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001447 .stageFlags = VK_SHADER_STAGE_ALL,
1448 .pImmutableSamplers = NULL,
1449 };
1450
1451 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1452 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1453 .pNext = NULL,
1454 .count = 1,
1455 .pBinding = &dsl_binding,
1456 };
1457 VkDescriptorSetLayout ds_layout;
1458 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1459 ASSERT_VK_SUCCESS(err);
1460
1461 VkDescriptorSet descriptorSet;
1462 uint32_t ds_count = 0;
1463 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1464 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001465
1466 const VkSamplerCreateInfo sampler_ci = {
1467 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1468 .pNext = NULL,
1469 .magFilter = VK_TEX_FILTER_NEAREST,
1470 .minFilter = VK_TEX_FILTER_NEAREST,
1471 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1472 .addressU = VK_TEX_ADDRESS_CLAMP,
1473 .addressV = VK_TEX_ADDRESS_CLAMP,
1474 .addressW = VK_TEX_ADDRESS_CLAMP,
1475 .mipLodBias = 1.0,
1476 .maxAnisotropy = 1,
1477 .compareOp = VK_COMPARE_OP_NEVER,
1478 .minLod = 1.0,
1479 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001480 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001481 };
1482 VkSampler sampler;
1483 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1484 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001485
1486 VkDescriptorInfo descriptor_info;
1487 memset(&descriptor_info, 0, sizeof(descriptor_info));
1488 descriptor_info.sampler = sampler;
1489
1490 VkWriteDescriptorSet descriptor_write;
1491 memset(&descriptor_write, 0, sizeof(descriptor_write));
1492 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1493 descriptor_write.destSet = descriptorSet;
1494 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1495 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001496 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001497 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1498 descriptor_write.pDescriptors = &descriptor_info;
1499
1500 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1501
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001502 msgFlags = m_errorMonitor->GetState(&msgString);
1503 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 +08001504 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1505 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 -06001506 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001507}
1508
1509TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1510{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001511 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001512 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001513 std::string msgString;
1514 VkResult err;
1515
1516 ASSERT_NO_FATAL_FAILURE(InitState());
1517 m_errorMonitor->ClearState();
1518 //VkDescriptorSetObj descriptorSet(m_device);
1519 const VkDescriptorTypeCount ds_type_count = {
1520 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1521 .count = 1,
1522 };
1523 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1524 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1525 .pNext = NULL,
1526 .count = 1,
1527 .pTypeCount = &ds_type_count,
1528 };
1529 VkDescriptorPool ds_pool;
1530 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1531 ASSERT_VK_SUCCESS(err);
1532 const VkDescriptorSetLayoutBinding dsl_binding = {
1533 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001534 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001535 .stageFlags = VK_SHADER_STAGE_ALL,
1536 .pImmutableSamplers = NULL,
1537 };
1538
1539 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1540 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1541 .pNext = NULL,
1542 .count = 1,
1543 .pBinding = &dsl_binding,
1544 };
1545 VkDescriptorSetLayout ds_layout;
1546 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1547 ASSERT_VK_SUCCESS(err);
1548
1549 VkDescriptorSet descriptorSet;
1550 uint32_t ds_count = 0;
1551 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1552 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001553
1554 const VkSamplerCreateInfo sampler_ci = {
1555 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1556 .pNext = NULL,
1557 .magFilter = VK_TEX_FILTER_NEAREST,
1558 .minFilter = VK_TEX_FILTER_NEAREST,
1559 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1560 .addressU = VK_TEX_ADDRESS_CLAMP,
1561 .addressV = VK_TEX_ADDRESS_CLAMP,
1562 .addressW = VK_TEX_ADDRESS_CLAMP,
1563 .mipLodBias = 1.0,
1564 .maxAnisotropy = 1,
1565 .compareOp = VK_COMPARE_OP_NEVER,
1566 .minLod = 1.0,
1567 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001568 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001569 };
1570 VkSampler sampler;
1571 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1572 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001573
1574 VkDescriptorInfo descriptor_info;
1575 memset(&descriptor_info, 0, sizeof(descriptor_info));
1576 descriptor_info.sampler = sampler;
1577
1578 VkWriteDescriptorSet descriptor_write;
1579 memset(&descriptor_write, 0, sizeof(descriptor_write));
1580 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1581 descriptor_write.destSet = descriptorSet;
1582 descriptor_write.destBinding = 2;
1583 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001584 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001585 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1586 descriptor_write.pDescriptors = &descriptor_info;
1587
1588 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1589
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001590 msgFlags = m_errorMonitor->GetState(&msgString);
1591 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 -06001592 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1593 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1594 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001595}
1596
1597TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1598{
1599 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001600 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001601 std::string msgString;
1602 VkResult err;
1603
1604 ASSERT_NO_FATAL_FAILURE(InitState());
1605 m_errorMonitor->ClearState();
1606 //VkDescriptorSetObj descriptorSet(m_device);
1607 const VkDescriptorTypeCount ds_type_count = {
1608 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1609 .count = 1,
1610 };
1611 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1612 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1613 .pNext = NULL,
1614 .count = 1,
1615 .pTypeCount = &ds_type_count,
1616 };
1617 VkDescriptorPool ds_pool;
1618 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1619 ASSERT_VK_SUCCESS(err);
1620 const VkDescriptorSetLayoutBinding dsl_binding = {
1621 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001622 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001623 .stageFlags = VK_SHADER_STAGE_ALL,
1624 .pImmutableSamplers = NULL,
1625 };
1626
1627 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1628 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1629 .pNext = NULL,
1630 .count = 1,
1631 .pBinding = &dsl_binding,
1632 };
1633 VkDescriptorSetLayout ds_layout;
1634 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1635 ASSERT_VK_SUCCESS(err);
1636
1637 VkDescriptorSet descriptorSet;
1638 uint32_t ds_count = 0;
1639 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1640 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001641
1642 const VkSamplerCreateInfo sampler_ci = {
1643 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1644 .pNext = NULL,
1645 .magFilter = VK_TEX_FILTER_NEAREST,
1646 .minFilter = VK_TEX_FILTER_NEAREST,
1647 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1648 .addressU = VK_TEX_ADDRESS_CLAMP,
1649 .addressV = VK_TEX_ADDRESS_CLAMP,
1650 .addressW = VK_TEX_ADDRESS_CLAMP,
1651 .mipLodBias = 1.0,
1652 .maxAnisotropy = 1,
1653 .compareOp = VK_COMPARE_OP_NEVER,
1654 .minLod = 1.0,
1655 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001656 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001657 };
1658 VkSampler sampler;
1659 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1660 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001661
1662
1663 VkDescriptorInfo descriptor_info;
1664 memset(&descriptor_info, 0, sizeof(descriptor_info));
1665 descriptor_info.sampler = sampler;
1666
1667 VkWriteDescriptorSet descriptor_write;
1668 memset(&descriptor_write, 0, sizeof(descriptor_write));
1669 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1670 descriptor_write.destSet = descriptorSet;
1671 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001672 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001673 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1674 descriptor_write.pDescriptors = &descriptor_info;
1675
1676 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1677
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001678 msgFlags = m_errorMonitor->GetState(&msgString);
1679 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ invalid struct type.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001680 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1681 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1682 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001683}
1684
1685TEST_F(VkLayerTest, NumSamplesMismatch)
1686{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001687 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001688 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001689 std::string msgString;
1690 VkResult err;
1691
1692 ASSERT_NO_FATAL_FAILURE(InitState());
1693 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1694 m_errorMonitor->ClearState();
1695 VkCommandBufferObj cmdBuffer(m_device);
1696 const VkDescriptorTypeCount ds_type_count = {
1697 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1698 .count = 1,
1699 };
1700 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1701 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1702 .pNext = NULL,
1703 .count = 1,
1704 .pTypeCount = &ds_type_count,
1705 };
1706 VkDescriptorPool ds_pool;
1707 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1708 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001709
1710 const VkDescriptorSetLayoutBinding dsl_binding = {
1711 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001712 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001713 .stageFlags = VK_SHADER_STAGE_ALL,
1714 .pImmutableSamplers = NULL,
1715 };
1716
1717 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1718 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1719 .pNext = NULL,
1720 .count = 1,
1721 .pBinding = &dsl_binding,
1722 };
1723 VkDescriptorSetLayout ds_layout;
1724 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1725 ASSERT_VK_SUCCESS(err);
1726
1727 VkDescriptorSet descriptorSet;
1728 uint32_t ds_count = 0;
1729 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1730 ASSERT_VK_SUCCESS(err);
1731
1732 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1733 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1734 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001735 .rasterSamples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001736 .multisampleEnable = 1,
1737 .sampleShadingEnable = 0,
1738 .minSampleShading = 1.0,
1739 .sampleMask = 15,
1740 };
1741
1742 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1743 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1744 .pNext = NULL,
1745 .descriptorSetCount = 1,
1746 .pSetLayouts = &ds_layout,
1747 };
1748
1749 VkPipelineLayout pipeline_layout;
1750 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1751 ASSERT_VK_SUCCESS(err);
1752
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001753 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001754
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001755 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1756 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1757 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001758 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001759 .shader = vs.obj(),
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001760 .linkConstBufferCount = 0,
1761 .pLinkConstBufferInfo = NULL,
1762 .pSpecializationInfo = NULL,
1763 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001764 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001765 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1766 .pNext = NULL,
1767 .stageCount = 1,
1768 .pStages = &pipe_vs_ci,
1769 .pVertexInputState = NULL,
1770 .pIaState = NULL,
1771 .pTessState = NULL,
1772 .pVpState = NULL,
1773 .pRsState = NULL,
1774 .pMsState = &pipe_ms_state_ci,
1775 .pDsState = NULL,
1776 .pCbState = NULL,
1777 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1778 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001779 };
1780
1781 VkPipeline pipeline;
1782 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1783 ASSERT_VK_SUCCESS(err);
1784
1785 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1786 BeginCommandBuffer(cmdBuffer);
1787 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1788
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001789 msgFlags = m_errorMonitor->GetState(&msgString);
1790 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 -06001791 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1792 FAIL() << "Error received was not 'Num samples mismatch!...'";
1793 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001794}
Tobin Ehlise4076782015-06-24 15:53:07 -06001795TEST_F(VkLayerTest, PipelineNotBound)
1796{
1797 VkFlags msgFlags;
1798 std::string msgString;
1799 VkResult err;
1800
1801 ASSERT_NO_FATAL_FAILURE(InitState());
1802 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1803 m_errorMonitor->ClearState();
1804 VkCommandBufferObj cmdBuffer(m_device);
1805 const VkDescriptorTypeCount ds_type_count = {
1806 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1807 .count = 1,
1808 };
1809 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1810 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1811 .pNext = NULL,
1812 .count = 1,
1813 .pTypeCount = &ds_type_count,
1814 };
1815 VkDescriptorPool ds_pool;
1816 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1817 ASSERT_VK_SUCCESS(err);
1818
1819 const VkDescriptorSetLayoutBinding dsl_binding = {
1820 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1821 .arraySize = 1,
1822 .stageFlags = VK_SHADER_STAGE_ALL,
1823 .pImmutableSamplers = NULL,
1824 };
1825
1826 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1827 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1828 .pNext = NULL,
1829 .count = 1,
1830 .pBinding = &dsl_binding,
1831 };
1832 VkDescriptorSetLayout ds_layout;
1833 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1834 ASSERT_VK_SUCCESS(err);
1835
1836 VkDescriptorSet descriptorSet;
1837 uint32_t ds_count = 0;
1838 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1839 ASSERT_VK_SUCCESS(err);
1840
1841 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1842 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1843 .pNext = NULL,
1844 .descriptorSetCount = 1,
1845 .pSetLayouts = &ds_layout,
1846 };
1847
1848 VkPipelineLayout pipeline_layout;
1849 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1850 ASSERT_VK_SUCCESS(err);
1851
Tobin Ehlise4076782015-06-24 15:53:07 -06001852 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
1853 //err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1854 ASSERT_VK_SUCCESS(err);
1855
1856 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1857 BeginCommandBuffer(cmdBuffer);
1858 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
1859
1860 msgFlags = m_errorMonitor->GetState(&msgString);
1861 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
1862 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
1863 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
1864 }
1865}
1866TEST_F(VkLayerTest, VtxBufferBadIndex)
1867{
1868 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1869 VkFlags msgFlags;
1870 std::string msgString;
1871 VkResult err;
1872
1873 ASSERT_NO_FATAL_FAILURE(InitState());
1874 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1875 m_errorMonitor->ClearState();
1876 VkCommandBufferObj cmdBuffer(m_device);
1877 const VkDescriptorTypeCount ds_type_count = {
1878 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1879 .count = 1,
1880 };
1881 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1882 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1883 .pNext = NULL,
1884 .count = 1,
1885 .pTypeCount = &ds_type_count,
1886 };
1887 VkDescriptorPool ds_pool;
1888 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1889 ASSERT_VK_SUCCESS(err);
1890
1891 const VkDescriptorSetLayoutBinding dsl_binding = {
1892 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1893 .arraySize = 1,
1894 .stageFlags = VK_SHADER_STAGE_ALL,
1895 .pImmutableSamplers = NULL,
1896 };
1897
1898 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1899 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1900 .pNext = NULL,
1901 .count = 1,
1902 .pBinding = &dsl_binding,
1903 };
1904 VkDescriptorSetLayout ds_layout;
1905 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1906 ASSERT_VK_SUCCESS(err);
1907
1908 VkDescriptorSet descriptorSet;
1909 uint32_t ds_count = 0;
1910 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1911 ASSERT_VK_SUCCESS(err);
1912
1913 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1914 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1915 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001916 .rasterSamples = 1,
Tobin Ehlise4076782015-06-24 15:53:07 -06001917 .multisampleEnable = 1,
1918 .sampleShadingEnable = 0,
1919 .minSampleShading = 1.0,
1920 .sampleMask = 15,
1921 };
1922
1923 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1924 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1925 .pNext = NULL,
1926 .descriptorSetCount = 1,
1927 .pSetLayouts = &ds_layout,
1928 };
1929
1930 VkPipelineLayout pipeline_layout;
1931 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1932 ASSERT_VK_SUCCESS(err);
1933
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001934 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlise4076782015-06-24 15:53:07 -06001935
1936 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1937 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1938 .pNext = NULL,
1939 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001940 .shader = vs.obj(),
Tobin Ehlise4076782015-06-24 15:53:07 -06001941 .linkConstBufferCount = 0,
1942 .pLinkConstBufferInfo = NULL,
1943 .pSpecializationInfo = NULL,
1944 };
1945 const VkGraphicsPipelineCreateInfo gp_ci = {
1946 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1947 .pNext = NULL,
1948 .stageCount = 1,
1949 .pStages = &pipe_vs_ci,
1950 .pVertexInputState = NULL,
1951 .pIaState = NULL,
1952 .pTessState = NULL,
1953 .pVpState = NULL,
1954 .pRsState = NULL,
1955 .pMsState = &pipe_ms_state_ci,
1956 .pDsState = NULL,
1957 .pCbState = NULL,
1958 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1959 .layout = pipeline_layout,
1960 };
1961
1962 VkPipeline pipeline;
1963 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1964 ASSERT_VK_SUCCESS(err);
1965
1966 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1967 BeginCommandBuffer(cmdBuffer);
1968 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1969 // Should error before calling to driver so don't care about actual data
1970 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1971
1972 msgFlags = m_errorMonitor->GetState(&msgString);
1973 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding Vtx Buffer w/o VBO attached to PSO.";
1974 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1975 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1976 }
1977}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001978#endif
1979#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001980#if GTEST_IS_THREADSAFE
1981struct thread_data_struct {
1982 VkCmdBuffer cmdBuffer;
1983 VkEvent event;
1984 bool bailout;
1985};
1986
1987extern "C" void *AddToCommandBuffer(void *arg)
1988{
1989 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1990 std::string msgString;
1991
1992 for (int i = 0; i<10000; i++) {
Tony Barbourc2e987e2015-06-29 16:20:35 -06001993 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPELINE_STAGE_ALL_GPU_COMMANDS);
Mike Stroyan09aae812015-05-12 16:00:45 -06001994 if (data->bailout) {
1995 break;
1996 }
1997 }
1998 return NULL;
1999}
2000
2001TEST_F(VkLayerTest, ThreadCmdBufferCollision)
2002{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002003 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06002004 std::string msgString;
2005 pthread_t thread;
2006 pthread_attr_t thread_attr;
2007
2008 ASSERT_NO_FATAL_FAILURE(InitState());
2009 ASSERT_NO_FATAL_FAILURE(InitViewport());
2010 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2011
2012 VkCommandBufferObj cmdBuffer(m_device);
2013
2014 m_errorMonitor->ClearState();
2015 pthread_attr_init(&thread_attr);
2016 BeginCommandBuffer(cmdBuffer);
2017
2018 VkEventCreateInfo event_info;
2019 VkEvent event;
2020 VkMemoryRequirements mem_req;
Mike Stroyan09aae812015-05-12 16:00:45 -06002021 VkResult err;
2022
2023 memset(&event_info, 0, sizeof(event_info));
2024 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2025
2026 err = vkCreateEvent(device(), &event_info, &event);
2027 ASSERT_VK_SUCCESS(err);
2028
Tony Barbour426b9052015-06-24 16:06:58 -06002029 err = vkGetObjectMemoryRequirements(device(), VK_OBJECT_TYPE_EVENT, event, &mem_req);
Mike Stroyan09aae812015-05-12 16:00:45 -06002030 ASSERT_VK_SUCCESS(err);
2031
2032 VkMemoryAllocInfo mem_info;
2033 VkDeviceMemory event_mem;
2034
Mike Stroyan09aae812015-05-12 16:00:45 -06002035 memset(&mem_info, 0, sizeof(mem_info));
2036 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
2037 mem_info.allocationSize = mem_req.size;
Mark Lobodzinski72346292015-07-02 16:49:40 -06002038 mem_info.memoryTypeIndex = 0;
2039
2040 err = m_device->gpu().set_memory_type(mem_req.memoryTypeBits, &mem_info, 0);
2041 ASSERT_VK_SUCCESS(err);
2042
Mike Stroyan09aae812015-05-12 16:00:45 -06002043 err = vkAllocMemory(device(), &mem_info, &event_mem);
2044 ASSERT_VK_SUCCESS(err);
2045
Mark Lobodzinski23182612015-05-29 09:32:35 -05002046 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06002047 ASSERT_VK_SUCCESS(err);
2048
2049 err = vkResetEvent(device(), event);
2050 ASSERT_VK_SUCCESS(err);
2051
2052 struct thread_data_struct data;
2053 data.cmdBuffer = cmdBuffer.obj();
2054 data.event = event;
2055 data.bailout = false;
2056 m_errorMonitor->SetBailout(&data.bailout);
2057 // Add many entries to command buffer from another thread.
2058 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
2059 // Add many entries to command buffer from this thread at the same time.
2060 AddToCommandBuffer(&data);
2061 pthread_join(thread, NULL);
2062 EndCommandBuffer(cmdBuffer);
2063
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002064 msgFlags = m_errorMonitor->GetState(&msgString);
Mike Stroyaned254572015-06-17 16:32:06 -06002065 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an err from using one VkCommandBufferObj in two threads";
Mike Stroyan09aae812015-05-12 16:00:45 -06002066 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05002067 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06002068 }
2069
2070}
2071#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06002072#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12002073#if SHADER_CHECKER_TESTS
2074TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
2075{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002076 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12002077 std::string msgString;
2078 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002079 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002080
2081 char const *vsSource =
2082 "#version 140\n"
2083 "#extension GL_ARB_separate_shader_objects: require\n"
2084 "#extension GL_ARB_shading_language_420pack: require\n"
2085 "\n"
2086 "layout(location=0) out float x;\n"
2087 "void main(){\n"
2088 " gl_Position = vec4(1);\n"
2089 " x = 0;\n"
2090 "}\n";
2091 char const *fsSource =
2092 "#version 140\n"
2093 "#extension GL_ARB_separate_shader_objects: require\n"
2094 "#extension GL_ARB_shading_language_420pack: require\n"
2095 "\n"
2096 "layout(location=0) out vec4 color;\n"
2097 "void main(){\n"
2098 " color = vec4(1);\n"
2099 "}\n";
2100
2101 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2102 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2103
2104 VkPipelineObj pipe(m_device);
2105 pipe.AddShader(&vs);
2106 pipe.AddShader(&fs);
2107
2108 VkCommandBufferObj dummyCmd(m_device);
2109 VkDescriptorSetObj descriptorSet(m_device);
2110 descriptorSet.AppendDummy();
2111 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2112
2113 m_errorMonitor->ClearState();
2114 pipe.CreateVKPipeline(descriptorSet);
2115
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002116 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002117
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002118 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002119 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
2120 FAIL() << "Incorrect warning: " << msgString;
2121 }
2122}
Chris Forbes5af3bf22015-05-25 11:13:08 +12002123
Chris Forbes3c10b852015-05-25 11:13:13 +12002124TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
2125{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002126 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12002127 std::string msgString;
2128 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002129 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12002130
2131 char const *vsSource =
2132 "#version 140\n"
2133 "#extension GL_ARB_separate_shader_objects: require\n"
2134 "#extension GL_ARB_shading_language_420pack: require\n"
2135 "\n"
2136 "void main(){\n"
2137 " gl_Position = vec4(1);\n"
2138 "}\n";
2139 char const *fsSource =
2140 "#version 140\n"
2141 "#extension GL_ARB_separate_shader_objects: require\n"
2142 "#extension GL_ARB_shading_language_420pack: require\n"
2143 "\n"
2144 "layout(location=0) in float x;\n"
2145 "layout(location=0) out vec4 color;\n"
2146 "void main(){\n"
2147 " color = vec4(x);\n"
2148 "}\n";
2149
2150 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2151 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2152
2153 VkPipelineObj pipe(m_device);
2154 pipe.AddShader(&vs);
2155 pipe.AddShader(&fs);
2156
2157 VkCommandBufferObj dummyCmd(m_device);
2158 VkDescriptorSetObj descriptorSet(m_device);
2159 descriptorSet.AppendDummy();
2160 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2161
2162 m_errorMonitor->ClearState();
2163 pipe.CreateVKPipeline(descriptorSet);
2164
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002165 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12002166
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002167 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12002168 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
2169 FAIL() << "Incorrect error: " << msgString;
2170 }
2171}
2172
Chris Forbescc281692015-05-25 11:13:17 +12002173TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
2174{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002175 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12002176 std::string msgString;
2177 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002178 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12002179
2180 char const *vsSource =
2181 "#version 140\n"
2182 "#extension GL_ARB_separate_shader_objects: require\n"
2183 "#extension GL_ARB_shading_language_420pack: require\n"
2184 "\n"
2185 "layout(location=0) out int x;\n"
2186 "void main(){\n"
2187 " x = 0;\n"
2188 " gl_Position = vec4(1);\n"
2189 "}\n";
2190 char const *fsSource =
2191 "#version 140\n"
2192 "#extension GL_ARB_separate_shader_objects: require\n"
2193 "#extension GL_ARB_shading_language_420pack: require\n"
2194 "\n"
2195 "layout(location=0) in float x;\n" /* VS writes int */
2196 "layout(location=0) out vec4 color;\n"
2197 "void main(){\n"
2198 " color = vec4(x);\n"
2199 "}\n";
2200
2201 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2202 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2203
2204 VkPipelineObj pipe(m_device);
2205 pipe.AddShader(&vs);
2206 pipe.AddShader(&fs);
2207
2208 VkCommandBufferObj dummyCmd(m_device);
2209 VkDescriptorSetObj descriptorSet(m_device);
2210 descriptorSet.AppendDummy();
2211 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2212
2213 m_errorMonitor->ClearState();
2214 pipe.CreateVKPipeline(descriptorSet);
2215
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002216 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12002217
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002218 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12002219 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
2220 FAIL() << "Incorrect error: " << msgString;
2221 }
2222}
2223
Chris Forbes8291c052015-05-25 11:13:28 +12002224TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
2225{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002226 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12002227 std::string msgString;
2228 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002229 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12002230
2231 VkVertexInputBindingDescription input_binding;
2232 memset(&input_binding, 0, sizeof(input_binding));
2233
2234 VkVertexInputAttributeDescription input_attrib;
2235 memset(&input_attrib, 0, sizeof(input_attrib));
2236 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2237
2238 char const *vsSource =
2239 "#version 140\n"
2240 "#extension GL_ARB_separate_shader_objects: require\n"
2241 "#extension GL_ARB_shading_language_420pack: require\n"
2242 "\n"
2243 "void main(){\n"
2244 " gl_Position = vec4(1);\n"
2245 "}\n";
2246 char const *fsSource =
2247 "#version 140\n"
2248 "#extension GL_ARB_separate_shader_objects: require\n"
2249 "#extension GL_ARB_shading_language_420pack: require\n"
2250 "\n"
2251 "layout(location=0) out vec4 color;\n"
2252 "void main(){\n"
2253 " color = vec4(1);\n"
2254 "}\n";
2255
2256 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2257 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2258
2259 VkPipelineObj pipe(m_device);
2260 pipe.AddShader(&vs);
2261 pipe.AddShader(&fs);
2262
2263 pipe.AddVertexInputBindings(&input_binding, 1);
2264 pipe.AddVertexInputAttribs(&input_attrib, 1);
2265
2266 VkCommandBufferObj dummyCmd(m_device);
2267 VkDescriptorSetObj descriptorSet(m_device);
2268 descriptorSet.AppendDummy();
2269 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2270
2271 m_errorMonitor->ClearState();
2272 pipe.CreateVKPipeline(descriptorSet);
2273
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002274 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes8291c052015-05-25 11:13:28 +12002275
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002276 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12002277 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
2278 FAIL() << "Incorrect warning: " << msgString;
2279 }
2280}
2281
Chris Forbes37367e62015-05-25 11:13:29 +12002282TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
2283{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002284 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12002285 std::string msgString;
2286 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002287 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12002288
2289 char const *vsSource =
2290 "#version 140\n"
2291 "#extension GL_ARB_separate_shader_objects: require\n"
2292 "#extension GL_ARB_shading_language_420pack: require\n"
2293 "\n"
2294 "layout(location=0) in vec4 x;\n" /* not provided */
2295 "void main(){\n"
2296 " gl_Position = x;\n"
2297 "}\n";
2298 char const *fsSource =
2299 "#version 140\n"
2300 "#extension GL_ARB_separate_shader_objects: require\n"
2301 "#extension GL_ARB_shading_language_420pack: require\n"
2302 "\n"
2303 "layout(location=0) out vec4 color;\n"
2304 "void main(){\n"
2305 " color = vec4(1);\n"
2306 "}\n";
2307
2308 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2309 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2310
2311 VkPipelineObj pipe(m_device);
2312 pipe.AddShader(&vs);
2313 pipe.AddShader(&fs);
2314
2315 VkCommandBufferObj dummyCmd(m_device);
2316 VkDescriptorSetObj descriptorSet(m_device);
2317 descriptorSet.AppendDummy();
2318 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2319
2320 m_errorMonitor->ClearState();
2321 pipe.CreateVKPipeline(descriptorSet);
2322
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002323 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002324
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002325 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002326 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2327 FAIL() << "Incorrect warning: " << msgString;
2328 }
2329}
2330
Chris Forbesa4b02322015-05-25 11:13:31 +12002331TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2332{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002333 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002334 std::string msgString;
2335 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002336 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002337
2338 VkVertexInputBindingDescription input_binding;
2339 memset(&input_binding, 0, sizeof(input_binding));
2340
2341 VkVertexInputAttributeDescription input_attrib;
2342 memset(&input_attrib, 0, sizeof(input_attrib));
2343 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2344
2345 char const *vsSource =
2346 "#version 140\n"
2347 "#extension GL_ARB_separate_shader_objects: require\n"
2348 "#extension GL_ARB_shading_language_420pack: require\n"
2349 "\n"
2350 "layout(location=0) in int x;\n" /* attrib provided float */
2351 "void main(){\n"
2352 " gl_Position = vec4(x);\n"
2353 "}\n";
2354 char const *fsSource =
2355 "#version 140\n"
2356 "#extension GL_ARB_separate_shader_objects: require\n"
2357 "#extension GL_ARB_shading_language_420pack: require\n"
2358 "\n"
2359 "layout(location=0) out vec4 color;\n"
2360 "void main(){\n"
2361 " color = vec4(1);\n"
2362 "}\n";
2363
2364 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2365 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2366
2367 VkPipelineObj pipe(m_device);
2368 pipe.AddShader(&vs);
2369 pipe.AddShader(&fs);
2370
2371 pipe.AddVertexInputBindings(&input_binding, 1);
2372 pipe.AddVertexInputAttribs(&input_attrib, 1);
2373
2374 VkCommandBufferObj dummyCmd(m_device);
2375 VkDescriptorSetObj descriptorSet(m_device);
2376 descriptorSet.AppendDummy();
2377 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2378
2379 m_errorMonitor->ClearState();
2380 pipe.CreateVKPipeline(descriptorSet);
2381
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002382 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002383
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002384 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002385 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2386 FAIL() << "Incorrect error: " << msgString;
2387 }
2388}
2389
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002390TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2391{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002392 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002393 std::string msgString;
2394 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002395 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002396
2397 /* Two binding descriptions for binding 0 */
2398 VkVertexInputBindingDescription input_bindings[2];
2399 memset(input_bindings, 0, sizeof(input_bindings));
2400
2401 VkVertexInputAttributeDescription input_attrib;
2402 memset(&input_attrib, 0, sizeof(input_attrib));
2403 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2404
2405 char const *vsSource =
2406 "#version 140\n"
2407 "#extension GL_ARB_separate_shader_objects: require\n"
2408 "#extension GL_ARB_shading_language_420pack: require\n"
2409 "\n"
2410 "layout(location=0) in float x;\n" /* attrib provided float */
2411 "void main(){\n"
2412 " gl_Position = vec4(x);\n"
2413 "}\n";
2414 char const *fsSource =
2415 "#version 140\n"
2416 "#extension GL_ARB_separate_shader_objects: require\n"
2417 "#extension GL_ARB_shading_language_420pack: require\n"
2418 "\n"
2419 "layout(location=0) out vec4 color;\n"
2420 "void main(){\n"
2421 " color = vec4(1);\n"
2422 "}\n";
2423
2424 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2425 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2426
2427 VkPipelineObj pipe(m_device);
2428 pipe.AddShader(&vs);
2429 pipe.AddShader(&fs);
2430
2431 pipe.AddVertexInputBindings(input_bindings, 2);
2432 pipe.AddVertexInputAttribs(&input_attrib, 1);
2433
2434 VkCommandBufferObj dummyCmd(m_device);
2435 VkDescriptorSetObj descriptorSet(m_device);
2436 descriptorSet.AppendDummy();
2437 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2438
2439 m_errorMonitor->ClearState();
2440 pipe.CreateVKPipeline(descriptorSet);
2441
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002442 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002443
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002444 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002445 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2446 FAIL() << "Incorrect error: " << msgString;
2447 }
2448}
Chris Forbes4c948702015-05-25 11:13:32 +12002449
Chris Forbesc12ef122015-05-25 11:13:40 +12002450/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2451 * rejects it. */
2452
2453TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2454{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002455 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002456 std::string msgString;
2457 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002458 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002459
2460 char const *vsSource =
2461 "#version 140\n"
2462 "#extension GL_ARB_separate_shader_objects: require\n"
2463 "#extension GL_ARB_shading_language_420pack: require\n"
2464 "\n"
2465 "void main(){\n"
2466 " gl_Position = vec4(1);\n"
2467 "}\n";
2468 char const *fsSource =
2469 "#version 140\n"
2470 "#extension GL_ARB_separate_shader_objects: require\n"
2471 "#extension GL_ARB_shading_language_420pack: require\n"
2472 "\n"
2473 "void main(){\n"
2474 "}\n";
2475
2476 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2477 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2478
2479 VkPipelineObj pipe(m_device);
2480 pipe.AddShader(&vs);
2481 pipe.AddShader(&fs);
2482
2483 /* implicit CB 0 set up by the test framework, not written */
2484
2485 VkCommandBufferObj dummyCmd(m_device);
2486 VkDescriptorSetObj descriptorSet(m_device);
2487 descriptorSet.AppendDummy();
2488 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2489
2490 m_errorMonitor->ClearState();
2491 pipe.CreateVKPipeline(descriptorSet);
2492
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002493 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002494
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002495 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002496 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2497 FAIL() << "Incorrect error: " << msgString;
2498 }
2499}
2500
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002501TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2502{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002503 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002504 std::string msgString;
2505 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002506 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002507
2508 char const *vsSource =
2509 "#version 140\n"
2510 "#extension GL_ARB_separate_shader_objects: require\n"
2511 "#extension GL_ARB_shading_language_420pack: require\n"
2512 "\n"
2513 "void main(){\n"
2514 " gl_Position = vec4(1);\n"
2515 "}\n";
2516 char const *fsSource =
2517 "#version 140\n"
2518 "#extension GL_ARB_separate_shader_objects: require\n"
2519 "#extension GL_ARB_shading_language_420pack: require\n"
2520 "\n"
2521 "layout(location=0) out vec4 x;\n"
2522 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2523 "void main(){\n"
2524 " x = vec4(1);\n"
2525 " y = vec4(1);\n"
2526 "}\n";
2527
2528 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2529 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2530
2531 VkPipelineObj pipe(m_device);
2532 pipe.AddShader(&vs);
2533 pipe.AddShader(&fs);
2534
2535 /* implicit CB 0 set up by the test framework */
2536 /* FS writes CB 1, but we don't configure it */
2537
2538 VkCommandBufferObj dummyCmd(m_device);
2539 VkDescriptorSetObj descriptorSet(m_device);
2540 descriptorSet.AppendDummy();
2541 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2542
2543 m_errorMonitor->ClearState();
2544 pipe.CreateVKPipeline(descriptorSet);
2545
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002546 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002547
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002548 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002549 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2550 FAIL() << "Incorrect warning: " << msgString;
2551 }
2552}
2553
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002554TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2555{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002556 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002557 std::string msgString;
2558 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002559 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002560
2561 char const *vsSource =
2562 "#version 140\n"
2563 "#extension GL_ARB_separate_shader_objects: require\n"
2564 "#extension GL_ARB_shading_language_420pack: require\n"
2565 "\n"
2566 "void main(){\n"
2567 " gl_Position = vec4(1);\n"
2568 "}\n";
2569 char const *fsSource =
2570 "#version 140\n"
2571 "#extension GL_ARB_separate_shader_objects: require\n"
2572 "#extension GL_ARB_shading_language_420pack: require\n"
2573 "\n"
2574 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2575 "void main(){\n"
2576 " x = ivec4(1);\n"
2577 "}\n";
2578
2579 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2580 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2581
2582 VkPipelineObj pipe(m_device);
2583 pipe.AddShader(&vs);
2584 pipe.AddShader(&fs);
2585
2586 /* implicit CB 0 set up by test framework, is UNORM. */
2587
2588 VkCommandBufferObj dummyCmd(m_device);
2589 VkDescriptorSetObj descriptorSet(m_device);
2590 descriptorSet.AppendDummy();
2591 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2592
2593 m_errorMonitor->ClearState();
2594 pipe.CreateVKPipeline(descriptorSet);
2595
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002596 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002597
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002598 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002599 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2600 FAIL() << "Incorrect error: " << msgString;
2601 }
2602}
Chris Forbesc2050732015-06-05 14:43:36 +12002603
2604TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2605{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002606 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002607 std::string msgString;
2608 ASSERT_NO_FATAL_FAILURE(InitState());
2609 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002610 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002611
2612 char const *vsSource =
2613 "#version 140\n"
2614 "#extension GL_ARB_separate_shader_objects: require\n"
2615 "#extension GL_ARB_shading_language_420pack: require\n"
2616 "\n"
2617 "void main(){\n"
2618 " gl_Position = vec4(1);\n"
2619 "}\n";
2620 char const *fsSource =
2621 "#version 140\n"
2622 "#extension GL_ARB_separate_shader_objects: require\n"
2623 "#extension GL_ARB_shading_language_420pack: require\n"
2624 "\n"
2625 "layout(location=0) out vec4 x;\n"
2626 "void main(){\n"
2627 " x = vec4(1);\n"
2628 "}\n";
2629
2630 m_errorMonitor->ClearState();
2631
2632 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2633 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2634
2635
2636 VkPipelineObj pipe(m_device);
2637 pipe.AddShader(&vs);
2638 pipe.AddShader(&fs);
2639
2640 /* implicit CB 0 set up by test framework, is UNORM. */
2641
2642 VkCommandBufferObj dummyCmd(m_device);
2643 VkDescriptorSetObj descriptorSet(m_device);
2644 descriptorSet.AppendDummy();
2645 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2646
2647 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2648 /* pipeline creation should have succeeded */
2649 ASSERT_EQ(VK_SUCCESS, res);
2650
2651 /* should have emitted a warning: the shader is not SPIRV, so we're
2652 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002653 msgFlags = m_errorMonitor->GetState(&msgString);
2654 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002655 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2656 FAIL() << "Incorrect warning: " << msgString;
2657 }
2658}
Chris Forbes01c9db72015-06-04 09:25:25 +12002659#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002660
Tony Barbour30486ea2015-04-07 13:44:53 -06002661int main(int argc, char **argv) {
2662 int result;
2663
2664 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002665 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002666
2667 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2668
2669 result = RUN_ALL_TESTS();
2670
Tony Barbour01999182015-04-09 12:58:51 -06002671 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002672 return result;
2673}