What is the equivalent in metal of glEnable(GL_DEPTH_TEST)? The Depth Test is a per-sample processing operation performed after the Fragment Shader (and sometimes before).
Use a depth-stencil state object created from a descriptor whose depthCompareFunction is not MTLCompareFunctionAlways.
Related
I have a case where I am writing to integer framebuffers, and I want to use logic operations when writing to pixels in the fragment shader. These are the steps I followed:
When creating the logical device, I set the VkPhysicalDeviceFeatures.logicOp to VK_TRUE (so this feature is enabled)
when creating the pipeline, I set VkPipelineColorBlendStateCreateInfo.logicOpEnable to VK_TRUE, and VkPipelineColorBlendStateCreateInfo.logicOp to VK_LOGIC_OP_COPY.
My framebuffer format is VK_FORMAT_R32G32B32A32_SINT
Once I render the frame, I see that nothing is getting updated in the frame buffer. Is there any step I am missing? (btw, I don't get any validation errors).
Thanks!
This question already has an answer here:
Synchronization between drawcalls in Vulkan
(1 answer)
Closed 3 years ago.
Suppose I have two VkPipelines and within a VkCommandBuffer I record...
vkCmdBeginRenderPass(cmd, /*...*/);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline1);
vkCmdDraw(cmd, /*...*/); // [1]
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline2);
vkCmdDraw(cmd, /*...*/); // [2]
vkCmdEndRenderPass(cmd);
When the command buffer is queued and executed, will it be as-if the rendering operations to the framebuffer attachments of [1] are fully realized before [2] starts executing.
ie Will [2] draw over [1] ?
Most stages in Vulkan execute in an arbitrary order relative to each other. However, rasterization order is respected with regard to framebuffer attachment processes within a subpass (between subpasses, you have to use subpass dependencies, and outside of the renderpass, you'll need either external subpass dependencies or a barrier). Each primitive is ordered relative to each other primitive, and the implementation must respect rasterization order when doing reordering.
The stages that follow rasterization order atomically include depth/stencil test, blending, write masking, and the like, but they do not include the fragment shader itself. That is, FS outputs have to go through rasterization order, but FS side effects (ie: writes via image store or SSBOs) do not.
There's a set of rules defined in 24.2. Rasterization Order regarding primitive drawing in a single subpass. According to these rules, blending operations and color writes of the second primitive should happen strictly after blending operations and color writes of the first primitive.
What is the equivalent in metal of glEnable(GL_STENCIL_TEST)? The Stencil Test is a per-sample operation performed after the Fragment Shader. The fragment's stencil value is tested against the value in the current stencil buffer; if the test fails, the fragment is culled.
Use a depth-stencil state object created from a descriptor whose frontFaceStencil and/or backFaceStencil are set to descriptors with a stencilCompareFunction other than MTLCompareFunctionAlways.
I have some simple vulkan app which have:
3 command buffers for each swapchain image (#1, #2, #3)
1 uniform buffer with projection matrix data
I want to bind uniform buffer once. i'm using command buffer #1 to bind uniform buffer:
begin();
bindDescriptorSets();
end();
submit();
waitIdle();
reset();
Then i record commands for each swapchain image (3 times):
begin()
bindVertexBuffers()
beginRenderPass()
bindPipeline()
draw()
endRenderPass()
end();
Drawing works as expected, but validation layer logs an error:
[ UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotBound ] Object: 0x1a57aad7910 (Type = 6) | VkPipeline 0x21 uses set #0 but that set is not bound.
If i move the bindDescriptorSets(); line to the second recording block, like this:
begin()
bindDescriptorSets();
bindVertexBuffers()
beginRenderPass()
bindPipeline()
draw()
endRenderPass()
end();
Validation is OK, but there is no difference in rendering.
So, the question is: do i have to bind descriptor sets for each buffer recording? If yes, why does the app work fine when i'm binding descriptor sets once?
I believe it relates to the current state of the Vulkan application. Let's see what specification says about the state:
2.2.1. Queue Operation
Commands recorded in command buffers either perform actions (...), set state (bind pipelines, descriptor sets,
and buffers, set dynamic state, push constants, set render
pass/subpass state), or perform synchronization (...). Some commands
perform more than one of these tasks. State setting commands update
the current state of the command buffer.
Notice I marked in bold that binding a descriptor set is a state command.
You bind descriptor set to a command buffer end that buffer and submit. Next, you start other command buffers. Let's see again what specification tells us about the command buffers:
Command Buffers
Each command buffer manages state independently of other command buffers. There is no inheritance of state across primary
and secondary command buffers, or between secondary command buffers.
When a command buffer begins recording, all state in that command
buffer is undefined.
So the specification and layers tell you that you have to bind descriptors to every command buffer that uses that state. Why it works even with warnings? I don't know, probably your implementation allows it, but I wouldn't recommend to keep it as it is.
First of all, I'm a total newbie with Vulkan (I'm using the binding provided by LWJGL). I know I should copy/paste more code, but I don't even know what would be relevant for now (so don't hesitate to ask me some specific piece of code).
I try to make something like that :
Use a ComputeShader to compute a buffer of pixel.
Use vkCmdCopyBufferToImage to directly copy this array into a framebuffer image.
So, no vertex/fragment shaders for now.
I allocated a Compute Pipeline, and a FrameBuffer. I have one {Queue/CommandPool/CommandBuffer} for Computation, and one other for Rendering.
When I try to submit the graphic queue with:
vkQueueSubmit(graphicQueue, renderPipeline.getFrameSubmission().getSubmitInfo(imageIndex));
I obtain the following error message (from validation) :
ERROR OCCURED: Object: VK_NULL_HANDLE (Type = 0) | vkQueueSubmit() call includes a stageMask with VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT bit set when device does not have geometryShader feature enabled. The spec valid usage text states 'If the geometry shaders feature is not enabled, each element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkSubmitInfo-pWaitDstStageMask-00076)
ERROR OCCURED: Object: VK_NULL_HANDLE (Type = 0) | vkQueueSubmit() call includes a stageMask with VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT and/or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT bit(s) set when device does not have tessellationShader feature enabled. The spec valid usage text states 'If the tessellation shaders feature is not enabled, each element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkSubmitInfo-pWaitDstStageMask-00077)
I tried to change the VkSubmitInfo.pWaitDstStageMask to different values (like VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT...) but nothing change.
So, what would be the best pWaitDstStageMask for my use case ?
Ok, I found my problem:
The pWaitDstStageMask must be an array with the same size than pWaitSemaphores.
I only putted 1 stage mask, for 2 semaphores.