blob: 59acc4ff19143024b48e494e92e471b56662dadf [file] [log] [blame]
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001#include <vulkan.h>
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002#include "vk_debug_report_lunarg.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06003#include "gtest-1.7.0/include/gtest/gtest.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06004#include "vkrenderframework.h"
Mark Lobodzinskia910dc82015-05-14 14:30:48 -05005#include "layers_config.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06006
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05007#define GLM_FORCE_RADIANS
8#include "glm/glm.hpp"
9#include <glm/gtc/matrix_transform.hpp>
10
Tobin Ehlis57e6a612015-05-26 16:11:58 -060011#define MEM_TRACKER_TESTS 1
12#define OBJ_TRACKER_TESTS 1
13#define DRAW_STATE_TESTS 1
14#define THREADING_TESTS 1
Chris Forbes5af3bf22015-05-25 11:13:08 +120015#define SHADER_CHECKER_TESTS 1
Tobin Ehlis57e6a612015-05-26 16:11:58 -060016
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050017//--------------------------------------------------------------------------------------
18// Mesh and VertexFormat Data
19//--------------------------------------------------------------------------------------
20struct Vertex
21{
22 float posX, posY, posZ, posW; // Position data
23 float r, g, b, a; // Color
24};
25
26#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
27
28typedef enum _BsoFailSelect {
29 BsoFailNone = 0x00000000,
30 BsoFailRaster = 0x00000001,
31 BsoFailViewport = 0x00000002,
32 BsoFailColorBlend = 0x00000004,
33 BsoFailDepthStencil = 0x00000008,
34} BsoFailSelect;
35
36struct vktriangle_vs_uniform {
37 // Must start with MVP
38 float mvp[4][4];
39 float position[3][4];
40 float color[3][4];
41};
42
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050043static const char bindStateVertShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050044 "#version 130\n"
45 "vec2 vertices[3];\n"
46 "void main() {\n"
47 " vertices[0] = vec2(-1.0, -1.0);\n"
48 " vertices[1] = vec2( 1.0, -1.0);\n"
49 " vertices[2] = vec2( 0.0, 1.0);\n"
50 " gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
51 "}\n";
52
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050053static const char bindStateFragShaderText[] =
Cody Northrop74a2d2c2015-06-16 17:32:04 -060054 "#version 140\n"
55 "#extension GL_ARB_separate_shader_objects: require\n"
56 "#extension GL_ARB_shading_language_420pack: require\n"
57 "\n"
58 "layout(location = 0) out vec4 uFragColor;\n"
59 "void main(){\n"
60 " uFragColor = vec4(0,1,0,1);\n"
61 "}\n";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050062
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060063static void myDbgFunc(
64 VkFlags msgFlags,
65 VkObjectType objType,
66 VkObject srcObject,
67 size_t location,
68 int32_t msgCode,
69 const char* pLayerPrefix,
70 const char* pMsg,
71 void* pUserData);
Tony Barbour30486ea2015-04-07 13:44:53 -060072
73class ErrorMonitor {
74public:
Tony Barbour0c1bdc62015-04-29 17:34:29 -060075 ErrorMonitor()
Tony Barbour30486ea2015-04-07 13:44:53 -060076 {
Mike Stroyan09aae812015-05-12 16:00:45 -060077 pthread_mutexattr_t attr;
78 pthread_mutexattr_init(&attr);
79 pthread_mutex_init(&m_mutex, &attr);
80 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060081 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Mike Stroyan09aae812015-05-12 16:00:45 -060082 m_bailout = NULL;
83 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060084 }
85 void ClearState()
86 {
Mike Stroyan09aae812015-05-12 16:00:45 -060087 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060088 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -060089 m_msgString.clear();
Mike Stroyan09aae812015-05-12 16:00:45 -060090 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060091 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060092 VkFlags GetState(std::string *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060093 {
Mike Stroyan09aae812015-05-12 16:00:45 -060094 pthread_mutex_lock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060095 *msgString = m_msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -060096 pthread_mutex_unlock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060097 return m_msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -060098 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060099 void SetState(VkFlags msgFlags, const char *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -0600100 {
Mike Stroyan09aae812015-05-12 16:00:45 -0600101 pthread_mutex_lock(&m_mutex);
102 if (m_bailout != NULL) {
103 *m_bailout = true;
104 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600105 m_msgFlags = msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600106 m_msgString.reserve(strlen(msgString));
107 m_msgString = msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -0600108 pthread_mutex_unlock(&m_mutex);
109 }
110 void SetBailout(bool *bailout)
111 {
112 m_bailout = bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600113 }
114
115private:
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600116 VkFlags m_msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -0600117 std::string m_msgString;
118 pthread_mutex_t m_mutex;
119 bool* m_bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600120};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500121
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600122static void myDbgFunc(
123 VkFlags msgFlags,
124 VkObjectType objType,
125 VkObject srcObject,
126 size_t location,
127 int32_t msgCode,
128 const char* pLayerPrefix,
129 const char* pMsg,
130 void* pUserData)
Tony Barbour30486ea2015-04-07 13:44:53 -0600131{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600132 if (msgFlags & (VK_DBG_REPORT_WARN_BIT | VK_DBG_REPORT_ERROR_BIT)) {
Tony Barbour8508b8e2015-04-09 10:48:04 -0600133 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600134 errMonitor->SetState(msgFlags, pMsg);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600135 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600136}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500137
Tony Barbour01999182015-04-09 12:58:51 -0600138class VkLayerTest : public VkRenderFramework
Tony Barbour30486ea2015-04-07 13:44:53 -0600139{
140public:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600141 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
142 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500143 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
144 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour30486ea2015-04-07 13:44:53 -0600145
146protected:
Tony Barbour01999182015-04-09 12:58:51 -0600147 VkMemoryRefManager m_memoryRefManager;
148 ErrorMonitor *m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600149
150 virtual void SetUp() {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600151 std::vector<const char *> instance_extension_names;
152 std::vector<const char *> device_extension_names;
Tony Barbour950ebc02015-04-23 12:55:36 -0600153
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600154 instance_extension_names.push_back(DEBUG_REPORT_EXTENSION_NAME);
Courtney Goeltzenleuchterde53c5b2015-06-16 15:59:11 -0600155 /*
156 * Since CreateDbgMsgCallback is an instance level extension call
157 * any extension / layer that utilizes that feature also needs
158 * to be enabled at create instance time.
159 */
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()) {
214 cmdBuffer.EndRenderPass(renderPass());
215 }
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
Tony Barbour54cdd192015-04-22 15:12:07 -0600829
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500830TEST_F(VkLayerTest, RasterStateNotBound)
831{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600832 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500833 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600834 ASSERT_NO_FATAL_FAILURE(InitState());
835 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500836 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
837
838 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
839
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600840 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600841 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 -0500842 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
843 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
844 }
845}
846
847TEST_F(VkLayerTest, ViewportStateNotBound)
848{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600849 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500850 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600851 ASSERT_NO_FATAL_FAILURE(InitState());
852 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500853 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
854
855 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
856
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600857 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600858 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 -0500859 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
860 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
861 }
862}
863
864TEST_F(VkLayerTest, ColorBlendStateNotBound)
865{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600866 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500867 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600868 ASSERT_NO_FATAL_FAILURE(InitState());
869 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500870 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
871
872 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
873
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600874 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600875 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 -0500876 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
877 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
878 }
879}
880
881TEST_F(VkLayerTest, DepthStencilStateNotBound)
882{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600883 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500884 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600885 ASSERT_NO_FATAL_FAILURE(InitState());
886 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500887 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
888
889 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
890
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600891 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600892 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 -0500893 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
894 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
895 }
Tony Barbourdb686622015-05-06 09:35:56 -0600896}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600897#endif
898#if DRAW_STATE_TESTS
Tobin Ehlise4076782015-06-24 15:53:07 -0600899TEST_F(VkLayerTest, BindPipelineNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600900{
901 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600902 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600903 std::string msgString;
904
905 ASSERT_NO_FATAL_FAILURE(InitState());
906 m_errorMonitor->ClearState();
907 VkCommandBufferObj cmdBuffer(m_device);
908 BeginCommandBuffer(cmdBuffer);
909 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
910 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600911 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -0600912 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding pipeline to CmdBuffer w/o active RenderPass";
913 if (!strstr(msgString.c_str(),"Incorrectly binding graphics pipeline ")) {
914 FAIL() << "Error received was not 'Incorrectly binding graphics pipeline (0xbaadb1be) without an active RenderPass'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600915 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600916}
917
918TEST_F(VkLayerTest, InvalidDescriptorPool)
919{
920 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
921 // The DS check for this is after driver has been called to validate DS internal data struct
922 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600923/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600924 std::string msgString;
925 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
926 vkResetDescriptorPool(device(), badPool);
927
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600928 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600929 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 -0600930 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
931 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
932 }*/
933}
934
935TEST_F(VkLayerTest, InvalidDescriptorSet)
936{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600937 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
938 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600939 // Create a valid cmd buffer
940 // call vkCmdBindDescriptorSets w/ false DS
941}
942
943TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
944{
945 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
946 // The DS check for this is after driver has been called to validate DS internal data struct
947}
948
949TEST_F(VkLayerTest, InvalidPipeline)
950{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600951 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
952 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600953 // Create a valid cmd buffer
954 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlise4076782015-06-24 15:53:07 -0600955// VkFlags msgFlags;
956// std::string msgString;
957//
958// ASSERT_NO_FATAL_FAILURE(InitState());
959// m_errorMonitor->ClearState();
960// VkCommandBufferObj cmdBuffer(m_device);
961// BeginCommandBuffer(cmdBuffer);
962// VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
963// vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
964// msgFlags = m_errorMonitor->GetState(&msgString);
965// ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
966// if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
967// FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
968// }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600969}
970
Tobin Ehlis254eca02015-06-25 15:46:59 -0600971TEST_F(VkLayerTest, DescriptorSetNotUpdated)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600972{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600973 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600974 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600975 std::string msgString;
976 VkResult err;
977
978 ASSERT_NO_FATAL_FAILURE(InitState());
979 m_errorMonitor->ClearState();
980 VkCommandBufferObj cmdBuffer(m_device);
981 const VkDescriptorTypeCount ds_type_count = {
982 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
983 .count = 1,
984 };
985 const VkDescriptorPoolCreateInfo ds_pool_ci = {
986 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
987 .pNext = NULL,
988 .count = 1,
989 .pTypeCount = &ds_type_count,
990 };
991 VkDescriptorPool ds_pool;
992 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
993 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600994
995 const VkDescriptorSetLayoutBinding dsl_binding = {
996 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800997 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600998 .stageFlags = VK_SHADER_STAGE_ALL,
999 .pImmutableSamplers = NULL,
1000 };
1001
1002 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1003 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1004 .pNext = NULL,
1005 .count = 1,
1006 .pBinding = &dsl_binding,
1007 };
1008 VkDescriptorSetLayout ds_layout;
1009 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1010 ASSERT_VK_SUCCESS(err);
1011
1012 VkDescriptorSet descriptorSet;
1013 uint32_t ds_count = 0;
1014 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1015 ASSERT_VK_SUCCESS(err);
1016
1017 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1018 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1019 .pNext = NULL,
1020 .descriptorSetCount = 1,
1021 .pSetLayouts = &ds_layout,
1022 };
1023
1024 VkPipelineLayout pipeline_layout;
1025 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1026 ASSERT_VK_SUCCESS(err);
1027
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001028 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001029
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001030 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1031 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1032 .pNext = NULL,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001033 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001034 .shader = vs.obj(),
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001035 .linkConstBufferCount = 0,
1036 .pLinkConstBufferInfo = NULL,
1037 .pSpecializationInfo = NULL,
1038 };
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001039 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001040 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1041 .pNext = NULL,
1042 .stageCount = 1,
1043 .pStages = &pipe_vs_ci,
1044 .pVertexInputState = NULL,
1045 .pIaState = NULL,
1046 .pTessState = NULL,
1047 .pVpState = NULL,
1048 .pRsState = NULL,
1049 .pMsState = NULL,
1050 .pDsState = NULL,
1051 .pCbState = NULL,
1052 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1053 .layout = pipeline_layout,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001054 };
1055
1056 VkPipeline pipeline;
1057 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1058 ASSERT_VK_SUCCESS(err);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001059 ASSERT_NO_FATAL_FAILURE(InitState());
1060 ASSERT_NO_FATAL_FAILURE(InitViewport());
1061 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1062 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1063 BeginCommandBuffer(cmdBuffer);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001064 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06001065 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptorSet, 0, NULL);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001066
Tobin Ehlis254eca02015-06-25 15:46:59 -06001067 msgFlags = m_errorMonitor->GetState(&msgString);
1068 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT) << "Did not warn after binding a DescriptorSet that was never updated.";
1069 if (!strstr(msgString.c_str()," bound but it was never updated. ")) {
1070 FAIL() << "Error received was not 'DS <blah> bound but it was never updated. You may want to either update it or not bind it.'";
1071 }
1072}
1073
1074TEST_F(VkLayerTest, NoBeginCmdBuffer)
1075{
1076 VkFlags msgFlags;
1077 std::string msgString;
1078
1079 ASSERT_NO_FATAL_FAILURE(InitState());
1080 m_errorMonitor->ClearState();
1081 VkCommandBufferObj cmdBuffer(m_device);
1082 // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
1083 vkEndCommandBuffer(cmdBuffer.GetBufferHandle());
1084 msgFlags = m_errorMonitor->GetState(&msgString);
1085 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after ending a CmdBuffer w/o calling BeginCommandBuffer()";
1086 if (!strstr(msgString.c_str(),"You must call vkBeginCommandBuffer() before this call to ")) {
1087 FAIL() << "Error received was not 'You must call vkBeginCommandBuffer() before this call to vkEndCommandBuffer()'";
1088 }
1089}
1090
1091TEST_F(VkLayerTest, InvalidPipelineCreateState)
1092{
1093 // Attempt to Create Gfx Pipeline w/o a VS
1094 VkFlags msgFlags;
1095 std::string msgString;
1096 VkResult err;
1097
1098 ASSERT_NO_FATAL_FAILURE(InitState());
1099 m_errorMonitor->ClearState();
1100 VkCommandBufferObj cmdBuffer(m_device);
1101 const VkDescriptorTypeCount ds_type_count = {
1102 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1103 .count = 1,
1104 };
1105 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1106 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1107 .pNext = NULL,
1108 .count = 1,
1109 .pTypeCount = &ds_type_count,
1110 };
1111 VkDescriptorPool ds_pool;
1112 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1113 ASSERT_VK_SUCCESS(err);
1114
1115 const VkDescriptorSetLayoutBinding dsl_binding = {
1116 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1117 .arraySize = 1,
1118 .stageFlags = VK_SHADER_STAGE_ALL,
1119 .pImmutableSamplers = NULL,
1120 };
1121
1122 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1123 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1124 .pNext = NULL,
1125 .count = 1,
1126 .pBinding = &dsl_binding,
1127 };
1128 VkDescriptorSetLayout ds_layout;
1129 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1130 ASSERT_VK_SUCCESS(err);
1131
1132 VkDescriptorSet descriptorSet;
1133 uint32_t ds_count = 0;
1134 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1135 ASSERT_VK_SUCCESS(err);
1136
1137 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1138 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1139 .pNext = NULL,
1140 .descriptorSetCount = 1,
1141 .pSetLayouts = &ds_layout,
1142 };
1143
1144 VkPipelineLayout pipeline_layout;
1145 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1146 ASSERT_VK_SUCCESS(err);
1147
1148 const VkGraphicsPipelineCreateInfo gp_ci = {
1149 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1150 .pNext = NULL,
1151 .stageCount = 0,
1152 .pStages = NULL, // Creating Gfx Pipeline w/o VS is a violation
1153 .pVertexInputState = NULL,
1154 .pIaState = NULL,
1155 .pTessState = NULL,
1156 .pVpState = NULL,
1157 .pRsState = NULL,
1158 .pMsState = NULL,
1159 .pDsState = NULL,
1160 .pCbState = NULL,
1161 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1162 .layout = pipeline_layout,
1163 };
1164
1165 VkPipeline pipeline;
1166 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001167
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001168 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001169 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after creating Gfx Pipeline w/o VS.";
1170 if (!strstr(msgString.c_str(),"Invalid Pipeline CreateInfo State: Vtx Shader required")) {
1171 FAIL() << "Error received was not 'Invalid Pipeline CreateInfo State: Vtx Shader required'";
1172 }
1173}
1174
Tobin Ehlisb8b06b52015-06-25 16:27:19 -06001175TEST_F(VkLayerTest, NullRenderPass)
1176{
1177 // Bind a NULL RenderPass
1178 VkFlags msgFlags;
1179 std::string msgString;
1180
1181 ASSERT_NO_FATAL_FAILURE(InitState());
1182 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1183 m_errorMonitor->ClearState();
1184 VkCommandBufferObj cmdBuffer(m_device);
1185
1186 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1187 BeginCommandBuffer(cmdBuffer);
1188 // Don't care about RenderPass handle b/c error should be flagged before that
1189 vkCmdBeginRenderPass(cmdBuffer.GetBufferHandle(), NULL);
1190
1191 msgFlags = m_errorMonitor->GetState(&msgString);
1192 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding NULL RenderPass.";
1193 if (!strstr(msgString.c_str(),"You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()")) {
1194 FAIL() << "Error received was not 'You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()'";
1195 }
1196}
1197
Tobin Ehlis254eca02015-06-25 15:46:59 -06001198TEST_F(VkLayerTest, RenderPassWithinRenderPass)
1199{
1200 // Bind a BeginRenderPass within an active RenderPass
1201 VkFlags msgFlags;
1202 std::string msgString;
1203
1204 ASSERT_NO_FATAL_FAILURE(InitState());
1205 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1206 m_errorMonitor->ClearState();
1207 VkCommandBufferObj cmdBuffer(m_device);
1208
1209 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1210 BeginCommandBuffer(cmdBuffer);
Tobin Ehlisb8b06b52015-06-25 16:27:19 -06001211 // Just create a dummy Renderpass that's non-NULL so we can get to the proper error
1212 const VkRenderPassBegin rp_begin = {
1213 .renderPass = (VkRenderPass) 0xc001d00d,
1214 .framebuffer = NULL
1215 };
1216 vkCmdBeginRenderPass(cmdBuffer.GetBufferHandle(), &rp_begin);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001217
1218 msgFlags = m_errorMonitor->GetState(&msgString);
1219 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding RenderPass w/i an active RenderPass.";
1220 if (!strstr(msgString.c_str(),"Cannot call vkCmdBeginRenderPass() during an active RenderPass ")) {
1221 FAIL() << "Error received was not 'Cannot call vkCmdBeginRenderPass() during an active RenderPass...'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001222 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001223}
1224
1225TEST_F(VkLayerTest, InvalidDynamicStateObject)
1226{
1227 // Create a valid cmd buffer
1228 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001229 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1230 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001231}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001232
Tobin Ehlise4076782015-06-24 15:53:07 -06001233TEST_F(VkLayerTest, VtxBufferNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001234{
1235 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001236 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001237 std::string msgString;
1238 VkResult err;
1239
1240 ASSERT_NO_FATAL_FAILURE(InitState());
1241 m_errorMonitor->ClearState();
1242 VkCommandBufferObj cmdBuffer(m_device);
1243 const VkDescriptorTypeCount ds_type_count = {
1244 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1245 .count = 1,
1246 };
1247 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1248 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1249 .pNext = NULL,
1250 .count = 1,
1251 .pTypeCount = &ds_type_count,
1252 };
1253 VkDescriptorPool ds_pool;
1254 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1255 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001256
1257 const VkDescriptorSetLayoutBinding dsl_binding = {
1258 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001259 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001260 .stageFlags = VK_SHADER_STAGE_ALL,
1261 .pImmutableSamplers = NULL,
1262 };
1263
1264 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1265 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1266 .pNext = NULL,
1267 .count = 1,
1268 .pBinding = &dsl_binding,
1269 };
1270 VkDescriptorSetLayout ds_layout;
1271 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1272 ASSERT_VK_SUCCESS(err);
1273
1274 VkDescriptorSet descriptorSet;
1275 uint32_t ds_count = 0;
1276 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1277 ASSERT_VK_SUCCESS(err);
1278
1279 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1280 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1281 .pNext = NULL,
1282 .descriptorSetCount = 1,
1283 .pSetLayouts = &ds_layout,
1284 };
1285
1286 VkPipelineLayout pipeline_layout;
1287 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1288 ASSERT_VK_SUCCESS(err);
1289
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001290 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001291
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001292 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1293 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1294 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001295 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001296 .shader = vs.obj(),
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001297 .linkConstBufferCount = 0,
1298 .pLinkConstBufferInfo = NULL,
1299 .pSpecializationInfo = NULL,
1300 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001301 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001302 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1303 .pNext = NULL,
1304 .stageCount = 1,
1305 .pStages = &pipe_vs_ci,
1306 .pVertexInputState = NULL,
1307 .pIaState = NULL,
1308 .pTessState = NULL,
1309 .pVpState = NULL,
1310 .pRsState = NULL,
1311 .pMsState = NULL,
1312 .pDsState = NULL,
1313 .pCbState = NULL,
1314 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1315 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001316 };
1317
1318 VkPipeline pipeline;
1319 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1320 ASSERT_VK_SUCCESS(err);
1321
1322 err= cmdBuffer.BeginCommandBuffer();
1323 ASSERT_VK_SUCCESS(err);
1324 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1325 // Should error before calling to driver so don't care about actual data
1326 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1327
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001328 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -06001329 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o active RenderPass.";
1330 if (!strstr(msgString.c_str(),"Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.")) {
1331 FAIL() << "Error received was not 'Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001332 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001333}
1334
1335TEST_F(VkLayerTest, DSTypeMismatch)
1336{
1337 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001338 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001339 std::string msgString;
1340 VkResult err;
1341
1342 ASSERT_NO_FATAL_FAILURE(InitState());
1343 m_errorMonitor->ClearState();
1344 //VkDescriptorSetObj descriptorSet(m_device);
1345 const VkDescriptorTypeCount ds_type_count = {
1346 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1347 .count = 1,
1348 };
1349 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1350 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1351 .pNext = NULL,
1352 .count = 1,
1353 .pTypeCount = &ds_type_count,
1354 };
1355 VkDescriptorPool ds_pool;
1356 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1357 ASSERT_VK_SUCCESS(err);
1358 const VkDescriptorSetLayoutBinding dsl_binding = {
1359 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001360 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001361 .stageFlags = VK_SHADER_STAGE_ALL,
1362 .pImmutableSamplers = NULL,
1363 };
1364
1365 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1366 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1367 .pNext = NULL,
1368 .count = 1,
1369 .pBinding = &dsl_binding,
1370 };
1371 VkDescriptorSetLayout ds_layout;
1372 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1373 ASSERT_VK_SUCCESS(err);
1374
1375 VkDescriptorSet descriptorSet;
1376 uint32_t ds_count = 0;
1377 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1378 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001379
1380 const VkSamplerCreateInfo sampler_ci = {
1381 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1382 .pNext = NULL,
1383 .magFilter = VK_TEX_FILTER_NEAREST,
1384 .minFilter = VK_TEX_FILTER_NEAREST,
1385 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1386 .addressU = VK_TEX_ADDRESS_CLAMP,
1387 .addressV = VK_TEX_ADDRESS_CLAMP,
1388 .addressW = VK_TEX_ADDRESS_CLAMP,
1389 .mipLodBias = 1.0,
1390 .maxAnisotropy = 1,
1391 .compareOp = VK_COMPARE_OP_NEVER,
1392 .minLod = 1.0,
1393 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001394 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001395 };
1396 VkSampler sampler;
1397 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1398 ASSERT_VK_SUCCESS(err);
1399
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001400 VkDescriptorInfo descriptor_info;
1401 memset(&descriptor_info, 0, sizeof(descriptor_info));
1402 descriptor_info.sampler = sampler;
1403
1404 VkWriteDescriptorSet descriptor_write;
1405 memset(&descriptor_write, 0, sizeof(descriptor_write));
1406 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1407 descriptor_write.destSet = descriptorSet;
1408 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001409 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001410 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1411 descriptor_write.pDescriptors = &descriptor_info;
1412
1413 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1414
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001415 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001416 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 +08001417 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1418 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 -06001419 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001420}
1421
1422TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1423{
1424 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001425 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001426 std::string msgString;
1427 VkResult err;
1428
1429 ASSERT_NO_FATAL_FAILURE(InitState());
1430 m_errorMonitor->ClearState();
1431 //VkDescriptorSetObj descriptorSet(m_device);
1432 const VkDescriptorTypeCount ds_type_count = {
1433 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1434 .count = 1,
1435 };
1436 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1437 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1438 .pNext = NULL,
1439 .count = 1,
1440 .pTypeCount = &ds_type_count,
1441 };
1442 VkDescriptorPool ds_pool;
1443 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1444 ASSERT_VK_SUCCESS(err);
1445 const VkDescriptorSetLayoutBinding dsl_binding = {
1446 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001447 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001448 .stageFlags = VK_SHADER_STAGE_ALL,
1449 .pImmutableSamplers = NULL,
1450 };
1451
1452 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1453 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1454 .pNext = NULL,
1455 .count = 1,
1456 .pBinding = &dsl_binding,
1457 };
1458 VkDescriptorSetLayout ds_layout;
1459 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1460 ASSERT_VK_SUCCESS(err);
1461
1462 VkDescriptorSet descriptorSet;
1463 uint32_t ds_count = 0;
1464 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1465 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001466
1467 const VkSamplerCreateInfo sampler_ci = {
1468 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1469 .pNext = NULL,
1470 .magFilter = VK_TEX_FILTER_NEAREST,
1471 .minFilter = VK_TEX_FILTER_NEAREST,
1472 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1473 .addressU = VK_TEX_ADDRESS_CLAMP,
1474 .addressV = VK_TEX_ADDRESS_CLAMP,
1475 .addressW = VK_TEX_ADDRESS_CLAMP,
1476 .mipLodBias = 1.0,
1477 .maxAnisotropy = 1,
1478 .compareOp = VK_COMPARE_OP_NEVER,
1479 .minLod = 1.0,
1480 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001481 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001482 };
1483 VkSampler sampler;
1484 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1485 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001486
1487 VkDescriptorInfo descriptor_info;
1488 memset(&descriptor_info, 0, sizeof(descriptor_info));
1489 descriptor_info.sampler = sampler;
1490
1491 VkWriteDescriptorSet descriptor_write;
1492 memset(&descriptor_write, 0, sizeof(descriptor_write));
1493 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1494 descriptor_write.destSet = descriptorSet;
1495 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1496 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001497 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001498 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1499 descriptor_write.pDescriptors = &descriptor_info;
1500
1501 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1502
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001503 msgFlags = m_errorMonitor->GetState(&msgString);
1504 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 +08001505 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1506 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 -06001507 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001508}
1509
1510TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1511{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001512 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001513 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001514 std::string msgString;
1515 VkResult err;
1516
1517 ASSERT_NO_FATAL_FAILURE(InitState());
1518 m_errorMonitor->ClearState();
1519 //VkDescriptorSetObj descriptorSet(m_device);
1520 const VkDescriptorTypeCount ds_type_count = {
1521 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1522 .count = 1,
1523 };
1524 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1525 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1526 .pNext = NULL,
1527 .count = 1,
1528 .pTypeCount = &ds_type_count,
1529 };
1530 VkDescriptorPool ds_pool;
1531 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1532 ASSERT_VK_SUCCESS(err);
1533 const VkDescriptorSetLayoutBinding dsl_binding = {
1534 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001535 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001536 .stageFlags = VK_SHADER_STAGE_ALL,
1537 .pImmutableSamplers = NULL,
1538 };
1539
1540 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1541 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1542 .pNext = NULL,
1543 .count = 1,
1544 .pBinding = &dsl_binding,
1545 };
1546 VkDescriptorSetLayout ds_layout;
1547 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1548 ASSERT_VK_SUCCESS(err);
1549
1550 VkDescriptorSet descriptorSet;
1551 uint32_t ds_count = 0;
1552 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1553 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001554
1555 const VkSamplerCreateInfo sampler_ci = {
1556 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1557 .pNext = NULL,
1558 .magFilter = VK_TEX_FILTER_NEAREST,
1559 .minFilter = VK_TEX_FILTER_NEAREST,
1560 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1561 .addressU = VK_TEX_ADDRESS_CLAMP,
1562 .addressV = VK_TEX_ADDRESS_CLAMP,
1563 .addressW = VK_TEX_ADDRESS_CLAMP,
1564 .mipLodBias = 1.0,
1565 .maxAnisotropy = 1,
1566 .compareOp = VK_COMPARE_OP_NEVER,
1567 .minLod = 1.0,
1568 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001569 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001570 };
1571 VkSampler sampler;
1572 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1573 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001574
1575 VkDescriptorInfo descriptor_info;
1576 memset(&descriptor_info, 0, sizeof(descriptor_info));
1577 descriptor_info.sampler = sampler;
1578
1579 VkWriteDescriptorSet descriptor_write;
1580 memset(&descriptor_write, 0, sizeof(descriptor_write));
1581 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1582 descriptor_write.destSet = descriptorSet;
1583 descriptor_write.destBinding = 2;
1584 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001585 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001586 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1587 descriptor_write.pDescriptors = &descriptor_info;
1588
1589 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1590
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001591 msgFlags = m_errorMonitor->GetState(&msgString);
1592 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 -06001593 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1594 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1595 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001596}
1597
1598TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1599{
1600 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001601 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001602 std::string msgString;
1603 VkResult err;
1604
1605 ASSERT_NO_FATAL_FAILURE(InitState());
1606 m_errorMonitor->ClearState();
1607 //VkDescriptorSetObj descriptorSet(m_device);
1608 const VkDescriptorTypeCount ds_type_count = {
1609 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1610 .count = 1,
1611 };
1612 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1613 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1614 .pNext = NULL,
1615 .count = 1,
1616 .pTypeCount = &ds_type_count,
1617 };
1618 VkDescriptorPool ds_pool;
1619 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1620 ASSERT_VK_SUCCESS(err);
1621 const VkDescriptorSetLayoutBinding dsl_binding = {
1622 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001623 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001624 .stageFlags = VK_SHADER_STAGE_ALL,
1625 .pImmutableSamplers = NULL,
1626 };
1627
1628 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1629 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1630 .pNext = NULL,
1631 .count = 1,
1632 .pBinding = &dsl_binding,
1633 };
1634 VkDescriptorSetLayout ds_layout;
1635 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1636 ASSERT_VK_SUCCESS(err);
1637
1638 VkDescriptorSet descriptorSet;
1639 uint32_t ds_count = 0;
1640 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1641 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001642
1643 const VkSamplerCreateInfo sampler_ci = {
1644 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1645 .pNext = NULL,
1646 .magFilter = VK_TEX_FILTER_NEAREST,
1647 .minFilter = VK_TEX_FILTER_NEAREST,
1648 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1649 .addressU = VK_TEX_ADDRESS_CLAMP,
1650 .addressV = VK_TEX_ADDRESS_CLAMP,
1651 .addressW = VK_TEX_ADDRESS_CLAMP,
1652 .mipLodBias = 1.0,
1653 .maxAnisotropy = 1,
1654 .compareOp = VK_COMPARE_OP_NEVER,
1655 .minLod = 1.0,
1656 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001657 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001658 };
1659 VkSampler sampler;
1660 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1661 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001662
1663
1664 VkDescriptorInfo descriptor_info;
1665 memset(&descriptor_info, 0, sizeof(descriptor_info));
1666 descriptor_info.sampler = sampler;
1667
1668 VkWriteDescriptorSet descriptor_write;
1669 memset(&descriptor_write, 0, sizeof(descriptor_write));
1670 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1671 descriptor_write.destSet = descriptorSet;
1672 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001673 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001674 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1675 descriptor_write.pDescriptors = &descriptor_info;
1676
1677 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1678
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001679 msgFlags = m_errorMonitor->GetState(&msgString);
1680 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 -06001681 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1682 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1683 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001684}
1685
1686TEST_F(VkLayerTest, NumSamplesMismatch)
1687{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001688 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001689 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001690 std::string msgString;
1691 VkResult err;
1692
1693 ASSERT_NO_FATAL_FAILURE(InitState());
1694 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1695 m_errorMonitor->ClearState();
1696 VkCommandBufferObj cmdBuffer(m_device);
1697 const VkDescriptorTypeCount ds_type_count = {
1698 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1699 .count = 1,
1700 };
1701 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1702 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1703 .pNext = NULL,
1704 .count = 1,
1705 .pTypeCount = &ds_type_count,
1706 };
1707 VkDescriptorPool ds_pool;
1708 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1709 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001710
1711 const VkDescriptorSetLayoutBinding dsl_binding = {
1712 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001713 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001714 .stageFlags = VK_SHADER_STAGE_ALL,
1715 .pImmutableSamplers = NULL,
1716 };
1717
1718 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1719 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1720 .pNext = NULL,
1721 .count = 1,
1722 .pBinding = &dsl_binding,
1723 };
1724 VkDescriptorSetLayout ds_layout;
1725 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1726 ASSERT_VK_SUCCESS(err);
1727
1728 VkDescriptorSet descriptorSet;
1729 uint32_t ds_count = 0;
1730 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1731 ASSERT_VK_SUCCESS(err);
1732
1733 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1734 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1735 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001736 .rasterSamples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001737 .multisampleEnable = 1,
1738 .sampleShadingEnable = 0,
1739 .minSampleShading = 1.0,
1740 .sampleMask = 15,
1741 };
1742
1743 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1744 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1745 .pNext = NULL,
1746 .descriptorSetCount = 1,
1747 .pSetLayouts = &ds_layout,
1748 };
1749
1750 VkPipelineLayout pipeline_layout;
1751 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1752 ASSERT_VK_SUCCESS(err);
1753
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001754 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001755
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001756 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1757 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1758 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001759 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001760 .shader = vs.obj(),
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001761 .linkConstBufferCount = 0,
1762 .pLinkConstBufferInfo = NULL,
1763 .pSpecializationInfo = NULL,
1764 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001765 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001766 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1767 .pNext = NULL,
1768 .stageCount = 1,
1769 .pStages = &pipe_vs_ci,
1770 .pVertexInputState = NULL,
1771 .pIaState = NULL,
1772 .pTessState = NULL,
1773 .pVpState = NULL,
1774 .pRsState = NULL,
1775 .pMsState = &pipe_ms_state_ci,
1776 .pDsState = NULL,
1777 .pCbState = NULL,
1778 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1779 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001780 };
1781
1782 VkPipeline pipeline;
1783 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1784 ASSERT_VK_SUCCESS(err);
1785
1786 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1787 BeginCommandBuffer(cmdBuffer);
1788 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1789
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001790 msgFlags = m_errorMonitor->GetState(&msgString);
1791 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 -06001792 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1793 FAIL() << "Error received was not 'Num samples mismatch!...'";
1794 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001795}
Tobin Ehlise4076782015-06-24 15:53:07 -06001796TEST_F(VkLayerTest, PipelineNotBound)
1797{
1798 VkFlags msgFlags;
1799 std::string msgString;
1800 VkResult err;
1801
1802 ASSERT_NO_FATAL_FAILURE(InitState());
1803 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1804 m_errorMonitor->ClearState();
1805 VkCommandBufferObj cmdBuffer(m_device);
1806 const VkDescriptorTypeCount ds_type_count = {
1807 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1808 .count = 1,
1809 };
1810 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1811 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1812 .pNext = NULL,
1813 .count = 1,
1814 .pTypeCount = &ds_type_count,
1815 };
1816 VkDescriptorPool ds_pool;
1817 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1818 ASSERT_VK_SUCCESS(err);
1819
1820 const VkDescriptorSetLayoutBinding dsl_binding = {
1821 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1822 .arraySize = 1,
1823 .stageFlags = VK_SHADER_STAGE_ALL,
1824 .pImmutableSamplers = NULL,
1825 };
1826
1827 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1828 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1829 .pNext = NULL,
1830 .count = 1,
1831 .pBinding = &dsl_binding,
1832 };
1833 VkDescriptorSetLayout ds_layout;
1834 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1835 ASSERT_VK_SUCCESS(err);
1836
1837 VkDescriptorSet descriptorSet;
1838 uint32_t ds_count = 0;
1839 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1840 ASSERT_VK_SUCCESS(err);
1841
1842 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1843 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1844 .pNext = NULL,
1845 .descriptorSetCount = 1,
1846 .pSetLayouts = &ds_layout,
1847 };
1848
1849 VkPipelineLayout pipeline_layout;
1850 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1851 ASSERT_VK_SUCCESS(err);
1852
Tobin Ehlise4076782015-06-24 15:53:07 -06001853 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
1854 //err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1855 ASSERT_VK_SUCCESS(err);
1856
1857 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1858 BeginCommandBuffer(cmdBuffer);
1859 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
1860
1861 msgFlags = m_errorMonitor->GetState(&msgString);
1862 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
1863 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
1864 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
1865 }
1866}
1867TEST_F(VkLayerTest, VtxBufferBadIndex)
1868{
1869 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1870 VkFlags msgFlags;
1871 std::string msgString;
1872 VkResult err;
1873
1874 ASSERT_NO_FATAL_FAILURE(InitState());
1875 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1876 m_errorMonitor->ClearState();
1877 VkCommandBufferObj cmdBuffer(m_device);
1878 const VkDescriptorTypeCount ds_type_count = {
1879 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1880 .count = 1,
1881 };
1882 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1883 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1884 .pNext = NULL,
1885 .count = 1,
1886 .pTypeCount = &ds_type_count,
1887 };
1888 VkDescriptorPool ds_pool;
1889 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1890 ASSERT_VK_SUCCESS(err);
1891
1892 const VkDescriptorSetLayoutBinding dsl_binding = {
1893 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1894 .arraySize = 1,
1895 .stageFlags = VK_SHADER_STAGE_ALL,
1896 .pImmutableSamplers = NULL,
1897 };
1898
1899 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1900 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1901 .pNext = NULL,
1902 .count = 1,
1903 .pBinding = &dsl_binding,
1904 };
1905 VkDescriptorSetLayout ds_layout;
1906 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1907 ASSERT_VK_SUCCESS(err);
1908
1909 VkDescriptorSet descriptorSet;
1910 uint32_t ds_count = 0;
1911 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1912 ASSERT_VK_SUCCESS(err);
1913
1914 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1915 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1916 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001917 .rasterSamples = 1,
Tobin Ehlise4076782015-06-24 15:53:07 -06001918 .multisampleEnable = 1,
1919 .sampleShadingEnable = 0,
1920 .minSampleShading = 1.0,
1921 .sampleMask = 15,
1922 };
1923
1924 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1925 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1926 .pNext = NULL,
1927 .descriptorSetCount = 1,
1928 .pSetLayouts = &ds_layout,
1929 };
1930
1931 VkPipelineLayout pipeline_layout;
1932 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1933 ASSERT_VK_SUCCESS(err);
1934
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001935 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlise4076782015-06-24 15:53:07 -06001936
1937 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1938 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1939 .pNext = NULL,
1940 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001941 .shader = vs.obj(),
Tobin Ehlise4076782015-06-24 15:53:07 -06001942 .linkConstBufferCount = 0,
1943 .pLinkConstBufferInfo = NULL,
1944 .pSpecializationInfo = NULL,
1945 };
1946 const VkGraphicsPipelineCreateInfo gp_ci = {
1947 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1948 .pNext = NULL,
1949 .stageCount = 1,
1950 .pStages = &pipe_vs_ci,
1951 .pVertexInputState = NULL,
1952 .pIaState = NULL,
1953 .pTessState = NULL,
1954 .pVpState = NULL,
1955 .pRsState = NULL,
1956 .pMsState = &pipe_ms_state_ci,
1957 .pDsState = NULL,
1958 .pCbState = NULL,
1959 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1960 .layout = pipeline_layout,
1961 };
1962
1963 VkPipeline pipeline;
1964 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1965 ASSERT_VK_SUCCESS(err);
1966
1967 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1968 BeginCommandBuffer(cmdBuffer);
1969 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1970 // Should error before calling to driver so don't care about actual data
1971 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1972
1973 msgFlags = m_errorMonitor->GetState(&msgString);
1974 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding Vtx Buffer w/o VBO attached to PSO.";
1975 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1976 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1977 }
1978}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001979#endif
1980#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001981#if GTEST_IS_THREADSAFE
1982struct thread_data_struct {
1983 VkCmdBuffer cmdBuffer;
1984 VkEvent event;
1985 bool bailout;
1986};
1987
1988extern "C" void *AddToCommandBuffer(void *arg)
1989{
1990 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1991 std::string msgString;
1992
1993 for (int i = 0; i<10000; i++) {
Tony Barbourc2e987e2015-06-29 16:20:35 -06001994 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPELINE_STAGE_ALL_GPU_COMMANDS);
Mike Stroyan09aae812015-05-12 16:00:45 -06001995 if (data->bailout) {
1996 break;
1997 }
1998 }
1999 return NULL;
2000}
2001
2002TEST_F(VkLayerTest, ThreadCmdBufferCollision)
2003{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002004 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06002005 std::string msgString;
2006 pthread_t thread;
2007 pthread_attr_t thread_attr;
2008
2009 ASSERT_NO_FATAL_FAILURE(InitState());
2010 ASSERT_NO_FATAL_FAILURE(InitViewport());
2011 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2012
2013 VkCommandBufferObj cmdBuffer(m_device);
2014
2015 m_errorMonitor->ClearState();
2016 pthread_attr_init(&thread_attr);
2017 BeginCommandBuffer(cmdBuffer);
2018
2019 VkEventCreateInfo event_info;
2020 VkEvent event;
2021 VkMemoryRequirements mem_req;
Mike Stroyan09aae812015-05-12 16:00:45 -06002022 VkResult err;
2023
2024 memset(&event_info, 0, sizeof(event_info));
2025 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2026
2027 err = vkCreateEvent(device(), &event_info, &event);
2028 ASSERT_VK_SUCCESS(err);
2029
Tony Barbour426b9052015-06-24 16:06:58 -06002030 err = vkGetObjectMemoryRequirements(device(), VK_OBJECT_TYPE_EVENT, event, &mem_req);
Mike Stroyan09aae812015-05-12 16:00:45 -06002031 ASSERT_VK_SUCCESS(err);
2032
2033 VkMemoryAllocInfo mem_info;
2034 VkDeviceMemory event_mem;
2035
Mike Stroyan09aae812015-05-12 16:00:45 -06002036 memset(&mem_info, 0, sizeof(mem_info));
2037 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
2038 mem_info.allocationSize = mem_req.size;
Mark Lobodzinski72346292015-07-02 16:49:40 -06002039 mem_info.memoryTypeIndex = 0;
2040
2041 err = m_device->gpu().set_memory_type(mem_req.memoryTypeBits, &mem_info, 0);
2042 ASSERT_VK_SUCCESS(err);
2043
Mike Stroyan09aae812015-05-12 16:00:45 -06002044 err = vkAllocMemory(device(), &mem_info, &event_mem);
2045 ASSERT_VK_SUCCESS(err);
2046
Mark Lobodzinski23182612015-05-29 09:32:35 -05002047 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06002048 ASSERT_VK_SUCCESS(err);
2049
2050 err = vkResetEvent(device(), event);
2051 ASSERT_VK_SUCCESS(err);
2052
2053 struct thread_data_struct data;
2054 data.cmdBuffer = cmdBuffer.obj();
2055 data.event = event;
2056 data.bailout = false;
2057 m_errorMonitor->SetBailout(&data.bailout);
2058 // Add many entries to command buffer from another thread.
2059 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
2060 // Add many entries to command buffer from this thread at the same time.
2061 AddToCommandBuffer(&data);
2062 pthread_join(thread, NULL);
2063 EndCommandBuffer(cmdBuffer);
2064
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002065 msgFlags = m_errorMonitor->GetState(&msgString);
Mike Stroyaned254572015-06-17 16:32:06 -06002066 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 -06002067 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05002068 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06002069 }
2070
2071}
2072#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06002073#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12002074
2075#if SHADER_CHECKER_TESTS
2076TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
2077{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002078 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12002079 std::string msgString;
2080 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002081 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002082
2083 char const *vsSource =
2084 "#version 140\n"
2085 "#extension GL_ARB_separate_shader_objects: require\n"
2086 "#extension GL_ARB_shading_language_420pack: require\n"
2087 "\n"
2088 "layout(location=0) out float x;\n"
2089 "void main(){\n"
2090 " gl_Position = vec4(1);\n"
2091 " x = 0;\n"
2092 "}\n";
2093 char const *fsSource =
2094 "#version 140\n"
2095 "#extension GL_ARB_separate_shader_objects: require\n"
2096 "#extension GL_ARB_shading_language_420pack: require\n"
2097 "\n"
2098 "layout(location=0) out vec4 color;\n"
2099 "void main(){\n"
2100 " color = vec4(1);\n"
2101 "}\n";
2102
2103 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2104 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2105
2106 VkPipelineObj pipe(m_device);
2107 pipe.AddShader(&vs);
2108 pipe.AddShader(&fs);
2109
2110 VkCommandBufferObj dummyCmd(m_device);
2111 VkDescriptorSetObj descriptorSet(m_device);
2112 descriptorSet.AppendDummy();
2113 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2114
2115 m_errorMonitor->ClearState();
2116 pipe.CreateVKPipeline(descriptorSet);
2117
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002118 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002119
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002120 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002121 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
2122 FAIL() << "Incorrect warning: " << msgString;
2123 }
2124}
Chris Forbes5af3bf22015-05-25 11:13:08 +12002125
Chris Forbes3c10b852015-05-25 11:13:13 +12002126TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
2127{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002128 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12002129 std::string msgString;
2130 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002131 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12002132
2133 char const *vsSource =
2134 "#version 140\n"
2135 "#extension GL_ARB_separate_shader_objects: require\n"
2136 "#extension GL_ARB_shading_language_420pack: require\n"
2137 "\n"
2138 "void main(){\n"
2139 " gl_Position = vec4(1);\n"
2140 "}\n";
2141 char const *fsSource =
2142 "#version 140\n"
2143 "#extension GL_ARB_separate_shader_objects: require\n"
2144 "#extension GL_ARB_shading_language_420pack: require\n"
2145 "\n"
2146 "layout(location=0) in float x;\n"
2147 "layout(location=0) out vec4 color;\n"
2148 "void main(){\n"
2149 " color = vec4(x);\n"
2150 "}\n";
2151
2152 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2153 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2154
2155 VkPipelineObj pipe(m_device);
2156 pipe.AddShader(&vs);
2157 pipe.AddShader(&fs);
2158
2159 VkCommandBufferObj dummyCmd(m_device);
2160 VkDescriptorSetObj descriptorSet(m_device);
2161 descriptorSet.AppendDummy();
2162 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2163
2164 m_errorMonitor->ClearState();
2165 pipe.CreateVKPipeline(descriptorSet);
2166
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002167 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12002168
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002169 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12002170 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
2171 FAIL() << "Incorrect error: " << msgString;
2172 }
2173}
2174
Chris Forbescc281692015-05-25 11:13:17 +12002175TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
2176{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002177 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12002178 std::string msgString;
2179 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002180 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12002181
2182 char const *vsSource =
2183 "#version 140\n"
2184 "#extension GL_ARB_separate_shader_objects: require\n"
2185 "#extension GL_ARB_shading_language_420pack: require\n"
2186 "\n"
2187 "layout(location=0) out int x;\n"
2188 "void main(){\n"
2189 " x = 0;\n"
2190 " gl_Position = vec4(1);\n"
2191 "}\n";
2192 char const *fsSource =
2193 "#version 140\n"
2194 "#extension GL_ARB_separate_shader_objects: require\n"
2195 "#extension GL_ARB_shading_language_420pack: require\n"
2196 "\n"
2197 "layout(location=0) in float x;\n" /* VS writes int */
2198 "layout(location=0) out vec4 color;\n"
2199 "void main(){\n"
2200 " color = vec4(x);\n"
2201 "}\n";
2202
2203 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2204 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2205
2206 VkPipelineObj pipe(m_device);
2207 pipe.AddShader(&vs);
2208 pipe.AddShader(&fs);
2209
2210 VkCommandBufferObj dummyCmd(m_device);
2211 VkDescriptorSetObj descriptorSet(m_device);
2212 descriptorSet.AppendDummy();
2213 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2214
2215 m_errorMonitor->ClearState();
2216 pipe.CreateVKPipeline(descriptorSet);
2217
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002218 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12002219
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002220 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12002221 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
2222 FAIL() << "Incorrect error: " << msgString;
2223 }
2224}
2225
Chris Forbes8291c052015-05-25 11:13:28 +12002226TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
2227{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002228 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12002229 std::string msgString;
2230 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002231 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12002232
2233 VkVertexInputBindingDescription input_binding;
2234 memset(&input_binding, 0, sizeof(input_binding));
2235
2236 VkVertexInputAttributeDescription input_attrib;
2237 memset(&input_attrib, 0, sizeof(input_attrib));
2238 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2239
2240 char const *vsSource =
2241 "#version 140\n"
2242 "#extension GL_ARB_separate_shader_objects: require\n"
2243 "#extension GL_ARB_shading_language_420pack: require\n"
2244 "\n"
2245 "void main(){\n"
2246 " gl_Position = vec4(1);\n"
2247 "}\n";
2248 char const *fsSource =
2249 "#version 140\n"
2250 "#extension GL_ARB_separate_shader_objects: require\n"
2251 "#extension GL_ARB_shading_language_420pack: require\n"
2252 "\n"
2253 "layout(location=0) out vec4 color;\n"
2254 "void main(){\n"
2255 " color = vec4(1);\n"
2256 "}\n";
2257
2258 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2259 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2260
2261 VkPipelineObj pipe(m_device);
2262 pipe.AddShader(&vs);
2263 pipe.AddShader(&fs);
2264
2265 pipe.AddVertexInputBindings(&input_binding, 1);
2266 pipe.AddVertexInputAttribs(&input_attrib, 1);
2267
2268 VkCommandBufferObj dummyCmd(m_device);
2269 VkDescriptorSetObj descriptorSet(m_device);
2270 descriptorSet.AppendDummy();
2271 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2272
2273 m_errorMonitor->ClearState();
2274 pipe.CreateVKPipeline(descriptorSet);
2275
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002276 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes8291c052015-05-25 11:13:28 +12002277
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002278 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12002279 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
2280 FAIL() << "Incorrect warning: " << msgString;
2281 }
2282}
2283
Chris Forbes37367e62015-05-25 11:13:29 +12002284TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
2285{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002286 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12002287 std::string msgString;
2288 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002289 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12002290
2291 char const *vsSource =
2292 "#version 140\n"
2293 "#extension GL_ARB_separate_shader_objects: require\n"
2294 "#extension GL_ARB_shading_language_420pack: require\n"
2295 "\n"
2296 "layout(location=0) in vec4 x;\n" /* not provided */
2297 "void main(){\n"
2298 " gl_Position = x;\n"
2299 "}\n";
2300 char const *fsSource =
2301 "#version 140\n"
2302 "#extension GL_ARB_separate_shader_objects: require\n"
2303 "#extension GL_ARB_shading_language_420pack: require\n"
2304 "\n"
2305 "layout(location=0) out vec4 color;\n"
2306 "void main(){\n"
2307 " color = vec4(1);\n"
2308 "}\n";
2309
2310 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2311 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2312
2313 VkPipelineObj pipe(m_device);
2314 pipe.AddShader(&vs);
2315 pipe.AddShader(&fs);
2316
2317 VkCommandBufferObj dummyCmd(m_device);
2318 VkDescriptorSetObj descriptorSet(m_device);
2319 descriptorSet.AppendDummy();
2320 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2321
2322 m_errorMonitor->ClearState();
2323 pipe.CreateVKPipeline(descriptorSet);
2324
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002325 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002326
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002327 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002328 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2329 FAIL() << "Incorrect warning: " << msgString;
2330 }
2331}
2332
Chris Forbesa4b02322015-05-25 11:13:31 +12002333TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2334{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002335 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002336 std::string msgString;
2337 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002338 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002339
2340 VkVertexInputBindingDescription input_binding;
2341 memset(&input_binding, 0, sizeof(input_binding));
2342
2343 VkVertexInputAttributeDescription input_attrib;
2344 memset(&input_attrib, 0, sizeof(input_attrib));
2345 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2346
2347 char const *vsSource =
2348 "#version 140\n"
2349 "#extension GL_ARB_separate_shader_objects: require\n"
2350 "#extension GL_ARB_shading_language_420pack: require\n"
2351 "\n"
2352 "layout(location=0) in int x;\n" /* attrib provided float */
2353 "void main(){\n"
2354 " gl_Position = vec4(x);\n"
2355 "}\n";
2356 char const *fsSource =
2357 "#version 140\n"
2358 "#extension GL_ARB_separate_shader_objects: require\n"
2359 "#extension GL_ARB_shading_language_420pack: require\n"
2360 "\n"
2361 "layout(location=0) out vec4 color;\n"
2362 "void main(){\n"
2363 " color = vec4(1);\n"
2364 "}\n";
2365
2366 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2367 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2368
2369 VkPipelineObj pipe(m_device);
2370 pipe.AddShader(&vs);
2371 pipe.AddShader(&fs);
2372
2373 pipe.AddVertexInputBindings(&input_binding, 1);
2374 pipe.AddVertexInputAttribs(&input_attrib, 1);
2375
2376 VkCommandBufferObj dummyCmd(m_device);
2377 VkDescriptorSetObj descriptorSet(m_device);
2378 descriptorSet.AppendDummy();
2379 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2380
2381 m_errorMonitor->ClearState();
2382 pipe.CreateVKPipeline(descriptorSet);
2383
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002384 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002385
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002386 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002387 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2388 FAIL() << "Incorrect error: " << msgString;
2389 }
2390}
2391
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002392TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2393{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002394 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002395 std::string msgString;
2396 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002397 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002398
2399 /* Two binding descriptions for binding 0 */
2400 VkVertexInputBindingDescription input_bindings[2];
2401 memset(input_bindings, 0, sizeof(input_bindings));
2402
2403 VkVertexInputAttributeDescription input_attrib;
2404 memset(&input_attrib, 0, sizeof(input_attrib));
2405 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2406
2407 char const *vsSource =
2408 "#version 140\n"
2409 "#extension GL_ARB_separate_shader_objects: require\n"
2410 "#extension GL_ARB_shading_language_420pack: require\n"
2411 "\n"
2412 "layout(location=0) in float x;\n" /* attrib provided float */
2413 "void main(){\n"
2414 " gl_Position = vec4(x);\n"
2415 "}\n";
2416 char const *fsSource =
2417 "#version 140\n"
2418 "#extension GL_ARB_separate_shader_objects: require\n"
2419 "#extension GL_ARB_shading_language_420pack: require\n"
2420 "\n"
2421 "layout(location=0) out vec4 color;\n"
2422 "void main(){\n"
2423 " color = vec4(1);\n"
2424 "}\n";
2425
2426 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2427 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2428
2429 VkPipelineObj pipe(m_device);
2430 pipe.AddShader(&vs);
2431 pipe.AddShader(&fs);
2432
2433 pipe.AddVertexInputBindings(input_bindings, 2);
2434 pipe.AddVertexInputAttribs(&input_attrib, 1);
2435
2436 VkCommandBufferObj dummyCmd(m_device);
2437 VkDescriptorSetObj descriptorSet(m_device);
2438 descriptorSet.AppendDummy();
2439 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2440
2441 m_errorMonitor->ClearState();
2442 pipe.CreateVKPipeline(descriptorSet);
2443
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002444 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002445
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002446 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002447 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2448 FAIL() << "Incorrect error: " << msgString;
2449 }
2450}
Chris Forbes4c948702015-05-25 11:13:32 +12002451
Chris Forbesc12ef122015-05-25 11:13:40 +12002452/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2453 * rejects it. */
2454
2455TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2456{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002457 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002458 std::string msgString;
2459 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002460 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002461
2462 char const *vsSource =
2463 "#version 140\n"
2464 "#extension GL_ARB_separate_shader_objects: require\n"
2465 "#extension GL_ARB_shading_language_420pack: require\n"
2466 "\n"
2467 "void main(){\n"
2468 " gl_Position = vec4(1);\n"
2469 "}\n";
2470 char const *fsSource =
2471 "#version 140\n"
2472 "#extension GL_ARB_separate_shader_objects: require\n"
2473 "#extension GL_ARB_shading_language_420pack: require\n"
2474 "\n"
2475 "void main(){\n"
2476 "}\n";
2477
2478 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2479 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2480
2481 VkPipelineObj pipe(m_device);
2482 pipe.AddShader(&vs);
2483 pipe.AddShader(&fs);
2484
2485 /* implicit CB 0 set up by the test framework, not written */
2486
2487 VkCommandBufferObj dummyCmd(m_device);
2488 VkDescriptorSetObj descriptorSet(m_device);
2489 descriptorSet.AppendDummy();
2490 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2491
2492 m_errorMonitor->ClearState();
2493 pipe.CreateVKPipeline(descriptorSet);
2494
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002495 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002496
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002497 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002498 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2499 FAIL() << "Incorrect error: " << msgString;
2500 }
2501}
2502
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002503TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2504{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002505 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002506 std::string msgString;
2507 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002508 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002509
2510 char const *vsSource =
2511 "#version 140\n"
2512 "#extension GL_ARB_separate_shader_objects: require\n"
2513 "#extension GL_ARB_shading_language_420pack: require\n"
2514 "\n"
2515 "void main(){\n"
2516 " gl_Position = vec4(1);\n"
2517 "}\n";
2518 char const *fsSource =
2519 "#version 140\n"
2520 "#extension GL_ARB_separate_shader_objects: require\n"
2521 "#extension GL_ARB_shading_language_420pack: require\n"
2522 "\n"
2523 "layout(location=0) out vec4 x;\n"
2524 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2525 "void main(){\n"
2526 " x = vec4(1);\n"
2527 " y = vec4(1);\n"
2528 "}\n";
2529
2530 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2531 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2532
2533 VkPipelineObj pipe(m_device);
2534 pipe.AddShader(&vs);
2535 pipe.AddShader(&fs);
2536
2537 /* implicit CB 0 set up by the test framework */
2538 /* FS writes CB 1, but we don't configure it */
2539
2540 VkCommandBufferObj dummyCmd(m_device);
2541 VkDescriptorSetObj descriptorSet(m_device);
2542 descriptorSet.AppendDummy();
2543 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2544
2545 m_errorMonitor->ClearState();
2546 pipe.CreateVKPipeline(descriptorSet);
2547
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002548 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002549
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002550 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002551 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2552 FAIL() << "Incorrect warning: " << msgString;
2553 }
2554}
2555
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002556TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2557{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002558 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002559 std::string msgString;
2560 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002561 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002562
2563 char const *vsSource =
2564 "#version 140\n"
2565 "#extension GL_ARB_separate_shader_objects: require\n"
2566 "#extension GL_ARB_shading_language_420pack: require\n"
2567 "\n"
2568 "void main(){\n"
2569 " gl_Position = vec4(1);\n"
2570 "}\n";
2571 char const *fsSource =
2572 "#version 140\n"
2573 "#extension GL_ARB_separate_shader_objects: require\n"
2574 "#extension GL_ARB_shading_language_420pack: require\n"
2575 "\n"
2576 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2577 "void main(){\n"
2578 " x = ivec4(1);\n"
2579 "}\n";
2580
2581 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2582 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2583
2584 VkPipelineObj pipe(m_device);
2585 pipe.AddShader(&vs);
2586 pipe.AddShader(&fs);
2587
2588 /* implicit CB 0 set up by test framework, is UNORM. */
2589
2590 VkCommandBufferObj dummyCmd(m_device);
2591 VkDescriptorSetObj descriptorSet(m_device);
2592 descriptorSet.AppendDummy();
2593 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2594
2595 m_errorMonitor->ClearState();
2596 pipe.CreateVKPipeline(descriptorSet);
2597
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002598 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002599
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002600 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002601 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2602 FAIL() << "Incorrect error: " << msgString;
2603 }
2604}
Chris Forbesc2050732015-06-05 14:43:36 +12002605
2606TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2607{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002608 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002609 std::string msgString;
2610 ASSERT_NO_FATAL_FAILURE(InitState());
2611 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002612 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002613
2614 char const *vsSource =
2615 "#version 140\n"
2616 "#extension GL_ARB_separate_shader_objects: require\n"
2617 "#extension GL_ARB_shading_language_420pack: require\n"
2618 "\n"
2619 "void main(){\n"
2620 " gl_Position = vec4(1);\n"
2621 "}\n";
2622 char const *fsSource =
2623 "#version 140\n"
2624 "#extension GL_ARB_separate_shader_objects: require\n"
2625 "#extension GL_ARB_shading_language_420pack: require\n"
2626 "\n"
2627 "layout(location=0) out vec4 x;\n"
2628 "void main(){\n"
2629 " x = vec4(1);\n"
2630 "}\n";
2631
2632 m_errorMonitor->ClearState();
2633
2634 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2635 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2636
2637
2638 VkPipelineObj pipe(m_device);
2639 pipe.AddShader(&vs);
2640 pipe.AddShader(&fs);
2641
2642 /* implicit CB 0 set up by test framework, is UNORM. */
2643
2644 VkCommandBufferObj dummyCmd(m_device);
2645 VkDescriptorSetObj descriptorSet(m_device);
2646 descriptorSet.AppendDummy();
2647 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2648
2649 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2650 /* pipeline creation should have succeeded */
2651 ASSERT_EQ(VK_SUCCESS, res);
2652
2653 /* should have emitted a warning: the shader is not SPIRV, so we're
2654 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002655 msgFlags = m_errorMonitor->GetState(&msgString);
2656 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002657 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2658 FAIL() << "Incorrect warning: " << msgString;
2659 }
2660}
Chris Forbes01c9db72015-06-04 09:25:25 +12002661#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002662
Tony Barbour30486ea2015-04-07 13:44:53 -06002663int main(int argc, char **argv) {
2664 int result;
2665
2666 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002667 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002668
2669 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2670
2671 result = RUN_ALL_TESTS();
2672
Tony Barbour01999182015-04-09 12:58:51 -06002673 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002674 return result;
2675}