Vulkan Instanced Rendering Weird Depth Buffer Behaviour - vulkan

I am rendering a single mesh test object that contains 8000 cubes, 1 monkey, and 1 plane. I checked normals and winding orders. all seems correct for mesh.
if I render a single instance, the depth buffer works correctly. if I render using instanced when instant number increase depth buffer doesn't work correctly.
//Depth Attachment
//Create Depth Image
depthImage = new Image(
physicalDevice_,
logicalDevice_,
VK_IMAGE_TYPE_2D,
depthFormat,
VK_IMAGE_TILING_OPTIMAL,
swapChainExtent.width,
swapChainExtent.height,
1,
sampleCount_, //do we really need to sample depth????
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
depthImageView = new ImageView(
logicalDevice_,
VK_IMAGE_VIEW_TYPE_2D,
depthImage->handle,
depthFormat,
1,
VK_IMAGE_ASPECT_DEPTH_BIT);
//Render pass Depth Attachment
VkAttachmentDescription depthAttachment{};
depthAttachment.format = depthFormat;
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
//Graphics Pipeline
VkPipelineDepthStencilStateCreateInfo depthStencil{};
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencil.depthTestEnable = VK_TRUE;
depthStencil.depthWriteEnable = VK_TRUE;
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
depthStencil.depthBoundsTestEnable = VK_FALSE;
depthStencil.minDepthBounds = 0.0f; // Optional
depthStencil.maxDepthBounds = 1.0f; // Optional
depthStencil.stencilTestEnable = VK_FALSE;
depthStencil.front = {}; // Optional
depthStencil.back = {}; // Optional
Below the screen is the view from the 100th instance of that mesh.
The higher the instance number, the more the depth buffer deteriorates.
The result is still the same if I use a different model.
What am I missing?
Result:
Depth Buffer:

For those who may struggle with similar issue. I found a solution.
Actually, this issue is not related to instancing directly but it's a bit confusing issue becomes visible as the instance index increases.
the cause is projection matrix z-near value was so small.
...
fieldOfView = 65.0f;
znear = 0.001f; // ! this much small value cause this problem
zfar = 5000.0f;
...
changed z-near to an acceptable value. Problem solved.
...
fieldOfView = 65.0f;
znear = 0.1f;
zfar = 5000.0f;
...

Related

VkSubpassDependency required for depth attachment, but not for color attachment

I have a very simple setup - in fact one of the earlier stages of vkguide.dev. So a single render pass with a single subpass. Those have one color and one depth attachment.
The color AttachmentDescription has .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED and .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR. In its SubPassDescription, it has .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
The depth AttachmentDescription has .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED and .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL. In its SubPassDescription, it has .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL.
I'm trying to understand the subpass dependencies, so I don't want to rely on the implicit ones the spec provides but provide my own, minimal ones.
When I provide "zeroed out" subpass dependencies, I get a the following error with sync validation turned on:
Validation Error: [ SYNC-HAZARD-WRITE_AFTER_WRITE ] Object 0: handle = 0x83d4ee000000000b, type = VK_OBJECT_TYPE_RENDER_PASS; | MessageID = 0xfdf9f5e1 | vkCmdBeginRenderPass: Hazard WRITE_AFTER_WRITE vs. layout transition in subpass 0 for attachment 1 aspect depth during load with loadOp VK_ATTACHMENT_LOAD_OP_CLEAR.
So he's complaining about the depth attachment (attachment 1). And I can fix this with the following set of explicit subpass dependencies:
constexpr VkSubpassDependency in_dependency{
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
};
constexpr VkSubpassDependency out_dependency = {
.srcSubpass = 0,
.dstSubpass = VK_SUBPASS_EXTERNAL,
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
.srcAccessMask = 0,
.dstAccessMask = 0,
.dependencyFlags = 0
};
The second of course is only there to not use the second implicit one and does nothing. The first one is an explicit dependency between things before the renderpass and the first/only subpass. But I don't really understand - a couple of questions:
does a srcAccessMask = 0 really define a real dependency? it's empty after all, or are things different with a VK_SUBPASS_EXTERNAL?
Why do I only need a dependency on the depth- and not on the color attachment?
I made the image below and am aware that color attachment gets loaded and stored in the same pipeline stage, and that the depth attachment does now. However I still don't understand why that eliminates the need for a dependency. That pipeline stage could still overlap between two renderpasses right?
does a srcAccessMask = 0 really define a real dependency? it's empty after all, or are things different with a VK_SUBPASS_EXTERNAL?
Yes it does. It is called an execution dependency (as opposed to memory dependency). It becomes relevant in dependency chaining.
Consider this code:
vkCmdPipelineBarrier(
srcStage = WHATEVER_STAGE, srcAccess = MEMORY_WRITE,
dstStage = COOL_STAGE, dstAccess = 0
);
vkCmdPipelineBarrier(
srcStage = COOL_STAGE, srcAccess = 0,
dstStage = WHATEVER_ELSE_STAGE, dstAccess = MEMORY_READ
);
It is equivalent to a single dependency:
vkCmdPipelineBarrier(
srcStage = WHATEVER_STAGE, srcAccess = MEMORY_WRITE,
dstStage = WHATEVER_ELSE_STAGE, dstAccess = MEMORY_READ
);
Why do I only need a dependency on the depth- and not on the color attachment?
The validation might be implemented imperfectly. Or likely the color attachment is treated differently in your code (the color images are presented, while the depth is not). Which either sneaks the dependency there, or makes it less trivial for the validator to catch.

What the equivalent of OpenGL glStencilFunc in Metal?

How to translate to Metal the following OpenGL instruction:
glStencilFunc(Func, Ref, Mask);
Let's try to extend Hamid's correct answer with some actual Swift code...
Assuming you already have the basic Metal setup done:
let metalView: MTKView = /* ... */
let commandBuffer: MTLCommandBuffer = /* ... */
let device: MTLDevice = metalView.device!
Let's create a MTLTexture to store the stencil buffer:
let stencilTexture: MTLTexture
// Set up a texture for rendering the *8 bit unsigned* stencil buffer.
let stencilTextureDescriptor = MTLTextureDescriptor()
stencilTextureDescriptor.textureType = .type2D
stencilTextureDescriptor.width = Int(metalView.frame.width)
stencilTextureDescriptor.height = Int(metalView.frame.height)
stencilTextureDescriptor.pixelFormat = .stencil8
stencilTextureDescriptor.storageMode = .private
// Set this option if you use the given texture
// as a stencil render target in any render pass.
stencilTextureDescriptor.usage = [.renderTarget]
stencilTexture = device.makeTexture(descriptor: stencilTextureDescriptor)
Create the MTLRenderPipelineState as usual but be sure to set the stencil attachment too:
let rendePipelineState: MTLRenderPipelineState
let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
/* ...standard render pipeline configuration (e.g., render states, etc)... */
renderPipelineDescriptor.stencilAttachmentPixelFormat = .stencil8
rendePipelineState = try! device.makeRenderPipelineState(descriptor: renderPipelineDescriptor)
Next configure the MTLRenderPassDescriptor and create a MTLRenderCommandEncoder:
let renderEncoder: MTLRenderCommandEncoder
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].loadAction = .clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 1)
renderPassDescriptor.colorAttachments[0].storeAction = .store
// Configure these depending on your rendering pass stencil semantics.
renderPassDescriptor.stencilAttachment.texture = stencilTexture
renderPassDescriptor.stencilAttachment.clearStencil = 0
renderPassDescriptor.stencilAttachment.loadAction = .clear
renderPassDescriptor.stencilAttachment.storeAction = .store
renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)!
renderEncoder.setRenderPipelineState(rendePipelineState)
Now create a MTLDepthStencilState with the desired stencil buffer configuration:
let depthAndStencilState: MTLDepthStencilState
let stencilDescriptor = MTLStencilDescriptor()
stencilDescriptor.depthStencilPassOperation = .incrementClamp
// ## glStencilFunc(FUNC, _, _) ##
stencilDescriptor.stencilCompareFunction = .equal
// ## glStencilFunc(_, _, MASK) ##
stencilDescriptor.readMask = 0xFF_FF_FF_FF
let depthAndStencilDescriptor = MTLDepthStencilDescriptor()
depthAndStencilDescriptor.depthCompareFunction = .always
depthAndStencilDescriptor.isDepthWriteEnabled = false
depthAndStencilDescriptor.frontFaceStencil = stencilDescriptor
depthAndStencilDescriptor.backFaceStencil = stencilDescriptor
depthAndStencilState = device.makeDepthStencilState(descriptor: depthAndStencilDescriptor)!
renderEncoder.setDepthStencilState(depthAndStencilState)
// ## glStencilFunc(_, REF, _) ##
renderEncoder.setStencilReferenceValue(1)
Finally, do the rendering as usual:
/* ...encode rendering primitives... */
renderEncoder.endEncoding()
MTLStencilDescriptor an object that defines the front-facing or back-facing stencil operations of a depth and stencil state object.
A stencil test is a comparison between a masked reference value and a
masked value stored in a stencil attachment. (A value is masked by
performing a logical AND operation on it with the readMask value.) The
MTLStencilDescriptor object defines how to update the contents of the
stencil attachment, based on the results of the stencil test and the
depth test.
The stencilCompareFunction property defines the stencil test. The
stencilFailureOperation, depthFailureOperation, and
depthStencilPassOperation properties specify what to do to a stencil
value stored in the stencil attachment for three different test
outcomes: if the stencil test fails, if the stencil test passes and
the depth test fails, or if both stencil and depth tests succeed,
respectively. writeMask determines which stencil bits can be modified
as the result of a stencil operation.
I see where to put the value of Func and Mask with
MTLStencilDescriptor, but where go the value of REF ?
setStencilReferenceValue sets a stencil reference value for both front and back stencil comparison tests.

Photoshop script to duplicate and rename layer

While creating a script that would automate all the different tasks I do when I start working on a new picture on Photoshop, I encountered the following problem.
I want to create different groups and different layers inside these groups. Everything goes perfectly fine until this :
#target photoshop
app.bringToFront();
var doc = app.activeDocument;
newCurve();
var clippingHelpLayerLight = doc.activeLayer;
clippingHelpLayerLight.blendMode = BlendMode.SCREEN;
clippingHelpLayerLight.name = "Clipping Help Layer - Light";
clippingHelpLayerLight.visible = false;
clippingHelpLayerLight.duplicate();
var clippingHelpLayerLighter = doc.activeLayer;
clippingHelpLayerLighter.name = "Clipping Help Layer - Lighter";
clippingHelpLayerLighter.visible = false;
function newCurve() {
var c_ADJ_LAYER = charIDToTypeID("AdjL");
var c_ADJUSTMENT = charIDToTypeID("Adjs");
var c_CHANNEL = charIDToTypeID("Chnl");
var c_COMPOSITE = charIDToTypeID("Cmps");
var c_CURVE = charIDToTypeID("Crv ");
var c_CURVE_A = charIDToTypeID("CrvA");
var c_CURVES = charIDToTypeID("Crvs");
var c_HORIZONTAL = charIDToTypeID("Hrzn");
var c_MAKE = charIDToTypeID("Mk ");
var c_NULL = charIDToTypeID("null");
var c_POINT = charIDToTypeID("Pnt ");
var c_TYPE = charIDToTypeID("Type");
var c_USING = charIDToTypeID("Usng");
var c_VERTICAL = charIDToTypeID("Vrtc");
var d_CURVES_LAYER = new ActionDescriptor();
// Contains all the information necessary to perform the "MAKE" action
var r_CLASS = new ActionReference();
r_CLASS.putClass(c_ADJ_LAYER);
d_CURVES_LAYER.putReference(c_NULL, r_CLASS);
// Class of make action is of an ajdustment layer
var d_TYPE_CURVES = new ActionDescriptor();
// Contains all the information about all the curves
var d_CHANNEL_CURVES = new ActionDescriptor();
var l_CHANNEL_CURVES = new ActionList();
// Contains a list of channel curves
var d_CHANNEL_CURVE = new ActionDescriptor();
// Information for 1 channel curve
var r_CHANNEL = new ActionReference();
r_CHANNEL.putEnumerated(c_CHANNEL, c_CHANNEL, c_COMPOSITE);
// This curve is for the composite channel - VARIES
d_CHANNEL_CURVE.putReference(c_CHANNEL, r_CHANNEL);
// Contains the point list
var l_POINTS = new ActionList();
// List of points for this channel - LENGTH VARIES
var d_POINT = new ActionDescriptor();
// One point on the curve, has INPUT and OUTPUT value
d_POINT.putDouble(c_HORIZONTAL, 0.000000);
d_POINT.putDouble(c_VERTICAL, 0.000000);
l_POINTS.putObject(c_POINT, d_POINT);
//var d_POINT3 = new ActionDescriptor();
d_POINT.putDouble(c_HORIZONTAL, 255.000000);
d_POINT.putDouble(c_VERTICAL, 255.000000);
l_POINTS.putObject(c_POINT, d_POINT);
// Made the list of points
d_CHANNEL_CURVE.putList(c_CURVE, l_POINTS);
// Now have a list of points for a specific channel
l_CHANNEL_CURVES.putObject(c_CURVE_A, d_CHANNEL_CURVE);
// Add to the list of channel curves
d_CHANNEL_CURVES.putList(c_ADJUSTMENT, l_CHANNEL_CURVES);
// All the channel curves are inside here
d_TYPE_CURVES.putObject(c_TYPE, c_CURVES, d_CHANNEL_CURVES);
// .....
d_CURVES_LAYER.putObject(c_USING, c_ADJ_LAYER, d_TYPE_CURVES);
// package the curves and definition of the adjustment layer type
executeAction(c_MAKE, d_CURVES_LAYER, DialogModes.NO);
}
I actually want to create a first layer called "Clipping Help Layer - Light", blend mode : screen and turn it off. Then duplicate it, change the name of the new layer as "Clipping Help Layer - Lighter" and turn it off too.
Like this : Screenshot of what I would like to do
It does create the 2 layers, but the first one has " copy" at the end of its name and it stays turned on.
Screenshot of the actual result
Why ?
I can't understand why it doesn't work as expected and can't manage to fix it.
Any help would be greatly appreciated !
I believe the problem you are encountering has to do with doc.activeLayer. After you duplicate "Clipping Help Layer - Light," the script does not seem to change what doc.activeLayer is pointing to so when you then try to assign it to clippingHelpLayerLighter, you are then pointing at an undefined layer. While I don't know exactly what is happening behind the scenes when you do that, I do believe this will fix your problem:
#target photoshop
app.bringToFront();
var doc = app.documents.add( 4, 4 );
doc = app.activeDocument;
var clippingHelpLayerLight = doc.activeLayer;
clippingHelpLayerLight.blendMode = BlendMode.SCREEN;
clippingHelpLayerLight.name = "Clipping Help Layer - Light";
clippingHelpLayerLight.visible = false;
clippingHelpLayerLight.duplicate();
doc.activeLayer = doc.layers[ "Clipping Help Layer - Light copy" ];
doc.activeLayer.name = "Clipping Help Layer - Lighter";
doc.activeLayer.visible = false;
//I am not sure if you need this pointer to be called upon later in your
//code. If you do not, just leave this line out.
var clippingHelpLayerLighter = doc.activeLayer;
Hope this helps! Let me know if you have any questions, I'm by no means an expert but I use scripts fairly often.

How to create fishnet in arcgis engine?

I found createfishnet method in arcobject, but it doesn't work.Where is my mistake?
Geoprocessor gp = new Geoprocessor();
gp.OverwriteOutput = true;
ESRI.ArcGIS.DataManagementTools.CreateFishnet fishnet = new ESRI.ArcGIS.DataManagementTools.CreateFishnet();
fishnet.template = buffer_out;
//txtOutputPath2.Text="E:\\program\\shenzhen_science_committee\\sc\\landuse_subway\\shenzhen_subway\\23_net.shp"
fishnet.out_feature_class = txtOutputPath2.Text;
IFeatureCursor cursor1=buffer_out.Search(null,true);
IFeature buffer=cursor1.NextFeature();
IPoint centerPoint =new ESRI.ArcGIS.Geometry.Point();
IArea pArea = buffer.Shape as IArea;
pArea.QueryCentroid(centerPoint);
fishnet.origin_coord = centerPoint;
double height=0;
double width=0;
fishnet.cell_height = 0.1;
fishnet.cell_width = 0.1;
fishnet.number_columns = 50;
fishnet.number_rows = 50;
IGeoProcessorResult results = (IGeoProcessorResult)gp.Execute(fishnet, null);
The result shows wrong HRESULT E_FAIL.
I have tried this in ArcObjects with Java. What I found was that the fishnet could not be generated for area within a particular polygon, as in the ArcMap application. You would have to intersect or use spatial filter on the fishnet output.
Also, try giving all the parameters, even the optional ones like set corner coordinate. If you are using data in a particular projection system, that can be set to the output by setting the template (and this takes only Envelope).
Below is the code that I have used. I wanted the fishnet label as well, so I have enabled it. Make sure you use a space between the x and y coordinate of a point, entered as a String, which is probably the issue here.
GeoProcessor gp = new GeoProcessor();
gp.setOverwriteOutput(true);
IEnvelope aoi = buffer_out.getEnvelope();
CreateFishnet createFishnet = new CreateFishnet();
createFishnet.setOutFeatureClass(tempDir+"/"+fishnetOutput+".shp");
createFishnet.setTemplate(aoi);
createFishnet.setOriginCoord(aoi.getXMin()+" "+aoi.getYMin());
createFishnet.setYAxisCoord(aoi.getXMin()+" "+aoi.getYMax());
createFishnet.setCornerCoord(aoi.getXMax()+" "+aoi.getYMax());
createFishnet.setCellHeight(30.0);
createFishnet.setCellWidth(30.0);
createFishnet.setNumberRows(0);
createFishnet.setNumberColumns(0);
createFishnet.setLabels("LABELS");
createFishnet.setGeometryType("POLYLINE");
gp.execute(createFishnet, null);
I hope you can use this example and apply it to your code.

Vulkan input attachment from previous subpass

I am trying to use the color attachment created in subpass 0 as an input attachment in subpass 1. However there is an issue that i cant get past.
My problem currently is the following, i try to clear attachment 0 at the beginning of the pass using VK_ATTACHMENT_LOAD_OP_CLEAR however gives the error.
Cannot clear attachment 0 with invalid first layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
Which seems weird to me, attachment 0 does not get layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL untill subpass 1 where it is a input attachment, while the clear should have already happened when the layout was still VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (AFAIK).
I have now tried to just continue running after the validation error, and attachment 0 does get cleared, which makes me even more unsure. I can apparently just ignore the validation error, but something weird might be going on that could cause problems later on so I am not confidant enough to just ignore it.
Here is the minimal code that will give the error:
VkAttachmentDescription attachments[1] {};
attachments[0].format = VK_FORMAT_R16G16B16A16_SFLOAT;
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference pass_0_ColorAttachments[1];
pass_0_ColorAttachments[0].attachment = 0;
pass_0_ColorAttachments[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference pass_1_InputAttachments[1];
pass_1_InputAttachments[0].attachment = 0;
pass_1_InputAttachments[0].layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkSubpassDescription subpasses[2] {};
subpasses[0].colorAttachmentCount = 1;
subpasses[0].pColorAttachments = pass_0_ColorAttachments;
subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpasses[1].inputAttachmentCount = 1;
subpasses[1].pInputAttachments = pass_1_InputAttachments;
subpasses[1].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
VkSubpassDependency subpassDependancies[1] {};
subpassDependancies[0].srcSubpass = 0;
subpassDependancies[0].dstSubpass = 1;
subpassDependancies[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassDependancies[0].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
subpassDependancies[0].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassDependancies[0].dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
subpassDependancies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
VkRenderPassCreateInfo renderpassCreateInfo {};
renderpassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderpassCreateInfo.attachmentCount = 1;
renderpassCreateInfo.pAttachments = attachments;
renderpassCreateInfo.subpassCount = 2;
renderpassCreateInfo.pSubpasses = subpasses;
renderpassCreateInfo.dependencyCount = 1;
renderpassCreateInfo.pDependencies = subpassDependancies;
VkRenderPass renderPass;
vkCreateRenderPass(device, &renderpassCreateInfo, nullptr, &renderPass);
The next part is only relevant if it is impossible to specify VK_ATTACHMENT_LOAD_OP_CLEAR for an attachment used as color attachment first and in a later subpass as input attachment (i see no reason why this would be impossible, unless vulkan does the load operation each subpass). So this is kind of a separate problem.
I could, instead of using VK_ATTACHMENT_LOAD_OP_CLEAR, manually clear the attachment using vkCmdClearAttachments and use VK_ATTACHMENT_LOAD_OP_DONT_CARE for the load operation of the attachment.
I have a crash error on calling vkCmdClearAttachments
I started the command buffer recording and the renderpass, and in the first subpass I call:
VkClearAttachment clearAtts[] = {{VK_IMAGE_ASPECT_COLOR_BIT, 1, {0,0,0,0}}};
VkClearRect rect = {{{0,0}, {1,1}}, 0, 1};
vkCmdClearAttachments(vkCommandBuffer, 1, clearAtts, 1, &rect);
{1,1} as the extent to show this is not the problem
You're having the same problem as was discovered here. It's a bug in the validation layer in 1.0.17. It would appear that the current Github head has a fix, but that fix is not in the 1.0.21 release.
But you still need to fix the stuff below ;)
subpassDependancies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
You are not going to read the image as a color attachment. You're going to read it as an input attachment. From the fragment shader. So that would mean VK_ACCESS_INPUT_ATTACHMENT_READ_BIT.
If that fixes the error, then I'd guess the validation layer got confused by your oddball dependency access mask. It therefore couldn't establish a valid dependency chain between subpasses 0 and 1, and thus thought that subpass 1 was first.
Also, your srcStageMask and dstStageMask bits are way over-specified. Every graphics stage is not going to write to the image, and every graphics stage is not going to access it after. You only wrote to the image as a color attachment, and you're only going to read from it in the fragment shader.
So your srcStageMask ought to just be VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, and your dstStageMask ought to be VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT.