shader: use push constants and buffer device address

This commit is contained in:
Zack Buhman 2026-04-05 13:15:39 -05:00
parent a978c8a9e6
commit df24407d9d
2 changed files with 76 additions and 16 deletions

View File

@ -1,24 +1,44 @@
static const float2 positions[3] = {
float2(0.0, -0.5),
float2(0.5, 0.5),
float2(-0.5, 0.5)
struct VSInput
{
float3 Position : POSITION0;
float3 Normal : NORMAL0;
float3 Texture : TEXCOORD0;
};
struct VSOutput
{
float4 Pos : SV_POSITION;
float4 Position : SV_POSITION;
float3 Normal : NORMAL0;
};
struct ShaderData
{
float4x4 Projection;
float4x4 View;
float4x4 Model;
float4 lightPosition;
uint32_t selected;
};
struct PushConstant {
vk::BufferPointer<ShaderData> data;
};
[[vk::push_constant]]
struct PushConstant constants;
[shader("vertex")]
VSOutput VSMain(uint VertexIndex: SV_VertexID)
VSOutput VSMain(VSInput input)
{
VSOutput output = (VSOutput)0;
output.Pos = float4(positions[VertexIndex], 0.0, 1.0);
output.Position = mul(constants.data.Get().Projection, mul(constants.data.Get().View, mul(constants.data.Get().Model, float4(input.Position.xyz, 1.0))));
//output.Normal = mul((float3x3)constants.data.Get().Model, input.Normal);
output.Normal = input.Normal * 0.5 + 0.5;
return output;
}
[shader("pixel")]
float4 PSMain() : SV_TARGET
float4 PSMain(VSOutput input) : SV_TARGET
{
return float4(1.0, 0.0, 0.0, 1.0);
return float4(input.Normal, 1.0);
}

View File

@ -115,19 +115,22 @@ XMINT2 windowSize{};
struct ShaderData {
XMFLOAT4X4 projection;
XMFLOAT4X4 view;
XMFLOAT4X4 model[3];
XMFLOAT4 lightPos{ 0.0f, -10.0f, 10.0f, 0.0f };
XMFLOAT4X4 model;
//XMFLOAT4X4 model[3];
XMFLOAT4 lightPosition{ 0.0f, -10.0f, 10.0f, 0.0f };
uint32_t selected{ 1 };
} shaderData{};
struct ShaderDataBuffer {
VkBuffer buffer{ VK_NULL_HANDLE };
VkDeviceAddress deviceAddress{};
VkDeviceMemory memory;
void * mappedData;
};
ShaderDataBuffer shaderDataBuffers[maxFramesInFlight];
static void print_memoryPropertyFlags(VkMemoryPropertyFlags propertyFlags)
void print_memoryPropertyFlags(VkMemoryPropertyFlags propertyFlags)
{
int index = 0;
while (propertyFlags) {
@ -156,6 +159,33 @@ uint32_t findMemoryTypeIndex(VkPhysicalDeviceMemoryProperties const * memoryProp
UNREACHABLE();
}
XMMATRIX currentProjection()
{
float fov_angle_y = XMConvertToRadians(45 * 1.0);
float aspect_ratio = windowSize.x / windowSize.y;
float near_z = 0.1;
float far_z = 100.0;
XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z);
return projection;
}
XMMATRIX currentView()
{
XMVECTOR eye = XMVectorSet(0, -3, 0, 0);
XMVECTOR at = XMVectorSet(0, 0, 0, 0);
XMVECTOR up = XMVectorSet(0, 0, 1, 0);
XMMATRIX view = XMMatrixLookAtRH(eye, at, up);
return view;
}
float theta = 0;
XMMATRIX currentModel()
{
theta += 0.01;
return XMMatrixTranslation(0, 0, -0.5) * XMMatrixRotationX(theta);
}
int main()
{
SDL_CHECK(SDL_Init(SDL_INIT_VIDEO));
@ -465,7 +495,7 @@ int main()
for (uint32_t i = 0; i < maxFramesInFlight; i++) {
VkBufferCreateInfo shaderBufferCreateInfo{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = sizeof(ShaderData),
.size = (sizeof (ShaderData)),
.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
};
@ -498,6 +528,10 @@ int main()
.buffer = shaderDataBuffers[i].buffer
};
shaderDataBuffers[i].deviceAddress = vkGetBufferDeviceAddress(device, &shaderBufferDeviceAddressInfo);
void * mappedData;
VK_CHECK(vkMapMemory(device, shaderBufferMemory, 0, (sizeof (ShaderData)), 0, &mappedData));
shaderDataBuffers[i].memory = shaderBufferMemory;
shaderDataBuffers[i].mappedData = mappedData;
}
//////////////////////////////////////////////////////////////////////
@ -564,7 +598,7 @@ int main()
VkPushConstantRange pushConstantRange{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.size = sizeof(VkDeviceAddress)
.size = (sizeof (VkDeviceAddress))
};
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
@ -702,6 +736,12 @@ int main()
// acquire next image
VK_CHECK_SWAPCHAIN(vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, presentSemaphores[frameIndex], VK_NULL_HANDLE, &imageIndex));
// shader data
XMStoreFloat4x4(&shaderData.projection, currentProjection());
XMStoreFloat4x4(&shaderData.view, currentView());
XMStoreFloat4x4(&shaderData.model, currentModel());
memcpy(shaderDataBuffers[frameIndex].mappedData, &shaderData, (sizeof (ShaderData)));
// command buffer
VkCommandBuffer& commandBuffer = commandBuffers[frameIndex];
VK_CHECK(vkResetCommandBuffer(commandBuffer, 0));
@ -793,8 +833,8 @@ int main()
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexIndexBuffer, &vertexOffset);
VkDeviceSize indexOffset{ vtxBufferSize };
vkCmdBindIndexBuffer(commandBuffer, vertexIndexBuffer, indexOffset, VK_INDEX_TYPE_UINT32);
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VkDeviceAddress), &shaderDataBuffers[frameIndex].deviceAddress);
VkDeviceSize indexCount{ 3 };
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, (sizeof (VkDeviceAddress)), &shaderDataBuffers[frameIndex].deviceAddress);
VkDeviceSize indexCount{ 9216 };
vkCmdDrawIndexed(commandBuffer, indexCount, 3, 0, 0, 0);
vkCmdEndRendering(commandBuffer);