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.
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!
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.
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.
Let's say I have an OpenGL program that has a uniform attribute "diffuseColor". I have set it as following:
GLint location = glGetUniformLocation(handle, "diffuseColor");
glUniform3f(location, 1, 0, 0);
Now I would like to return it to the default value, which is encoded in the shader code. I do not have access to the source code, but I can call OpenGL API functions on the compiled program. Is there a way to read default value and set it with glUniform3f? Or even better, is there a something like glResetUniform3f(GLint loc)?
Uniform initializers are applied upon linking the program. The value can then be read using glGetUniformfv/glGetUniformiv. There is no way to read the initial value of the uniform after you changed the uniform value.
There is no way to reset a single uniform to its initial value, but relinking the program will reset all uniforms in it. Linking a program is a costly operation and should be avoided in between frames.