fix: single push constant range (0-160, Vertex|Fragment) — fixes validation errors
- Vulkan spec: each stage can only appear in ONE push constant range - Merged 3 ranges into 1: offset=0, size=160, stageFlags=Vertex|Fragment - Both main and shadow pipelines use same single range - Push constants packed into 160-byte buffer and sent in one call - Shadow pass: restored vertex/index buffer binding + push constants - Fixes: device lost, validation errors, missing shadow geometry
This commit is contained in:
@@ -150,24 +150,11 @@ internal sealed unsafe class VulkanPipeline : IDisposable
|
|||||||
pDynamicStates = dynamicStates,
|
pDynamicStates = dynamicStates,
|
||||||
};
|
};
|
||||||
|
|
||||||
var pushConstantRanges = stackalloc VkPushConstantRange[3];
|
var pushConstantRange = new VkPushConstantRange
|
||||||
pushConstantRanges[0] = new VkPushConstantRange
|
|
||||||
{
|
|
||||||
stageFlags = VkShaderStageFlags.Vertex,
|
|
||||||
offset = 0,
|
|
||||||
size = 64,
|
|
||||||
};
|
|
||||||
pushConstantRanges[1] = new VkPushConstantRange
|
|
||||||
{
|
|
||||||
stageFlags = VkShaderStageFlags.Fragment,
|
|
||||||
offset = 64,
|
|
||||||
size = 32,
|
|
||||||
};
|
|
||||||
pushConstantRanges[2] = new VkPushConstantRange
|
|
||||||
{
|
{
|
||||||
stageFlags = VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment,
|
stageFlags = VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment,
|
||||||
offset = 96,
|
offset = 0,
|
||||||
size = 64,
|
size = 160,
|
||||||
};
|
};
|
||||||
|
|
||||||
var descLayout = DescriptorSetLayout;
|
var descLayout = DescriptorSetLayout;
|
||||||
@@ -176,8 +163,8 @@ internal sealed unsafe class VulkanPipeline : IDisposable
|
|||||||
sType = VkStructureType.PipelineLayoutCreateInfo,
|
sType = VkStructureType.PipelineLayoutCreateInfo,
|
||||||
setLayoutCount = 1,
|
setLayoutCount = 1,
|
||||||
pSetLayouts = &descLayout,
|
pSetLayouts = &descLayout,
|
||||||
pushConstantRangeCount = 3,
|
pushConstantRangeCount = 1,
|
||||||
pPushConstantRanges = (nint)pushConstantRanges,
|
pPushConstantRanges = (nint)(&pushConstantRange),
|
||||||
};
|
};
|
||||||
|
|
||||||
fixed (VkPipelineLayout* layoutPtr = &PipelineLayout)
|
fixed (VkPipelineLayout* layoutPtr = &PipelineLayout)
|
||||||
|
|||||||
@@ -235,6 +235,22 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
|||||||
if (!dc.castShadow) continue;
|
if (!dc.castShadow) continue;
|
||||||
|
|
||||||
var vertexBuf = dc.vertexBuf;
|
var vertexBuf = dc.vertexBuf;
|
||||||
|
ulong offset = 0;
|
||||||
|
Vk.vkCmdBindVertexBuffers(cmd, 0, 1, &vertexBuf, &offset);
|
||||||
|
Vk.vkCmdBindIndexBuffer(cmd, dc.indexBuf, 0, 1);
|
||||||
|
|
||||||
|
// Pack all push constants for shadow pass
|
||||||
|
var pcData = stackalloc byte[160];
|
||||||
|
var modelCopy = dc.model;
|
||||||
|
System.Buffer.MemoryCopy(&modelCopy, pcData, 64, 64);
|
||||||
|
var lpCopy = lightPos;
|
||||||
|
System.Buffer.MemoryCopy(&lpCopy, pcData + 64, 16, 16);
|
||||||
|
var lcCopy = lightColor;
|
||||||
|
System.Buffer.MemoryCopy(&lcCopy, pcData + 80, 16, 16);
|
||||||
|
var lvpCopy = lightViewProj;
|
||||||
|
System.Buffer.MemoryCopy(&lvpCopy, pcData + 96, 64, 64);
|
||||||
|
|
||||||
|
Vk.vkCmdPushConstants(cmd, _shadowMap.PipelineLayout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, 0, 160, pcData);
|
||||||
|
|
||||||
Vk.vkCmdDrawIndexed(cmd, dc.indexCount, 1, 0, 0, 0);
|
Vk.vkCmdDrawIndexed(cmd, dc.indexCount, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@@ -332,18 +348,18 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
|||||||
Vk.vkCmdBindVertexBuffers(cmd, 0, 1, &vertexBuf, &offset);
|
Vk.vkCmdBindVertexBuffers(cmd, 0, 1, &vertexBuf, &offset);
|
||||||
Vk.vkCmdBindIndexBuffer(cmd, dc.indexBuf, 0, 1);
|
Vk.vkCmdBindIndexBuffer(cmd, dc.indexBuf, 0, 1);
|
||||||
|
|
||||||
var model = dc.model;
|
// Pack all push constants: model(64) + lightPos(16) + lightColor(16) + lightViewProj(64) = 160
|
||||||
Vk.vkCmdPushConstants(cmd, _pipeline.PipelineLayout, VkShaderStageFlags.Vertex, 0, 64, &model);
|
var pcData = stackalloc byte[160];
|
||||||
|
var modelCopy = dc.model;
|
||||||
// Light data as push constants at offset 64 (fragment stage)
|
System.Buffer.MemoryCopy(&modelCopy, pcData, 64, 64);
|
||||||
var lpCopy = lightPos;
|
var lpCopy = lightPos;
|
||||||
Vk.vkCmdPushConstants(cmd, _pipeline.PipelineLayout, VkShaderStageFlags.Fragment, 64, 16, &lpCopy);
|
System.Buffer.MemoryCopy(&lpCopy, pcData + 64, 16, 16);
|
||||||
var lcCopy = lightColor;
|
var lcCopy = lightColor;
|
||||||
Vk.vkCmdPushConstants(cmd, _pipeline.PipelineLayout, VkShaderStageFlags.Fragment, 80, 16, &lcCopy);
|
System.Buffer.MemoryCopy(&lcCopy, pcData + 80, 16, 16);
|
||||||
|
|
||||||
// Light view-proj at offset 96 (vertex + fragment)
|
|
||||||
var lvpCopy = lightViewProj;
|
var lvpCopy = lightViewProj;
|
||||||
Vk.vkCmdPushConstants(cmd, _pipeline.PipelineLayout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, 96, 64, &lvpCopy);
|
System.Buffer.MemoryCopy(&lvpCopy, pcData + 96, 64, 64);
|
||||||
|
|
||||||
|
Vk.vkCmdPushConstants(cmd, _pipeline.PipelineLayout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, 0, 160, pcData);
|
||||||
|
|
||||||
Vk.vkCmdDrawIndexed(cmd, dc.indexCount, 1, 0, 0, 0);
|
Vk.vkCmdDrawIndexed(cmd, dc.indexCount, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,16 +205,14 @@ internal sealed unsafe class VulkanShadowMap : IDisposable
|
|||||||
pDynamicStates = dynamicStates,
|
pDynamicStates = dynamicStates,
|
||||||
};
|
};
|
||||||
|
|
||||||
var pushConstantRanges = stackalloc VkPushConstantRange[2];
|
var pushConstantRange = new VkPushConstantRange { stageFlags = VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, offset = 0, size = 160 };
|
||||||
pushConstantRanges[0] = new VkPushConstantRange { stageFlags = VkShaderStageFlags.Vertex, offset = 0, size = 64 };
|
|
||||||
pushConstantRanges[1] = new VkPushConstantRange { stageFlags = VkShaderStageFlags.Fragment, offset = 64, size = 96 };
|
|
||||||
|
|
||||||
var layoutInfo = new VkPipelineLayoutCreateInfo
|
var layoutInfo = new VkPipelineLayoutCreateInfo
|
||||||
{
|
{
|
||||||
sType = VkStructureType.PipelineLayoutCreateInfo,
|
sType = VkStructureType.PipelineLayoutCreateInfo,
|
||||||
setLayoutCount = 0,
|
setLayoutCount = 0,
|
||||||
pushConstantRangeCount = 2,
|
pushConstantRangeCount = 1,
|
||||||
pPushConstantRanges = (nint)pushConstantRanges,
|
pPushConstantRanges = (nint)(&pushConstantRange),
|
||||||
};
|
};
|
||||||
|
|
||||||
var pl = VkPipelineLayout.Null;
|
var pl = VkPipelineLayout.Null;
|
||||||
|
|||||||
Reference in New Issue
Block a user