blob: 3f178727496bdaf52371a1f86fd785662e1a499a [file] [log] [blame]
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001#include <vulkan.h>
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002#include "vk_debug_report_lunarg.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06003#include "gtest-1.7.0/include/gtest/gtest.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06004#include "vkrenderframework.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -06005#include "vk_layer_config.h"
Tony Barbour30486ea2015-04-07 13:44:53 -06006
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05007#define GLM_FORCE_RADIANS
8#include "glm/glm.hpp"
9#include <glm/gtc/matrix_transform.hpp>
10
Tobin Ehlis57e6a612015-05-26 16:11:58 -060011#define MEM_TRACKER_TESTS 1
12#define OBJ_TRACKER_TESTS 1
13#define DRAW_STATE_TESTS 1
14#define THREADING_TESTS 1
Chris Forbes5af3bf22015-05-25 11:13:08 +120015#define SHADER_CHECKER_TESTS 1
Tobin Ehlis57e6a612015-05-26 16:11:58 -060016
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050017//--------------------------------------------------------------------------------------
18// Mesh and VertexFormat Data
19//--------------------------------------------------------------------------------------
20struct Vertex
21{
22 float posX, posY, posZ, posW; // Position data
23 float r, g, b, a; // Color
24};
25
26#define XYZ1(_x_, _y_, _z_) (_x_), (_y_), (_z_), 1.f
27
28typedef enum _BsoFailSelect {
29 BsoFailNone = 0x00000000,
30 BsoFailRaster = 0x00000001,
31 BsoFailViewport = 0x00000002,
32 BsoFailColorBlend = 0x00000004,
33 BsoFailDepthStencil = 0x00000008,
34} BsoFailSelect;
35
36struct vktriangle_vs_uniform {
37 // Must start with MVP
38 float mvp[4][4];
39 float position[3][4];
40 float color[3][4];
41};
42
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050043static const char bindStateVertShaderText[] =
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050044 "#version 130\n"
45 "vec2 vertices[3];\n"
46 "void main() {\n"
47 " vertices[0] = vec2(-1.0, -1.0);\n"
48 " vertices[1] = vec2( 1.0, -1.0);\n"
49 " vertices[2] = vec2( 0.0, 1.0);\n"
50 " gl_Position = vec4(vertices[gl_VertexID % 3], 0.0, 1.0);\n"
51 "}\n";
52
Mark Lobodzinski6bbdff12015-06-02 09:41:30 -050053static const char bindStateFragShaderText[] =
Cody Northrop74a2d2c2015-06-16 17:32:04 -060054 "#version 140\n"
55 "#extension GL_ARB_separate_shader_objects: require\n"
56 "#extension GL_ARB_shading_language_420pack: require\n"
57 "\n"
58 "layout(location = 0) out vec4 uFragColor;\n"
59 "void main(){\n"
60 " uFragColor = vec4(0,1,0,1);\n"
61 "}\n";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -050062
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060063static void myDbgFunc(
64 VkFlags msgFlags,
65 VkObjectType objType,
66 VkObject srcObject,
67 size_t location,
68 int32_t msgCode,
69 const char* pLayerPrefix,
70 const char* pMsg,
71 void* pUserData);
Tony Barbour30486ea2015-04-07 13:44:53 -060072
73class ErrorMonitor {
74public:
Tony Barbour0c1bdc62015-04-29 17:34:29 -060075 ErrorMonitor()
Tony Barbour30486ea2015-04-07 13:44:53 -060076 {
Mike Stroyan09aae812015-05-12 16:00:45 -060077 pthread_mutexattr_t attr;
78 pthread_mutexattr_init(&attr);
79 pthread_mutex_init(&m_mutex, &attr);
80 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060081 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Mike Stroyan09aae812015-05-12 16:00:45 -060082 m_bailout = NULL;
83 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060084 }
85 void ClearState()
86 {
Mike Stroyan09aae812015-05-12 16:00:45 -060087 pthread_mutex_lock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060088 m_msgFlags = VK_DBG_REPORT_INFO_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -060089 m_msgString.clear();
Mike Stroyan09aae812015-05-12 16:00:45 -060090 pthread_mutex_unlock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060091 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060092 VkFlags GetState(std::string *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -060093 {
Mike Stroyan09aae812015-05-12 16:00:45 -060094 pthread_mutex_lock(&m_mutex);
Tony Barbour30486ea2015-04-07 13:44:53 -060095 *msgString = m_msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -060096 pthread_mutex_unlock(&m_mutex);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060097 return m_msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -060098 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060099 void SetState(VkFlags msgFlags, const char *msgString)
Tony Barbour30486ea2015-04-07 13:44:53 -0600100 {
Mike Stroyan09aae812015-05-12 16:00:45 -0600101 pthread_mutex_lock(&m_mutex);
102 if (m_bailout != NULL) {
103 *m_bailout = true;
104 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600105 m_msgFlags = msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600106 m_msgString.reserve(strlen(msgString));
107 m_msgString = msgString;
Mike Stroyan09aae812015-05-12 16:00:45 -0600108 pthread_mutex_unlock(&m_mutex);
109 }
110 void SetBailout(bool *bailout)
111 {
112 m_bailout = bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600113 }
114
115private:
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600116 VkFlags m_msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -0600117 std::string m_msgString;
118 pthread_mutex_t m_mutex;
119 bool* m_bailout;
Tony Barbour30486ea2015-04-07 13:44:53 -0600120};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500121
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600122static void myDbgFunc(
123 VkFlags msgFlags,
124 VkObjectType objType,
125 VkObject srcObject,
126 size_t location,
127 int32_t msgCode,
128 const char* pLayerPrefix,
129 const char* pMsg,
130 void* pUserData)
Tony Barbour30486ea2015-04-07 13:44:53 -0600131{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600132 if (msgFlags & (VK_DBG_REPORT_WARN_BIT | VK_DBG_REPORT_ERROR_BIT)) {
Tony Barbour8508b8e2015-04-09 10:48:04 -0600133 ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600134 errMonitor->SetState(msgFlags, pMsg);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600135 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600136}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500137
Tony Barbour01999182015-04-09 12:58:51 -0600138class VkLayerTest : public VkRenderFramework
Tony Barbour30486ea2015-04-07 13:44:53 -0600139{
140public:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600141 VkResult BeginCommandBuffer(VkCommandBufferObj &cmdBuffer);
142 VkResult EndCommandBuffer(VkCommandBufferObj &cmdBuffer);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500143 void VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask);
144 void GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask);
Tony Barbour30486ea2015-04-07 13:44:53 -0600145
146protected:
Tony Barbour01999182015-04-09 12:58:51 -0600147 VkMemoryRefManager m_memoryRefManager;
148 ErrorMonitor *m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600149
150 virtual void SetUp() {
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600151 std::vector<const char *> instance_layer_names;
152 std::vector<const char *> device_layer_names;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600153 std::vector<const char *> instance_extension_names;
154 std::vector<const char *> device_extension_names;
Tony Barbour950ebc02015-04-23 12:55:36 -0600155
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600156 instance_extension_names.push_back(DEBUG_REPORT_EXTENSION_NAME);
Courtney Goeltzenleuchterde53c5b2015-06-16 15:59:11 -0600157 /*
158 * Since CreateDbgMsgCallback is an instance level extension call
159 * any extension / layer that utilizes that feature also needs
160 * to be enabled at create instance time.
161 */
Mike Stroyaned254572015-06-17 16:32:06 -0600162 // Use Threading layer first to protect others from ThreadCmdBufferCollision test
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600163 instance_layer_names.push_back("Threading");
164 instance_layer_names.push_back("ObjectTracker");
165 instance_layer_names.push_back("MemTracker");
166 instance_layer_names.push_back("DrawState");
167 instance_layer_names.push_back("ShaderChecker");
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600168
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600169 device_layer_names.push_back("Threading");
170 device_layer_names.push_back("ObjectTracker");
171 device_layer_names.push_back("MemTracker");
172 device_layer_names.push_back("DrawState");
173 device_layer_names.push_back("ShaderChecker");
Tony Barbour30486ea2015-04-07 13:44:53 -0600174
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600175 this->app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
Tony Barbour30486ea2015-04-07 13:44:53 -0600176 this->app_info.pNext = NULL;
177 this->app_info.pAppName = "layer_tests";
178 this->app_info.appVersion = 1;
179 this->app_info.pEngineName = "unittest";
180 this->app_info.engineVersion = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600181 this->app_info.apiVersion = VK_API_VERSION;
Tony Barbour30486ea2015-04-07 13:44:53 -0600182
Tony Barbour0c1bdc62015-04-29 17:34:29 -0600183 m_errorMonitor = new ErrorMonitor;
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600184 InitFramework(instance_layer_names, device_layer_names,
185 instance_extension_names, device_extension_names,
186 myDbgFunc, m_errorMonitor);
Tony Barbour30486ea2015-04-07 13:44:53 -0600187 }
188
189 virtual void TearDown() {
190 // Clean up resources before we reset
Tony Barbour30486ea2015-04-07 13:44:53 -0600191 ShutdownFramework();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600192 delete m_errorMonitor;
Tony Barbour30486ea2015-04-07 13:44:53 -0600193 }
194};
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500195
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600196VkResult VkLayerTest::BeginCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600197{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600198 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600199
200 result = cmdBuffer.BeginCommandBuffer();
201
202 /*
203 * For render test all drawing happens in a single render pass
204 * on a single command buffer.
205 */
Chris Forbesfe133ef2015-06-16 14:05:59 +1200206 if (VK_SUCCESS == result && renderPass()) {
Tony Barbour30486ea2015-04-07 13:44:53 -0600207 cmdBuffer.BeginRenderPass(renderPass(), framebuffer());
208 }
209
210 return result;
211}
212
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600213VkResult VkLayerTest::EndCommandBuffer(VkCommandBufferObj &cmdBuffer)
Tony Barbour30486ea2015-04-07 13:44:53 -0600214{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600215 VkResult result;
Tony Barbour30486ea2015-04-07 13:44:53 -0600216
Chris Forbesfe133ef2015-06-16 14:05:59 +1200217 if (renderPass()) {
Chia-I Wu88eaa3b2015-06-26 15:34:39 +0800218 cmdBuffer.EndRenderPass();
Chris Forbesfe133ef2015-06-16 14:05:59 +1200219 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600220
221 result = cmdBuffer.EndCommandBuffer();
222
223 return result;
224}
225
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500226void VkLayerTest::VKTriangleTest(const char *vertShaderText, const char *fragShaderText, BsoFailSelect failMask)
227{
228 // Create identity matrix
229 int i;
230 struct vktriangle_vs_uniform data;
231
232 glm::mat4 Projection = glm::mat4(1.0f);
233 glm::mat4 View = glm::mat4(1.0f);
234 glm::mat4 Model = glm::mat4(1.0f);
235 glm::mat4 MVP = Projection * View * Model;
236 const int matrixSize = sizeof(MVP);
237 const int bufSize = sizeof(vktriangle_vs_uniform) / sizeof(float);
238
239 memcpy(&data.mvp, &MVP[0][0], matrixSize);
240
241 static const Vertex tri_data[] =
242 {
243 { XYZ1( -1, -1, 0 ), XYZ1( 1.f, 0.f, 0.f ) },
244 { XYZ1( 1, -1, 0 ), XYZ1( 0.f, 1.f, 0.f ) },
245 { XYZ1( 0, 1, 0 ), XYZ1( 0.f, 0.f, 1.f ) },
246 };
247
248 for (i=0; i<3; i++) {
249 data.position[i][0] = tri_data[i].posX;
250 data.position[i][1] = tri_data[i].posY;
251 data.position[i][2] = tri_data[i].posZ;
252 data.position[i][3] = tri_data[i].posW;
253 data.color[i][0] = tri_data[i].r;
254 data.color[i][1] = tri_data[i].g;
255 data.color[i][2] = tri_data[i].b;
256 data.color[i][3] = tri_data[i].a;
257 }
258
259 ASSERT_NO_FATAL_FAILURE(InitState());
260 ASSERT_NO_FATAL_FAILURE(InitViewport());
261
262 VkConstantBufferObj constantBuffer(m_device, bufSize*2, sizeof(float), (const void*) &data);
263
264 VkShaderObj vs(m_device,vertShaderText,VK_SHADER_STAGE_VERTEX, this);
265 VkShaderObj ps(m_device,fragShaderText, VK_SHADER_STAGE_FRAGMENT, this);
266
267 VkPipelineObj pipelineobj(m_device);
268 pipelineobj.AddShader(&vs);
269 pipelineobj.AddShader(&ps);
270
271 VkDescriptorSetObj descriptorSet(m_device);
272 descriptorSet.AppendBuffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, constantBuffer);
273
274 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
275 VkCommandBufferObj cmdBuffer(m_device);
276 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
277
278 ASSERT_VK_SUCCESS(BeginCommandBuffer(cmdBuffer));
279
280 GenericDrawPreparation(&cmdBuffer, pipelineobj, descriptorSet, failMask);
281
282 // render triangle
283 cmdBuffer.Draw(0, 3, 0, 1);
284
285 // finalize recording of the command buffer
286 EndCommandBuffer(cmdBuffer);
287
288 cmdBuffer.QueueCommandBuffer();
289}
290
291void VkLayerTest::GenericDrawPreparation(VkCommandBufferObj *cmdBuffer, VkPipelineObj &pipelineobj, VkDescriptorSetObj &descriptorSet, BsoFailSelect failMask)
292{
293 if (m_depthStencil->Initialized()) {
294 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, m_depthStencil);
295 } else {
296 cmdBuffer->ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
297 }
298
299 cmdBuffer->PrepareAttachments();
300 if ((failMask & BsoFailRaster) != BsoFailRaster) {
301 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_RASTER, m_stateRaster);
302 }
303 if ((failMask & BsoFailViewport) != BsoFailViewport) {
304 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_VIEWPORT, m_stateViewport);
305 }
306 if ((failMask & BsoFailColorBlend) != BsoFailColorBlend) {
307 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_COLOR_BLEND, m_colorBlend);
308 }
309 if ((failMask & BsoFailDepthStencil) != BsoFailDepthStencil) {
310 cmdBuffer->BindStateObject(VK_STATE_BIND_POINT_DEPTH_STENCIL, m_stateDepthStencil);
311 }
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600312 // Make sure depthWriteEnable is set so that DepthStencil fail test will work correctly
313 VkStencilOpState stencil = {
314 .stencilFailOp = VK_STENCIL_OP_KEEP,
315 .stencilPassOp = VK_STENCIL_OP_KEEP,
316 .stencilDepthFailOp = VK_STENCIL_OP_KEEP,
317 .stencilCompareOp = VK_COMPARE_OP_NEVER
318 };
319 VkPipelineDsStateCreateInfo ds_ci = {
320 .sType = VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO,
321 .pNext = NULL,
322 .format = VK_FORMAT_D24_UNORM_S8_UINT,
323 .depthTestEnable = VK_FALSE,
324 .depthWriteEnable = VK_TRUE,
325 .depthCompareOp = VK_COMPARE_OP_NEVER,
326 .depthBoundsEnable = VK_FALSE,
327 .stencilTestEnable = VK_FALSE,
328 .front = stencil,
329 .back = stencil
330 };
331 pipelineobj.SetDepthStencil(&ds_ci);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500332 descriptorSet.CreateVKDescriptorSet(cmdBuffer);
333 pipelineobj.CreateVKPipeline(descriptorSet);
334 cmdBuffer->BindPipeline(pipelineobj);
335 cmdBuffer->BindDescriptorSet(descriptorSet);
336}
337
338// ********************************************************************************************************************
339// ********************************************************************************************************************
340// ********************************************************************************************************************
341// ********************************************************************************************************************
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600342#if MEM_TRACKER_TESTS
Mark Lobodzinski81078192015-05-19 10:28:29 -0500343TEST_F(VkLayerTest, CallResetCmdBufferBeforeCompletion)
344{
345 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600346 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500347 std::string msgString;
348
349 VkFenceCreateInfo fenceInfo = {};
350 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
351 fenceInfo.pNext = NULL;
352 fenceInfo.flags = 0;
353
354 ASSERT_NO_FATAL_FAILURE(InitState());
355 ASSERT_NO_FATAL_FAILURE(InitViewport());
356 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
357
358 VkCommandBufferObj cmdBuffer(m_device);
359 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
360
361 BeginCommandBuffer(cmdBuffer);
362 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
363 EndCommandBuffer(cmdBuffer);
364
365 testFence.init(*m_device, fenceInfo);
366
367 // Bypass framework since it does the waits automatically
368 VkResult err = VK_SUCCESS;
369 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
370 ASSERT_VK_SUCCESS( err );
371
372 m_errorMonitor->ClearState();
373 // Introduce failure by calling begin again before checking fence
374 vkResetCommandBuffer(cmdBuffer.obj());
375
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600376 msgFlags = m_errorMonitor->GetState(&msgString);
377 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 -0500378 if (!strstr(msgString.c_str(),"Resetting CB")) {
379 FAIL() << "Error received was not 'Resetting CB (0xaddress) before it has completed. You must check CB flag before'";
380 }
381}
382
383TEST_F(VkLayerTest, CallBeginCmdBufferBeforeCompletion)
384{
385 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600386 VkFlags msgFlags;
Mark Lobodzinski81078192015-05-19 10:28:29 -0500387 std::string msgString;
388
389 VkFenceCreateInfo fenceInfo = {};
390 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
391 fenceInfo.pNext = NULL;
392 fenceInfo.flags = 0;
393
394 ASSERT_NO_FATAL_FAILURE(InitState());
395 ASSERT_NO_FATAL_FAILURE(InitViewport());
396 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
397
398 VkCommandBufferObj cmdBuffer(m_device);
399 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
400
401 BeginCommandBuffer(cmdBuffer);
402 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
403 EndCommandBuffer(cmdBuffer);
404
405 testFence.init(*m_device, fenceInfo);
406
407 // Bypass framework since it does the waits automatically
408 VkResult err = VK_SUCCESS;
409 err = vkQueueSubmit( m_device->m_queue, 1, &cmdBuffer.obj(), testFence.obj());
410 ASSERT_VK_SUCCESS( err );
411
412 m_errorMonitor->ClearState();
413 // Introduce failure by calling begin again before checking fence
414 BeginCommandBuffer(cmdBuffer);
415
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600416 msgFlags = m_errorMonitor->GetState(&msgString);
417 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 -0500418 if (!strstr(msgString.c_str(),"Calling vkBeginCommandBuffer() on active CB")) {
419 FAIL() << "Error received was not 'Calling vkBeginCommandBuffer() on an active CB (0xaddress) before it has completed'";
420 }
421}
422
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500423TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit)
424{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600425 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500426 std::string msgString;
427 VkResult err;
428
429 ASSERT_NO_FATAL_FAILURE(InitState());
430 m_errorMonitor->ClearState();
431
432 // Create an image, allocate memory, free it, and then try to bind it
433 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500434 VkDeviceMemory mem;
435 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500436
437 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
438 const int32_t tex_width = 32;
439 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500440
441 const VkImageCreateInfo image_create_info = {
442 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
443 .pNext = NULL,
444 .imageType = VK_IMAGE_TYPE_2D,
445 .format = tex_format,
446 .extent = { tex_width, tex_height, 1 },
447 .mipLevels = 1,
448 .arraySize = 1,
449 .samples = 1,
450 .tiling = VK_IMAGE_TILING_LINEAR,
451 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
452 .flags = 0,
453 };
454 VkMemoryAllocInfo mem_alloc = {
455 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
456 .pNext = NULL,
457 .allocationSize = 0,
458 // Introduce failure, do NOT set memProps to VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
Mark Lobodzinski72346292015-07-02 16:49:40 -0600459 .memoryTypeIndex = 1,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500460 };
461
462 err = vkCreateImage(m_device->device(), &image_create_info, &image);
463 ASSERT_VK_SUCCESS(err);
464
Tony Barbour426b9052015-06-24 16:06:58 -0600465 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500466 VK_OBJECT_TYPE_IMAGE,
467 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500468 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500469 ASSERT_VK_SUCCESS(err);
470
Mark Lobodzinski23182612015-05-29 09:32:35 -0500471 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500472
473 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500474 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500475 ASSERT_VK_SUCCESS(err);
476
477 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500478 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500479 ASSERT_VK_SUCCESS(err);
480
481 // Map memory as if to initialize the image
482 void *mappedAddress = NULL;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500483 err = vkMapMemory(m_device->device(), mem, 0, 0, 0, &mappedAddress);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500484
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600485 msgFlags = m_errorMonitor->GetState(&msgString);
486 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 -0500487 if (!strstr(msgString.c_str(),"Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT")) {
488 FAIL() << "Error received did not match expected error message from vkMapMemory in MemTracker";
489 }
490}
491
492TEST_F(VkLayerTest, BindInvalidMemory)
493{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600494 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500495 std::string msgString;
496 VkResult err;
497
498 ASSERT_NO_FATAL_FAILURE(InitState());
499 m_errorMonitor->ClearState();
500
501 // Create an image, allocate memory, free it, and then try to bind it
502 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500503 VkDeviceMemory mem;
504 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500505
506 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
507 const int32_t tex_width = 32;
508 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500509
510 const VkImageCreateInfo image_create_info = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600511 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
512 .pNext = NULL,
513 .imageType = VK_IMAGE_TYPE_2D,
514 .format = tex_format,
515 .extent = { tex_width, tex_height, 1 },
516 .mipLevels = 1,
517 .arraySize = 1,
518 .samples = 1,
519 .tiling = VK_IMAGE_TILING_LINEAR,
520 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
521 .flags = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500522 };
523 VkMemoryAllocInfo mem_alloc = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600524 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
525 .pNext = NULL,
526 .allocationSize = 0,
527 .memoryTypeIndex = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500528 };
529
530 err = vkCreateImage(m_device->device(), &image_create_info, &image);
531 ASSERT_VK_SUCCESS(err);
532
Tony Barbour426b9052015-06-24 16:06:58 -0600533 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500534 VK_OBJECT_TYPE_IMAGE,
535 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500536 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500537 ASSERT_VK_SUCCESS(err);
538
Mark Lobodzinski23182612015-05-29 09:32:35 -0500539 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500540
Mark Lobodzinski72346292015-07-02 16:49:40 -0600541 err = m_device->gpu().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
542 ASSERT_VK_SUCCESS(err);
543
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500544 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500545 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500546 ASSERT_VK_SUCCESS(err);
547
548 // Introduce validation failure, free memory before binding
Mark Lobodzinski23182612015-05-29 09:32:35 -0500549 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500550 ASSERT_VK_SUCCESS(err);
551
552 // Try to bind free memory that has been freed
Mark Lobodzinski23182612015-05-29 09:32:35 -0500553 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500554 ASSERT_VK_SUCCESS(err);
555
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600556 msgFlags = m_errorMonitor->GetState(&msgString);
557 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 -0500558 if (!strstr(msgString.c_str(),"couldn't find info for mem obj")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500559 FAIL() << "Error received did not match expected error message from BindObjectMemory in MemTracker";
560 }
561}
562
563TEST_F(VkLayerTest, FreeBoundMemory)
564{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600565 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500566 std::string msgString;
567 VkResult err;
568
569 ASSERT_NO_FATAL_FAILURE(InitState());
570 m_errorMonitor->ClearState();
571
572 // Create an image, allocate memory, free it, and then try to bind it
573 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500574 VkDeviceMemory mem;
575 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500576
577 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
578 const int32_t tex_width = 32;
579 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500580
581 const VkImageCreateInfo image_create_info = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600582 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
583 .pNext = NULL,
584 .imageType = VK_IMAGE_TYPE_2D,
585 .format = tex_format,
586 .extent = { tex_width, tex_height, 1 },
587 .mipLevels = 1,
588 .arraySize = 1,
589 .samples = 1,
590 .tiling = VK_IMAGE_TILING_LINEAR,
591 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
592 .flags = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500593 };
594 VkMemoryAllocInfo mem_alloc = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600595 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
596 .pNext = NULL,
597 .allocationSize = 0,
598 .memoryTypeIndex = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500599 };
600
601 err = vkCreateImage(m_device->device(), &image_create_info, &image);
602 ASSERT_VK_SUCCESS(err);
603
Tony Barbour426b9052015-06-24 16:06:58 -0600604 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500605 VK_OBJECT_TYPE_IMAGE,
606 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500607 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500608 ASSERT_VK_SUCCESS(err);
609
Mark Lobodzinski23182612015-05-29 09:32:35 -0500610 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500611
Mark Lobodzinski72346292015-07-02 16:49:40 -0600612 err = m_device->gpu().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
613 ASSERT_VK_SUCCESS(err);
614
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500615 // allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500616 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500617 ASSERT_VK_SUCCESS(err);
618
619 // Bind memory to Image object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500620 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500621 ASSERT_VK_SUCCESS(err);
622
623 // Introduce validation failure, free memory while still bound to object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500624 vkFreeMemory(m_device->device(), mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500625 ASSERT_VK_SUCCESS(err);
626
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600627 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter7dc4c8b2015-06-13 21:48:47 -0600628 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 -0500629 if (!strstr(msgString.c_str(),"Freeing memory object while it still has references")) {
630 FAIL() << "Warning received did not match expected message from freeMemObjInfo in MemTracker";
631 }
632}
633
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500634TEST_F(VkLayerTest, RebindMemory)
635{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600636 VkFlags msgFlags;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500637 std::string msgString;
638 VkResult err;
639
640 ASSERT_NO_FATAL_FAILURE(InitState());
641 m_errorMonitor->ClearState();
642
643 // Create an image, allocate memory, free it, and then try to bind it
644 VkImage image;
645 VkDeviceMemory mem1;
646 VkDeviceMemory mem2;
647 VkMemoryRequirements mem_reqs;
648
649 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
650 const int32_t tex_width = 32;
651 const int32_t tex_height = 32;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500652
653 const VkImageCreateInfo image_create_info = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600654 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
655 .pNext = NULL,
656 .imageType = VK_IMAGE_TYPE_2D,
657 .format = tex_format,
658 .extent = { tex_width, tex_height, 1 },
659 .mipLevels = 1,
660 .arraySize = 1,
661 .samples = 1,
662 .tiling = VK_IMAGE_TILING_LINEAR,
663 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
664 .flags = 0,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500665 };
666 VkMemoryAllocInfo mem_alloc = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600667 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
668 .pNext = NULL,
669 .allocationSize = 0,
670 .memoryTypeIndex = 0,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500671 };
672
673 err = vkCreateImage(m_device->device(), &image_create_info, &image);
674 ASSERT_VK_SUCCESS(err);
675
Tony Barbour426b9052015-06-24 16:06:58 -0600676 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500677 VK_OBJECT_TYPE_IMAGE,
678 image,
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500679 &mem_reqs);
680 ASSERT_VK_SUCCESS(err);
681
682 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski72346292015-07-02 16:49:40 -0600683 err = m_device->gpu().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
684 ASSERT_VK_SUCCESS(err);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500685
686 // allocate 2 memory objects
687 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem1);
688 ASSERT_VK_SUCCESS(err);
689 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem2);
690 ASSERT_VK_SUCCESS(err);
691
692 // Bind first memory object to Image object
693 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem1, 0);
694 ASSERT_VK_SUCCESS(err);
695
696 // Introduce validation failure, try to bind a different memory object to the same image object
697 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem2, 0);
698 ASSERT_VK_SUCCESS(err);
699
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600700 msgFlags = m_errorMonitor->GetState(&msgString);
701 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 -0500702 if (!strstr(msgString.c_str(),"which has already been bound to mem object")) {
703 FAIL() << "Error received did not match expected message when rebinding memory to an object";
704 }
705}
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500706
707TEST_F(VkLayerTest, BindMemoryToDestroyedObject)
708{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600709 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500710 std::string msgString;
711 VkResult err;
712
713 ASSERT_NO_FATAL_FAILURE(InitState());
714 m_errorMonitor->ClearState();
715
716 // Create an image object, allocate memory, destroy the object and then try to bind it
717 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500718 VkDeviceMemory mem;
719 VkMemoryRequirements mem_reqs;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500720
721 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
722 const int32_t tex_width = 32;
723 const int32_t tex_height = 32;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500724
725 const VkImageCreateInfo image_create_info = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600726 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
727 .pNext = NULL,
728 .imageType = VK_IMAGE_TYPE_2D,
729 .format = tex_format,
730 .extent = { tex_width, tex_height, 1 },
731 .mipLevels = 1,
732 .arraySize = 1,
733 .samples = 1,
734 .tiling = VK_IMAGE_TILING_LINEAR,
735 .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
736 .flags = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500737 };
738 VkMemoryAllocInfo mem_alloc = {
Mark Lobodzinski72346292015-07-02 16:49:40 -0600739 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
740 .pNext = NULL,
741 .allocationSize = 0,
742 .memoryTypeIndex = 0,
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500743 };
744
745 err = vkCreateImage(m_device->device(), &image_create_info, &image);
746 ASSERT_VK_SUCCESS(err);
747
Tony Barbour426b9052015-06-24 16:06:58 -0600748 err = vkGetObjectMemoryRequirements(m_device->device(),
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500749 VK_OBJECT_TYPE_IMAGE,
750 image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500751 &mem_reqs);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500752 ASSERT_VK_SUCCESS(err);
753
Mark Lobodzinski23182612015-05-29 09:32:35 -0500754 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski72346292015-07-02 16:49:40 -0600755 err = m_device->gpu().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
756 ASSERT_VK_SUCCESS(err);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500757
758 // Allocate memory
Mark Lobodzinski23182612015-05-29 09:32:35 -0500759 err = vkAllocMemory(m_device->device(), &mem_alloc, &mem);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500760 ASSERT_VK_SUCCESS(err);
761
762 // Introduce validation failure, destroy Image object before binding
763 vkDestroyObject(m_device->device(), VK_OBJECT_TYPE_IMAGE, image);
764 ASSERT_VK_SUCCESS(err);
765
766 // Now Try to bind memory to this destroyted object
Mark Lobodzinski23182612015-05-29 09:32:35 -0500767 err = vkBindObjectMemory(m_device->device(), VK_OBJECT_TYPE_IMAGE, image, mem, 0);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500768 ASSERT_VK_SUCCESS(err);
769
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600770 msgFlags = m_errorMonitor->GetState(&msgString);
771 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 -0500772 if (!strstr(msgString.c_str(),"that's not in global list")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500773 FAIL() << "Error received did not match expected error message from updateObjectBinding in MemTracker";
774 }
775}
776
Tony Barbour8508b8e2015-04-09 10:48:04 -0600777TEST_F(VkLayerTest, SubmitSignaledFence)
Tony Barbour30486ea2015-04-07 13:44:53 -0600778{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600779 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600780 VkFlags msgFlags;
Tony Barbour30486ea2015-04-07 13:44:53 -0600781 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600782
783 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600784 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
785 fenceInfo.pNext = NULL;
786 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
Tony Barbour30486ea2015-04-07 13:44:53 -0600787
Tony Barbour30486ea2015-04-07 13:44:53 -0600788 ASSERT_NO_FATAL_FAILURE(InitState());
789 ASSERT_NO_FATAL_FAILURE(InitViewport());
790 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
791
Tony Barbour01999182015-04-09 12:58:51 -0600792 VkCommandBufferObj cmdBuffer(m_device);
Tony Barbour30486ea2015-04-07 13:44:53 -0600793 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
794
Tony Barbour8508b8e2015-04-09 10:48:04 -0600795 BeginCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600796 cmdBuffer.ClearAllBuffers(m_clear_color, m_depth_clear_color, m_stencil_clear_color, NULL);
Tony Barbour8508b8e2015-04-09 10:48:04 -0600797 EndCommandBuffer(cmdBuffer);
Tony Barbour30486ea2015-04-07 13:44:53 -0600798
799 testFence.init(*m_device, fenceInfo);
800 m_errorMonitor->ClearState();
Tony Barbour8508b8e2015-04-09 10:48:04 -0600801 cmdBuffer.QueueCommandBuffer(testFence.obj());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600802 msgFlags = m_errorMonitor->GetState(&msgString);
803 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 -0600804 if (!strstr(msgString.c_str(),"submitted in SIGNALED state. Fences must be reset before being submitted")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500805 FAIL() << "Error received was not 'VkQueueSubmit with fence in SIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600806 }
807
808}
809
810TEST_F(VkLayerTest, ResetUnsignaledFence)
811{
812 vk_testing::Fence testFence;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600813 VkFlags msgFlags;
Tony Barbour8508b8e2015-04-09 10:48:04 -0600814 std::string msgString;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600815 VkFenceCreateInfo fenceInfo = {};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600816 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
817 fenceInfo.pNext = NULL;
818
Tony Barbour8508b8e2015-04-09 10:48:04 -0600819 ASSERT_NO_FATAL_FAILURE(InitState());
820 testFence.init(*m_device, fenceInfo);
821 m_errorMonitor->ClearState();
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600822 VkFence fences[1] = {testFence.obj()};
Tony Barbour8508b8e2015-04-09 10:48:04 -0600823 vkResetFences(m_device->device(), 1, fences);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600824 msgFlags = m_errorMonitor->GetState(&msgString);
825 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 -0600826 if (!strstr(msgString.c_str(),"submitted to VkResetFences in UNSIGNALED STATE")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500827 FAIL() << "Error received was not 'VkResetFences with fence in UNSIGNALED_STATE'";
Tony Barbour8508b8e2015-04-09 10:48:04 -0600828 }
Tony Barbour30486ea2015-04-07 13:44:53 -0600829
830}
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600831
832TEST_F(VkLayerTest, InvalidUsageBits)
833{
834 // Initiate Draw w/o a PSO bound
835 VkFlags msgFlags;
836 std::string msgString;
837
838 ASSERT_NO_FATAL_FAILURE(InitState());
839 m_errorMonitor->ClearState();
840 VkCommandBufferObj cmdBuffer(m_device);
841 BeginCommandBuffer(cmdBuffer);
842
843 const VkExtent3D e3d = {
844 .width = 128,
845 .height = 128,
846 .depth = 1,
847 };
848 const VkImageCreateInfo ici = {
849 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
850 .pNext = NULL,
851 .imageType = VK_IMAGE_TYPE_2D,
852 .format = VK_FORMAT_D32_SFLOAT_S8_UINT,
853 .extent = e3d,
854 .mipLevels = 1,
855 .arraySize = 1,
856 .samples = 1,
857 .tiling = VK_IMAGE_TILING_LINEAR,
858 .usage = 0, // Not setting VK_IMAGE_USAGE_DEPTH_STENCIL_BIT
859 .flags = 0,
860 };
861
862 VkImage dsi;
863 vkCreateImage(m_device->device(), &ici, &dsi);
864 VkDepthStencilView dsv;
865 const VkDepthStencilViewCreateInfo dsvci = {
866 .sType = VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO,
867 .pNext = NULL,
868 .image = dsi,
869 .mipLevel = 0,
870 .baseArraySlice = 0,
871 .arraySize = 1,
872 .flags = 0,
873 };
874 vkCreateDepthStencilView(m_device->device(), &dsvci, &dsv);
875 msgFlags = m_errorMonitor->GetState(&msgString);
876 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after attempting to create DSView w/ image lacking USAGE_DS_BIT flag";
877 if (!strstr(msgString.c_str(),"Invalid usage flag for image ")) {
878 FAIL() << "Error received was not 'Invalid usage flag for image...'";
879 }
880}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600881#endif
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600882#if OBJ_TRACKER_TESTS
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500883TEST_F(VkLayerTest, RasterStateNotBound)
884{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600885 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500886 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600887 ASSERT_NO_FATAL_FAILURE(InitState());
888 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500889 TEST_DESCRIPTION("Simple Draw Call that validates failure when a raster state object is not bound beforehand");
890
891 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailRaster);
892
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600893 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600894 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 -0500895 if (!strstr(msgString.c_str(),"Raster object not bound to this command buffer")) {
896 FAIL() << "Error received was not 'Raster object not bound to this command buffer'";
897 }
898}
899
900TEST_F(VkLayerTest, ViewportStateNotBound)
901{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600902 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500903 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600904 ASSERT_NO_FATAL_FAILURE(InitState());
905 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500906 TEST_DESCRIPTION("Simple Draw Call that validates failure when a viewport state object is not bound beforehand");
907
908 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
909
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600910 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600911 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 -0500912 if (!strstr(msgString.c_str(),"Viewport object not bound to this command buffer")) {
913 FAIL() << "Error received was not 'Viewport object not bound to this command buffer'";
914 }
915}
916
917TEST_F(VkLayerTest, ColorBlendStateNotBound)
918{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600919 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500920 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600921 ASSERT_NO_FATAL_FAILURE(InitState());
922 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500923 TEST_DESCRIPTION("Simple Draw Call that validates failure when a color-blend state object is not bound beforehand");
924
925 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailColorBlend);
926
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600927 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600928 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive an error from Not Binding a ColorBlend State Object";
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500929 if (!strstr(msgString.c_str(),"Color-blend object not bound to this command buffer")) {
930 FAIL() << "Error received was not 'Color-blend object not bound to this command buffer'";
931 }
932}
933
934TEST_F(VkLayerTest, DepthStencilStateNotBound)
935{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600936 VkFlags msgFlags;
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500937 std::string msgString;
Tobin Ehlis254eca02015-06-25 15:46:59 -0600938 ASSERT_NO_FATAL_FAILURE(InitState());
939 m_errorMonitor->ClearState();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500940 TEST_DESCRIPTION("Simple Draw Call that validates failure when a depth-stencil state object is not bound beforehand");
941
942 VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailDepthStencil);
943
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600944 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600945 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 -0500946 if (!strstr(msgString.c_str(),"Depth-stencil object not bound to this command buffer")) {
947 FAIL() << "Error received was not 'Depth-stencil object not bound to this command buffer'";
948 }
Tony Barbourdb686622015-05-06 09:35:56 -0600949}
Tobin Ehlis57e6a612015-05-26 16:11:58 -0600950#endif
951#if DRAW_STATE_TESTS
Tobin Ehlise4076782015-06-24 15:53:07 -0600952TEST_F(VkLayerTest, BindPipelineNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600953{
954 // Initiate Draw w/o a PSO bound
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600955 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600956 std::string msgString;
957
958 ASSERT_NO_FATAL_FAILURE(InitState());
959 m_errorMonitor->ClearState();
960 VkCommandBufferObj cmdBuffer(m_device);
961 BeginCommandBuffer(cmdBuffer);
962 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
963 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600964 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -0600965 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding pipeline to CmdBuffer w/o active RenderPass";
966 if (!strstr(msgString.c_str(),"Incorrectly binding graphics pipeline ")) {
967 FAIL() << "Error received was not 'Incorrectly binding graphics pipeline (0xbaadb1be) without an active RenderPass'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600968 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600969}
970
971TEST_F(VkLayerTest, InvalidDescriptorPool)
972{
973 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
974 // The DS check for this is after driver has been called to validate DS internal data struct
975 // Attempt to clear DS Pool with bad object
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600976/* VkFlags msgFlags;
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600977 std::string msgString;
978 VkDescriptorPool badPool = (VkDescriptorPool)0xbaad6001;
979 vkResetDescriptorPool(device(), badPool);
980
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600981 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis40e9f522015-06-25 11:58:41 -0600982 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 -0600983 if (!strstr(msgString.c_str(),"Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call")) {
984 FAIL() << "Error received was note 'Unable to find pool node for pool 0xbaad6001 specified in vkResetDescriptorPool() call'";
985 }*/
986}
987
988TEST_F(VkLayerTest, InvalidDescriptorSet)
989{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -0600990 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
991 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -0600992 // Create a valid cmd buffer
993 // call vkCmdBindDescriptorSets w/ false DS
994}
995
996TEST_F(VkLayerTest, InvalidDescriptorSetLayout)
997{
998 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
999 // The DS check for this is after driver has been called to validate DS internal data struct
1000}
1001
1002TEST_F(VkLayerTest, InvalidPipeline)
1003{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001004 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1005 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001006 // Create a valid cmd buffer
1007 // call vkCmdBindPipeline w/ false Pipeline
Tobin Ehlise4076782015-06-24 15:53:07 -06001008// VkFlags msgFlags;
1009// std::string msgString;
1010//
1011// ASSERT_NO_FATAL_FAILURE(InitState());
1012// m_errorMonitor->ClearState();
1013// VkCommandBufferObj cmdBuffer(m_device);
1014// BeginCommandBuffer(cmdBuffer);
1015// VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
1016// vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
1017// msgFlags = m_errorMonitor->GetState(&msgString);
1018// ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
1019// if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
1020// FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
1021// }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001022}
1023
Tobin Ehlis254eca02015-06-25 15:46:59 -06001024TEST_F(VkLayerTest, DescriptorSetNotUpdated)
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001025{
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001026 // Create and update CmdBuffer then call QueueSubmit w/o calling End on CmdBuffer
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001027 VkFlags msgFlags;
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001028 std::string msgString;
1029 VkResult err;
1030
1031 ASSERT_NO_FATAL_FAILURE(InitState());
1032 m_errorMonitor->ClearState();
1033 VkCommandBufferObj cmdBuffer(m_device);
1034 const VkDescriptorTypeCount ds_type_count = {
1035 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1036 .count = 1,
1037 };
1038 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1039 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1040 .pNext = NULL,
1041 .count = 1,
1042 .pTypeCount = &ds_type_count,
1043 };
1044 VkDescriptorPool ds_pool;
1045 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1046 ASSERT_VK_SUCCESS(err);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001047
1048 const VkDescriptorSetLayoutBinding dsl_binding = {
1049 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001050 .arraySize = 1,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001051 .stageFlags = VK_SHADER_STAGE_ALL,
1052 .pImmutableSamplers = NULL,
1053 };
1054
1055 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1056 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1057 .pNext = NULL,
1058 .count = 1,
1059 .pBinding = &dsl_binding,
1060 };
1061 VkDescriptorSetLayout ds_layout;
1062 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1063 ASSERT_VK_SUCCESS(err);
1064
1065 VkDescriptorSet descriptorSet;
1066 uint32_t ds_count = 0;
1067 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1068 ASSERT_VK_SUCCESS(err);
1069
1070 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1071 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1072 .pNext = NULL,
1073 .descriptorSetCount = 1,
1074 .pSetLayouts = &ds_layout,
1075 };
1076
1077 VkPipelineLayout pipeline_layout;
1078 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1079 ASSERT_VK_SUCCESS(err);
1080
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001081 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001082
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001083 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1084 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1085 .pNext = NULL,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001086 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001087 .shader = vs.obj(),
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001088 .linkConstBufferCount = 0,
1089 .pLinkConstBufferInfo = NULL,
1090 .pSpecializationInfo = NULL,
1091 };
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001092 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001093 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1094 .pNext = NULL,
1095 .stageCount = 1,
1096 .pStages = &pipe_vs_ci,
1097 .pVertexInputState = NULL,
1098 .pIaState = NULL,
1099 .pTessState = NULL,
1100 .pVpState = NULL,
1101 .pRsState = NULL,
1102 .pMsState = NULL,
1103 .pDsState = NULL,
1104 .pCbState = NULL,
1105 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1106 .layout = pipeline_layout,
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001107 };
Jon Ashburn0d60d272015-07-09 15:02:25 -06001108 const VkPipelineCacheCreateInfo pc_ci = {
1109 .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
1110 .pNext = NULL,
1111 .initialSize = 0,
1112 .initialData = 0,
1113 .maxSize = 0,
1114 };
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001115
1116 VkPipeline pipeline;
Jon Ashburn0d60d272015-07-09 15:02:25 -06001117 VkPipelineCache pipelineCache;
1118
1119 err = vkCreatePipelineCache(m_device->device(), &pc_ci, &pipelineCache);
1120 ASSERT_VK_SUCCESS(err);
1121 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, &pipeline);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001122 ASSERT_VK_SUCCESS(err);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001123 ASSERT_NO_FATAL_FAILURE(InitState());
1124 ASSERT_NO_FATAL_FAILURE(InitViewport());
1125 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1126 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1127 BeginCommandBuffer(cmdBuffer);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001128 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06001129 vkCmdBindDescriptorSets(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptorSet, 0, NULL);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001130
Tobin Ehlis254eca02015-06-25 15:46:59 -06001131 msgFlags = m_errorMonitor->GetState(&msgString);
1132 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT) << "Did not warn after binding a DescriptorSet that was never updated.";
1133 if (!strstr(msgString.c_str()," bound but it was never updated. ")) {
1134 FAIL() << "Error received was not 'DS <blah> bound but it was never updated. You may want to either update it or not bind it.'";
1135 }
1136}
1137
1138TEST_F(VkLayerTest, NoBeginCmdBuffer)
1139{
1140 VkFlags msgFlags;
1141 std::string msgString;
1142
1143 ASSERT_NO_FATAL_FAILURE(InitState());
1144 m_errorMonitor->ClearState();
1145 VkCommandBufferObj cmdBuffer(m_device);
1146 // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
1147 vkEndCommandBuffer(cmdBuffer.GetBufferHandle());
1148 msgFlags = m_errorMonitor->GetState(&msgString);
1149 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after ending a CmdBuffer w/o calling BeginCommandBuffer()";
1150 if (!strstr(msgString.c_str(),"You must call vkBeginCommandBuffer() before this call to ")) {
1151 FAIL() << "Error received was not 'You must call vkBeginCommandBuffer() before this call to vkEndCommandBuffer()'";
1152 }
1153}
1154
1155TEST_F(VkLayerTest, InvalidPipelineCreateState)
1156{
1157 // Attempt to Create Gfx Pipeline w/o a VS
1158 VkFlags msgFlags;
1159 std::string msgString;
1160 VkResult err;
1161
1162 ASSERT_NO_FATAL_FAILURE(InitState());
1163 m_errorMonitor->ClearState();
1164 VkCommandBufferObj cmdBuffer(m_device);
1165 const VkDescriptorTypeCount ds_type_count = {
1166 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1167 .count = 1,
1168 };
1169 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1170 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1171 .pNext = NULL,
1172 .count = 1,
1173 .pTypeCount = &ds_type_count,
1174 };
1175 VkDescriptorPool ds_pool;
1176 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1177 ASSERT_VK_SUCCESS(err);
1178
1179 const VkDescriptorSetLayoutBinding dsl_binding = {
1180 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1181 .arraySize = 1,
1182 .stageFlags = VK_SHADER_STAGE_ALL,
1183 .pImmutableSamplers = NULL,
1184 };
1185
1186 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1187 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1188 .pNext = NULL,
1189 .count = 1,
1190 .pBinding = &dsl_binding,
1191 };
1192 VkDescriptorSetLayout ds_layout;
1193 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1194 ASSERT_VK_SUCCESS(err);
1195
1196 VkDescriptorSet descriptorSet;
1197 uint32_t ds_count = 0;
1198 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1199 ASSERT_VK_SUCCESS(err);
1200
1201 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1202 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1203 .pNext = NULL,
1204 .descriptorSetCount = 1,
1205 .pSetLayouts = &ds_layout,
1206 };
1207
1208 VkPipelineLayout pipeline_layout;
1209 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1210 ASSERT_VK_SUCCESS(err);
1211
1212 const VkGraphicsPipelineCreateInfo gp_ci = {
1213 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1214 .pNext = NULL,
1215 .stageCount = 0,
1216 .pStages = NULL, // Creating Gfx Pipeline w/o VS is a violation
1217 .pVertexInputState = NULL,
1218 .pIaState = NULL,
1219 .pTessState = NULL,
1220 .pVpState = NULL,
1221 .pRsState = NULL,
1222 .pMsState = NULL,
1223 .pDsState = NULL,
1224 .pCbState = NULL,
1225 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1226 .layout = pipeline_layout,
1227 };
Jon Ashburn0d60d272015-07-09 15:02:25 -06001228 const VkPipelineCacheCreateInfo pc_ci = {
1229 .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
1230 .pNext = NULL,
1231 .initialSize = 0,
1232 .initialData = 0,
1233 .maxSize = 0,
1234 };
Tobin Ehlis254eca02015-06-25 15:46:59 -06001235
1236 VkPipeline pipeline;
Jon Ashburn0d60d272015-07-09 15:02:25 -06001237 VkPipelineCache pipelineCache;
1238
1239 err = vkCreatePipelineCache(m_device->device(), &pc_ci, &pipelineCache);
1240 ASSERT_VK_SUCCESS(err);
1241 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, &pipeline);
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001242
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001243 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001244 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after creating Gfx Pipeline w/o VS.";
1245 if (!strstr(msgString.c_str(),"Invalid Pipeline CreateInfo State: Vtx Shader required")) {
1246 FAIL() << "Error received was not 'Invalid Pipeline CreateInfo State: Vtx Shader required'";
1247 }
1248}
1249
Tobin Ehlisb8b06b52015-06-25 16:27:19 -06001250TEST_F(VkLayerTest, NullRenderPass)
1251{
1252 // Bind a NULL RenderPass
1253 VkFlags msgFlags;
1254 std::string msgString;
1255
1256 ASSERT_NO_FATAL_FAILURE(InitState());
1257 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1258 m_errorMonitor->ClearState();
1259 VkCommandBufferObj cmdBuffer(m_device);
1260
1261 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1262 BeginCommandBuffer(cmdBuffer);
1263 // Don't care about RenderPass handle b/c error should be flagged before that
1264 vkCmdBeginRenderPass(cmdBuffer.GetBufferHandle(), NULL);
1265
1266 msgFlags = m_errorMonitor->GetState(&msgString);
1267 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding NULL RenderPass.";
1268 if (!strstr(msgString.c_str(),"You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()")) {
1269 FAIL() << "Error received was not 'You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()'";
1270 }
1271}
1272
Tobin Ehlis254eca02015-06-25 15:46:59 -06001273TEST_F(VkLayerTest, RenderPassWithinRenderPass)
1274{
1275 // Bind a BeginRenderPass within an active RenderPass
1276 VkFlags msgFlags;
1277 std::string msgString;
1278
1279 ASSERT_NO_FATAL_FAILURE(InitState());
1280 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1281 m_errorMonitor->ClearState();
1282 VkCommandBufferObj cmdBuffer(m_device);
1283
1284 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1285 BeginCommandBuffer(cmdBuffer);
Tobin Ehlisb8b06b52015-06-25 16:27:19 -06001286 // Just create a dummy Renderpass that's non-NULL so we can get to the proper error
1287 const VkRenderPassBegin rp_begin = {
1288 .renderPass = (VkRenderPass) 0xc001d00d,
1289 .framebuffer = NULL
1290 };
1291 vkCmdBeginRenderPass(cmdBuffer.GetBufferHandle(), &rp_begin);
Tobin Ehlis254eca02015-06-25 15:46:59 -06001292
1293 msgFlags = m_errorMonitor->GetState(&msgString);
1294 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding RenderPass w/i an active RenderPass.";
1295 if (!strstr(msgString.c_str(),"Cannot call vkCmdBeginRenderPass() during an active RenderPass ")) {
1296 FAIL() << "Error received was not 'Cannot call vkCmdBeginRenderPass() during an active RenderPass...'";
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001297 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001298}
1299
1300TEST_F(VkLayerTest, InvalidDynamicStateObject)
1301{
1302 // Create a valid cmd buffer
1303 // call vkCmdBindDynamicStateObject w/ false DS Obj
Tobin Ehlis6bdfa372015-05-27 14:32:28 -06001304 // TODO : Simple check for bad object should be added to ObjectTracker to catch this case
1305 // The DS check for this is after driver has been called to validate DS internal data struct
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001306}
Tobin Ehlis201b1ba2015-05-27 14:55:35 -06001307
Tobin Ehlise4076782015-06-24 15:53:07 -06001308TEST_F(VkLayerTest, VtxBufferNoRenderPass)
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001309{
1310 // Bind VBO out-of-bounds for given PSO
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001311 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001312 std::string msgString;
1313 VkResult err;
1314
1315 ASSERT_NO_FATAL_FAILURE(InitState());
1316 m_errorMonitor->ClearState();
1317 VkCommandBufferObj cmdBuffer(m_device);
1318 const VkDescriptorTypeCount ds_type_count = {
1319 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1320 .count = 1,
1321 };
1322 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1323 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1324 .pNext = NULL,
1325 .count = 1,
1326 .pTypeCount = &ds_type_count,
1327 };
1328 VkDescriptorPool ds_pool;
1329 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1330 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001331
1332 const VkDescriptorSetLayoutBinding dsl_binding = {
1333 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001334 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001335 .stageFlags = VK_SHADER_STAGE_ALL,
1336 .pImmutableSamplers = NULL,
1337 };
1338
1339 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1340 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1341 .pNext = NULL,
1342 .count = 1,
1343 .pBinding = &dsl_binding,
1344 };
1345 VkDescriptorSetLayout ds_layout;
1346 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1347 ASSERT_VK_SUCCESS(err);
1348
1349 VkDescriptorSet descriptorSet;
1350 uint32_t ds_count = 0;
1351 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1352 ASSERT_VK_SUCCESS(err);
1353
1354 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1355 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1356 .pNext = NULL,
1357 .descriptorSetCount = 1,
1358 .pSetLayouts = &ds_layout,
1359 };
1360
1361 VkPipelineLayout pipeline_layout;
1362 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1363 ASSERT_VK_SUCCESS(err);
1364
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001365 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001366
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001367 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1368 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1369 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001370 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001371 .shader = vs.obj(),
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001372 .linkConstBufferCount = 0,
1373 .pLinkConstBufferInfo = NULL,
1374 .pSpecializationInfo = NULL,
1375 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001376 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001377 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1378 .pNext = NULL,
1379 .stageCount = 1,
1380 .pStages = &pipe_vs_ci,
1381 .pVertexInputState = NULL,
1382 .pIaState = NULL,
1383 .pTessState = NULL,
1384 .pVpState = NULL,
1385 .pRsState = NULL,
1386 .pMsState = NULL,
1387 .pDsState = NULL,
1388 .pCbState = NULL,
1389 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1390 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001391 };
Jon Ashburn0d60d272015-07-09 15:02:25 -06001392 const VkPipelineCacheCreateInfo pc_ci = {
1393 .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
1394 .pNext = NULL,
1395 .initialSize = 0,
1396 .initialData = 0,
1397 .maxSize = 0,
1398 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001399
1400 VkPipeline pipeline;
Jon Ashburn0d60d272015-07-09 15:02:25 -06001401 VkPipelineCache pipelineCache;
1402
1403 err = vkCreatePipelineCache(m_device->device(), &pc_ci, &pipelineCache);
1404 ASSERT_VK_SUCCESS(err);
1405 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, &pipeline);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001406 ASSERT_VK_SUCCESS(err);
1407
1408 err= cmdBuffer.BeginCommandBuffer();
1409 ASSERT_VK_SUCCESS(err);
1410 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1411 // Should error before calling to driver so don't care about actual data
1412 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
1413
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001414 msgFlags = m_errorMonitor->GetState(&msgString);
Tobin Ehlise4076782015-06-24 15:53:07 -06001415 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after vkCmdBindVertexBuffers() w/o active RenderPass.";
1416 if (!strstr(msgString.c_str(),"Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.")) {
1417 FAIL() << "Error received was not 'Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.'";
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001418 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001419}
1420
1421TEST_F(VkLayerTest, DSTypeMismatch)
1422{
1423 // Create DS w/ layout of one type and attempt Update w/ mis-matched type
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001424 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001425 std::string msgString;
1426 VkResult err;
1427
1428 ASSERT_NO_FATAL_FAILURE(InitState());
1429 m_errorMonitor->ClearState();
1430 //VkDescriptorSetObj descriptorSet(m_device);
1431 const VkDescriptorTypeCount ds_type_count = {
1432 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1433 .count = 1,
1434 };
1435 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1436 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1437 .pNext = NULL,
1438 .count = 1,
1439 .pTypeCount = &ds_type_count,
1440 };
1441 VkDescriptorPool ds_pool;
1442 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1443 ASSERT_VK_SUCCESS(err);
1444 const VkDescriptorSetLayoutBinding dsl_binding = {
1445 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001446 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001447 .stageFlags = VK_SHADER_STAGE_ALL,
1448 .pImmutableSamplers = NULL,
1449 };
1450
1451 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1452 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1453 .pNext = NULL,
1454 .count = 1,
1455 .pBinding = &dsl_binding,
1456 };
1457 VkDescriptorSetLayout ds_layout;
1458 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1459 ASSERT_VK_SUCCESS(err);
1460
1461 VkDescriptorSet descriptorSet;
1462 uint32_t ds_count = 0;
1463 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1464 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001465
1466 const VkSamplerCreateInfo sampler_ci = {
1467 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1468 .pNext = NULL,
1469 .magFilter = VK_TEX_FILTER_NEAREST,
1470 .minFilter = VK_TEX_FILTER_NEAREST,
1471 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1472 .addressU = VK_TEX_ADDRESS_CLAMP,
1473 .addressV = VK_TEX_ADDRESS_CLAMP,
1474 .addressW = VK_TEX_ADDRESS_CLAMP,
1475 .mipLodBias = 1.0,
1476 .maxAnisotropy = 1,
1477 .compareOp = VK_COMPARE_OP_NEVER,
1478 .minLod = 1.0,
1479 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001480 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001481 };
1482 VkSampler sampler;
1483 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1484 ASSERT_VK_SUCCESS(err);
1485
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001486 VkDescriptorInfo descriptor_info;
1487 memset(&descriptor_info, 0, sizeof(descriptor_info));
1488 descriptor_info.sampler = sampler;
1489
1490 VkWriteDescriptorSet descriptor_write;
1491 memset(&descriptor_write, 0, sizeof(descriptor_write));
1492 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1493 descriptor_write.destSet = descriptorSet;
1494 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001495 // This is a mismatched type for the layout which expects BUFFER
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001496 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1497 descriptor_write.pDescriptors = &descriptor_info;
1498
1499 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1500
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001501 msgFlags = m_errorMonitor->GetState(&msgString);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001502 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 +08001503 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET does not match ")) {
1504 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 -06001505 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001506}
1507
1508TEST_F(VkLayerTest, DSUpdateOutOfBounds)
1509{
1510 // For overlapping Update, have arrayIndex exceed that of layout
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001511 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001512 std::string msgString;
1513 VkResult err;
1514
1515 ASSERT_NO_FATAL_FAILURE(InitState());
1516 m_errorMonitor->ClearState();
1517 //VkDescriptorSetObj descriptorSet(m_device);
1518 const VkDescriptorTypeCount ds_type_count = {
1519 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1520 .count = 1,
1521 };
1522 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1523 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1524 .pNext = NULL,
1525 .count = 1,
1526 .pTypeCount = &ds_type_count,
1527 };
1528 VkDescriptorPool ds_pool;
1529 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1530 ASSERT_VK_SUCCESS(err);
1531 const VkDescriptorSetLayoutBinding dsl_binding = {
1532 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001533 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001534 .stageFlags = VK_SHADER_STAGE_ALL,
1535 .pImmutableSamplers = NULL,
1536 };
1537
1538 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1539 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1540 .pNext = NULL,
1541 .count = 1,
1542 .pBinding = &dsl_binding,
1543 };
1544 VkDescriptorSetLayout ds_layout;
1545 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1546 ASSERT_VK_SUCCESS(err);
1547
1548 VkDescriptorSet descriptorSet;
1549 uint32_t ds_count = 0;
1550 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1551 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001552
1553 const VkSamplerCreateInfo sampler_ci = {
1554 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1555 .pNext = NULL,
1556 .magFilter = VK_TEX_FILTER_NEAREST,
1557 .minFilter = VK_TEX_FILTER_NEAREST,
1558 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1559 .addressU = VK_TEX_ADDRESS_CLAMP,
1560 .addressV = VK_TEX_ADDRESS_CLAMP,
1561 .addressW = VK_TEX_ADDRESS_CLAMP,
1562 .mipLodBias = 1.0,
1563 .maxAnisotropy = 1,
1564 .compareOp = VK_COMPARE_OP_NEVER,
1565 .minLod = 1.0,
1566 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001567 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001568 };
1569 VkSampler sampler;
1570 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1571 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001572
1573 VkDescriptorInfo descriptor_info;
1574 memset(&descriptor_info, 0, sizeof(descriptor_info));
1575 descriptor_info.sampler = sampler;
1576
1577 VkWriteDescriptorSet descriptor_write;
1578 memset(&descriptor_write, 0, sizeof(descriptor_write));
1579 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1580 descriptor_write.destSet = descriptorSet;
1581 descriptor_write.destArrayElement = 1; /* This index out of bounds for the update */
1582 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001583 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001584 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1585 descriptor_write.pDescriptors = &descriptor_info;
1586
1587 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1588
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001589 msgFlags = m_errorMonitor->GetState(&msgString);
1590 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 +08001591 if (!strstr(msgString.c_str(),"Descriptor update type of VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET is out of bounds for matching binding")) {
1592 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 -06001593 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001594}
1595
1596TEST_F(VkLayerTest, InvalidDSUpdateIndex)
1597{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001598 // Create layout w/ count of 1 and attempt update to that layout w/ binding index 2
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001599 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001600 std::string msgString;
1601 VkResult err;
1602
1603 ASSERT_NO_FATAL_FAILURE(InitState());
1604 m_errorMonitor->ClearState();
1605 //VkDescriptorSetObj descriptorSet(m_device);
1606 const VkDescriptorTypeCount ds_type_count = {
1607 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1608 .count = 1,
1609 };
1610 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1611 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1612 .pNext = NULL,
1613 .count = 1,
1614 .pTypeCount = &ds_type_count,
1615 };
1616 VkDescriptorPool ds_pool;
1617 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1618 ASSERT_VK_SUCCESS(err);
1619 const VkDescriptorSetLayoutBinding dsl_binding = {
1620 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001621 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001622 .stageFlags = VK_SHADER_STAGE_ALL,
1623 .pImmutableSamplers = NULL,
1624 };
1625
1626 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1627 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1628 .pNext = NULL,
1629 .count = 1,
1630 .pBinding = &dsl_binding,
1631 };
1632 VkDescriptorSetLayout ds_layout;
1633 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1634 ASSERT_VK_SUCCESS(err);
1635
1636 VkDescriptorSet descriptorSet;
1637 uint32_t ds_count = 0;
1638 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1639 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001640
1641 const VkSamplerCreateInfo sampler_ci = {
1642 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1643 .pNext = NULL,
1644 .magFilter = VK_TEX_FILTER_NEAREST,
1645 .minFilter = VK_TEX_FILTER_NEAREST,
1646 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1647 .addressU = VK_TEX_ADDRESS_CLAMP,
1648 .addressV = VK_TEX_ADDRESS_CLAMP,
1649 .addressW = VK_TEX_ADDRESS_CLAMP,
1650 .mipLodBias = 1.0,
1651 .maxAnisotropy = 1,
1652 .compareOp = VK_COMPARE_OP_NEVER,
1653 .minLod = 1.0,
1654 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001655 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001656 };
1657 VkSampler sampler;
1658 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1659 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001660
1661 VkDescriptorInfo descriptor_info;
1662 memset(&descriptor_info, 0, sizeof(descriptor_info));
1663 descriptor_info.sampler = sampler;
1664
1665 VkWriteDescriptorSet descriptor_write;
1666 memset(&descriptor_write, 0, sizeof(descriptor_write));
1667 descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1668 descriptor_write.destSet = descriptorSet;
1669 descriptor_write.destBinding = 2;
1670 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001671 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001672 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1673 descriptor_write.pDescriptors = &descriptor_info;
1674
1675 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1676
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001677 msgFlags = m_errorMonitor->GetState(&msgString);
1678 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 -06001679 if (!strstr(msgString.c_str()," does not have binding to match update binding ")) {
1680 FAIL() << "Error received was not 'Descriptor Set <blah> does not have binding to match update binding '";
1681 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001682}
1683
1684TEST_F(VkLayerTest, InvalidDSUpdateStruct)
1685{
1686 // Call UpdateDS w/ struct type other than valid VK_STRUCTUR_TYPE_UPDATE_* types
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001687 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001688 std::string msgString;
1689 VkResult err;
1690
1691 ASSERT_NO_FATAL_FAILURE(InitState());
1692 m_errorMonitor->ClearState();
1693 //VkDescriptorSetObj descriptorSet(m_device);
1694 const VkDescriptorTypeCount ds_type_count = {
1695 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1696 .count = 1,
1697 };
1698 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1699 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1700 .pNext = NULL,
1701 .count = 1,
1702 .pTypeCount = &ds_type_count,
1703 };
1704 VkDescriptorPool ds_pool;
1705 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1706 ASSERT_VK_SUCCESS(err);
1707 const VkDescriptorSetLayoutBinding dsl_binding = {
1708 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001709 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001710 .stageFlags = VK_SHADER_STAGE_ALL,
1711 .pImmutableSamplers = NULL,
1712 };
1713
1714 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1715 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1716 .pNext = NULL,
1717 .count = 1,
1718 .pBinding = &dsl_binding,
1719 };
1720 VkDescriptorSetLayout ds_layout;
1721 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1722 ASSERT_VK_SUCCESS(err);
1723
1724 VkDescriptorSet descriptorSet;
1725 uint32_t ds_count = 0;
1726 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1727 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001728
1729 const VkSamplerCreateInfo sampler_ci = {
1730 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1731 .pNext = NULL,
1732 .magFilter = VK_TEX_FILTER_NEAREST,
1733 .minFilter = VK_TEX_FILTER_NEAREST,
1734 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
1735 .addressU = VK_TEX_ADDRESS_CLAMP,
1736 .addressV = VK_TEX_ADDRESS_CLAMP,
1737 .addressW = VK_TEX_ADDRESS_CLAMP,
1738 .mipLodBias = 1.0,
1739 .maxAnisotropy = 1,
1740 .compareOp = VK_COMPARE_OP_NEVER,
1741 .minLod = 1.0,
1742 .maxLod = 1.0,
Tony Barbour2c4e7c72015-06-25 16:56:44 -06001743 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001744 };
1745 VkSampler sampler;
1746 err = vkCreateSampler(m_device->device(), &sampler_ci, &sampler);
1747 ASSERT_VK_SUCCESS(err);
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001748
1749
1750 VkDescriptorInfo descriptor_info;
1751 memset(&descriptor_info, 0, sizeof(descriptor_info));
1752 descriptor_info.sampler = sampler;
1753
1754 VkWriteDescriptorSet descriptor_write;
1755 memset(&descriptor_write, 0, sizeof(descriptor_write));
1756 descriptor_write.sType = (VkStructureType)0x99999999; /* Intentionally broken struct type */
1757 descriptor_write.destSet = descriptorSet;
1758 descriptor_write.count = 1;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001759 // This is the wrong type, but out of bounds will be flagged first
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001760 descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1761 descriptor_write.pDescriptors = &descriptor_info;
1762
1763 vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
1764
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001765 msgFlags = m_errorMonitor->GetState(&msgString);
1766 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 -06001767 if (!strstr(msgString.c_str(),"Unexpected UPDATE struct of type ")) {
1768 FAIL() << "Error received was not 'Unexpected UPDATE struct of type '";
1769 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001770}
1771
1772TEST_F(VkLayerTest, NumSamplesMismatch)
1773{
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001774 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001775 VkFlags msgFlags;
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001776 std::string msgString;
1777 VkResult err;
1778
1779 ASSERT_NO_FATAL_FAILURE(InitState());
1780 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1781 m_errorMonitor->ClearState();
1782 VkCommandBufferObj cmdBuffer(m_device);
1783 const VkDescriptorTypeCount ds_type_count = {
1784 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1785 .count = 1,
1786 };
1787 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1788 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1789 .pNext = NULL,
1790 .count = 1,
1791 .pTypeCount = &ds_type_count,
1792 };
1793 VkDescriptorPool ds_pool;
1794 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1795 ASSERT_VK_SUCCESS(err);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001796
1797 const VkDescriptorSetLayoutBinding dsl_binding = {
1798 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
Chia-I Wud3114a22015-05-25 16:22:52 +08001799 .arraySize = 1,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001800 .stageFlags = VK_SHADER_STAGE_ALL,
1801 .pImmutableSamplers = NULL,
1802 };
1803
1804 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1805 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1806 .pNext = NULL,
1807 .count = 1,
1808 .pBinding = &dsl_binding,
1809 };
1810 VkDescriptorSetLayout ds_layout;
1811 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1812 ASSERT_VK_SUCCESS(err);
1813
1814 VkDescriptorSet descriptorSet;
1815 uint32_t ds_count = 0;
1816 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1817 ASSERT_VK_SUCCESS(err);
1818
1819 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
1820 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
1821 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06001822 .rasterSamples = 4,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001823 .multisampleEnable = 1,
1824 .sampleShadingEnable = 0,
1825 .minSampleShading = 1.0,
1826 .sampleMask = 15,
1827 };
1828
1829 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1830 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1831 .pNext = NULL,
1832 .descriptorSetCount = 1,
1833 .pSetLayouts = &ds_layout,
1834 };
1835
1836 VkPipelineLayout pipeline_layout;
1837 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1838 ASSERT_VK_SUCCESS(err);
1839
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001840 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001841
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001842 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
1843 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1844 .pNext = NULL,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001845 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001846 .shader = vs.obj(),
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001847 .linkConstBufferCount = 0,
1848 .pLinkConstBufferInfo = NULL,
1849 .pSpecializationInfo = NULL,
1850 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001851 const VkGraphicsPipelineCreateInfo gp_ci = {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001852 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1853 .pNext = NULL,
1854 .stageCount = 1,
1855 .pStages = &pipe_vs_ci,
1856 .pVertexInputState = NULL,
1857 .pIaState = NULL,
1858 .pTessState = NULL,
1859 .pVpState = NULL,
1860 .pRsState = NULL,
1861 .pMsState = &pipe_ms_state_ci,
1862 .pDsState = NULL,
1863 .pCbState = NULL,
1864 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
1865 .layout = pipeline_layout,
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001866 };
Jon Ashburn0d60d272015-07-09 15:02:25 -06001867 const VkPipelineCacheCreateInfo pc_ci = {
1868 .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
1869 .pNext = NULL,
1870 .initialSize = 0,
1871 .initialData = 0,
1872 .maxSize = 0,
1873 };
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001874
1875 VkPipeline pipeline;
Jon Ashburn0d60d272015-07-09 15:02:25 -06001876 VkPipelineCache pipelineCache;
1877
1878 err = vkCreatePipelineCache(m_device->device(), &pc_ci, &pipelineCache);
1879 ASSERT_VK_SUCCESS(err);
1880 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, &pipeline);
Tobin Ehlis2f87d2d2015-05-28 12:11:26 -06001881 ASSERT_VK_SUCCESS(err);
1882
1883 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1884 BeginCommandBuffer(cmdBuffer);
1885 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1886
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001887 msgFlags = m_errorMonitor->GetState(&msgString);
1888 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 -06001889 if (!strstr(msgString.c_str(),"Num samples mismatch! ")) {
1890 FAIL() << "Error received was not 'Num samples mismatch!...'";
1891 }
Tobin Ehlis138b7f12015-05-22 12:38:55 -06001892}
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06001893
Tobin Ehlise4076782015-06-24 15:53:07 -06001894TEST_F(VkLayerTest, PipelineNotBound)
1895{
1896 VkFlags msgFlags;
1897 std::string msgString;
1898 VkResult err;
1899
1900 ASSERT_NO_FATAL_FAILURE(InitState());
1901 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1902 m_errorMonitor->ClearState();
1903 VkCommandBufferObj cmdBuffer(m_device);
1904 const VkDescriptorTypeCount ds_type_count = {
1905 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1906 .count = 1,
1907 };
1908 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1909 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1910 .pNext = NULL,
1911 .count = 1,
1912 .pTypeCount = &ds_type_count,
1913 };
1914 VkDescriptorPool ds_pool;
1915 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1916 ASSERT_VK_SUCCESS(err);
1917
1918 const VkDescriptorSetLayoutBinding dsl_binding = {
1919 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1920 .arraySize = 1,
1921 .stageFlags = VK_SHADER_STAGE_ALL,
1922 .pImmutableSamplers = NULL,
1923 };
1924
1925 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1926 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1927 .pNext = NULL,
1928 .count = 1,
1929 .pBinding = &dsl_binding,
1930 };
1931 VkDescriptorSetLayout ds_layout;
1932 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
1933 ASSERT_VK_SUCCESS(err);
1934
1935 VkDescriptorSet descriptorSet;
1936 uint32_t ds_count = 0;
1937 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
1938 ASSERT_VK_SUCCESS(err);
1939
1940 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
1941 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1942 .pNext = NULL,
1943 .descriptorSetCount = 1,
1944 .pSetLayouts = &ds_layout,
1945 };
1946
1947 VkPipelineLayout pipeline_layout;
1948 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
1949 ASSERT_VK_SUCCESS(err);
1950
Tobin Ehlise4076782015-06-24 15:53:07 -06001951 VkPipeline badPipeline = (VkPipeline)0xbaadb1be;
1952 //err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
1953 ASSERT_VK_SUCCESS(err);
1954
1955 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
1956 BeginCommandBuffer(cmdBuffer);
1957 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, badPipeline);
1958
1959 msgFlags = m_errorMonitor->GetState(&msgString);
1960 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding invalid pipeline to CmdBuffer";
1961 if (!strstr(msgString.c_str(),"Attempt to bind Pipeline ")) {
1962 FAIL() << "Error received was not 'Attempt to bind Pipeline 0xbaadb1be that doesn't exist!'";
1963 }
1964}
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06001965
1966TEST_F(VkLayerTest, ClearCmdNoDraw)
1967{
1968 // Create CmdBuffer where we add ClearCmd for FB Color attachment prior to issuing a Draw
1969 VkFlags msgFlags;
1970 std::string msgString;
1971 VkResult err;
1972
1973 ASSERT_NO_FATAL_FAILURE(InitState());
1974 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1975 m_errorMonitor->ClearState();
1976 VkCommandBufferObj cmdBuffer(m_device);
1977 const VkDescriptorTypeCount ds_type_count = {
1978 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1979 .count = 1,
1980 };
1981 const VkDescriptorPoolCreateInfo ds_pool_ci = {
1982 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1983 .pNext = NULL,
1984 .count = 1,
1985 .pTypeCount = &ds_type_count,
1986 };
1987 VkDescriptorPool ds_pool;
1988 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
1989 ASSERT_VK_SUCCESS(err);
1990
1991 const VkDescriptorSetLayoutBinding dsl_binding = {
1992 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1993 .arraySize = 1,
1994 .stageFlags = VK_SHADER_STAGE_ALL,
1995 .pImmutableSamplers = NULL,
1996 };
1997
1998 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
1999 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
2000 .pNext = NULL,
2001 .count = 1,
2002 .pBinding = &dsl_binding,
2003 };
2004 VkDescriptorSetLayout ds_layout;
2005 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
2006 ASSERT_VK_SUCCESS(err);
2007
2008 VkDescriptorSet descriptorSet;
2009 uint32_t ds_count = 0;
2010 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
2011 ASSERT_VK_SUCCESS(err);
2012
2013 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
2014 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
2015 .pNext = NULL,
2016 .rasterSamples = 4,
2017 .multisampleEnable = 1,
2018 .sampleShadingEnable = 0,
2019 .minSampleShading = 1.0,
2020 .sampleMask = 15,
2021 };
2022
2023 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
2024 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2025 .pNext = NULL,
2026 .descriptorSetCount = 1,
2027 .pSetLayouts = &ds_layout,
2028 };
2029
2030 VkPipelineLayout pipeline_layout;
2031 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
2032 ASSERT_VK_SUCCESS(err);
2033
2034 size_t shader_len = strlen(bindStateVertShaderText);
2035 size_t codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
2036 void* pCode = malloc(codeSize);
2037
2038 /* try version 0 first: VkShaderStage followed by GLSL */
2039 ((uint32_t *) pCode)[0] = ICD_SPV_MAGIC;
2040 ((uint32_t *) pCode)[1] = 0;
2041 ((uint32_t *) pCode)[2] = VK_SHADER_STAGE_VERTEX;
2042 memcpy(((uint32_t *) pCode + 3), bindStateVertShaderText, shader_len + 1);
2043
2044 const VkShaderModuleCreateInfo smci = {
2045 .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
2046 .pNext = NULL,
2047 .codeSize = codeSize,
2048 .pCode = pCode,
2049 .flags = 0,
2050 };
2051 VkShaderModule vksm;
2052 err = vkCreateShaderModule(m_device->device(), &smci, &vksm);
2053 ASSERT_VK_SUCCESS(err);
2054 const VkShaderCreateInfo vs_ci = {
2055 .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
2056 .pNext = NULL,
2057 .module = vksm,
2058 .pName = "main",
2059 .flags = 0,
2060 };
2061 VkShader vs;
2062 err = vkCreateShader(m_device->device(), &vs_ci, &vs);
2063 ASSERT_VK_SUCCESS(err);
2064
2065 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
2066 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2067 .pNext = NULL,
2068 .stage = VK_SHADER_STAGE_VERTEX,
2069 .shader = vs,
2070 .linkConstBufferCount = 0,
2071 .pLinkConstBufferInfo = NULL,
2072 .pSpecializationInfo = NULL,
2073 };
2074 const VkGraphicsPipelineCreateInfo gp_ci = {
2075 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
2076 .pNext = NULL,
2077 .stageCount = 1,
2078 .pStages = &pipe_vs_ci,
2079 .pVertexInputState = NULL,
2080 .pIaState = NULL,
2081 .pTessState = NULL,
2082 .pVpState = NULL,
2083 .pRsState = NULL,
2084 .pMsState = &pipe_ms_state_ci,
2085 .pDsState = NULL,
2086 .pCbState = NULL,
2087 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
2088 .layout = pipeline_layout,
2089 };
Jon Ashburn0d60d272015-07-09 15:02:25 -06002090 const VkPipelineCacheCreateInfo pc_ci = {
2091 .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
2092 .pNext = NULL,
2093 .initialSize = 0,
2094 .initialData = 0,
2095 .maxSize = 0,
2096 };
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002097
2098 VkPipeline pipeline;
Jon Ashburn0d60d272015-07-09 15:02:25 -06002099 VkPipelineCache pipelineCache;
2100
2101 err = vkCreatePipelineCache(m_device->device(), &pc_ci, &pipelineCache);
2102 ASSERT_VK_SUCCESS(err);
2103 err = vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &gp_ci, &pipeline);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002104 ASSERT_VK_SUCCESS(err);
2105
2106 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
2107 BeginCommandBuffer(cmdBuffer);
2108
2109 m_errorMonitor->ClearState();
2110 // Main thing we care about for this test is that the VkImage obj we're clearing matches Color Attachment of FB
2111 // Also pass down other dummy params to keep driver and paramchecker happy
2112 VkClearColorValue cCV;
2113 cCV.f32[0] = 1.0;
2114 cCV.f32[1] = 1.0;
2115 cCV.f32[2] = 1.0;
2116 cCV.f32[3] = 1.0;
2117
2118 vkCmdClearColorAttachment(cmdBuffer.GetBufferHandle(), 0, (VkImageLayout)NULL, &cCV, 0, NULL);
2119 msgFlags = m_errorMonitor->GetState(&msgString);
2120 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT) << "Did not receive error after issuing Clear Cmd on FB color attachment prior to Draw Cmd.";
2121 if (!strstr(msgString.c_str(),"vkCmdClearColorAttachment() issued on CB object ")) {
2122 FAIL() << "Error received was not 'vkCmdClearColorAttachment() issued on CB object...'";
2123 }
2124}
2125
Tobin Ehlise4076782015-06-24 15:53:07 -06002126TEST_F(VkLayerTest, VtxBufferBadIndex)
2127{
2128 // Create CmdBuffer where MSAA samples doesn't match RenderPass sampleCount
2129 VkFlags msgFlags;
2130 std::string msgString;
2131 VkResult err;
2132
2133 ASSERT_NO_FATAL_FAILURE(InitState());
2134 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2135 m_errorMonitor->ClearState();
2136 VkCommandBufferObj cmdBuffer(m_device);
2137 const VkDescriptorTypeCount ds_type_count = {
2138 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
2139 .count = 1,
2140 };
2141 const VkDescriptorPoolCreateInfo ds_pool_ci = {
2142 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
2143 .pNext = NULL,
2144 .count = 1,
2145 .pTypeCount = &ds_type_count,
2146 };
2147 VkDescriptorPool ds_pool;
2148 err = vkCreateDescriptorPool(m_device->device(), VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, &ds_pool_ci, &ds_pool);
2149 ASSERT_VK_SUCCESS(err);
2150
2151 const VkDescriptorSetLayoutBinding dsl_binding = {
2152 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
2153 .arraySize = 1,
2154 .stageFlags = VK_SHADER_STAGE_ALL,
2155 .pImmutableSamplers = NULL,
2156 };
2157
2158 const VkDescriptorSetLayoutCreateInfo ds_layout_ci = {
2159 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
2160 .pNext = NULL,
2161 .count = 1,
2162 .pBinding = &dsl_binding,
2163 };
2164 VkDescriptorSetLayout ds_layout;
2165 err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, &ds_layout);
2166 ASSERT_VK_SUCCESS(err);
2167
2168 VkDescriptorSet descriptorSet;
2169 uint32_t ds_count = 0;
2170 err = vkAllocDescriptorSets(m_device->device(), ds_pool, VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, 1, &ds_layout, &descriptorSet, &ds_count);
2171 ASSERT_VK_SUCCESS(err);
2172
2173 const VkPipelineMsStateCreateInfo pipe_ms_state_ci = {
2174 .sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO,
2175 .pNext = NULL,
Tony Barboure094edf2015-06-26 10:18:34 -06002176 .rasterSamples = 1,
Tobin Ehlise4076782015-06-24 15:53:07 -06002177 .multisampleEnable = 1,
2178 .sampleShadingEnable = 0,
2179 .minSampleShading = 1.0,
2180 .sampleMask = 15,
2181 };
2182
2183 const VkPipelineLayoutCreateInfo pipeline_layout_ci = {
2184 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2185 .pNext = NULL,
2186 .descriptorSetCount = 1,
2187 .pSetLayouts = &ds_layout,
2188 };
2189
2190 VkPipelineLayout pipeline_layout;
2191 err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, &pipeline_layout);
2192 ASSERT_VK_SUCCESS(err);
2193
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06002194 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX, this);
Tobin Ehlise4076782015-06-24 15:53:07 -06002195
2196 const VkPipelineShaderStageCreateInfo pipe_vs_ci = {
2197 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2198 .pNext = NULL,
2199 .stage = VK_SHADER_STAGE_VERTEX,
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06002200 .shader = vs.obj(),
Tobin Ehlise4076782015-06-24 15:53:07 -06002201 .linkConstBufferCount = 0,
2202 .pLinkConstBufferInfo = NULL,
2203 .pSpecializationInfo = NULL,
2204 };
2205 const VkGraphicsPipelineCreateInfo gp_ci = {
2206 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
2207 .pNext = NULL,
2208 .stageCount = 1,
2209 .pStages = &pipe_vs_ci,
2210 .pVertexInputState = NULL,
2211 .pIaState = NULL,
2212 .pTessState = NULL,
2213 .pVpState = NULL,
2214 .pRsState = NULL,
2215 .pMsState = &pipe_ms_state_ci,
2216 .pDsState = NULL,
2217 .pCbState = NULL,
2218 .flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
2219 .layout = pipeline_layout,
2220 };
2221
2222 VkPipeline pipeline;
2223 err = vkCreateGraphicsPipeline(m_device->device(), &gp_ci, &pipeline);
2224 ASSERT_VK_SUCCESS(err);
2225
2226 cmdBuffer.AddRenderTarget(m_renderTargets[0]);
2227 BeginCommandBuffer(cmdBuffer);
2228 vkCmdBindPipeline(cmdBuffer.GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
2229 // Should error before calling to driver so don't care about actual data
2230 vkCmdBindVertexBuffers(cmdBuffer.GetBufferHandle(), 0, 1, NULL, NULL);
2231
2232 msgFlags = m_errorMonitor->GetState(&msgString);
2233 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT) << "Did not receive error after binding Vtx Buffer w/o VBO attached to PSO.";
2234 if (!strstr(msgString.c_str(),"Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.")) {
2235 FAIL() << "Error received was not 'Vtx Buffer Index 0 was bound, but no vtx buffers are attached to PSO.'";
2236 }
2237}
Tobin Ehlis57e6a612015-05-26 16:11:58 -06002238#endif
2239#if THREADING_TESTS
Mike Stroyan09aae812015-05-12 16:00:45 -06002240#if GTEST_IS_THREADSAFE
2241struct thread_data_struct {
2242 VkCmdBuffer cmdBuffer;
2243 VkEvent event;
2244 bool bailout;
2245};
2246
2247extern "C" void *AddToCommandBuffer(void *arg)
2248{
2249 struct thread_data_struct *data = (struct thread_data_struct *) arg;
2250 std::string msgString;
2251
2252 for (int i = 0; i<10000; i++) {
Tony Barbourc2e987e2015-06-29 16:20:35 -06002253 vkCmdSetEvent(data->cmdBuffer, data->event, VK_PIPELINE_STAGE_ALL_GPU_COMMANDS);
Mike Stroyan09aae812015-05-12 16:00:45 -06002254 if (data->bailout) {
2255 break;
2256 }
2257 }
2258 return NULL;
2259}
2260
2261TEST_F(VkLayerTest, ThreadCmdBufferCollision)
2262{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002263 VkFlags msgFlags;
Mike Stroyan09aae812015-05-12 16:00:45 -06002264 std::string msgString;
2265 pthread_t thread;
2266 pthread_attr_t thread_attr;
2267
2268 ASSERT_NO_FATAL_FAILURE(InitState());
2269 ASSERT_NO_FATAL_FAILURE(InitViewport());
2270 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2271
2272 VkCommandBufferObj cmdBuffer(m_device);
2273
2274 m_errorMonitor->ClearState();
2275 pthread_attr_init(&thread_attr);
2276 BeginCommandBuffer(cmdBuffer);
2277
2278 VkEventCreateInfo event_info;
2279 VkEvent event;
2280 VkMemoryRequirements mem_req;
Mike Stroyan09aae812015-05-12 16:00:45 -06002281 VkResult err;
2282
2283 memset(&event_info, 0, sizeof(event_info));
2284 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2285
2286 err = vkCreateEvent(device(), &event_info, &event);
2287 ASSERT_VK_SUCCESS(err);
2288
Tony Barbour426b9052015-06-24 16:06:58 -06002289 err = vkGetObjectMemoryRequirements(device(), VK_OBJECT_TYPE_EVENT, event, &mem_req);
Mike Stroyan09aae812015-05-12 16:00:45 -06002290 ASSERT_VK_SUCCESS(err);
2291
2292 VkMemoryAllocInfo mem_info;
2293 VkDeviceMemory event_mem;
2294
Mike Stroyan09aae812015-05-12 16:00:45 -06002295 memset(&mem_info, 0, sizeof(mem_info));
2296 mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
2297 mem_info.allocationSize = mem_req.size;
Mark Lobodzinski72346292015-07-02 16:49:40 -06002298 mem_info.memoryTypeIndex = 0;
2299
2300 err = m_device->gpu().set_memory_type(mem_req.memoryTypeBits, &mem_info, 0);
2301 ASSERT_VK_SUCCESS(err);
2302
Mike Stroyan09aae812015-05-12 16:00:45 -06002303 err = vkAllocMemory(device(), &mem_info, &event_mem);
2304 ASSERT_VK_SUCCESS(err);
2305
Mark Lobodzinski23182612015-05-29 09:32:35 -05002306 err = vkBindObjectMemory(device(), VK_OBJECT_TYPE_EVENT, event, event_mem, 0);
Mike Stroyan09aae812015-05-12 16:00:45 -06002307 ASSERT_VK_SUCCESS(err);
2308
2309 err = vkResetEvent(device(), event);
2310 ASSERT_VK_SUCCESS(err);
2311
2312 struct thread_data_struct data;
2313 data.cmdBuffer = cmdBuffer.obj();
2314 data.event = event;
2315 data.bailout = false;
2316 m_errorMonitor->SetBailout(&data.bailout);
2317 // Add many entries to command buffer from another thread.
2318 pthread_create(&thread, &thread_attr, AddToCommandBuffer, (void *)&data);
2319 // Add many entries to command buffer from this thread at the same time.
2320 AddToCommandBuffer(&data);
2321 pthread_join(thread, NULL);
2322 EndCommandBuffer(cmdBuffer);
2323
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002324 msgFlags = m_errorMonitor->GetState(&msgString);
Mike Stroyaned254572015-06-17 16:32:06 -06002325 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 -06002326 if (!strstr(msgString.c_str(),"THREADING ERROR")) {
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05002327 FAIL() << "Error received was not 'THREADING ERROR'";
Mike Stroyan09aae812015-05-12 16:00:45 -06002328 }
2329
2330}
2331#endif
Tobin Ehlis57e6a612015-05-26 16:11:58 -06002332#endif
Chris Forbes5af3bf22015-05-25 11:13:08 +12002333#if SHADER_CHECKER_TESTS
2334TEST_F(VkLayerTest, CreatePipelineVertexOutputNotConsumed)
2335{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002336 VkFlags msgFlags;
Chris Forbes5af3bf22015-05-25 11:13:08 +12002337 std::string msgString;
2338 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002339 ScopedUseGlsl useGlsl(false);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002340
2341 char const *vsSource =
2342 "#version 140\n"
2343 "#extension GL_ARB_separate_shader_objects: require\n"
2344 "#extension GL_ARB_shading_language_420pack: require\n"
2345 "\n"
2346 "layout(location=0) out float x;\n"
2347 "void main(){\n"
2348 " gl_Position = vec4(1);\n"
2349 " x = 0;\n"
2350 "}\n";
2351 char const *fsSource =
2352 "#version 140\n"
2353 "#extension GL_ARB_separate_shader_objects: require\n"
2354 "#extension GL_ARB_shading_language_420pack: require\n"
2355 "\n"
2356 "layout(location=0) out vec4 color;\n"
2357 "void main(){\n"
2358 " color = vec4(1);\n"
2359 "}\n";
2360
2361 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2362 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2363
2364 VkPipelineObj pipe(m_device);
2365 pipe.AddShader(&vs);
2366 pipe.AddShader(&fs);
2367
2368 VkCommandBufferObj dummyCmd(m_device);
2369 VkDescriptorSetObj descriptorSet(m_device);
2370 descriptorSet.AppendDummy();
2371 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2372
2373 m_errorMonitor->ClearState();
2374 pipe.CreateVKPipeline(descriptorSet);
2375
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002376 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002377
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002378 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5af3bf22015-05-25 11:13:08 +12002379 if (!strstr(msgString.c_str(),"not consumed by fragment shader")) {
2380 FAIL() << "Incorrect warning: " << msgString;
2381 }
2382}
Chris Forbes5af3bf22015-05-25 11:13:08 +12002383
Chris Forbes3c10b852015-05-25 11:13:13 +12002384TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided)
2385{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002386 VkFlags msgFlags;
Chris Forbes3c10b852015-05-25 11:13:13 +12002387 std::string msgString;
2388 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002389 ScopedUseGlsl useGlsl(false);
Chris Forbes3c10b852015-05-25 11:13:13 +12002390
2391 char const *vsSource =
2392 "#version 140\n"
2393 "#extension GL_ARB_separate_shader_objects: require\n"
2394 "#extension GL_ARB_shading_language_420pack: require\n"
2395 "\n"
2396 "void main(){\n"
2397 " gl_Position = vec4(1);\n"
2398 "}\n";
2399 char const *fsSource =
2400 "#version 140\n"
2401 "#extension GL_ARB_separate_shader_objects: require\n"
2402 "#extension GL_ARB_shading_language_420pack: require\n"
2403 "\n"
2404 "layout(location=0) in float x;\n"
2405 "layout(location=0) out vec4 color;\n"
2406 "void main(){\n"
2407 " color = vec4(x);\n"
2408 "}\n";
2409
2410 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2411 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2412
2413 VkPipelineObj pipe(m_device);
2414 pipe.AddShader(&vs);
2415 pipe.AddShader(&fs);
2416
2417 VkCommandBufferObj dummyCmd(m_device);
2418 VkDescriptorSetObj descriptorSet(m_device);
2419 descriptorSet.AppendDummy();
2420 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2421
2422 m_errorMonitor->ClearState();
2423 pipe.CreateVKPipeline(descriptorSet);
2424
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002425 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes3c10b852015-05-25 11:13:13 +12002426
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002427 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes3c10b852015-05-25 11:13:13 +12002428 if (!strstr(msgString.c_str(),"not written by vertex shader")) {
2429 FAIL() << "Incorrect error: " << msgString;
2430 }
2431}
2432
Chris Forbescc281692015-05-25 11:13:17 +12002433TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch)
2434{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002435 VkFlags msgFlags;
Chris Forbescc281692015-05-25 11:13:17 +12002436 std::string msgString;
2437 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002438 ScopedUseGlsl useGlsl(false);
Chris Forbescc281692015-05-25 11:13:17 +12002439
2440 char const *vsSource =
2441 "#version 140\n"
2442 "#extension GL_ARB_separate_shader_objects: require\n"
2443 "#extension GL_ARB_shading_language_420pack: require\n"
2444 "\n"
2445 "layout(location=0) out int x;\n"
2446 "void main(){\n"
2447 " x = 0;\n"
2448 " gl_Position = vec4(1);\n"
2449 "}\n";
2450 char const *fsSource =
2451 "#version 140\n"
2452 "#extension GL_ARB_separate_shader_objects: require\n"
2453 "#extension GL_ARB_shading_language_420pack: require\n"
2454 "\n"
2455 "layout(location=0) in float x;\n" /* VS writes int */
2456 "layout(location=0) out vec4 color;\n"
2457 "void main(){\n"
2458 " color = vec4(x);\n"
2459 "}\n";
2460
2461 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2462 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2463
2464 VkPipelineObj pipe(m_device);
2465 pipe.AddShader(&vs);
2466 pipe.AddShader(&fs);
2467
2468 VkCommandBufferObj dummyCmd(m_device);
2469 VkDescriptorSetObj descriptorSet(m_device);
2470 descriptorSet.AppendDummy();
2471 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2472
2473 m_errorMonitor->ClearState();
2474 pipe.CreateVKPipeline(descriptorSet);
2475
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002476 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbescc281692015-05-25 11:13:17 +12002477
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002478 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbescc281692015-05-25 11:13:17 +12002479 if (!strstr(msgString.c_str(),"Type mismatch on location 0")) {
2480 FAIL() << "Incorrect error: " << msgString;
2481 }
2482}
2483
Chris Forbes8291c052015-05-25 11:13:28 +12002484TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed)
2485{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002486 VkFlags msgFlags;
Chris Forbes8291c052015-05-25 11:13:28 +12002487 std::string msgString;
2488 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002489 ScopedUseGlsl useGlsl(false);
Chris Forbes8291c052015-05-25 11:13:28 +12002490
2491 VkVertexInputBindingDescription input_binding;
2492 memset(&input_binding, 0, sizeof(input_binding));
2493
2494 VkVertexInputAttributeDescription input_attrib;
2495 memset(&input_attrib, 0, sizeof(input_attrib));
2496 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2497
2498 char const *vsSource =
2499 "#version 140\n"
2500 "#extension GL_ARB_separate_shader_objects: require\n"
2501 "#extension GL_ARB_shading_language_420pack: require\n"
2502 "\n"
2503 "void main(){\n"
2504 " gl_Position = vec4(1);\n"
2505 "}\n";
2506 char const *fsSource =
2507 "#version 140\n"
2508 "#extension GL_ARB_separate_shader_objects: require\n"
2509 "#extension GL_ARB_shading_language_420pack: require\n"
2510 "\n"
2511 "layout(location=0) out vec4 color;\n"
2512 "void main(){\n"
2513 " color = vec4(1);\n"
2514 "}\n";
2515
2516 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2517 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2518
2519 VkPipelineObj pipe(m_device);
2520 pipe.AddShader(&vs);
2521 pipe.AddShader(&fs);
2522
2523 pipe.AddVertexInputBindings(&input_binding, 1);
2524 pipe.AddVertexInputAttribs(&input_attrib, 1);
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 Forbes8291c052015-05-25 11:13:28 +12002535
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002536 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes8291c052015-05-25 11:13:28 +12002537 if (!strstr(msgString.c_str(),"location 0 not consumed by VS")) {
2538 FAIL() << "Incorrect warning: " << msgString;
2539 }
2540}
2541
Chris Forbes37367e62015-05-25 11:13:29 +12002542TEST_F(VkLayerTest, CreatePipelineAttribNotProvided)
2543{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002544 VkFlags msgFlags;
Chris Forbes37367e62015-05-25 11:13:29 +12002545 std::string msgString;
2546 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002547 ScopedUseGlsl useGlsl(false);
Chris Forbes37367e62015-05-25 11:13:29 +12002548
2549 char const *vsSource =
2550 "#version 140\n"
2551 "#extension GL_ARB_separate_shader_objects: require\n"
2552 "#extension GL_ARB_shading_language_420pack: require\n"
2553 "\n"
2554 "layout(location=0) in vec4 x;\n" /* not provided */
2555 "void main(){\n"
2556 " gl_Position = x;\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 color;\n"
2564 "void main(){\n"
2565 " color = vec4(1);\n"
2566 "}\n";
2567
2568 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2569 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2570
2571 VkPipelineObj pipe(m_device);
2572 pipe.AddShader(&vs);
2573 pipe.AddShader(&fs);
2574
2575 VkCommandBufferObj dummyCmd(m_device);
2576 VkDescriptorSetObj descriptorSet(m_device);
2577 descriptorSet.AppendDummy();
2578 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2579
2580 m_errorMonitor->ClearState();
2581 pipe.CreateVKPipeline(descriptorSet);
2582
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002583 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes37367e62015-05-25 11:13:29 +12002584
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002585 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes37367e62015-05-25 11:13:29 +12002586 if (!strstr(msgString.c_str(),"VS consumes input at location 0 but not provided")) {
2587 FAIL() << "Incorrect warning: " << msgString;
2588 }
2589}
2590
Chris Forbesa4b02322015-05-25 11:13:31 +12002591TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch)
2592{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002593 VkFlags msgFlags;
Chris Forbesa4b02322015-05-25 11:13:31 +12002594 std::string msgString;
2595 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002596 ScopedUseGlsl useGlsl(false);
Chris Forbesa4b02322015-05-25 11:13:31 +12002597
2598 VkVertexInputBindingDescription input_binding;
2599 memset(&input_binding, 0, sizeof(input_binding));
2600
2601 VkVertexInputAttributeDescription input_attrib;
2602 memset(&input_attrib, 0, sizeof(input_attrib));
2603 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2604
2605 char const *vsSource =
2606 "#version 140\n"
2607 "#extension GL_ARB_separate_shader_objects: require\n"
2608 "#extension GL_ARB_shading_language_420pack: require\n"
2609 "\n"
2610 "layout(location=0) in int x;\n" /* attrib provided float */
2611 "void main(){\n"
2612 " gl_Position = vec4(x);\n"
2613 "}\n";
2614 char const *fsSource =
2615 "#version 140\n"
2616 "#extension GL_ARB_separate_shader_objects: require\n"
2617 "#extension GL_ARB_shading_language_420pack: require\n"
2618 "\n"
2619 "layout(location=0) out vec4 color;\n"
2620 "void main(){\n"
2621 " color = vec4(1);\n"
2622 "}\n";
2623
2624 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2625 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2626
2627 VkPipelineObj pipe(m_device);
2628 pipe.AddShader(&vs);
2629 pipe.AddShader(&fs);
2630
2631 pipe.AddVertexInputBindings(&input_binding, 1);
2632 pipe.AddVertexInputAttribs(&input_attrib, 1);
2633
2634 VkCommandBufferObj dummyCmd(m_device);
2635 VkDescriptorSetObj descriptorSet(m_device);
2636 descriptorSet.AppendDummy();
2637 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2638
2639 m_errorMonitor->ClearState();
2640 pipe.CreateVKPipeline(descriptorSet);
2641
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002642 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesa4b02322015-05-25 11:13:31 +12002643
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002644 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesa4b02322015-05-25 11:13:31 +12002645 if (!strstr(msgString.c_str(),"location 0 does not match VS input type")) {
2646 FAIL() << "Incorrect error: " << msgString;
2647 }
2648}
2649
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002650TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict)
2651{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002652 VkFlags msgFlags;
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002653 std::string msgString;
2654 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002655 ScopedUseGlsl useGlsl(false);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002656
2657 /* Two binding descriptions for binding 0 */
2658 VkVertexInputBindingDescription input_bindings[2];
2659 memset(input_bindings, 0, sizeof(input_bindings));
2660
2661 VkVertexInputAttributeDescription input_attrib;
2662 memset(&input_attrib, 0, sizeof(input_attrib));
2663 input_attrib.format = VK_FORMAT_R32_SFLOAT;
2664
2665 char const *vsSource =
2666 "#version 140\n"
2667 "#extension GL_ARB_separate_shader_objects: require\n"
2668 "#extension GL_ARB_shading_language_420pack: require\n"
2669 "\n"
2670 "layout(location=0) in float x;\n" /* attrib provided float */
2671 "void main(){\n"
2672 " gl_Position = vec4(x);\n"
2673 "}\n";
2674 char const *fsSource =
2675 "#version 140\n"
2676 "#extension GL_ARB_separate_shader_objects: require\n"
2677 "#extension GL_ARB_shading_language_420pack: require\n"
2678 "\n"
2679 "layout(location=0) out vec4 color;\n"
2680 "void main(){\n"
2681 " color = vec4(1);\n"
2682 "}\n";
2683
2684 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2685 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2686
2687 VkPipelineObj pipe(m_device);
2688 pipe.AddShader(&vs);
2689 pipe.AddShader(&fs);
2690
2691 pipe.AddVertexInputBindings(input_bindings, 2);
2692 pipe.AddVertexInputAttribs(&input_attrib, 1);
2693
2694 VkCommandBufferObj dummyCmd(m_device);
2695 VkDescriptorSetObj descriptorSet(m_device);
2696 descriptorSet.AppendDummy();
2697 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2698
2699 m_errorMonitor->ClearState();
2700 pipe.CreateVKPipeline(descriptorSet);
2701
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002702 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002703
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002704 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes0bf8fe12015-06-12 11:16:41 +12002705 if (!strstr(msgString.c_str(),"Duplicate vertex input binding descriptions for binding 0")) {
2706 FAIL() << "Incorrect error: " << msgString;
2707 }
2708}
Chris Forbes4c948702015-05-25 11:13:32 +12002709
Chris Forbesc12ef122015-05-25 11:13:40 +12002710/* TODO: would be nice to test the mixed broadcast & custom case, but the GLSL->SPV compiler
2711 * rejects it. */
2712
2713TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten)
2714{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002715 VkFlags msgFlags;
Chris Forbesc12ef122015-05-25 11:13:40 +12002716 std::string msgString;
2717 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002718 ScopedUseGlsl useGlsl(false);
Chris Forbesc12ef122015-05-25 11:13:40 +12002719
2720 char const *vsSource =
2721 "#version 140\n"
2722 "#extension GL_ARB_separate_shader_objects: require\n"
2723 "#extension GL_ARB_shading_language_420pack: require\n"
2724 "\n"
2725 "void main(){\n"
2726 " gl_Position = vec4(1);\n"
2727 "}\n";
2728 char const *fsSource =
2729 "#version 140\n"
2730 "#extension GL_ARB_separate_shader_objects: require\n"
2731 "#extension GL_ARB_shading_language_420pack: require\n"
2732 "\n"
2733 "void main(){\n"
2734 "}\n";
2735
2736 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2737 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2738
2739 VkPipelineObj pipe(m_device);
2740 pipe.AddShader(&vs);
2741 pipe.AddShader(&fs);
2742
2743 /* implicit CB 0 set up by the test framework, not written */
2744
2745 VkCommandBufferObj dummyCmd(m_device);
2746 VkDescriptorSetObj descriptorSet(m_device);
2747 descriptorSet.AppendDummy();
2748 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2749
2750 m_errorMonitor->ClearState();
2751 pipe.CreateVKPipeline(descriptorSet);
2752
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002753 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbesc12ef122015-05-25 11:13:40 +12002754
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002755 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbesc12ef122015-05-25 11:13:40 +12002756 if (!strstr(msgString.c_str(),"Attachment 0 not written by FS")) {
2757 FAIL() << "Incorrect error: " << msgString;
2758 }
2759}
2760
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002761TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed)
2762{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002763 VkFlags msgFlags;
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002764 std::string msgString;
2765 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002766 ScopedUseGlsl useGlsl(false);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002767
2768 char const *vsSource =
2769 "#version 140\n"
2770 "#extension GL_ARB_separate_shader_objects: require\n"
2771 "#extension GL_ARB_shading_language_420pack: require\n"
2772 "\n"
2773 "void main(){\n"
2774 " gl_Position = vec4(1);\n"
2775 "}\n";
2776 char const *fsSource =
2777 "#version 140\n"
2778 "#extension GL_ARB_separate_shader_objects: require\n"
2779 "#extension GL_ARB_shading_language_420pack: require\n"
2780 "\n"
2781 "layout(location=0) out vec4 x;\n"
2782 "layout(location=1) out vec4 y;\n" /* no matching attachment for this */
2783 "void main(){\n"
2784 " x = vec4(1);\n"
2785 " y = vec4(1);\n"
2786 "}\n";
2787
2788 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2789 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2790
2791 VkPipelineObj pipe(m_device);
2792 pipe.AddShader(&vs);
2793 pipe.AddShader(&fs);
2794
2795 /* implicit CB 0 set up by the test framework */
2796 /* FS writes CB 1, but we don't configure it */
2797
2798 VkCommandBufferObj dummyCmd(m_device);
2799 VkDescriptorSetObj descriptorSet(m_device);
2800 descriptorSet.AppendDummy();
2801 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2802
2803 m_errorMonitor->ClearState();
2804 pipe.CreateVKPipeline(descriptorSet);
2805
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002806 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002807
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002808 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbes5d15a4f2015-05-25 11:13:43 +12002809 if (!strstr(msgString.c_str(),"FS writes to output location 1 with no matching attachment")) {
2810 FAIL() << "Incorrect warning: " << msgString;
2811 }
2812}
2813
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002814TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch)
2815{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002816 VkFlags msgFlags;
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002817 std::string msgString;
2818 ASSERT_NO_FATAL_FAILURE(InitState());
Cody Northrop1cfbd172015-06-03 16:49:20 -06002819 ScopedUseGlsl useGlsl(false);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002820
2821 char const *vsSource =
2822 "#version 140\n"
2823 "#extension GL_ARB_separate_shader_objects: require\n"
2824 "#extension GL_ARB_shading_language_420pack: require\n"
2825 "\n"
2826 "void main(){\n"
2827 " gl_Position = vec4(1);\n"
2828 "}\n";
2829 char const *fsSource =
2830 "#version 140\n"
2831 "#extension GL_ARB_separate_shader_objects: require\n"
2832 "#extension GL_ARB_shading_language_420pack: require\n"
2833 "\n"
2834 "layout(location=0) out ivec4 x;\n" /* not UNORM */
2835 "void main(){\n"
2836 " x = ivec4(1);\n"
2837 "}\n";
2838
2839 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2840 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2841
2842 VkPipelineObj pipe(m_device);
2843 pipe.AddShader(&vs);
2844 pipe.AddShader(&fs);
2845
2846 /* implicit CB 0 set up by test framework, is UNORM. */
2847
2848 VkCommandBufferObj dummyCmd(m_device);
2849 VkDescriptorSetObj descriptorSet(m_device);
2850 descriptorSet.AppendDummy();
2851 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2852
2853 m_errorMonitor->ClearState();
2854 pipe.CreateVKPipeline(descriptorSet);
2855
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002856 msgFlags = m_errorMonitor->GetState(&msgString);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002857
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002858 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_ERROR_BIT);
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002859 if (!strstr(msgString.c_str(),"does not match FS output type")) {
2860 FAIL() << "Incorrect error: " << msgString;
2861 }
2862}
Chris Forbesc2050732015-06-05 14:43:36 +12002863
2864TEST_F(VkLayerTest, CreatePipelineNonSpirvShader)
2865{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002866 VkFlags msgFlags;
Chris Forbesc2050732015-06-05 14:43:36 +12002867 std::string msgString;
2868 ASSERT_NO_FATAL_FAILURE(InitState());
2869 /* Intentionally provided GLSL rather than compiling to SPIRV first */
Cody Northrop1cfbd172015-06-03 16:49:20 -06002870 ScopedUseGlsl useGlsl(true);
Chris Forbesc2050732015-06-05 14:43:36 +12002871
2872 char const *vsSource =
2873 "#version 140\n"
2874 "#extension GL_ARB_separate_shader_objects: require\n"
2875 "#extension GL_ARB_shading_language_420pack: require\n"
2876 "\n"
2877 "void main(){\n"
2878 " gl_Position = vec4(1);\n"
2879 "}\n";
2880 char const *fsSource =
2881 "#version 140\n"
2882 "#extension GL_ARB_separate_shader_objects: require\n"
2883 "#extension GL_ARB_shading_language_420pack: require\n"
2884 "\n"
2885 "layout(location=0) out vec4 x;\n"
2886 "void main(){\n"
2887 " x = vec4(1);\n"
2888 "}\n";
2889
2890 m_errorMonitor->ClearState();
2891
2892 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX, this);
2893 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT, this);
2894
2895
2896 VkPipelineObj pipe(m_device);
2897 pipe.AddShader(&vs);
2898 pipe.AddShader(&fs);
2899
2900 /* implicit CB 0 set up by test framework, is UNORM. */
2901
2902 VkCommandBufferObj dummyCmd(m_device);
2903 VkDescriptorSetObj descriptorSet(m_device);
2904 descriptorSet.AppendDummy();
2905 descriptorSet.CreateVKDescriptorSet(&dummyCmd);
2906
2907 VkResult res = pipe.CreateVKPipeline(descriptorSet);
2908 /* pipeline creation should have succeeded */
2909 ASSERT_EQ(VK_SUCCESS, res);
2910
2911 /* should have emitted a warning: the shader is not SPIRV, so we're
2912 * not going to be able to analyze it */
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002913 msgFlags = m_errorMonitor->GetState(&msgString);
2914 ASSERT_TRUE(msgFlags & VK_DBG_REPORT_WARN_BIT);
Chris Forbesc2050732015-06-05 14:43:36 +12002915 if (!strstr(msgString.c_str(),"is not SPIR-V")) {
2916 FAIL() << "Incorrect warning: " << msgString;
2917 }
2918}
Chris Forbes01c9db72015-06-04 09:25:25 +12002919#endif
Chris Forbes7d64a4f2015-05-25 11:13:44 +12002920
Tony Barbour30486ea2015-04-07 13:44:53 -06002921int main(int argc, char **argv) {
2922 int result;
2923
2924 ::testing::InitGoogleTest(&argc, argv);
Tony Barbour01999182015-04-09 12:58:51 -06002925 VkTestFramework::InitArgs(&argc, argv);
Tony Barbour30486ea2015-04-07 13:44:53 -06002926
2927 ::testing::AddGlobalTestEnvironment(new TestEnvironment);
2928
2929 result = RUN_ALL_TESTS();
2930
Tony Barbour01999182015-04-09 12:58:51 -06002931 VkTestFramework::Finish();
Tony Barbour30486ea2015-04-07 13:44:53 -06002932 return result;
2933}