blob: 4aa594b337444afaaaa5c138505d656c40a85a1e [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
455 .memProps = 0,
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 = {
507 .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,
518 };
519 VkMemoryAllocInfo mem_alloc = {
520 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
521 .pNext = NULL,
522 .allocationSize = 0,
523 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
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
537 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500538 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500539 ASSERT_VK_SUCCESS(err);
540
541 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500542 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500543 ASSERT_VK_SUCCESS(err);
544
545 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500546 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500547 ASSERT_VK_SUCCESS(err);
548
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600549 msgFlags = m_errorMonitor->GetState(&msgString);
550 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 -0500551 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500552 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
553 }
554}
555
556TEST_F(VkLayerTest, FreeBoundMemory)
557{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600558 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500559 std::string msgString;
560 VkResult err;
561
562 ASSERT_NO_FATAL_FAILURE(InitState());
563 m_errorMonitor->ClearState();
564
565 // Create an image, allocate memory, free it, and then try to bind it
566 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500567 VkDeviceMemory mem;
568 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500569
570 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
571 const int32_t tex_width = 32;
572 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500573
574 const VkImageCreateInfo image_create_info = {
575 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
576 .pNext = NULL,
577 .imageType = VK_IMAGE_TYPE_2D,
578 .format = tex_format,
579 .extent = { tex_width, tex_height, 1 },
580 .mipLevels = 1,
581 .arraySize = 1,
582 .samples = 1,
583 .tiling = VK_IMAGE_TILING_LINEAR,
584 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
585 .flags = 0,
586 };
587 VkMemoryAllocInfo mem_alloc = {
588 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
589 .pNext = NULL,
590 .allocationSize = 0,
591 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500592 };
593
594 err = vkCreateImage(m_device->device(), &image_create_info, &image);
595 ASSERT_VK_SUCCESS(err);
596
Tony Barbour426b9052015-06-24 16:06:58 -0600597 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500598 VK_OBJECT_TYPE_IMAGE,
599 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500600 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500601 ASSERT_VK_SUCCESS(err);
602
Mark Lobodzinski23182612015-05-29 09:32:35 -0500603 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500604
605 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500606 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500607 ASSERT_VK_SUCCESS(err);
608
609 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500610 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500611 ASSERT_VK_SUCCESS(err);
612
613 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500614 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500615 ASSERT_VK_SUCCESS(err);
616
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600617 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter7dc4c8b2015-06-13 21:48:47 -0600618 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 -0500619 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
620 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
621 }
622}
623
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500624TEST_F(VkLayerTest, RebindMemory)
625{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600626 VkFlags msgFlags;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500627 std::string msgString;
628 VkResult err;
629
630 ASSERT_NO_FATAL_FAILURE(InitState());
631 m_errorMonitor->ClearState();
632
633 // Create an image, allocate memory, free it, and then try to bind it
634 VkImage image;
635 VkDeviceMemory mem1;
636 VkDeviceMemory mem2;
637 VkMemoryRequirements mem_reqs;
638
639 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
640 const int32_t tex_width = 32;
641 const int32_t tex_height = 32;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500642
643 const VkImageCreateInfo image_create_info = {
644 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
645 .pNext = NULL,
646 .imageType = VK_IMAGE_TYPE_2D,
647 .format = tex_format,
648 .extent = { tex_width, tex_height, 1 },
649 .mipLevels = 1,
650 .arraySize = 1,
651 .samples = 1,
652 .tiling = VK_IMAGE_TILING_LINEAR,
653 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
654 .flags = 0,
655 };
656 VkMemoryAllocInfo mem_alloc = {
657 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
658 .pNext = NULL,
659 .allocationSize = 0,
660 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500661 };
662
663 err = vkCreateImage(m_device->device(), &image_create_info, &image);
664 ASSERT_VK_SUCCESS(err);
665
Tony Barbour426b9052015-06-24 16:06:58 -0600666 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500667 VK_OBJECT_TYPE_IMAGE,
668 image,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500669 &mem_reqs);
670 ASSERT_VK_SUCCESS(err);
671
672 mem_alloc.allocationSize = mem_reqs.size;
673
674 // allocate 2 memory objects
675 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
676 ASSERT_VK_SUCCESS(err);
677 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
678 ASSERT_VK_SUCCESS(err);
679
680 // Bind first memory object to Image object
681 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
682 ASSERT_VK_SUCCESS(err);
683
684 // Introduce validation failure, try to bind a different memory object to the same image object
685 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
686 ASSERT_VK_SUCCESS(err);
687
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600688 msgFlags = m_errorMonitor->GetState(&msgString);
689 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 -0500690 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
691 FAIL() << "Error received did not match expected message when rebinding memory to an object";
692 }
693}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500694
695TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
696{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600697 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500698 std::string msgString;
699 VkResult err;
700
701 ASSERT_NO_FATAL_FAILURE(InitState());
702 m_errorMonitor->ClearState();
703
704 // Create an image object, allocate memory, destroy the object and then try to bind it
705 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500706 VkDeviceMemory mem;
707 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500708
709 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
710 const int32_t tex_width = 32;
711 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500712
713 const VkImageCreateInfo image_create_info = {
714 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
715 .pNext = NULL,
716 .imageType = VK_IMAGE_TYPE_2D,
717 .format = tex_format,
718 .extent = { tex_width, tex_height, 1 },
719 .mipLevels = 1,
720 .arraySize = 1,
721 .samples = 1,
722 .tiling = VK_IMAGE_TILING_LINEAR,
723 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
724 .flags = 0,
725 };
726 VkMemoryAllocInfo mem_alloc = {
727 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
728 .pNext = NULL,
729 .allocationSize = 0,
730 .memProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500731 };
732
733 err = vkCreateImage(m_device->device(), &image_create_info, &image);
734 ASSERT_VK_SUCCESS(err);
735
Tony Barbour426b9052015-06-24 16:06:58 -0600736 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500737 VK_OBJECT_TYPE_IMAGE,
738 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500739 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500740 ASSERT_VK_SUCCESS(err);
741
Mark Lobodzinski23182612015-05-29 09:32:35 -0500742 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500743
744 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500745 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500746 ASSERT_VK_SUCCESS(err);
747
748 // Introduce validation failure, destroy Image object before binding
749 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
750 ASSERT_VK_SUCCESS(err);
751
752 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500753 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500754 ASSERT_VK_SUCCESS(err);
755
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600756 msgFlags = m_errorMonitor->GetState(&msgString);
757 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 -0500758 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500759 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
760 }
761}
762
Tony Barbour8508b8e2015-04-09 10:48:04 -0600763TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600764{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600765 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600766 VkFlags msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -0600767 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600768
769 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600770 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
771 fenceInfo.pNext = NULL;
772 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600773
Tony Barbour30486ea2015-04-07 13:44:53 -0600774 ASSERT_NO_FATAL_FAILURE(InitState());
775 ASSERT_NO_FATAL_FAILURE(InitViewport());
776 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
777
Tony Barbour01999182015-04-09 12:58:51 -0600778 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600779 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
780
Tony Barbour8508b8e2015-04-09 10:48:04 -0600781 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600782 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600783 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600784
785 testFence.init(*m_device, fenceInfo);
786 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600787 cmdBuffer.QueueCommandBuffer(testFence.obj());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600788 msgFlags = m_errorMonitor->GetState(&msgString);
789 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 -0600790 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500791 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600792 }
793
794}
795
796TEST_F(VkLayerTest, ResetUnsignaledFence)
797{
798 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600799 VkFlags msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600800 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600801 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600802 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
803 fenceInfo.pNext = NULL;
804
Tony Barbour8508b8e2015-04-09 10:48:04 -0600805 ASSERT_NO_FATAL_FAILURE(InitState());
806 testFence.init(*m_device, fenceInfo);
807 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600808 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600809 vkResetFences(m_device->device(), 1, fences);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600810 msgFlags = m_errorMonitor->GetState(&msgString);
811 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 -0600812 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500813 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600814 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600815
816}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600817#endif
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600818#if OBJ_TRACKER_TESTS
Tony Barbour54cdd192015-04-22 15:12:07 -0600819
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500820TEST_F(VkLayerTest, RasterStateNotBound)
821{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600822 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500823 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600824 ASSERT_NO_FATAL_FAILURE(InitState());
825 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500826 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
827
828 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
829
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600830 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600831 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 -0500832 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
833 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
834 }
835}
836
837TEST_F(VkLayerTest, ViewportStateNotBound)
838{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600839 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500840 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600841 ASSERT_NO_FATAL_FAILURE(InitState());
842 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500843 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
844
845 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
846
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600847 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600848 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 -0500849 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
850 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
851 }
852}
853
854TEST_F(VkLayerTest, ColorBlendStateNotBound)
855{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600856 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500857 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600858 ASSERT_NO_FATAL_FAILURE(InitState());
859 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500860 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
861
862 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
863
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600864 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600865 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 -0500866 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
867 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
868 }
869}
870
871TEST_F(VkLayerTest, DepthStencilStateNotBound)
872{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600873 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500874 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600875 ASSERT_NO_FATAL_FAILURE(InitState());
876 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500877 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
878
879 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
880
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600881 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600882 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 -0500883 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
884 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
885 }
Tony Barbourdb686622015-05-06 09:35:56 -0600886}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600887#endif
888#if DRAW_STATE_TESTS
Tobin Ehlise4076782015-06-24 15:53:07 -0600889TEST_F(VkLayerTest, BindPipelineNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600890{
891 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600892 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600893 std::string msgString;
894
895 ASSERT_NO_FATAL_FAILURE(InitState());
896 m_errorMonitor->ClearState();
897 VkCommandBufferObj cmdBuffer(m_device);
898 BeginCommandBuffer(cmdBuffer);
899 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
900 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600901 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -0600902 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding pipeline to CmdBuffer w/o active RenderPass";
903 if (!strstr(msgString.c_str(),"Incorrectly binding graphics pipeline ")) {
904 FAIL() << "Error received was not 'Incorrectly binding graphics pipeline (0xbaadb1be) without an active RenderPass'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600905 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600906}
907
908TEST_F(VkLayerTest, InvalidDescriptorPool)
909{
910 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
911 // The DS check for this is after driver has been called to validate DS internal data struct
912 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600913/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600914 std::string msgString;
915 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
916 vkResetDescriptorPool(device(), badPool);
917
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600918 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600919 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 -0600920 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
921 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
922 }*/
923}
924
925TEST_F(VkLayerTest, InvalidDescriptorSet)
926{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600927 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
928 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600929 // Create a valid cmd buffer
930 // call vkCmdBindDescriptorSets w/ false DS
931}
932
933TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
934{
935 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
936 // The DS check for this is after driver has been called to validate DS internal data struct
937}
938
939TEST_F(VkLayerTest, InvalidPipeline)
940{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600941 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
942 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600943 // Create a valid cmd buffer
944 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlise4076782015-06-24 15:53:07 -0600945// VkFlags msgFlags;
946// std::string msgString;
947//
948// ASSERT_NO_FATAL_FAILURE(InitState());
949// m_errorMonitor->ClearState();
950// VkCommandBufferObj cmdBuffer(m_device);
951// BeginCommandBuffer(cmdBuffer);
952// VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
953// vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
954// msgFlags = m_errorMonitor->GetState(&msgString);
955// ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
956// if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
957// FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
958// }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600959}
960
Tobin Ehlis254eca02015-06-25 15:46:59 -0600961TEST_F(VkLayerTest, DescriptorSetNotUpdated)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600962{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600963 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600964 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600965 std::string msgString;
966 VkResult err;
967
968 ASSERT_NO_FATAL_FAILURE(InitState());
969 m_errorMonitor->ClearState();
970 VkCommandBufferObj cmdBuffer(m_device);
971 const VkDescriptorTypeCount ds_type_count = {
972 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
973 .count = 1,
974 };
975 const VkDescriptorPoolCreateInfo ds_pool_ci = {
976 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
977 .pNext = NULL,
978 .count = 1,
979 .pTypeCount = &ds_type_count,
980 };
981 VkDescriptorPool ds_pool;
982 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
983 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600984
985 const VkDescriptorSetLayoutBinding dsl_binding = {
986 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800987 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600988 .stageFlags = VK_SHADER_STAGE_ALL,
989 .pImmutableSamplers = NULL,
990 };
991
992 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
993 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
994 .pNext = NULL,
995 .count = 1,
996 .pBinding = &dsl_binding,
997 };
998 VkDescriptorSetLayout ds_layout;
999 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1000 ASSERT_VK_SUCCESS(err);
1001
1002 VkDescriptorSet descriptorSet;
1003 uint32_t ds_count = 0;
1004 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1005 ASSERT_VK_SUCCESS(err);
1006
1007 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1008 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1009 .pNext = NULL,
1010 .descriptorSetCount = 1,
1011 .pSetLayouts = &ds_layout,
1012 };
1013
1014 VkPipelineLayout pipeline_layout;
1015 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1016 ASSERT_VK_SUCCESS(err);
1017
1018 size_t shader_len = strlen(bindStateVertShaderText);
1019 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1020 void* pCode = malloc(codeSize);
1021
1022 /* try version 0 first: VkShaderStage followed by GLSL */
1023 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1024 ((uint32_t *) pCode)[1] = 0;
1025 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1026 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1027
1028 const VkShaderCreateInfo vs_ci = {
1029 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1030 .pNext = NULL,
Courtney Goeltzenleuchter1d723102015-06-18 21:49:59 -06001031 .module = VK_NULL_HANDLE,
1032 .name = "main",
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001033 .codeSize = codeSize,
1034 .pCode = pCode,
1035 .flags = 0,
1036 };
1037 VkShader vs;
1038 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1039 ASSERT_VK_SUCCESS(err);
1040
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001041 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1042 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1043 .pNext = NULL,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001044 .stage = VK_SHADER_STAGE_VERTEX,
1045 .shader = vs,
1046 .linkConstBufferCount = 0,
1047 .pLinkConstBufferInfo = NULL,
1048 .pSpecializationInfo = NULL,
1049 };
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001050 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001051 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1052 .pNext = NULL,
1053 .stageCount = 1,
1054 .pStages = &pipe_vs_ci,
1055 .pVertexInputState = NULL,
1056 .pIaState = NULL,
1057 .pTessState = NULL,
1058 .pVpState = NULL,
1059 .pRsState = NULL,
1060 .pMsState = NULL,
1061 .pDsState = NULL,
1062 .pCbState = NULL,
1063 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1064 .layout = pipeline_layout,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001065 };
1066
1067 VkPipeline pipeline;
1068 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1069 ASSERT_VK_SUCCESS(err);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001070 ASSERT_NO_FATAL_FAILURE(InitState());
1071 ASSERT_NO_FATAL_FAILURE(InitViewport());
1072 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1073 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1074 BeginCommandBuffer(cmdBuffer);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001075 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06001076 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptorSet, 0, NULL);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001077
Tobin Ehlis254eca02015-06-25 15:46:59 -06001078 msgFlags = m_errorMonitor->GetState(&msgString);
1079 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT) << "Did not warn after binding a DescriptorSet that was never updated.";
1080 if (!strstr(msgString.c_str()," bound but it was never updated. ")) {
1081 FAIL() << "Error received was not 'DS <blah> bound but it was never updated. You may want to either update it or not bind it.'";
1082 }
1083}
1084
1085TEST_F(VkLayerTest, NoBeginCmdBuffer)
1086{
1087 VkFlags msgFlags;
1088 std::string msgString;
1089
1090 ASSERT_NO_FATAL_FAILURE(InitState());
1091 m_errorMonitor->ClearState();
1092 VkCommandBufferObj cmdBuffer(m_device);
1093 // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
1094 vkEndCommandBuffer(cmdBuffer.GetBufferHandle());
1095 msgFlags = m_errorMonitor->GetState(&msgString);
1096 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after ending a CmdBuffer w/o calling BeginCommandBuffer()";
1097 if (!strstr(msgString.c_str(),"You must call vkBeginCommandBuffer() before this call to ")) {
1098 FAIL() << "Error received was not 'You must call vkBeginCommandBuffer() before this call to vkEndCommandBuffer()'";
1099 }
1100}
1101
1102TEST_F(VkLayerTest, InvalidPipelineCreateState)
1103{
1104 // Attempt to Create Gfx Pipeline w/o a VS
1105 VkFlags msgFlags;
1106 std::string msgString;
1107 VkResult err;
1108
1109 ASSERT_NO_FATAL_FAILURE(InitState());
1110 m_errorMonitor->ClearState();
1111 VkCommandBufferObj cmdBuffer(m_device);
1112 const VkDescriptorTypeCount ds_type_count = {
1113 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1114 .count = 1,
1115 };
1116 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1117 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1118 .pNext = NULL,
1119 .count = 1,
1120 .pTypeCount = &ds_type_count,
1121 };
1122 VkDescriptorPool ds_pool;
1123 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1124 ASSERT_VK_SUCCESS(err);
1125
1126 const VkDescriptorSetLayoutBinding dsl_binding = {
1127 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1128 .arraySize = 1,
1129 .stageFlags = VK_SHADER_STAGE_ALL,
1130 .pImmutableSamplers = NULL,
1131 };
1132
1133 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1134 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1135 .pNext = NULL,
1136 .count = 1,
1137 .pBinding = &dsl_binding,
1138 };
1139 VkDescriptorSetLayout ds_layout;
1140 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1141 ASSERT_VK_SUCCESS(err);
1142
1143 VkDescriptorSet descriptorSet;
1144 uint32_t ds_count = 0;
1145 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1146 ASSERT_VK_SUCCESS(err);
1147
1148 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1149 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1150 .pNext = NULL,
1151 .descriptorSetCount = 1,
1152 .pSetLayouts = &ds_layout,
1153 };
1154
1155 VkPipelineLayout pipeline_layout;
1156 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1157 ASSERT_VK_SUCCESS(err);
1158
1159 const VkGraphicsPipelineCreateInfo gp_ci = {
1160 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1161 .pNext = NULL,
1162 .stageCount = 0,
1163 .pStages = NULL, // Creating Gfx Pipeline w/o VS is a violation
1164 .pVertexInputState = NULL,
1165 .pIaState = NULL,
1166 .pTessState = NULL,
1167 .pVpState = NULL,
1168 .pRsState = NULL,
1169 .pMsState = NULL,
1170 .pDsState = NULL,
1171 .pCbState = NULL,
1172 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1173 .layout = pipeline_layout,
1174 };
1175
1176 VkPipeline pipeline;
1177 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001178
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001179 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001180 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after creating Gfx Pipeline w/o VS.";
1181 if (!strstr(msgString.c_str(),"Invalid Pipeline CreateInfo State: Vtx Shader required")) {
1182 FAIL() << "Error received was not 'Invalid Pipeline CreateInfo State: Vtx Shader required'";
1183 }
1184}
1185
Tobin Ehlisb8b06b52015-06-25 16:27:19 -06001186TEST_F(VkLayerTest, NullRenderPass)
1187{
1188 // Bind a NULL RenderPass
1189 VkFlags msgFlags;
1190 std::string msgString;
1191
1192 ASSERT_NO_FATAL_FAILURE(InitState());
1193 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1194 m_errorMonitor->ClearState();
1195 VkCommandBufferObj cmdBuffer(m_device);
1196
1197 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1198 BeginCommandBuffer(cmdBuffer);
1199 // Don't care about RenderPass handle b/c error should be flagged before that
1200 vkCmdBeginRenderPass(cmdBuffer.GetBufferHandle(), NULL);
1201
1202 msgFlags = m_errorMonitor->GetState(&msgString);
1203 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding NULL RenderPass.";
1204 if (!strstr(msgString.c_str(),"You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()")) {
1205 FAIL() << "Error received was not 'You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()'";
1206 }
1207}
1208
Tobin Ehlis254eca02015-06-25 15:46:59 -06001209TEST_F(VkLayerTest, RenderPassWithinRenderPass)
1210{
1211 // Bind a BeginRenderPass within an active RenderPass
1212 VkFlags msgFlags;
1213 std::string msgString;
1214
1215 ASSERT_NO_FATAL_FAILURE(InitState());
1216 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1217 m_errorMonitor->ClearState();
1218 VkCommandBufferObj cmdBuffer(m_device);
1219
1220 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1221 BeginCommandBuffer(cmdBuffer);
Tobin Ehlisb8b06b52015-06-25 16:27:19 -06001222 // Just create a dummy Renderpass that's non-NULL so we can get to the proper error
1223 const VkRenderPassBegin rp_begin = {
1224 .renderPass = (VkRenderPass) 0xc001d00d,
1225 .framebuffer = NULL
1226 };
1227 vkCmdBeginRenderPass(cmdBuffer.GetBufferHandle(), &rp_begin);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001228
1229 msgFlags = m_errorMonitor->GetState(&msgString);
1230 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding RenderPass w/i an active RenderPass.";
1231 if (!strstr(msgString.c_str(),"Cannot call vkCmdBeginRenderPass() during an active RenderPass ")) {
1232 FAIL() << "Error received was not 'Cannot call vkCmdBeginRenderPass() during an active RenderPass...'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001233 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001234}
1235
1236TEST_F(VkLayerTest, InvalidDynamicStateObject)
1237{
1238 // Create a valid cmd buffer
1239 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001240 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1241 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001242}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001243
Tobin Ehlise4076782015-06-24 15:53:07 -06001244TEST_F(VkLayerTest, VtxBufferNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001245{
1246 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001247 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001248 std::string msgString;
1249 VkResult err;
1250
1251 ASSERT_NO_FATAL_FAILURE(InitState());
1252 m_errorMonitor->ClearState();
1253 VkCommandBufferObj cmdBuffer(m_device);
1254 const VkDescriptorTypeCount ds_type_count = {
1255 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1256 .count = 1,
1257 };
1258 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1259 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1260 .pNext = NULL,
1261 .count = 1,
1262 .pTypeCount = &ds_type_count,
1263 };
1264 VkDescriptorPool ds_pool;
1265 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1266 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001267
1268 const VkDescriptorSetLayoutBinding dsl_binding = {
1269 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001270 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001271 .stageFlags = VK_SHADER_STAGE_ALL,
1272 .pImmutableSamplers = NULL,
1273 };
1274
1275 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1276 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1277 .pNext = NULL,
1278 .count = 1,
1279 .pBinding = &dsl_binding,
1280 };
1281 VkDescriptorSetLayout ds_layout;
1282 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1283 ASSERT_VK_SUCCESS(err);
1284
1285 VkDescriptorSet descriptorSet;
1286 uint32_t ds_count = 0;
1287 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1288 ASSERT_VK_SUCCESS(err);
1289
1290 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1291 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1292 .pNext = NULL,
1293 .descriptorSetCount = 1,
1294 .pSetLayouts = &ds_layout,
1295 };
1296
1297 VkPipelineLayout pipeline_layout;
1298 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1299 ASSERT_VK_SUCCESS(err);
1300
1301 size_t shader_len = strlen(bindStateVertShaderText);
1302 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1303 void* pCode = malloc(codeSize);
1304
1305 /* try version 0 first: VkShaderStage followed by GLSL */
1306 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1307 ((uint32_t *) pCode)[1] = 0;
1308 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1309 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1310
1311 const VkShaderCreateInfo vs_ci = {
1312 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1313 .pNext = NULL,
Courtney Goeltzenleuchter1d723102015-06-18 21:49:59 -06001314 .module = VK_NULL_HANDLE,
1315 .name = "main",
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001316 .codeSize = codeSize,
1317 .pCode = pCode,
1318 .flags = 0,
1319 };
1320 VkShader vs;
1321 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1322
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001323 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1324 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1325 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001326 .stage = VK_SHADER_STAGE_VERTEX,
1327 .shader = vs,
1328 .linkConstBufferCount = 0,
1329 .pLinkConstBufferInfo = NULL,
1330 .pSpecializationInfo = NULL,
1331 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001332 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001333 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1334 .pNext = NULL,
1335 .stageCount = 1,
1336 .pStages = &pipe_vs_ci,
1337 .pVertexInputState = NULL,
1338 .pIaState = NULL,
1339 .pTessState = NULL,
1340 .pVpState = NULL,
1341 .pRsState = NULL,
1342 .pMsState = NULL,
1343 .pDsState = NULL,
1344 .pCbState = NULL,
1345 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1346 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001347 };
1348
1349 VkPipeline pipeline;
1350 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1351 ASSERT_VK_SUCCESS(err);
1352
1353 err= cmdBuffer.BeginCommandBuffer();
1354 ASSERT_VK_SUCCESS(err);
1355 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1356 // Should error before calling to driver so don't care about actual data
1357 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1358
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001359 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -06001360 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o active RenderPass.";
1361 if (!strstr(msgString.c_str(),"Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.")) {
1362 FAIL() << "Error received was not 'Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001363 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001364}
1365
1366TEST_F(VkLayerTest, DSTypeMismatch)
1367{
1368 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001369 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001370 std::string msgString;
1371 VkResult err;
1372
1373 ASSERT_NO_FATAL_FAILURE(InitState());
1374 m_errorMonitor->ClearState();
1375 //VkDescriptorSetObj descriptorSet(m_device);
1376 const VkDescriptorTypeCount ds_type_count = {
1377 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1378 .count = 1,
1379 };
1380 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1381 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1382 .pNext = NULL,
1383 .count = 1,
1384 .pTypeCount = &ds_type_count,
1385 };
1386 VkDescriptorPool ds_pool;
1387 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1388 ASSERT_VK_SUCCESS(err);
1389 const VkDescriptorSetLayoutBinding dsl_binding = {
1390 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001391 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001392 .stageFlags = VK_SHADER_STAGE_ALL,
1393 .pImmutableSamplers = NULL,
1394 };
1395
1396 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1397 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1398 .pNext = NULL,
1399 .count = 1,
1400 .pBinding = &dsl_binding,
1401 };
1402 VkDescriptorSetLayout ds_layout;
1403 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1404 ASSERT_VK_SUCCESS(err);
1405
1406 VkDescriptorSet descriptorSet;
1407 uint32_t ds_count = 0;
1408 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1409 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001410
1411 const VkSamplerCreateInfo sampler_ci = {
1412 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1413 .pNext = NULL,
1414 .magFilter = VK_TEX_FILTER_NEAREST,
1415 .minFilter = VK_TEX_FILTER_NEAREST,
1416 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1417 .addressU = VK_TEX_ADDRESS_CLAMP,
1418 .addressV = VK_TEX_ADDRESS_CLAMP,
1419 .addressW = VK_TEX_ADDRESS_CLAMP,
1420 .mipLodBias = 1.0,
1421 .maxAnisotropy = 1,
1422 .compareOp = VK_COMPARE_OP_NEVER,
1423 .minLod = 1.0,
1424 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001425 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001426 };
1427 VkSampler sampler;
1428 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1429 ASSERT_VK_SUCCESS(err);
1430
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001431 VkDescriptorInfo descriptor_info;
1432 memset(&descriptor_info, 0, sizeof(descriptor_info));
1433 descriptor_info.sampler = sampler;
1434
1435 VkWriteDescriptorSet descriptor_write;
1436 memset(&descriptor_write, 0, sizeof(descriptor_write));
1437 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1438 descriptor_write.destSet = descriptorSet;
1439 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001440 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001441 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1442 descriptor_write.pDescriptors = &descriptor_info;
1443
1444 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1445
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001446 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001447 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 +08001448 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1449 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 -06001450 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001451}
1452
1453TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1454{
1455 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001456 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001457 std::string msgString;
1458 VkResult err;
1459
1460 ASSERT_NO_FATAL_FAILURE(InitState());
1461 m_errorMonitor->ClearState();
1462 //VkDescriptorSetObj descriptorSet(m_device);
1463 const VkDescriptorTypeCount ds_type_count = {
1464 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1465 .count = 1,
1466 };
1467 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1468 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1469 .pNext = NULL,
1470 .count = 1,
1471 .pTypeCount = &ds_type_count,
1472 };
1473 VkDescriptorPool ds_pool;
1474 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1475 ASSERT_VK_SUCCESS(err);
1476 const VkDescriptorSetLayoutBinding dsl_binding = {
1477 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001478 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001479 .stageFlags = VK_SHADER_STAGE_ALL,
1480 .pImmutableSamplers = NULL,
1481 };
1482
1483 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1484 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1485 .pNext = NULL,
1486 .count = 1,
1487 .pBinding = &dsl_binding,
1488 };
1489 VkDescriptorSetLayout ds_layout;
1490 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1491 ASSERT_VK_SUCCESS(err);
1492
1493 VkDescriptorSet descriptorSet;
1494 uint32_t ds_count = 0;
1495 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1496 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001497
1498 const VkSamplerCreateInfo sampler_ci = {
1499 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1500 .pNext = NULL,
1501 .magFilter = VK_TEX_FILTER_NEAREST,
1502 .minFilter = VK_TEX_FILTER_NEAREST,
1503 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1504 .addressU = VK_TEX_ADDRESS_CLAMP,
1505 .addressV = VK_TEX_ADDRESS_CLAMP,
1506 .addressW = VK_TEX_ADDRESS_CLAMP,
1507 .mipLodBias = 1.0,
1508 .maxAnisotropy = 1,
1509 .compareOp = VK_COMPARE_OP_NEVER,
1510 .minLod = 1.0,
1511 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001512 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001513 };
1514 VkSampler sampler;
1515 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1516 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001517
1518 VkDescriptorInfo descriptor_info;
1519 memset(&descriptor_info, 0, sizeof(descriptor_info));
1520 descriptor_info.sampler = sampler;
1521
1522 VkWriteDescriptorSet descriptor_write;
1523 memset(&descriptor_write, 0, sizeof(descriptor_write));
1524 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1525 descriptor_write.destSet = descriptorSet;
1526 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1527 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001528 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001529 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1530 descriptor_write.pDescriptors = &descriptor_info;
1531
1532 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1533
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001534 msgFlags = m_errorMonitor->GetState(&msgString);
1535 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 +08001536 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1537 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 -06001538 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001539}
1540
1541TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1542{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001543 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001544 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001545 std::string msgString;
1546 VkResult err;
1547
1548 ASSERT_NO_FATAL_FAILURE(InitState());
1549 m_errorMonitor->ClearState();
1550 //VkDescriptorSetObj descriptorSet(m_device);
1551 const VkDescriptorTypeCount ds_type_count = {
1552 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1553 .count = 1,
1554 };
1555 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1556 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1557 .pNext = NULL,
1558 .count = 1,
1559 .pTypeCount = &ds_type_count,
1560 };
1561 VkDescriptorPool ds_pool;
1562 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1563 ASSERT_VK_SUCCESS(err);
1564 const VkDescriptorSetLayoutBinding dsl_binding = {
1565 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001566 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001567 .stageFlags = VK_SHADER_STAGE_ALL,
1568 .pImmutableSamplers = NULL,
1569 };
1570
1571 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1572 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1573 .pNext = NULL,
1574 .count = 1,
1575 .pBinding = &dsl_binding,
1576 };
1577 VkDescriptorSetLayout ds_layout;
1578 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1579 ASSERT_VK_SUCCESS(err);
1580
1581 VkDescriptorSet descriptorSet;
1582 uint32_t ds_count = 0;
1583 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1584 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001585
1586 const VkSamplerCreateInfo sampler_ci = {
1587 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1588 .pNext = NULL,
1589 .magFilter = VK_TEX_FILTER_NEAREST,
1590 .minFilter = VK_TEX_FILTER_NEAREST,
1591 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1592 .addressU = VK_TEX_ADDRESS_CLAMP,
1593 .addressV = VK_TEX_ADDRESS_CLAMP,
1594 .addressW = VK_TEX_ADDRESS_CLAMP,
1595 .mipLodBias = 1.0,
1596 .maxAnisotropy = 1,
1597 .compareOp = VK_COMPARE_OP_NEVER,
1598 .minLod = 1.0,
1599 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001600 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001601 };
1602 VkSampler sampler;
1603 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1604 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001605
1606 VkDescriptorInfo descriptor_info;
1607 memset(&descriptor_info, 0, sizeof(descriptor_info));
1608 descriptor_info.sampler = sampler;
1609
1610 VkWriteDescriptorSet descriptor_write;
1611 memset(&descriptor_write, 0, sizeof(descriptor_write));
1612 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1613 descriptor_write.destSet = descriptorSet;
1614 descriptor_write.destBinding = 2;
1615 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001616 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001617 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1618 descriptor_write.pDescriptors = &descriptor_info;
1619
1620 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1621
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001622 msgFlags = m_errorMonitor->GetState(&msgString);
1623 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 -06001624 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1625 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1626 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001627}
1628
1629TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1630{
1631 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001632 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001633 std::string msgString;
1634 VkResult err;
1635
1636 ASSERT_NO_FATAL_FAILURE(InitState());
1637 m_errorMonitor->ClearState();
1638 //VkDescriptorSetObj descriptorSet(m_device);
1639 const VkDescriptorTypeCount ds_type_count = {
1640 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1641 .count = 1,
1642 };
1643 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1644 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1645 .pNext = NULL,
1646 .count = 1,
1647 .pTypeCount = &ds_type_count,
1648 };
1649 VkDescriptorPool ds_pool;
1650 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1651 ASSERT_VK_SUCCESS(err);
1652 const VkDescriptorSetLayoutBinding dsl_binding = {
1653 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001654 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001655 .stageFlags = VK_SHADER_STAGE_ALL,
1656 .pImmutableSamplers = NULL,
1657 };
1658
1659 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1660 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1661 .pNext = NULL,
1662 .count = 1,
1663 .pBinding = &dsl_binding,
1664 };
1665 VkDescriptorSetLayout ds_layout;
1666 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1667 ASSERT_VK_SUCCESS(err);
1668
1669 VkDescriptorSet descriptorSet;
1670 uint32_t ds_count = 0;
1671 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1672 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001673
1674 const VkSamplerCreateInfo sampler_ci = {
1675 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1676 .pNext = NULL,
1677 .magFilter = VK_TEX_FILTER_NEAREST,
1678 .minFilter = VK_TEX_FILTER_NEAREST,
1679 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1680 .addressU = VK_TEX_ADDRESS_CLAMP,
1681 .addressV = VK_TEX_ADDRESS_CLAMP,
1682 .addressW = VK_TEX_ADDRESS_CLAMP,
1683 .mipLodBias = 1.0,
1684 .maxAnisotropy = 1,
1685 .compareOp = VK_COMPARE_OP_NEVER,
1686 .minLod = 1.0,
1687 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001688 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001689 };
1690 VkSampler sampler;
1691 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1692 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001693
1694
1695 VkDescriptorInfo descriptor_info;
1696 memset(&descriptor_info, 0, sizeof(descriptor_info));
1697 descriptor_info.sampler = sampler;
1698
1699 VkWriteDescriptorSet descriptor_write;
1700 memset(&descriptor_write, 0, sizeof(descriptor_write));
1701 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1702 descriptor_write.destSet = descriptorSet;
1703 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001704 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001705 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1706 descriptor_write.pDescriptors = &descriptor_info;
1707
1708 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1709
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001710 msgFlags = m_errorMonitor->GetState(&msgString);
1711 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 -06001712 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1713 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1714 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001715}
1716
1717TEST_F(VkLayerTest, NumSamplesMismatch)
1718{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001719 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001720 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001721 std::string msgString;
1722 VkResult err;
1723
1724 ASSERT_NO_FATAL_FAILURE(InitState());
1725 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1726 m_errorMonitor->ClearState();
1727 VkCommandBufferObj cmdBuffer(m_device);
1728 const VkDescriptorTypeCount ds_type_count = {
1729 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1730 .count = 1,
1731 };
1732 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1733 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1734 .pNext = NULL,
1735 .count = 1,
1736 .pTypeCount = &ds_type_count,
1737 };
1738 VkDescriptorPool ds_pool;
1739 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1740 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001741
1742 const VkDescriptorSetLayoutBinding dsl_binding = {
1743 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001744 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001745 .stageFlags = VK_SHADER_STAGE_ALL,
1746 .pImmutableSamplers = NULL,
1747 };
1748
1749 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1750 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1751 .pNext = NULL,
1752 .count = 1,
1753 .pBinding = &dsl_binding,
1754 };
1755 VkDescriptorSetLayout ds_layout;
1756 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1757 ASSERT_VK_SUCCESS(err);
1758
1759 VkDescriptorSet descriptorSet;
1760 uint32_t ds_count = 0;
1761 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1762 ASSERT_VK_SUCCESS(err);
1763
1764 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1765 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1766 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001767 .rasterSamples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001768 .multisampleEnable = 1,
1769 .sampleShadingEnable = 0,
1770 .minSampleShading = 1.0,
1771 .sampleMask = 15,
1772 };
1773
1774 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1775 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1776 .pNext = NULL,
1777 .descriptorSetCount = 1,
1778 .pSetLayouts = &ds_layout,
1779 };
1780
1781 VkPipelineLayout pipeline_layout;
1782 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1783 ASSERT_VK_SUCCESS(err);
1784
1785 size_t shader_len = strlen(bindStateVertShaderText);
1786 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1787 void* pCode = malloc(codeSize);
1788
1789 /* try version 0 first: VkShaderStage followed by GLSL */
1790 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1791 ((uint32_t *) pCode)[1] = 0;
1792 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1793 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1794
1795 const VkShaderCreateInfo vs_ci = {
1796 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1797 .pNext = NULL,
Courtney Goeltzenleuchter1d723102015-06-18 21:49:59 -06001798 .module = VK_NULL_HANDLE,
1799 .name = "main",
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001800 .codeSize = codeSize,
1801 .pCode = pCode,
1802 .flags = 0,
1803 };
1804 VkShader vs;
1805 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1806 ASSERT_VK_SUCCESS(err);
1807
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001808 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1809 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1810 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001811 .stage = VK_SHADER_STAGE_VERTEX,
1812 .shader = vs,
1813 .linkConstBufferCount = 0,
1814 .pLinkConstBufferInfo = NULL,
1815 .pSpecializationInfo = NULL,
1816 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001817 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001818 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1819 .pNext = NULL,
1820 .stageCount = 1,
1821 .pStages = &pipe_vs_ci,
1822 .pVertexInputState = NULL,
1823 .pIaState = NULL,
1824 .pTessState = NULL,
1825 .pVpState = NULL,
1826 .pRsState = NULL,
1827 .pMsState = &pipe_ms_state_ci,
1828 .pDsState = NULL,
1829 .pCbState = NULL,
1830 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1831 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001832 };
1833
1834 VkPipeline pipeline;
1835 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1836 ASSERT_VK_SUCCESS(err);
1837
1838 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1839 BeginCommandBuffer(cmdBuffer);
1840 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1841
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001842 msgFlags = m_errorMonitor->GetState(&msgString);
1843 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 -06001844 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1845 FAIL() << "Error received was not 'Num samples mismatch!...'";
1846 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001847}
Tobin Ehlise4076782015-06-24 15:53:07 -06001848TEST_F(VkLayerTest, PipelineNotBound)
1849{
1850 VkFlags msgFlags;
1851 std::string msgString;
1852 VkResult err;
1853
1854 ASSERT_NO_FATAL_FAILURE(InitState());
1855 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1856 m_errorMonitor->ClearState();
1857 VkCommandBufferObj cmdBuffer(m_device);
1858 const VkDescriptorTypeCount ds_type_count = {
1859 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1860 .count = 1,
1861 };
1862 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1863 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1864 .pNext = NULL,
1865 .count = 1,
1866 .pTypeCount = &ds_type_count,
1867 };
1868 VkDescriptorPool ds_pool;
1869 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1870 ASSERT_VK_SUCCESS(err);
1871
1872 const VkDescriptorSetLayoutBinding dsl_binding = {
1873 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1874 .arraySize = 1,
1875 .stageFlags = VK_SHADER_STAGE_ALL,
1876 .pImmutableSamplers = NULL,
1877 };
1878
1879 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1880 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1881 .pNext = NULL,
1882 .count = 1,
1883 .pBinding = &dsl_binding,
1884 };
1885 VkDescriptorSetLayout ds_layout;
1886 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1887 ASSERT_VK_SUCCESS(err);
1888
1889 VkDescriptorSet descriptorSet;
1890 uint32_t ds_count = 0;
1891 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1892 ASSERT_VK_SUCCESS(err);
1893
1894 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1895 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1896 .pNext = NULL,
1897 .descriptorSetCount = 1,
1898 .pSetLayouts = &ds_layout,
1899 };
1900
1901 VkPipelineLayout pipeline_layout;
1902 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1903 ASSERT_VK_SUCCESS(err);
1904
1905 size_t shader_len = strlen(bindStateVertShaderText);
1906 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1907 void* pCode = malloc(codeSize);
1908
1909 /* try version 0 first: VkShaderStage followed by GLSL */
1910 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1911 ((uint32_t *) pCode)[1] = 0;
1912 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1913 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1914
1915 const VkShaderCreateInfo vs_ci = {
1916 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1917 .pNext = NULL,
1918 .module = VK_NULL_HANDLE,
1919 .name = "main",
1920 .codeSize = codeSize,
1921 .pCode = pCode,
1922 .flags = 0,
1923 };
1924 VkShader vs;
1925 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1926 ASSERT_VK_SUCCESS(err);
1927
1928 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
1929 //err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1930 ASSERT_VK_SUCCESS(err);
1931
1932 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1933 BeginCommandBuffer(cmdBuffer);
1934 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
1935
1936 msgFlags = m_errorMonitor->GetState(&msgString);
1937 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
1938 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
1939 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
1940 }
1941}
1942TEST_F(VkLayerTest, VtxBufferBadIndex)
1943{
1944 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1945 VkFlags msgFlags;
1946 std::string msgString;
1947 VkResult err;
1948
1949 ASSERT_NO_FATAL_FAILURE(InitState());
1950 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1951 m_errorMonitor->ClearState();
1952 VkCommandBufferObj cmdBuffer(m_device);
1953 const VkDescriptorTypeCount ds_type_count = {
1954 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1955 .count = 1,
1956 };
1957 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1958 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1959 .pNext = NULL,
1960 .count = 1,
1961 .pTypeCount = &ds_type_count,
1962 };
1963 VkDescriptorPool ds_pool;
1964 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1965 ASSERT_VK_SUCCESS(err);
1966
1967 const VkDescriptorSetLayoutBinding dsl_binding = {
1968 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1969 .arraySize = 1,
1970 .stageFlags = VK_SHADER_STAGE_ALL,
1971 .pImmutableSamplers = NULL,
1972 };
1973
1974 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1975 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1976 .pNext = NULL,
1977 .count = 1,
1978 .pBinding = &dsl_binding,
1979 };
1980 VkDescriptorSetLayout ds_layout;
1981 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1982 ASSERT_VK_SUCCESS(err);
1983
1984 VkDescriptorSet descriptorSet;
1985 uint32_t ds_count = 0;
1986 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1987 ASSERT_VK_SUCCESS(err);
1988
1989 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1990 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1991 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001992 .rasterSamples = 1,
Tobin Ehlise4076782015-06-24 15:53:07 -06001993 .multisampleEnable = 1,
1994 .sampleShadingEnable = 0,
1995 .minSampleShading = 1.0,
1996 .sampleMask = 15,
1997 };
1998
1999 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
2000 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2001 .pNext = NULL,
2002 .descriptorSetCount = 1,
2003 .pSetLayouts = &ds_layout,
2004 };
2005
2006 VkPipelineLayout pipeline_layout;
2007 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
2008 ASSERT_VK_SUCCESS(err);
2009
2010 size_t shader_len = strlen(bindStateVertShaderText);
2011 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
2012 void* pCode = malloc(codeSize);
2013
2014 /* try version 0 first: VkShaderStage followed by GLSL */
2015 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
2016 ((uint32_t *) pCode)[1] = 0;
2017 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
2018 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
2019
2020 const VkShaderCreateInfo vs_ci = {
2021 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
2022 .pNext = NULL,
2023 .module = VK_NULL_HANDLE,
2024 .name = "main",
2025 .codeSize = codeSize,
2026 .pCode = pCode,
2027 .flags = 0,
2028 };
2029 VkShader vs;
2030 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
2031 ASSERT_VK_SUCCESS(err);
2032
2033 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
2034 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2035 .pNext = NULL,
2036 .stage = VK_SHADER_STAGE_VERTEX,
2037 .shader = vs,
2038 .linkConstBufferCount = 0,
2039 .pLinkConstBufferInfo = NULL,
2040 .pSpecializationInfo = NULL,
2041 };
2042 const VkGraphicsPipelineCreateInfo gp_ci = {
2043 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
2044 .pNext = NULL,
2045 .stageCount = 1,
2046 .pStages = &pipe_vs_ci,
2047 .pVertexInputState = NULL,
2048 .pIaState = NULL,
2049 .pTessState = NULL,
2050 .pVpState = NULL,
2051 .pRsState = NULL,
2052 .pMsState = &pipe_ms_state_ci,
2053 .pDsState = NULL,
2054 .pCbState = NULL,
2055 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
2056 .layout = pipeline_layout,
2057 };
2058
2059 VkPipeline pipeline;
2060 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
2061 ASSERT_VK_SUCCESS(err);
2062
2063 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
2064 BeginCommandBuffer(cmdBuffer);
2065 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
2066 // Should error before calling to driver so don't care about actual data
2067 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
2068
2069 msgFlags = m_errorMonitor->GetState(&msgString);
2070 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding Vtx Buffer w/o VBO attached to PSO.";
2071 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
2072 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
2073 }
2074}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06002075#endif
2076#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06002077#if GTEST_IS_THREADSAFE
2078struct thread_data_struct {
2079 VkCmdBuffer cmdBuffer;
2080 VkEvent event;
2081 bool bailout;
2082};
2083
2084extern "C" void *AddToCommandBuffer(void *arg)
2085{
2086 struct thread_data_struct *data = (struct thread_data_struct *) arg;
2087 std::string msgString;
2088
2089 for (int i = 0; i<10000; i++) {
Tony Barbourc2e987e2015-06-29 16:20:35 -06002090 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPELINE_STAGE_ALL_GPU_COMMANDS);
Mike Stroyan09aae812015-05-12 16:00:45 -06002091 if (data->bailout) {
2092 break;
2093 }
2094 }
2095 return NULL;
2096}
2097
2098TEST_F(VkLayerTest, ThreadCmdBufferCollision)
2099{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002100 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06002101 std::string msgString;
2102 pthread_t thread;
2103 pthread_attr_t thread_attr;
2104
2105 ASSERT_NO_FATAL_FAILURE(InitState());
2106 ASSERT_NO_FATAL_FAILURE(InitViewport());
2107 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2108
2109 VkCommandBufferObj cmdBuffer(m_device);
2110
2111 m_errorMonitor->ClearState();
2112 pthread_attr_init(&thread_attr);
2113 BeginCommandBuffer(cmdBuffer);
2114
2115 VkEventCreateInfo event_info;
2116 VkEvent event;
2117 VkMemoryRequirements mem_req;
Mike Stroyan09aae812015-05-12 16:00:45 -06002118 VkResult err;
2119
2120 memset(&event_info, 0, sizeof(event_info));
2121 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2122
2123 err = vkCreateEvent(device(), &event_info, &event);
2124 ASSERT_VK_SUCCESS(err);
2125
Tony Barbour426b9052015-06-24 16:06:58 -06002126 err = vkGetObjectMemoryRequirements(device(), VK_OBJECT_TYPE_EVENT, event, &mem_req);
Mike Stroyan09aae812015-05-12 16:00:45 -06002127 ASSERT_VK_SUCCESS(err);
2128
2129 VkMemoryAllocInfo mem_info;
2130 VkDeviceMemory event_mem;
2131
Mike Stroyan09aae812015-05-12 16:00:45 -06002132 memset(&mem_info, 0, sizeof(mem_info));
2133 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
2134 mem_info.allocationSize = mem_req.size;
Courtney Goeltzenleuchterb25c9b92015-06-18 17:01:41 -06002135 mem_info.memProps = 0;
Mike Stroyan09aae812015-05-12 16:00:45 -06002136 err = vkAllocMemory(device(), &mem_info, &event_mem);
2137 ASSERT_VK_SUCCESS(err);
2138
Mark Lobodzinski23182612015-05-29 09:32:35 -05002139 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06002140 ASSERT_VK_SUCCESS(err);
2141
2142 err = vkResetEvent(device(), event);
2143 ASSERT_VK_SUCCESS(err);
2144
2145 struct thread_data_struct data;
2146 data.cmdBuffer = cmdBuffer.obj();
2147 data.event = event;
2148 data.bailout = false;
2149 m_errorMonitor->SetBailout(&data.bailout);
2150 // Add many entries to command buffer from another thread.
2151 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
2152 // Add many entries to command buffer from this thread at the same time.
2153 AddToCommandBuffer(&data);
2154 pthread_join(thread, NULL);
2155 EndCommandBuffer(cmdBuffer);
2156
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002157 msgFlags = m_errorMonitor->GetState(&msgString);
Mike Stroyaned254572015-06-17 16:32:06 -06002158 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 -06002159 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05002160 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06002161 }
2162
2163}
2164#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06002165#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12002166
2167#if SHADER_CHECKER_TESTS
2168TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
2169{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002170 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12002171 std::string msgString;
2172 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002173 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002174
2175 char const *vsSource =
2176 "#version 140\n"
2177 "#extension GL_ARB_separate_shader_objects: require\n"
2178 "#extension GL_ARB_shading_language_420pack: require\n"
2179 "\n"
2180 "layout(location=0) out float x;\n"
2181 "void main(){\n"
2182 " gl_Position = vec4(1);\n"
2183 " x = 0;\n"
2184 "}\n";
2185 char const *fsSource =
2186 "#version 140\n"
2187 "#extension GL_ARB_separate_shader_objects: require\n"
2188 "#extension GL_ARB_shading_language_420pack: require\n"
2189 "\n"
2190 "layout(location=0) out vec4 color;\n"
2191 "void main(){\n"
2192 " color = vec4(1);\n"
2193 "}\n";
2194
2195 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2196 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2197
2198 VkPipelineObj pipe(m_device);
2199 pipe.AddShader(&vs);
2200 pipe.AddShader(&fs);
2201
2202 VkCommandBufferObj dummyCmd(m_device);
2203 VkDescriptorSetObj descriptorSet(m_device);
2204 descriptorSet.AppendDummy();
2205 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2206
2207 m_errorMonitor->ClearState();
2208 pipe.CreateVKPipeline(descriptorSet);
2209
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002210 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002211
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002212 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002213 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
2214 FAIL() << "Incorrect warning: " << msgString;
2215 }
2216}
Chris Forbes5af3bf22015-05-25 11:13:08 +12002217
Chris Forbes3c10b852015-05-25 11:13:13 +12002218TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
2219{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002220 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12002221 std::string msgString;
2222 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002223 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12002224
2225 char const *vsSource =
2226 "#version 140\n"
2227 "#extension GL_ARB_separate_shader_objects: require\n"
2228 "#extension GL_ARB_shading_language_420pack: require\n"
2229 "\n"
2230 "void main(){\n"
2231 " gl_Position = vec4(1);\n"
2232 "}\n";
2233 char const *fsSource =
2234 "#version 140\n"
2235 "#extension GL_ARB_separate_shader_objects: require\n"
2236 "#extension GL_ARB_shading_language_420pack: require\n"
2237 "\n"
2238 "layout(location=0) in float x;\n"
2239 "layout(location=0) out vec4 color;\n"
2240 "void main(){\n"
2241 " color = vec4(x);\n"
2242 "}\n";
2243
2244 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2245 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2246
2247 VkPipelineObj pipe(m_device);
2248 pipe.AddShader(&vs);
2249 pipe.AddShader(&fs);
2250
2251 VkCommandBufferObj dummyCmd(m_device);
2252 VkDescriptorSetObj descriptorSet(m_device);
2253 descriptorSet.AppendDummy();
2254 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2255
2256 m_errorMonitor->ClearState();
2257 pipe.CreateVKPipeline(descriptorSet);
2258
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002259 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12002260
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002261 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12002262 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
2263 FAIL() << "Incorrect error: " << msgString;
2264 }
2265}
2266
Chris Forbescc281692015-05-25 11:13:17 +12002267TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
2268{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002269 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12002270 std::string msgString;
2271 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002272 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12002273
2274 char const *vsSource =
2275 "#version 140\n"
2276 "#extension GL_ARB_separate_shader_objects: require\n"
2277 "#extension GL_ARB_shading_language_420pack: require\n"
2278 "\n"
2279 "layout(location=0) out int x;\n"
2280 "void main(){\n"
2281 " x = 0;\n"
2282 " gl_Position = vec4(1);\n"
2283 "}\n";
2284 char const *fsSource =
2285 "#version 140\n"
2286 "#extension GL_ARB_separate_shader_objects: require\n"
2287 "#extension GL_ARB_shading_language_420pack: require\n"
2288 "\n"
2289 "layout(location=0) in float x;\n" /* VS writes int */
2290 "layout(location=0) out vec4 color;\n"
2291 "void main(){\n"
2292 " color = vec4(x);\n"
2293 "}\n";
2294
2295 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2296 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2297
2298 VkPipelineObj pipe(m_device);
2299 pipe.AddShader(&vs);
2300 pipe.AddShader(&fs);
2301
2302 VkCommandBufferObj dummyCmd(m_device);
2303 VkDescriptorSetObj descriptorSet(m_device);
2304 descriptorSet.AppendDummy();
2305 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2306
2307 m_errorMonitor->ClearState();
2308 pipe.CreateVKPipeline(descriptorSet);
2309
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002310 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12002311
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002312 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12002313 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
2314 FAIL() << "Incorrect error: " << msgString;
2315 }
2316}
2317
Chris Forbes8291c052015-05-25 11:13:28 +12002318TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
2319{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002320 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12002321 std::string msgString;
2322 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002323 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12002324
2325 VkVertexInputBindingDescription input_binding;
2326 memset(&input_binding, 0, sizeof(input_binding));
2327
2328 VkVertexInputAttributeDescription input_attrib;
2329 memset(&input_attrib, 0, sizeof(input_attrib));
2330 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2331
2332 char const *vsSource =
2333 "#version 140\n"
2334 "#extension GL_ARB_separate_shader_objects: require\n"
2335 "#extension GL_ARB_shading_language_420pack: require\n"
2336 "\n"
2337 "void main(){\n"
2338 " gl_Position = vec4(1);\n"
2339 "}\n";
2340 char const *fsSource =
2341 "#version 140\n"
2342 "#extension GL_ARB_separate_shader_objects: require\n"
2343 "#extension GL_ARB_shading_language_420pack: require\n"
2344 "\n"
2345 "layout(location=0) out vec4 color;\n"
2346 "void main(){\n"
2347 " color = vec4(1);\n"
2348 "}\n";
2349
2350 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2351 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2352
2353 VkPipelineObj pipe(m_device);
2354 pipe.AddShader(&vs);
2355 pipe.AddShader(&fs);
2356
2357 pipe.AddVertexInputBindings(&input_binding, 1);
2358 pipe.AddVertexInputAttribs(&input_attrib, 1);
2359
2360 VkCommandBufferObj dummyCmd(m_device);
2361 VkDescriptorSetObj descriptorSet(m_device);
2362 descriptorSet.AppendDummy();
2363 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2364
2365 m_errorMonitor->ClearState();
2366 pipe.CreateVKPipeline(descriptorSet);
2367
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002368 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes8291c052015-05-25 11:13:28 +12002369
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002370 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12002371 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
2372 FAIL() << "Incorrect warning: " << msgString;
2373 }
2374}
2375
Chris Forbes37367e62015-05-25 11:13:29 +12002376TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
2377{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002378 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12002379 std::string msgString;
2380 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002381 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12002382
2383 char const *vsSource =
2384 "#version 140\n"
2385 "#extension GL_ARB_separate_shader_objects: require\n"
2386 "#extension GL_ARB_shading_language_420pack: require\n"
2387 "\n"
2388 "layout(location=0) in vec4 x;\n" /* not provided */
2389 "void main(){\n"
2390 " gl_Position = x;\n"
2391 "}\n";
2392 char const *fsSource =
2393 "#version 140\n"
2394 "#extension GL_ARB_separate_shader_objects: require\n"
2395 "#extension GL_ARB_shading_language_420pack: require\n"
2396 "\n"
2397 "layout(location=0) out vec4 color;\n"
2398 "void main(){\n"
2399 " color = vec4(1);\n"
2400 "}\n";
2401
2402 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2403 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2404
2405 VkPipelineObj pipe(m_device);
2406 pipe.AddShader(&vs);
2407 pipe.AddShader(&fs);
2408
2409 VkCommandBufferObj dummyCmd(m_device);
2410 VkDescriptorSetObj descriptorSet(m_device);
2411 descriptorSet.AppendDummy();
2412 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2413
2414 m_errorMonitor->ClearState();
2415 pipe.CreateVKPipeline(descriptorSet);
2416
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002417 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002418
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002419 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002420 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2421 FAIL() << "Incorrect warning: " << msgString;
2422 }
2423}
2424
Chris Forbesa4b02322015-05-25 11:13:31 +12002425TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2426{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002427 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002428 std::string msgString;
2429 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002430 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002431
2432 VkVertexInputBindingDescription input_binding;
2433 memset(&input_binding, 0, sizeof(input_binding));
2434
2435 VkVertexInputAttributeDescription input_attrib;
2436 memset(&input_attrib, 0, sizeof(input_attrib));
2437 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2438
2439 char const *vsSource =
2440 "#version 140\n"
2441 "#extension GL_ARB_separate_shader_objects: require\n"
2442 "#extension GL_ARB_shading_language_420pack: require\n"
2443 "\n"
2444 "layout(location=0) in int x;\n" /* attrib provided float */
2445 "void main(){\n"
2446 " gl_Position = vec4(x);\n"
2447 "}\n";
2448 char const *fsSource =
2449 "#version 140\n"
2450 "#extension GL_ARB_separate_shader_objects: require\n"
2451 "#extension GL_ARB_shading_language_420pack: require\n"
2452 "\n"
2453 "layout(location=0) out vec4 color;\n"
2454 "void main(){\n"
2455 " color = vec4(1);\n"
2456 "}\n";
2457
2458 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2459 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2460
2461 VkPipelineObj pipe(m_device);
2462 pipe.AddShader(&vs);
2463 pipe.AddShader(&fs);
2464
2465 pipe.AddVertexInputBindings(&input_binding, 1);
2466 pipe.AddVertexInputAttribs(&input_attrib, 1);
2467
2468 VkCommandBufferObj dummyCmd(m_device);
2469 VkDescriptorSetObj descriptorSet(m_device);
2470 descriptorSet.AppendDummy();
2471 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2472
2473 m_errorMonitor->ClearState();
2474 pipe.CreateVKPipeline(descriptorSet);
2475
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002476 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002477
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002478 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002479 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2480 FAIL() << "Incorrect error: " << msgString;
2481 }
2482}
2483
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002484TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2485{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002486 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002487 std::string msgString;
2488 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002489 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002490
2491 /* Two binding descriptions for binding 0 */
2492 VkVertexInputBindingDescription input_bindings[2];
2493 memset(input_bindings, 0, sizeof(input_bindings));
2494
2495 VkVertexInputAttributeDescription input_attrib;
2496 memset(&input_attrib, 0, sizeof(input_attrib));
2497 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2498
2499 char const *vsSource =
2500 "#version 140\n"
2501 "#extension GL_ARB_separate_shader_objects: require\n"
2502 "#extension GL_ARB_shading_language_420pack: require\n"
2503 "\n"
2504 "layout(location=0) in float x;\n" /* attrib provided float */
2505 "void main(){\n"
2506 " gl_Position = vec4(x);\n"
2507 "}\n";
2508 char const *fsSource =
2509 "#version 140\n"
2510 "#extension GL_ARB_separate_shader_objects: require\n"
2511 "#extension GL_ARB_shading_language_420pack: require\n"
2512 "\n"
2513 "layout(location=0) out vec4 color;\n"
2514 "void main(){\n"
2515 " color = vec4(1);\n"
2516 "}\n";
2517
2518 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2519 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2520
2521 VkPipelineObj pipe(m_device);
2522 pipe.AddShader(&vs);
2523 pipe.AddShader(&fs);
2524
2525 pipe.AddVertexInputBindings(input_bindings, 2);
2526 pipe.AddVertexInputAttribs(&input_attrib, 1);
2527
2528 VkCommandBufferObj dummyCmd(m_device);
2529 VkDescriptorSetObj descriptorSet(m_device);
2530 descriptorSet.AppendDummy();
2531 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2532
2533 m_errorMonitor->ClearState();
2534 pipe.CreateVKPipeline(descriptorSet);
2535
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002536 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002537
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002538 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002539 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2540 FAIL() << "Incorrect error: " << msgString;
2541 }
2542}
Chris Forbes4c948702015-05-25 11:13:32 +12002543
Chris Forbesc12ef122015-05-25 11:13:40 +12002544/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2545 * rejects it. */
2546
2547TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2548{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002549 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002550 std::string msgString;
2551 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002552 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002553
2554 char const *vsSource =
2555 "#version 140\n"
2556 "#extension GL_ARB_separate_shader_objects: require\n"
2557 "#extension GL_ARB_shading_language_420pack: require\n"
2558 "\n"
2559 "void main(){\n"
2560 " gl_Position = vec4(1);\n"
2561 "}\n";
2562 char const *fsSource =
2563 "#version 140\n"
2564 "#extension GL_ARB_separate_shader_objects: require\n"
2565 "#extension GL_ARB_shading_language_420pack: require\n"
2566 "\n"
2567 "void main(){\n"
2568 "}\n";
2569
2570 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2571 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2572
2573 VkPipelineObj pipe(m_device);
2574 pipe.AddShader(&vs);
2575 pipe.AddShader(&fs);
2576
2577 /* implicit CB 0 set up by the test framework, not written */
2578
2579 VkCommandBufferObj dummyCmd(m_device);
2580 VkDescriptorSetObj descriptorSet(m_device);
2581 descriptorSet.AppendDummy();
2582 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2583
2584 m_errorMonitor->ClearState();
2585 pipe.CreateVKPipeline(descriptorSet);
2586
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002587 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002588
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002589 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002590 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2591 FAIL() << "Incorrect error: " << msgString;
2592 }
2593}
2594
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002595TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2596{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002597 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002598 std::string msgString;
2599 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002600 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002601
2602 char const *vsSource =
2603 "#version 140\n"
2604 "#extension GL_ARB_separate_shader_objects: require\n"
2605 "#extension GL_ARB_shading_language_420pack: require\n"
2606 "\n"
2607 "void main(){\n"
2608 " gl_Position = vec4(1);\n"
2609 "}\n";
2610 char const *fsSource =
2611 "#version 140\n"
2612 "#extension GL_ARB_separate_shader_objects: require\n"
2613 "#extension GL_ARB_shading_language_420pack: require\n"
2614 "\n"
2615 "layout(location=0) out vec4 x;\n"
2616 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2617 "void main(){\n"
2618 " x = vec4(1);\n"
2619 " y = vec4(1);\n"
2620 "}\n";
2621
2622 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2623 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2624
2625 VkPipelineObj pipe(m_device);
2626 pipe.AddShader(&vs);
2627 pipe.AddShader(&fs);
2628
2629 /* implicit CB 0 set up by the test framework */
2630 /* FS writes CB 1, but we don't configure it */
2631
2632 VkCommandBufferObj dummyCmd(m_device);
2633 VkDescriptorSetObj descriptorSet(m_device);
2634 descriptorSet.AppendDummy();
2635 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2636
2637 m_errorMonitor->ClearState();
2638 pipe.CreateVKPipeline(descriptorSet);
2639
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002640 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002641
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002642 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002643 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2644 FAIL() << "Incorrect warning: " << msgString;
2645 }
2646}
2647
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002648TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2649{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002650 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002651 std::string msgString;
2652 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002653 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002654
2655 char const *vsSource =
2656 "#version 140\n"
2657 "#extension GL_ARB_separate_shader_objects: require\n"
2658 "#extension GL_ARB_shading_language_420pack: require\n"
2659 "\n"
2660 "void main(){\n"
2661 " gl_Position = vec4(1);\n"
2662 "}\n";
2663 char const *fsSource =
2664 "#version 140\n"
2665 "#extension GL_ARB_separate_shader_objects: require\n"
2666 "#extension GL_ARB_shading_language_420pack: require\n"
2667 "\n"
2668 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2669 "void main(){\n"
2670 " x = ivec4(1);\n"
2671 "}\n";
2672
2673 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2674 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2675
2676 VkPipelineObj pipe(m_device);
2677 pipe.AddShader(&vs);
2678 pipe.AddShader(&fs);
2679
2680 /* implicit CB 0 set up by test framework, is UNORM. */
2681
2682 VkCommandBufferObj dummyCmd(m_device);
2683 VkDescriptorSetObj descriptorSet(m_device);
2684 descriptorSet.AppendDummy();
2685 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2686
2687 m_errorMonitor->ClearState();
2688 pipe.CreateVKPipeline(descriptorSet);
2689
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002690 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002691
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002692 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002693 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2694 FAIL() << "Incorrect error: " << msgString;
2695 }
2696}
Chris Forbesc2050732015-06-05 14:43:36 +12002697
2698TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2699{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002700 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002701 std::string msgString;
2702 ASSERT_NO_FATAL_FAILURE(InitState());
2703 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002704 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002705
2706 char const *vsSource =
2707 "#version 140\n"
2708 "#extension GL_ARB_separate_shader_objects: require\n"
2709 "#extension GL_ARB_shading_language_420pack: require\n"
2710 "\n"
2711 "void main(){\n"
2712 " gl_Position = vec4(1);\n"
2713 "}\n";
2714 char const *fsSource =
2715 "#version 140\n"
2716 "#extension GL_ARB_separate_shader_objects: require\n"
2717 "#extension GL_ARB_shading_language_420pack: require\n"
2718 "\n"
2719 "layout(location=0) out vec4 x;\n"
2720 "void main(){\n"
2721 " x = vec4(1);\n"
2722 "}\n";
2723
2724 m_errorMonitor->ClearState();
2725
2726 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2727 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2728
2729
2730 VkPipelineObj pipe(m_device);
2731 pipe.AddShader(&vs);
2732 pipe.AddShader(&fs);
2733
2734 /* implicit CB 0 set up by test framework, is UNORM. */
2735
2736 VkCommandBufferObj dummyCmd(m_device);
2737 VkDescriptorSetObj descriptorSet(m_device);
2738 descriptorSet.AppendDummy();
2739 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2740
2741 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2742 /* pipeline creation should have succeeded */
2743 ASSERT_EQ(VK_SUCCESS, res);
2744
2745 /* should have emitted a warning: the shader is not SPIRV, so we're
2746 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002747 msgFlags = m_errorMonitor->GetState(&msgString);
2748 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002749 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2750 FAIL() << "Incorrect warning: " << msgString;
2751 }
2752}
Chris Forbes01c9db72015-06-04 09:25:25 +12002753#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002754
Tony Barbour30486ea2015-04-07 13:44:53 -06002755int main(int argc, char **argv) {
2756 int result;
2757
2758 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002759 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002760
2761 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2762
2763 result = RUN_ALL_TESTS();
2764
Tony Barbour01999182015-04-09 12:58:51 -06002765 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002766 return result;
2767}