blob: 158b9789bbbb18aa5e9baf69e40ca03453da015a [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;
824
825 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
826
827 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
828
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600829 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600830 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 -0500831 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
832 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
833 }
834}
835
836TEST_F(VkLayerTest, ViewportStateNotBound)
837{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600838 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500839 std::string msgString;
840 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
841
842 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
843
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600844 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600845 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 -0500846 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
847 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
848 }
849}
850
851TEST_F(VkLayerTest, ColorBlendStateNotBound)
852{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600853 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500854 std::string msgString;
855
856 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
857
858 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
859
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600860 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600861 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 -0500862 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
863 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
864 }
865}
866
867TEST_F(VkLayerTest, DepthStencilStateNotBound)
868{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600869 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500870 std::string msgString;
871
872 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
873
874 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
875
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600876 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600877 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 -0500878 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
879 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
880 }
Tony Barbourdb686622015-05-06 09:35:56 -0600881}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600882#endif
883#if DRAW_STATE_TESTS
Tobin Ehlise4076782015-06-24 15:53:07 -0600884TEST_F(VkLayerTest, BindPipelineNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600885{
886 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600887 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600888 std::string msgString;
889
890 ASSERT_NO_FATAL_FAILURE(InitState());
891 m_errorMonitor->ClearState();
892 VkCommandBufferObj cmdBuffer(m_device);
893 BeginCommandBuffer(cmdBuffer);
894 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
895 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600896 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -0600897 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding pipeline to CmdBuffer w/o active RenderPass";
898 if (!strstr(msgString.c_str(),"Incorrectly binding graphics pipeline ")) {
899 FAIL() << "Error received was not 'Incorrectly binding graphics pipeline (0xbaadb1be) without an active RenderPass'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600900 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600901}
902
903TEST_F(VkLayerTest, InvalidDescriptorPool)
904{
905 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
906 // The DS check for this is after driver has been called to validate DS internal data struct
907 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600908/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600909 std::string msgString;
910 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
911 vkResetDescriptorPool(device(), badPool);
912
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600913 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600914 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 -0600915 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
916 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
917 }*/
918}
919
920TEST_F(VkLayerTest, InvalidDescriptorSet)
921{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600922 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
923 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600924 // Create a valid cmd buffer
925 // call vkCmdBindDescriptorSets w/ false DS
926}
927
928TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
929{
930 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
931 // The DS check for this is after driver has been called to validate DS internal data struct
932}
933
934TEST_F(VkLayerTest, InvalidPipeline)
935{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600936 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
937 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600938 // Create a valid cmd buffer
939 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlise4076782015-06-24 15:53:07 -0600940// VkFlags msgFlags;
941// std::string msgString;
942//
943// ASSERT_NO_FATAL_FAILURE(InitState());
944// m_errorMonitor->ClearState();
945// VkCommandBufferObj cmdBuffer(m_device);
946// BeginCommandBuffer(cmdBuffer);
947// VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
948// vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
949// msgFlags = m_errorMonitor->GetState(&msgString);
950// ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
951// if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
952// FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
953// }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600954}
955
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600956TEST_F(VkLayerTest, NoEndCmdBuffer)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600957{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600958 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600959 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600960 std::string msgString;
961 VkResult err;
962
963 ASSERT_NO_FATAL_FAILURE(InitState());
964 m_errorMonitor->ClearState();
965 VkCommandBufferObj cmdBuffer(m_device);
966 const VkDescriptorTypeCount ds_type_count = {
967 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
968 .count = 1,
969 };
970 const VkDescriptorPoolCreateInfo ds_pool_ci = {
971 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
972 .pNext = NULL,
973 .count = 1,
974 .pTypeCount = &ds_type_count,
975 };
976 VkDescriptorPool ds_pool;
977 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
978 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600979
980 const VkDescriptorSetLayoutBinding dsl_binding = {
981 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800982 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600983 .stageFlags = VK_SHADER_STAGE_ALL,
984 .pImmutableSamplers = NULL,
985 };
986
987 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
988 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
989 .pNext = NULL,
990 .count = 1,
991 .pBinding = &dsl_binding,
992 };
993 VkDescriptorSetLayout ds_layout;
994 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
995 ASSERT_VK_SUCCESS(err);
996
997 VkDescriptorSet descriptorSet;
998 uint32_t ds_count = 0;
999 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1000 ASSERT_VK_SUCCESS(err);
1001
1002 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1003 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1004 .pNext = NULL,
1005 .descriptorSetCount = 1,
1006 .pSetLayouts = &ds_layout,
1007 };
1008
1009 VkPipelineLayout pipeline_layout;
1010 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1011 ASSERT_VK_SUCCESS(err);
1012
1013 size_t shader_len = strlen(bindStateVertShaderText);
1014 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1015 void* pCode = malloc(codeSize);
1016
1017 /* try version 0 first: VkShaderStage followed by GLSL */
1018 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1019 ((uint32_t *) pCode)[1] = 0;
1020 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1021 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1022
1023 const VkShaderCreateInfo vs_ci = {
1024 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1025 .pNext = NULL,
Courtney Goeltzenleuchter1d723102015-06-18 21:49:59 -06001026 .module = VK_NULL_HANDLE,
1027 .name = "main",
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001028 .codeSize = codeSize,
1029 .pCode = pCode,
1030 .flags = 0,
1031 };
1032 VkShader vs;
1033 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1034 ASSERT_VK_SUCCESS(err);
1035
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001036 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1037 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1038 .pNext = NULL,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001039 .stage = VK_SHADER_STAGE_VERTEX,
1040 .shader = vs,
1041 .linkConstBufferCount = 0,
1042 .pLinkConstBufferInfo = NULL,
1043 .pSpecializationInfo = NULL,
1044 };
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001045 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001046 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1047 .pNext = NULL,
1048 .stageCount = 1,
1049 .pStages = &pipe_vs_ci,
1050 .pVertexInputState = NULL,
1051 .pIaState = NULL,
1052 .pTessState = NULL,
1053 .pVpState = NULL,
1054 .pRsState = NULL,
1055 .pMsState = NULL,
1056 .pDsState = NULL,
1057 .pCbState = NULL,
1058 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1059 .layout = pipeline_layout,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001060 };
1061
1062 VkPipeline pipeline;
1063 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1064 ASSERT_VK_SUCCESS(err);
1065
1066 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06001067 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptorSet, 0, NULL);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001068
1069 VkCmdBuffer localCmdBuffer = cmdBuffer.GetBufferHandle();
1070 m_device->get_device_queue();
1071 vkQueueSubmit(m_device->m_queue, 1, &localCmdBuffer, NULL);
1072
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001073 msgFlags = m_errorMonitor->GetState(&msgString);
1074 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkEndDescriptorPoolUpdate() w/o first calling vkBeginDescriptorPoolUpdate().";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001075 if (!strstr(msgString.c_str(),"You must call vkEndCommandBuffer() on CB ")) {
1076 FAIL() << "Error received was not 'You must call vkEndCommandBuffer() on CB <0xblah> before this call to vkQueueSubmit()!'";
1077 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001078}
1079
1080TEST_F(VkLayerTest, InvalidDynamicStateObject)
1081{
1082 // Create a valid cmd buffer
1083 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001084 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1085 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001086}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001087
Tobin Ehlise4076782015-06-24 15:53:07 -06001088TEST_F(VkLayerTest, VtxBufferNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001089{
1090 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001091 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001092 std::string msgString;
1093 VkResult err;
1094
1095 ASSERT_NO_FATAL_FAILURE(InitState());
1096 m_errorMonitor->ClearState();
1097 VkCommandBufferObj cmdBuffer(m_device);
1098 const VkDescriptorTypeCount ds_type_count = {
1099 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1100 .count = 1,
1101 };
1102 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1103 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1104 .pNext = NULL,
1105 .count = 1,
1106 .pTypeCount = &ds_type_count,
1107 };
1108 VkDescriptorPool ds_pool;
1109 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1110 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001111
1112 const VkDescriptorSetLayoutBinding dsl_binding = {
1113 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001114 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001115 .stageFlags = VK_SHADER_STAGE_ALL,
1116 .pImmutableSamplers = NULL,
1117 };
1118
1119 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1120 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1121 .pNext = NULL,
1122 .count = 1,
1123 .pBinding = &dsl_binding,
1124 };
1125 VkDescriptorSetLayout ds_layout;
1126 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1127 ASSERT_VK_SUCCESS(err);
1128
1129 VkDescriptorSet descriptorSet;
1130 uint32_t ds_count = 0;
1131 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1132 ASSERT_VK_SUCCESS(err);
1133
1134 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1135 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1136 .pNext = NULL,
1137 .descriptorSetCount = 1,
1138 .pSetLayouts = &ds_layout,
1139 };
1140
1141 VkPipelineLayout pipeline_layout;
1142 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1143 ASSERT_VK_SUCCESS(err);
1144
1145 size_t shader_len = strlen(bindStateVertShaderText);
1146 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1147 void* pCode = malloc(codeSize);
1148
1149 /* try version 0 first: VkShaderStage followed by GLSL */
1150 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1151 ((uint32_t *) pCode)[1] = 0;
1152 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1153 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1154
1155 const VkShaderCreateInfo vs_ci = {
1156 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1157 .pNext = NULL,
Courtney Goeltzenleuchter1d723102015-06-18 21:49:59 -06001158 .module = VK_NULL_HANDLE,
1159 .name = "main",
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001160 .codeSize = codeSize,
1161 .pCode = pCode,
1162 .flags = 0,
1163 };
1164 VkShader vs;
1165 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1166
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001167 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1168 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1169 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001170 .stage = VK_SHADER_STAGE_VERTEX,
1171 .shader = vs,
1172 .linkConstBufferCount = 0,
1173 .pLinkConstBufferInfo = NULL,
1174 .pSpecializationInfo = NULL,
1175 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001176 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001177 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1178 .pNext = NULL,
1179 .stageCount = 1,
1180 .pStages = &pipe_vs_ci,
1181 .pVertexInputState = NULL,
1182 .pIaState = NULL,
1183 .pTessState = NULL,
1184 .pVpState = NULL,
1185 .pRsState = NULL,
1186 .pMsState = NULL,
1187 .pDsState = NULL,
1188 .pCbState = NULL,
1189 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1190 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001191 };
1192
1193 VkPipeline pipeline;
1194 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1195 ASSERT_VK_SUCCESS(err);
1196
1197 err= cmdBuffer.BeginCommandBuffer();
1198 ASSERT_VK_SUCCESS(err);
1199 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1200 // Should error before calling to driver so don't care about actual data
1201 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1202
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001203 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -06001204 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o active RenderPass.";
1205 if (!strstr(msgString.c_str(),"Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.")) {
1206 FAIL() << "Error received was not 'Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001207 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001208}
1209
1210TEST_F(VkLayerTest, DSTypeMismatch)
1211{
1212 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001213 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001214 std::string msgString;
1215 VkResult err;
1216
1217 ASSERT_NO_FATAL_FAILURE(InitState());
1218 m_errorMonitor->ClearState();
1219 //VkDescriptorSetObj descriptorSet(m_device);
1220 const VkDescriptorTypeCount ds_type_count = {
1221 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1222 .count = 1,
1223 };
1224 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1225 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1226 .pNext = NULL,
1227 .count = 1,
1228 .pTypeCount = &ds_type_count,
1229 };
1230 VkDescriptorPool ds_pool;
1231 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1232 ASSERT_VK_SUCCESS(err);
1233 const VkDescriptorSetLayoutBinding dsl_binding = {
1234 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001235 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001236 .stageFlags = VK_SHADER_STAGE_ALL,
1237 .pImmutableSamplers = NULL,
1238 };
1239
1240 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1241 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1242 .pNext = NULL,
1243 .count = 1,
1244 .pBinding = &dsl_binding,
1245 };
1246 VkDescriptorSetLayout ds_layout;
1247 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1248 ASSERT_VK_SUCCESS(err);
1249
1250 VkDescriptorSet descriptorSet;
1251 uint32_t ds_count = 0;
1252 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1253 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001254
1255 const VkSamplerCreateInfo sampler_ci = {
1256 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1257 .pNext = NULL,
1258 .magFilter = VK_TEX_FILTER_NEAREST,
1259 .minFilter = VK_TEX_FILTER_NEAREST,
1260 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1261 .addressU = VK_TEX_ADDRESS_CLAMP,
1262 .addressV = VK_TEX_ADDRESS_CLAMP,
1263 .addressW = VK_TEX_ADDRESS_CLAMP,
1264 .mipLodBias = 1.0,
1265 .maxAnisotropy = 1,
1266 .compareOp = VK_COMPARE_OP_NEVER,
1267 .minLod = 1.0,
1268 .maxLod = 1.0,
1269 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1270 };
1271 VkSampler sampler;
1272 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1273 ASSERT_VK_SUCCESS(err);
1274
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001275 VkDescriptorInfo descriptor_info;
1276 memset(&descriptor_info, 0, sizeof(descriptor_info));
1277 descriptor_info.sampler = sampler;
1278
1279 VkWriteDescriptorSet descriptor_write;
1280 memset(&descriptor_write, 0, sizeof(descriptor_write));
1281 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1282 descriptor_write.destSet = descriptorSet;
1283 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001284 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001285 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1286 descriptor_write.pDescriptors = &descriptor_info;
1287
1288 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1289
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001290 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001291 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating BUFFER Descriptor w/ incorrect type of SAMPLER.";
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001292 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1293 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match overlapping binding type!'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001294 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001295}
1296
1297TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1298{
1299 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001300 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001301 std::string msgString;
1302 VkResult err;
1303
1304 ASSERT_NO_FATAL_FAILURE(InitState());
1305 m_errorMonitor->ClearState();
1306 //VkDescriptorSetObj descriptorSet(m_device);
1307 const VkDescriptorTypeCount ds_type_count = {
1308 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1309 .count = 1,
1310 };
1311 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1312 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1313 .pNext = NULL,
1314 .count = 1,
1315 .pTypeCount = &ds_type_count,
1316 };
1317 VkDescriptorPool ds_pool;
1318 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1319 ASSERT_VK_SUCCESS(err);
1320 const VkDescriptorSetLayoutBinding dsl_binding = {
1321 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001322 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001323 .stageFlags = VK_SHADER_STAGE_ALL,
1324 .pImmutableSamplers = NULL,
1325 };
1326
1327 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1328 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1329 .pNext = NULL,
1330 .count = 1,
1331 .pBinding = &dsl_binding,
1332 };
1333 VkDescriptorSetLayout ds_layout;
1334 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1335 ASSERT_VK_SUCCESS(err);
1336
1337 VkDescriptorSet descriptorSet;
1338 uint32_t ds_count = 0;
1339 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1340 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001341
1342 const VkSamplerCreateInfo sampler_ci = {
1343 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1344 .pNext = NULL,
1345 .magFilter = VK_TEX_FILTER_NEAREST,
1346 .minFilter = VK_TEX_FILTER_NEAREST,
1347 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1348 .addressU = VK_TEX_ADDRESS_CLAMP,
1349 .addressV = VK_TEX_ADDRESS_CLAMP,
1350 .addressW = VK_TEX_ADDRESS_CLAMP,
1351 .mipLodBias = 1.0,
1352 .maxAnisotropy = 1,
1353 .compareOp = VK_COMPARE_OP_NEVER,
1354 .minLod = 1.0,
1355 .maxLod = 1.0,
1356 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1357 };
1358 VkSampler sampler;
1359 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1360 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001361
1362 VkDescriptorInfo descriptor_info;
1363 memset(&descriptor_info, 0, sizeof(descriptor_info));
1364 descriptor_info.sampler = sampler;
1365
1366 VkWriteDescriptorSet descriptor_write;
1367 memset(&descriptor_write, 0, sizeof(descriptor_write));
1368 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1369 descriptor_write.destSet = descriptorSet;
1370 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1371 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001372 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001373 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1374 descriptor_write.pDescriptors = &descriptor_info;
1375
1376 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1377
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001378 msgFlags = m_errorMonitor->GetState(&msgString);
1379 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ index out of bounds.";
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001380 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1381 FAIL() << "Error received was not 'Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding...'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001382 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001383}
1384
1385TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1386{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001387 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001388 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001389 std::string msgString;
1390 VkResult err;
1391
1392 ASSERT_NO_FATAL_FAILURE(InitState());
1393 m_errorMonitor->ClearState();
1394 //VkDescriptorSetObj descriptorSet(m_device);
1395 const VkDescriptorTypeCount ds_type_count = {
1396 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1397 .count = 1,
1398 };
1399 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1400 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1401 .pNext = NULL,
1402 .count = 1,
1403 .pTypeCount = &ds_type_count,
1404 };
1405 VkDescriptorPool ds_pool;
1406 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1407 ASSERT_VK_SUCCESS(err);
1408 const VkDescriptorSetLayoutBinding dsl_binding = {
1409 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001410 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001411 .stageFlags = VK_SHADER_STAGE_ALL,
1412 .pImmutableSamplers = NULL,
1413 };
1414
1415 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1416 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1417 .pNext = NULL,
1418 .count = 1,
1419 .pBinding = &dsl_binding,
1420 };
1421 VkDescriptorSetLayout ds_layout;
1422 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1423 ASSERT_VK_SUCCESS(err);
1424
1425 VkDescriptorSet descriptorSet;
1426 uint32_t ds_count = 0;
1427 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1428 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001429
1430 const VkSamplerCreateInfo sampler_ci = {
1431 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1432 .pNext = NULL,
1433 .magFilter = VK_TEX_FILTER_NEAREST,
1434 .minFilter = VK_TEX_FILTER_NEAREST,
1435 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1436 .addressU = VK_TEX_ADDRESS_CLAMP,
1437 .addressV = VK_TEX_ADDRESS_CLAMP,
1438 .addressW = VK_TEX_ADDRESS_CLAMP,
1439 .mipLodBias = 1.0,
1440 .maxAnisotropy = 1,
1441 .compareOp = VK_COMPARE_OP_NEVER,
1442 .minLod = 1.0,
1443 .maxLod = 1.0,
1444 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1445 };
1446 VkSampler sampler;
1447 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1448 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001449
1450 VkDescriptorInfo descriptor_info;
1451 memset(&descriptor_info, 0, sizeof(descriptor_info));
1452 descriptor_info.sampler = sampler;
1453
1454 VkWriteDescriptorSet descriptor_write;
1455 memset(&descriptor_write, 0, sizeof(descriptor_write));
1456 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1457 descriptor_write.destSet = descriptorSet;
1458 descriptor_write.destBinding = 2;
1459 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001460 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001461 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1462 descriptor_write.pDescriptors = &descriptor_info;
1463
1464 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1465
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001466 msgFlags = m_errorMonitor->GetState(&msgString);
1467 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ count too large for layout.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001468 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1469 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1470 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001471}
1472
1473TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1474{
1475 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001476 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001477 std::string msgString;
1478 VkResult err;
1479
1480 ASSERT_NO_FATAL_FAILURE(InitState());
1481 m_errorMonitor->ClearState();
1482 //VkDescriptorSetObj descriptorSet(m_device);
1483 const VkDescriptorTypeCount ds_type_count = {
1484 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1485 .count = 1,
1486 };
1487 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1488 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1489 .pNext = NULL,
1490 .count = 1,
1491 .pTypeCount = &ds_type_count,
1492 };
1493 VkDescriptorPool ds_pool;
1494 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1495 ASSERT_VK_SUCCESS(err);
1496 const VkDescriptorSetLayoutBinding dsl_binding = {
1497 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001498 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001499 .stageFlags = VK_SHADER_STAGE_ALL,
1500 .pImmutableSamplers = NULL,
1501 };
1502
1503 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1504 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1505 .pNext = NULL,
1506 .count = 1,
1507 .pBinding = &dsl_binding,
1508 };
1509 VkDescriptorSetLayout ds_layout;
1510 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1511 ASSERT_VK_SUCCESS(err);
1512
1513 VkDescriptorSet descriptorSet;
1514 uint32_t ds_count = 0;
1515 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1516 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001517
1518 const VkSamplerCreateInfo sampler_ci = {
1519 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1520 .pNext = NULL,
1521 .magFilter = VK_TEX_FILTER_NEAREST,
1522 .minFilter = VK_TEX_FILTER_NEAREST,
1523 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1524 .addressU = VK_TEX_ADDRESS_CLAMP,
1525 .addressV = VK_TEX_ADDRESS_CLAMP,
1526 .addressW = VK_TEX_ADDRESS_CLAMP,
1527 .mipLodBias = 1.0,
1528 .maxAnisotropy = 1,
1529 .compareOp = VK_COMPARE_OP_NEVER,
1530 .minLod = 1.0,
1531 .maxLod = 1.0,
1532 .borderColor = VK_BORDER_COLOR_OPAQUE_WHITE,
1533 };
1534 VkSampler sampler;
1535 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1536 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001537
1538
1539 VkDescriptorInfo descriptor_info;
1540 memset(&descriptor_info, 0, sizeof(descriptor_info));
1541 descriptor_info.sampler = sampler;
1542
1543 VkWriteDescriptorSet descriptor_write;
1544 memset(&descriptor_write, 0, sizeof(descriptor_write));
1545 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1546 descriptor_write.destSet = descriptorSet;
1547 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001548 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001549 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1550 descriptor_write.pDescriptors = &descriptor_info;
1551
1552 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1553
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001554 msgFlags = m_errorMonitor->GetState(&msgString);
1555 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after updating Descriptor w/ invalid struct type.";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001556 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1557 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1558 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001559}
1560
1561TEST_F(VkLayerTest, NumSamplesMismatch)
1562{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001563 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001564 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001565 std::string msgString;
1566 VkResult err;
1567
1568 ASSERT_NO_FATAL_FAILURE(InitState());
1569 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1570 m_errorMonitor->ClearState();
1571 VkCommandBufferObj cmdBuffer(m_device);
1572 const VkDescriptorTypeCount ds_type_count = {
1573 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1574 .count = 1,
1575 };
1576 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1577 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1578 .pNext = NULL,
1579 .count = 1,
1580 .pTypeCount = &ds_type_count,
1581 };
1582 VkDescriptorPool ds_pool;
1583 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1584 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001585
1586 const VkDescriptorSetLayoutBinding dsl_binding = {
1587 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001588 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001589 .stageFlags = VK_SHADER_STAGE_ALL,
1590 .pImmutableSamplers = NULL,
1591 };
1592
1593 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1594 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1595 .pNext = NULL,
1596 .count = 1,
1597 .pBinding = &dsl_binding,
1598 };
1599 VkDescriptorSetLayout ds_layout;
1600 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1601 ASSERT_VK_SUCCESS(err);
1602
1603 VkDescriptorSet descriptorSet;
1604 uint32_t ds_count = 0;
1605 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1606 ASSERT_VK_SUCCESS(err);
1607
1608 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1609 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1610 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001611 .rasterSamples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001612 .multisampleEnable = 1,
1613 .sampleShadingEnable = 0,
1614 .minSampleShading = 1.0,
1615 .sampleMask = 15,
1616 };
1617
1618 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1619 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1620 .pNext = NULL,
1621 .descriptorSetCount = 1,
1622 .pSetLayouts = &ds_layout,
1623 };
1624
1625 VkPipelineLayout pipeline_layout;
1626 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1627 ASSERT_VK_SUCCESS(err);
1628
1629 size_t shader_len = strlen(bindStateVertShaderText);
1630 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1631 void* pCode = malloc(codeSize);
1632
1633 /* try version 0 first: VkShaderStage followed by GLSL */
1634 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1635 ((uint32_t *) pCode)[1] = 0;
1636 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1637 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1638
1639 const VkShaderCreateInfo vs_ci = {
1640 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1641 .pNext = NULL,
Courtney Goeltzenleuchter1d723102015-06-18 21:49:59 -06001642 .module = VK_NULL_HANDLE,
1643 .name = "main",
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001644 .codeSize = codeSize,
1645 .pCode = pCode,
1646 .flags = 0,
1647 };
1648 VkShader vs;
1649 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1650 ASSERT_VK_SUCCESS(err);
1651
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001652 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1653 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1654 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001655 .stage = VK_SHADER_STAGE_VERTEX,
1656 .shader = vs,
1657 .linkConstBufferCount = 0,
1658 .pLinkConstBufferInfo = NULL,
1659 .pSpecializationInfo = NULL,
1660 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001661 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001662 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1663 .pNext = NULL,
1664 .stageCount = 1,
1665 .pStages = &pipe_vs_ci,
1666 .pVertexInputState = NULL,
1667 .pIaState = NULL,
1668 .pTessState = NULL,
1669 .pVpState = NULL,
1670 .pRsState = NULL,
1671 .pMsState = &pipe_ms_state_ci,
1672 .pDsState = NULL,
1673 .pCbState = NULL,
1674 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1675 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001676 };
1677
1678 VkPipeline pipeline;
1679 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1680 ASSERT_VK_SUCCESS(err);
1681
1682 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1683 BeginCommandBuffer(cmdBuffer);
1684 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1685
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001686 msgFlags = m_errorMonitor->GetState(&msgString);
1687 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 -06001688 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1689 FAIL() << "Error received was not 'Num samples mismatch!...'";
1690 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001691}
Tobin Ehlise4076782015-06-24 15:53:07 -06001692TEST_F(VkLayerTest, PipelineNotBound)
1693{
1694 VkFlags msgFlags;
1695 std::string msgString;
1696 VkResult err;
1697
1698 ASSERT_NO_FATAL_FAILURE(InitState());
1699 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1700 m_errorMonitor->ClearState();
1701 VkCommandBufferObj cmdBuffer(m_device);
1702 const VkDescriptorTypeCount ds_type_count = {
1703 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1704 .count = 1,
1705 };
1706 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1707 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1708 .pNext = NULL,
1709 .count = 1,
1710 .pTypeCount = &ds_type_count,
1711 };
1712 VkDescriptorPool ds_pool;
1713 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1714 ASSERT_VK_SUCCESS(err);
1715
1716 const VkDescriptorSetLayoutBinding dsl_binding = {
1717 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1718 .arraySize = 1,
1719 .stageFlags = VK_SHADER_STAGE_ALL,
1720 .pImmutableSamplers = NULL,
1721 };
1722
1723 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1724 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1725 .pNext = NULL,
1726 .count = 1,
1727 .pBinding = &dsl_binding,
1728 };
1729 VkDescriptorSetLayout ds_layout;
1730 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1731 ASSERT_VK_SUCCESS(err);
1732
1733 VkDescriptorSet descriptorSet;
1734 uint32_t ds_count = 0;
1735 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1736 ASSERT_VK_SUCCESS(err);
1737
1738 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1739 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1740 .pNext = NULL,
1741 .descriptorSetCount = 1,
1742 .pSetLayouts = &ds_layout,
1743 };
1744
1745 VkPipelineLayout pipeline_layout;
1746 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1747 ASSERT_VK_SUCCESS(err);
1748
1749 size_t shader_len = strlen(bindStateVertShaderText);
1750 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1751 void* pCode = malloc(codeSize);
1752
1753 /* try version 0 first: VkShaderStage followed by GLSL */
1754 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1755 ((uint32_t *) pCode)[1] = 0;
1756 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1757 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1758
1759 const VkShaderCreateInfo vs_ci = {
1760 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1761 .pNext = NULL,
1762 .module = VK_NULL_HANDLE,
1763 .name = "main",
1764 .codeSize = codeSize,
1765 .pCode = pCode,
1766 .flags = 0,
1767 };
1768 VkShader vs;
1769 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1770 ASSERT_VK_SUCCESS(err);
1771
1772 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
1773 //err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1774 ASSERT_VK_SUCCESS(err);
1775
1776 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1777 BeginCommandBuffer(cmdBuffer);
1778 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
1779
1780 msgFlags = m_errorMonitor->GetState(&msgString);
1781 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
1782 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
1783 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
1784 }
1785}
1786TEST_F(VkLayerTest, VtxBufferBadIndex)
1787{
1788 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
1789 VkFlags msgFlags;
1790 std::string msgString;
1791 VkResult err;
1792
1793 ASSERT_NO_FATAL_FAILURE(InitState());
1794 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1795 m_errorMonitor->ClearState();
1796 VkCommandBufferObj cmdBuffer(m_device);
1797 const VkDescriptorTypeCount ds_type_count = {
1798 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1799 .count = 1,
1800 };
1801 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1802 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1803 .pNext = NULL,
1804 .count = 1,
1805 .pTypeCount = &ds_type_count,
1806 };
1807 VkDescriptorPool ds_pool;
1808 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1809 ASSERT_VK_SUCCESS(err);
1810
1811 const VkDescriptorSetLayoutBinding dsl_binding = {
1812 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1813 .arraySize = 1,
1814 .stageFlags = VK_SHADER_STAGE_ALL,
1815 .pImmutableSamplers = NULL,
1816 };
1817
1818 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1819 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1820 .pNext = NULL,
1821 .count = 1,
1822 .pBinding = &dsl_binding,
1823 };
1824 VkDescriptorSetLayout ds_layout;
1825 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1826 ASSERT_VK_SUCCESS(err);
1827
1828 VkDescriptorSet descriptorSet;
1829 uint32_t ds_count = 0;
1830 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1831 ASSERT_VK_SUCCESS(err);
1832
1833 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1834 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1835 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001836 .rasterSamples = 1,
Tobin Ehlise4076782015-06-24 15:53:07 -06001837 .multisampleEnable = 1,
1838 .sampleShadingEnable = 0,
1839 .minSampleShading = 1.0,
1840 .sampleMask = 15,
1841 };
1842
1843 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1844 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1845 .pNext = NULL,
1846 .descriptorSetCount = 1,
1847 .pSetLayouts = &ds_layout,
1848 };
1849
1850 VkPipelineLayout pipeline_layout;
1851 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1852 ASSERT_VK_SUCCESS(err);
1853
1854 size_t shader_len = strlen(bindStateVertShaderText);
1855 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
1856 void* pCode = malloc(codeSize);
1857
1858 /* try version 0 first: VkShaderStage followed by GLSL */
1859 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
1860 ((uint32_t *) pCode)[1] = 0;
1861 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
1862 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
1863
1864 const VkShaderCreateInfo vs_ci = {
1865 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1866 .pNext = NULL,
1867 .module = VK_NULL_HANDLE,
1868 .name = "main",
1869 .codeSize = codeSize,
1870 .pCode = pCode,
1871 .flags = 0,
1872 };
1873 VkShader vs;
1874 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
1875 ASSERT_VK_SUCCESS(err);
1876
1877 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1878 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1879 .pNext = NULL,
1880 .stage = VK_SHADER_STAGE_VERTEX,
1881 .shader = vs,
1882 .linkConstBufferCount = 0,
1883 .pLinkConstBufferInfo = NULL,
1884 .pSpecializationInfo = NULL,
1885 };
1886 const VkGraphicsPipelineCreateInfo gp_ci = {
1887 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1888 .pNext = NULL,
1889 .stageCount = 1,
1890 .pStages = &pipe_vs_ci,
1891 .pVertexInputState = NULL,
1892 .pIaState = NULL,
1893 .pTessState = NULL,
1894 .pVpState = NULL,
1895 .pRsState = NULL,
1896 .pMsState = &pipe_ms_state_ci,
1897 .pDsState = NULL,
1898 .pCbState = NULL,
1899 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1900 .layout = pipeline_layout,
1901 };
1902
1903 VkPipeline pipeline;
1904 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1905 ASSERT_VK_SUCCESS(err);
1906
1907 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1908 BeginCommandBuffer(cmdBuffer);
1909 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1910 // Should error before calling to driver so don't care about actual data
1911 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1912
1913 msgFlags = m_errorMonitor->GetState(&msgString);
1914 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding Vtx Buffer w/o VBO attached to PSO.";
1915 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
1916 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
1917 }
1918}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06001919#endif
1920#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06001921#if GTEST_IS_THREADSAFE
1922struct thread_data_struct {
1923 VkCmdBuffer cmdBuffer;
1924 VkEvent event;
1925 bool bailout;
1926};
1927
1928extern "C" void *AddToCommandBuffer(void *arg)
1929{
1930 struct thread_data_struct *data = (struct thread_data_struct *) arg;
1931 std::string msgString;
1932
1933 for (int i = 0; i<10000; i++) {
1934 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPE_EVENT_COMMANDS_COMPLETE);
1935 if (data->bailout) {
1936 break;
1937 }
1938 }
1939 return NULL;
1940}
1941
1942TEST_F(VkLayerTest, ThreadCmdBufferCollision)
1943{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001944 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06001945 std::string msgString;
1946 pthread_t thread;
1947 pthread_attr_t thread_attr;
1948
1949 ASSERT_NO_FATAL_FAILURE(InitState());
1950 ASSERT_NO_FATAL_FAILURE(InitViewport());
1951 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1952
1953 VkCommandBufferObj cmdBuffer(m_device);
1954
1955 m_errorMonitor->ClearState();
1956 pthread_attr_init(&thread_attr);
1957 BeginCommandBuffer(cmdBuffer);
1958
1959 VkEventCreateInfo event_info;
1960 VkEvent event;
1961 VkMemoryRequirements mem_req;
Mike Stroyan09aae812015-05-12 16:00:45 -06001962 VkResult err;
1963
1964 memset(&event_info, 0, sizeof(event_info));
1965 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1966
1967 err = vkCreateEvent(device(), &event_info, &event);
1968 ASSERT_VK_SUCCESS(err);
1969
Tony Barbour426b9052015-06-24 16:06:58 -06001970 err = vkGetObjectMemoryRequirements(device(), VK_OBJECT_TYPE_EVENT, event, &mem_req);
Mike Stroyan09aae812015-05-12 16:00:45 -06001971 ASSERT_VK_SUCCESS(err);
1972
1973 VkMemoryAllocInfo mem_info;
1974 VkDeviceMemory event_mem;
1975
Mike Stroyan09aae812015-05-12 16:00:45 -06001976 memset(&mem_info, 0, sizeof(mem_info));
1977 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
1978 mem_info.allocationSize = mem_req.size;
Courtney Goeltzenleuchterb25c9b92015-06-18 17:01:41 -06001979 mem_info.memProps = 0;
Mike Stroyan09aae812015-05-12 16:00:45 -06001980 err = vkAllocMemory(device(), &mem_info, &event_mem);
1981 ASSERT_VK_SUCCESS(err);
1982
Mark Lobodzinski23182612015-05-29 09:32:35 -05001983 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06001984 ASSERT_VK_SUCCESS(err);
1985
1986 err = vkResetEvent(device(), event);
1987 ASSERT_VK_SUCCESS(err);
1988
1989 struct thread_data_struct data;
1990 data.cmdBuffer = cmdBuffer.obj();
1991 data.event = event;
1992 data.bailout = false;
1993 m_errorMonitor->SetBailout(&data.bailout);
1994 // Add many entries to command buffer from another thread.
1995 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
1996 // Add many entries to command buffer from this thread at the same time.
1997 AddToCommandBuffer(&data);
1998 pthread_join(thread, NULL);
1999 EndCommandBuffer(cmdBuffer);
2000
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002001 msgFlags = m_errorMonitor->GetState(&msgString);
Mike Stroyaned254572015-06-17 16:32:06 -06002002 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 -06002003 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05002004 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06002005 }
2006
2007}
2008#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06002009#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12002010
2011#if SHADER_CHECKER_TESTS
2012TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
2013{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002014 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12002015 std::string msgString;
2016 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002017 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002018
2019 char const *vsSource =
2020 "#version 140\n"
2021 "#extension GL_ARB_separate_shader_objects: require\n"
2022 "#extension GL_ARB_shading_language_420pack: require\n"
2023 "\n"
2024 "layout(location=0) out float x;\n"
2025 "void main(){\n"
2026 " gl_Position = vec4(1);\n"
2027 " x = 0;\n"
2028 "}\n";
2029 char const *fsSource =
2030 "#version 140\n"
2031 "#extension GL_ARB_separate_shader_objects: require\n"
2032 "#extension GL_ARB_shading_language_420pack: require\n"
2033 "\n"
2034 "layout(location=0) out vec4 color;\n"
2035 "void main(){\n"
2036 " color = vec4(1);\n"
2037 "}\n";
2038
2039 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2040 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2041
2042 VkPipelineObj pipe(m_device);
2043 pipe.AddShader(&vs);
2044 pipe.AddShader(&fs);
2045
2046 VkCommandBufferObj dummyCmd(m_device);
2047 VkDescriptorSetObj descriptorSet(m_device);
2048 descriptorSet.AppendDummy();
2049 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2050
2051 m_errorMonitor->ClearState();
2052 pipe.CreateVKPipeline(descriptorSet);
2053
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002054 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002055
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002056 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002057 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
2058 FAIL() << "Incorrect warning: " << msgString;
2059 }
2060}
Chris Forbes5af3bf22015-05-25 11:13:08 +12002061
Chris Forbes3c10b852015-05-25 11:13:13 +12002062TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
2063{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002064 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12002065 std::string msgString;
2066 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002067 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12002068
2069 char const *vsSource =
2070 "#version 140\n"
2071 "#extension GL_ARB_separate_shader_objects: require\n"
2072 "#extension GL_ARB_shading_language_420pack: require\n"
2073 "\n"
2074 "void main(){\n"
2075 " gl_Position = vec4(1);\n"
2076 "}\n";
2077 char const *fsSource =
2078 "#version 140\n"
2079 "#extension GL_ARB_separate_shader_objects: require\n"
2080 "#extension GL_ARB_shading_language_420pack: require\n"
2081 "\n"
2082 "layout(location=0) in float x;\n"
2083 "layout(location=0) out vec4 color;\n"
2084 "void main(){\n"
2085 " color = vec4(x);\n"
2086 "}\n";
2087
2088 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2089 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2090
2091 VkPipelineObj pipe(m_device);
2092 pipe.AddShader(&vs);
2093 pipe.AddShader(&fs);
2094
2095 VkCommandBufferObj dummyCmd(m_device);
2096 VkDescriptorSetObj descriptorSet(m_device);
2097 descriptorSet.AppendDummy();
2098 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2099
2100 m_errorMonitor->ClearState();
2101 pipe.CreateVKPipeline(descriptorSet);
2102
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002103 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12002104
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002105 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12002106 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
2107 FAIL() << "Incorrect error: " << msgString;
2108 }
2109}
2110
Chris Forbescc281692015-05-25 11:13:17 +12002111TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
2112{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002113 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12002114 std::string msgString;
2115 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002116 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12002117
2118 char const *vsSource =
2119 "#version 140\n"
2120 "#extension GL_ARB_separate_shader_objects: require\n"
2121 "#extension GL_ARB_shading_language_420pack: require\n"
2122 "\n"
2123 "layout(location=0) out int x;\n"
2124 "void main(){\n"
2125 " x = 0;\n"
2126 " gl_Position = vec4(1);\n"
2127 "}\n";
2128 char const *fsSource =
2129 "#version 140\n"
2130 "#extension GL_ARB_separate_shader_objects: require\n"
2131 "#extension GL_ARB_shading_language_420pack: require\n"
2132 "\n"
2133 "layout(location=0) in float x;\n" /* VS writes int */
2134 "layout(location=0) out vec4 color;\n"
2135 "void main(){\n"
2136 " color = vec4(x);\n"
2137 "}\n";
2138
2139 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2140 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2141
2142 VkPipelineObj pipe(m_device);
2143 pipe.AddShader(&vs);
2144 pipe.AddShader(&fs);
2145
2146 VkCommandBufferObj dummyCmd(m_device);
2147 VkDescriptorSetObj descriptorSet(m_device);
2148 descriptorSet.AppendDummy();
2149 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2150
2151 m_errorMonitor->ClearState();
2152 pipe.CreateVKPipeline(descriptorSet);
2153
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002154 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12002155
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002156 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12002157 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
2158 FAIL() << "Incorrect error: " << msgString;
2159 }
2160}
2161
Chris Forbes8291c052015-05-25 11:13:28 +12002162TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
2163{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002164 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12002165 std::string msgString;
2166 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002167 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12002168
2169 VkVertexInputBindingDescription input_binding;
2170 memset(&input_binding, 0, sizeof(input_binding));
2171
2172 VkVertexInputAttributeDescription input_attrib;
2173 memset(&input_attrib, 0, sizeof(input_attrib));
2174 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2175
2176 char const *vsSource =
2177 "#version 140\n"
2178 "#extension GL_ARB_separate_shader_objects: require\n"
2179 "#extension GL_ARB_shading_language_420pack: require\n"
2180 "\n"
2181 "void main(){\n"
2182 " gl_Position = vec4(1);\n"
2183 "}\n";
2184 char const *fsSource =
2185 "#version 140\n"
2186 "#extension GL_ARB_separate_shader_objects: require\n"
2187 "#extension GL_ARB_shading_language_420pack: require\n"
2188 "\n"
2189 "layout(location=0) out vec4 color;\n"
2190 "void main(){\n"
2191 " color = vec4(1);\n"
2192 "}\n";
2193
2194 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2195 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2196
2197 VkPipelineObj pipe(m_device);
2198 pipe.AddShader(&vs);
2199 pipe.AddShader(&fs);
2200
2201 pipe.AddVertexInputBindings(&input_binding, 1);
2202 pipe.AddVertexInputAttribs(&input_attrib, 1);
2203
2204 VkCommandBufferObj dummyCmd(m_device);
2205 VkDescriptorSetObj descriptorSet(m_device);
2206 descriptorSet.AppendDummy();
2207 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2208
2209 m_errorMonitor->ClearState();
2210 pipe.CreateVKPipeline(descriptorSet);
2211
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002212 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes8291c052015-05-25 11:13:28 +12002213
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002214 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12002215 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
2216 FAIL() << "Incorrect warning: " << msgString;
2217 }
2218}
2219
Chris Forbes37367e62015-05-25 11:13:29 +12002220TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
2221{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002222 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12002223 std::string msgString;
2224 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002225 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12002226
2227 char const *vsSource =
2228 "#version 140\n"
2229 "#extension GL_ARB_separate_shader_objects: require\n"
2230 "#extension GL_ARB_shading_language_420pack: require\n"
2231 "\n"
2232 "layout(location=0) in vec4 x;\n" /* not provided */
2233 "void main(){\n"
2234 " gl_Position = x;\n"
2235 "}\n";
2236 char const *fsSource =
2237 "#version 140\n"
2238 "#extension GL_ARB_separate_shader_objects: require\n"
2239 "#extension GL_ARB_shading_language_420pack: require\n"
2240 "\n"
2241 "layout(location=0) out vec4 color;\n"
2242 "void main(){\n"
2243 " color = vec4(1);\n"
2244 "}\n";
2245
2246 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2247 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2248
2249 VkPipelineObj pipe(m_device);
2250 pipe.AddShader(&vs);
2251 pipe.AddShader(&fs);
2252
2253 VkCommandBufferObj dummyCmd(m_device);
2254 VkDescriptorSetObj descriptorSet(m_device);
2255 descriptorSet.AppendDummy();
2256 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2257
2258 m_errorMonitor->ClearState();
2259 pipe.CreateVKPipeline(descriptorSet);
2260
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002261 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002262
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002263 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002264 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2265 FAIL() << "Incorrect warning: " << msgString;
2266 }
2267}
2268
Chris Forbesa4b02322015-05-25 11:13:31 +12002269TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2270{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002271 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002272 std::string msgString;
2273 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002274 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002275
2276 VkVertexInputBindingDescription input_binding;
2277 memset(&input_binding, 0, sizeof(input_binding));
2278
2279 VkVertexInputAttributeDescription input_attrib;
2280 memset(&input_attrib, 0, sizeof(input_attrib));
2281 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2282
2283 char const *vsSource =
2284 "#version 140\n"
2285 "#extension GL_ARB_separate_shader_objects: require\n"
2286 "#extension GL_ARB_shading_language_420pack: require\n"
2287 "\n"
2288 "layout(location=0) in int x;\n" /* attrib provided float */
2289 "void main(){\n"
2290 " gl_Position = vec4(x);\n"
2291 "}\n";
2292 char const *fsSource =
2293 "#version 140\n"
2294 "#extension GL_ARB_separate_shader_objects: require\n"
2295 "#extension GL_ARB_shading_language_420pack: require\n"
2296 "\n"
2297 "layout(location=0) out vec4 color;\n"
2298 "void main(){\n"
2299 " color = vec4(1);\n"
2300 "}\n";
2301
2302 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2303 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2304
2305 VkPipelineObj pipe(m_device);
2306 pipe.AddShader(&vs);
2307 pipe.AddShader(&fs);
2308
2309 pipe.AddVertexInputBindings(&input_binding, 1);
2310 pipe.AddVertexInputAttribs(&input_attrib, 1);
2311
2312 VkCommandBufferObj dummyCmd(m_device);
2313 VkDescriptorSetObj descriptorSet(m_device);
2314 descriptorSet.AppendDummy();
2315 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2316
2317 m_errorMonitor->ClearState();
2318 pipe.CreateVKPipeline(descriptorSet);
2319
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002320 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002321
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002322 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002323 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2324 FAIL() << "Incorrect error: " << msgString;
2325 }
2326}
2327
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002328TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2329{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002330 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002331 std::string msgString;
2332 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002333 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002334
2335 /* Two binding descriptions for binding 0 */
2336 VkVertexInputBindingDescription input_bindings[2];
2337 memset(input_bindings, 0, sizeof(input_bindings));
2338
2339 VkVertexInputAttributeDescription input_attrib;
2340 memset(&input_attrib, 0, sizeof(input_attrib));
2341 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2342
2343 char const *vsSource =
2344 "#version 140\n"
2345 "#extension GL_ARB_separate_shader_objects: require\n"
2346 "#extension GL_ARB_shading_language_420pack: require\n"
2347 "\n"
2348 "layout(location=0) in float x;\n" /* attrib provided float */
2349 "void main(){\n"
2350 " gl_Position = vec4(x);\n"
2351 "}\n";
2352 char const *fsSource =
2353 "#version 140\n"
2354 "#extension GL_ARB_separate_shader_objects: require\n"
2355 "#extension GL_ARB_shading_language_420pack: require\n"
2356 "\n"
2357 "layout(location=0) out vec4 color;\n"
2358 "void main(){\n"
2359 " color = vec4(1);\n"
2360 "}\n";
2361
2362 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2363 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2364
2365 VkPipelineObj pipe(m_device);
2366 pipe.AddShader(&vs);
2367 pipe.AddShader(&fs);
2368
2369 pipe.AddVertexInputBindings(input_bindings, 2);
2370 pipe.AddVertexInputAttribs(&input_attrib, 1);
2371
2372 VkCommandBufferObj dummyCmd(m_device);
2373 VkDescriptorSetObj descriptorSet(m_device);
2374 descriptorSet.AppendDummy();
2375 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2376
2377 m_errorMonitor->ClearState();
2378 pipe.CreateVKPipeline(descriptorSet);
2379
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002380 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002381
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002382 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002383 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2384 FAIL() << "Incorrect error: " << msgString;
2385 }
2386}
Chris Forbes4c948702015-05-25 11:13:32 +12002387
Chris Forbesc12ef122015-05-25 11:13:40 +12002388/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2389 * rejects it. */
2390
2391TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2392{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002393 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002394 std::string msgString;
2395 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002396 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002397
2398 char const *vsSource =
2399 "#version 140\n"
2400 "#extension GL_ARB_separate_shader_objects: require\n"
2401 "#extension GL_ARB_shading_language_420pack: require\n"
2402 "\n"
2403 "void main(){\n"
2404 " gl_Position = vec4(1);\n"
2405 "}\n";
2406 char const *fsSource =
2407 "#version 140\n"
2408 "#extension GL_ARB_separate_shader_objects: require\n"
2409 "#extension GL_ARB_shading_language_420pack: require\n"
2410 "\n"
2411 "void main(){\n"
2412 "}\n";
2413
2414 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2415 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2416
2417 VkPipelineObj pipe(m_device);
2418 pipe.AddShader(&vs);
2419 pipe.AddShader(&fs);
2420
2421 /* implicit CB 0 set up by the test framework, not written */
2422
2423 VkCommandBufferObj dummyCmd(m_device);
2424 VkDescriptorSetObj descriptorSet(m_device);
2425 descriptorSet.AppendDummy();
2426 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2427
2428 m_errorMonitor->ClearState();
2429 pipe.CreateVKPipeline(descriptorSet);
2430
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002431 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002432
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002433 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002434 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2435 FAIL() << "Incorrect error: " << msgString;
2436 }
2437}
2438
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002439TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2440{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002441 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002442 std::string msgString;
2443 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002444 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002445
2446 char const *vsSource =
2447 "#version 140\n"
2448 "#extension GL_ARB_separate_shader_objects: require\n"
2449 "#extension GL_ARB_shading_language_420pack: require\n"
2450 "\n"
2451 "void main(){\n"
2452 " gl_Position = vec4(1);\n"
2453 "}\n";
2454 char const *fsSource =
2455 "#version 140\n"
2456 "#extension GL_ARB_separate_shader_objects: require\n"
2457 "#extension GL_ARB_shading_language_420pack: require\n"
2458 "\n"
2459 "layout(location=0) out vec4 x;\n"
2460 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2461 "void main(){\n"
2462 " x = vec4(1);\n"
2463 " y = vec4(1);\n"
2464 "}\n";
2465
2466 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2467 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2468
2469 VkPipelineObj pipe(m_device);
2470 pipe.AddShader(&vs);
2471 pipe.AddShader(&fs);
2472
2473 /* implicit CB 0 set up by the test framework */
2474 /* FS writes CB 1, but we don't configure it */
2475
2476 VkCommandBufferObj dummyCmd(m_device);
2477 VkDescriptorSetObj descriptorSet(m_device);
2478 descriptorSet.AppendDummy();
2479 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2480
2481 m_errorMonitor->ClearState();
2482 pipe.CreateVKPipeline(descriptorSet);
2483
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002484 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002485
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002486 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002487 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2488 FAIL() << "Incorrect warning: " << msgString;
2489 }
2490}
2491
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002492TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2493{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002494 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002495 std::string msgString;
2496 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002497 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002498
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 "void main(){\n"
2505 " gl_Position = vec4(1);\n"
2506 "}\n";
2507 char const *fsSource =
2508 "#version 140\n"
2509 "#extension GL_ARB_separate_shader_objects: require\n"
2510 "#extension GL_ARB_shading_language_420pack: require\n"
2511 "\n"
2512 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2513 "void main(){\n"
2514 " x = ivec4(1);\n"
2515 "}\n";
2516
2517 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2518 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2519
2520 VkPipelineObj pipe(m_device);
2521 pipe.AddShader(&vs);
2522 pipe.AddShader(&fs);
2523
2524 /* implicit CB 0 set up by test framework, is UNORM. */
2525
2526 VkCommandBufferObj dummyCmd(m_device);
2527 VkDescriptorSetObj descriptorSet(m_device);
2528 descriptorSet.AppendDummy();
2529 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2530
2531 m_errorMonitor->ClearState();
2532 pipe.CreateVKPipeline(descriptorSet);
2533
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002534 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002535
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002536 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002537 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2538 FAIL() << "Incorrect error: " << msgString;
2539 }
2540}
Chris Forbesc2050732015-06-05 14:43:36 +12002541
2542TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2543{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002544 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002545 std::string msgString;
2546 ASSERT_NO_FATAL_FAILURE(InitState());
2547 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002548 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002549
2550 char const *vsSource =
2551 "#version 140\n"
2552 "#extension GL_ARB_separate_shader_objects: require\n"
2553 "#extension GL_ARB_shading_language_420pack: require\n"
2554 "\n"
2555 "void main(){\n"
2556 " gl_Position = vec4(1);\n"
2557 "}\n";
2558 char const *fsSource =
2559 "#version 140\n"
2560 "#extension GL_ARB_separate_shader_objects: require\n"
2561 "#extension GL_ARB_shading_language_420pack: require\n"
2562 "\n"
2563 "layout(location=0) out vec4 x;\n"
2564 "void main(){\n"
2565 " x = vec4(1);\n"
2566 "}\n";
2567
2568 m_errorMonitor->ClearState();
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
2574 VkPipelineObj pipe(m_device);
2575 pipe.AddShader(&vs);
2576 pipe.AddShader(&fs);
2577
2578 /* implicit CB 0 set up by test framework, is UNORM. */
2579
2580 VkCommandBufferObj dummyCmd(m_device);
2581 VkDescriptorSetObj descriptorSet(m_device);
2582 descriptorSet.AppendDummy();
2583 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2584
2585 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2586 /* pipeline creation should have succeeded */
2587 ASSERT_EQ(VK_SUCCESS, res);
2588
2589 /* should have emitted a warning: the shader is not SPIRV, so we're
2590 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002591 msgFlags = m_errorMonitor->GetState(&msgString);
2592 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002593 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2594 FAIL() << "Incorrect warning: " << msgString;
2595 }
2596}
Chris Forbes01c9db72015-06-04 09:25:25 +12002597#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002598
Tony Barbour30486ea2015-04-07 13:44:53 -06002599int main(int argc, char **argv) {
2600 int result;
2601
2602 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002603 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002604
2605 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2606
2607 result = RUN_ALL_TESTS();
2608
Tony Barbour01999182015-04-09 12:58:51 -06002609 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002610 return result;
2611}