[Pipeline][Shader] Render a triangle but get no result

I am trying to draw a triangle in the render pass, but I am unable to get any result from vkDraw and there is no error message output by validation-layers anyway, it’s weird.

        Render::BeginRenderPass(renderTarget, primaryCamera);
            // Render::Draw(pipeline);
			auto pl = std::dynamic_pointer_cast<Vulkan::Pipeline>(pipeline);
			auto drawCmdBuf = Vulkan::RenderContext::That->GetCommandBuffer();
			// Bind descriptor sets describing shader binding points
			vkCmdBindDescriptorSets(*drawCmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pl->Layout(), 0, 1, &pl->GetDescriptorSet(), 0, nullptr);

			// Bind the rendering pipeline
			// The pipeline (state object) contains all states of the rendering pipeline, binding it will set all the states specified at pipeline creation time
			vkCmdBindPipeline(*drawCmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pl);

			// Bind triangle vertex buffer (contains position and colors)
			VkDeviceSize offsets[1] = { 0 };
			vkCmdBindVertexBuffers(*drawCmdBuf, 0, 1, &vertices.buffer, offsets);

			// Bind triangle index buffer
			vkCmdBindIndexBuffer(*drawCmdBuf, indices.buffer, 0, VK_INDEX_TYPE_UINT32);

			// Draw indexed triangle
			vkCmdDrawIndexed(*drawCmdBuf, indices.count, 1, 0, 0, 1);

The above is how I bind vertex buffer and draw indexed.

	struct Vertex {
		float position[3];
		float color[3];

        const std::vector<Vertex> vertices = {
            { {  1.0f,  1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f } },
            { { -1.0f,  1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f } },
            { {  0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }

        const std::vector<uint32_t> indices = {
            0, 1, 2

		// Vertex input binding
		// This example uses a single vertex input binding at binding point 0 (see vkCmdBindVertexBuffers)
		VkVertexInputBindingDescription vertexInputBinding = {};
		vertexInputBinding.binding = 0;
		vertexInputBinding.stride = sizeof(Vertex);
		vertexInputBinding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

		// Input attribute bindings describe shader attribute locations and memory layouts
		std::array<VkVertexInputAttributeDescription, 2> vertexInputAttributs;
		// These match the following shader layout (see triangle.vert):
		//	layout (location = 0) in vec3 inPos;
		//	layout (location = 1) in vec3 inColor;
		// Attribute location 0: Position
		vertexInputAttributs[0].binding = 0;
		vertexInputAttributs[0].location = 0;
		// Position attribute is three 32 bit signed (SFLOAT) floats (R32 G32 B32)
		vertexInputAttributs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
		vertexInputAttributs[0].offset = offsetof(Vertex, position);
		// Attribute location 1: Color
		vertexInputAttributs[1].binding = 0;
		vertexInputAttributs[1].location = 1;
		// Color attribute is three 32 bit signed (SFLOAT) floats (R32 G32 B32)
		vertexInputAttributs[1].format = VK_FORMAT_R32G32B32_SFLOAT;
		vertexInputAttributs[1].offset = offsetof(Vertex, color);

		// Vertex input state used for pipeline creation
		VkPipelineVertexInputStateCreateInfo vertexInputState = {};
		vertexInputState.vertexBindingDescriptionCount = 1;
		vertexInputState.pVertexBindingDescriptions = &vertexInputBinding;
		vertexInputState.vertexAttributeDescriptionCount = 2;
		vertexInputState.pVertexAttributeDescriptions = vertexInputAttributs.data();

The above is how I create vertex input.

#version 450

layout (location = 0) in vec3 inPos;
layout (location = 1) in vec3 inColor;

layout (location = 0) out vec3 outColor;

void main()
	outColor = inColor;
	gl_Position = vec4(inPos.xyz, 1.0);

#version 450

layout (location = 0) in vec3 inColor;

layout (location = 0) out vec4 outFragColor;

void main()
  outFragColor = vec4(inColor, 1.0);

The above is vertex and fragment shader. Is this shader is incorrect?

The final color attachment I got used as a texture. Only the clear color of the render pass is shown, but there is no triangle from the shader. I’m trying to copy codes from the tutorial but it still gets nothing. The most trouble is that there is no error or warning message generated by validation layers. Is there anyone that has the same or familiar situation like this or knows how to get it resolved? I beg your pardon here for my noobiness.

Why is your firstInstance from vkCmdDrawIndexed set to 1?

Anyway, when learning proceed systematically. Do not rush to the outcome.

If you are suspicious about validation, then just test it by breaking something that would be picked up. Working validation is necessary condition for development, so make sure it actually works in practice.

If stuck, make a minimal example. Either you will resolve your problem by the act of making it, or it will become useful when you ask for help. You don’t need inColor; it could be hardcoded for your first Vulkan attempt. You don’t need Descriptors for a triangle, so you can throw those out. You don’t need index buffer, if it is just 0, 1, 2.

Your triangle winding is clockwise, so make sure that matches the settings (or better yet, turn off backface culling while learning). Other than that I don’t immediately see any issues with the code you have shown. You might want to post your whole thing, which will allow anyone to run it and do their own debuging to quickly find the problem.

1 Like


Try it:

vkCmdDrawIndexed(*drawCmdBuf, indices.count, 1, 0, 0, 0);

If it doesn’t help you, then:

Could you provide a minimal test project? It can help us to understand you problem.
Try to capture a frame using Renderdoc, you should investigate at least VS In and VS Out pages for Mesh’s Viewer window.

Hi there,

Thanks, @krOoze, and @AndreyOGL_D3D. I‘m sorry to respond so later for our different time zone.

This reminds me I may have a problem with pipeline state initialization.
Here is how I create my pipeline state: Immortal/Pipeline.cpp at 605fe5aa47b7657ef76f30d51eb0147a397b2503 · QSXW/Immortal · GitHub

When I comment on these lines:

    //state->depthStencil.depthTestEnable  = VK_TRUE;
    //state->depthStencil.depthWriteEnable = VK_TRUE;
    //state->depthStencil.depthCompareOp   = VK_COMPARE_OP_GREATER;
    //state->depthStencil.front            = state->depthStencil.back;
    //state->depthStencil.back.compareOp   = VK_COMPARE_OP_ALWAYS;

Finally, I’m able to see a triangle.

Though it’s a white one totally. Looks like it’s a depth image?

It works when I changed colorBlendState.blendEnable = VK_FALSE