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] = { struct VSInput
float2(0.0, -0.5), {
float2(0.5, 0.5), float3 Position : POSITION0;
float2(-0.5, 0.5) float3 Normal : NORMAL0;
float3 Texture : TEXCOORD0;
}; };
struct VSOutput 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")] [shader("vertex")]
VSOutput VSMain(uint VertexIndex: SV_VertexID) VSOutput VSMain(VSInput input)
{ {
VSOutput output = (VSOutput)0; 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; return output;
} }
[shader("pixel")] [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 { struct ShaderData {
XMFLOAT4X4 projection; XMFLOAT4X4 projection;
XMFLOAT4X4 view; XMFLOAT4X4 view;
XMFLOAT4X4 model[3]; XMFLOAT4X4 model;
XMFLOAT4 lightPos{ 0.0f, -10.0f, 10.0f, 0.0f }; //XMFLOAT4X4 model[3];
XMFLOAT4 lightPosition{ 0.0f, -10.0f, 10.0f, 0.0f };
uint32_t selected{ 1 }; uint32_t selected{ 1 };
} shaderData{}; } shaderData{};
struct ShaderDataBuffer { struct ShaderDataBuffer {
VkBuffer buffer{ VK_NULL_HANDLE }; VkBuffer buffer{ VK_NULL_HANDLE };
VkDeviceAddress deviceAddress{}; VkDeviceAddress deviceAddress{};
VkDeviceMemory memory;
void * mappedData;
}; };
ShaderDataBuffer shaderDataBuffers[maxFramesInFlight]; ShaderDataBuffer shaderDataBuffers[maxFramesInFlight];
static void print_memoryPropertyFlags(VkMemoryPropertyFlags propertyFlags) void print_memoryPropertyFlags(VkMemoryPropertyFlags propertyFlags)
{ {
int index = 0; int index = 0;
while (propertyFlags) { while (propertyFlags) {
@ -156,6 +159,33 @@ uint32_t findMemoryTypeIndex(VkPhysicalDeviceMemoryProperties const * memoryProp
UNREACHABLE(); 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() int main()
{ {
SDL_CHECK(SDL_Init(SDL_INIT_VIDEO)); SDL_CHECK(SDL_Init(SDL_INIT_VIDEO));
@ -465,7 +495,7 @@ int main()
for (uint32_t i = 0; i < maxFramesInFlight; i++) { for (uint32_t i = 0; i < maxFramesInFlight; i++) {
VkBufferCreateInfo shaderBufferCreateInfo{ VkBufferCreateInfo shaderBufferCreateInfo{
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = sizeof(ShaderData), .size = (sizeof (ShaderData)),
.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, .usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE .sharingMode = VK_SHARING_MODE_EXCLUSIVE
}; };
@ -498,6 +528,10 @@ int main()
.buffer = shaderDataBuffers[i].buffer .buffer = shaderDataBuffers[i].buffer
}; };
shaderDataBuffers[i].deviceAddress = vkGetBufferDeviceAddress(device, &shaderBufferDeviceAddressInfo); 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{ VkPushConstantRange pushConstantRange{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT, .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.size = sizeof(VkDeviceAddress) .size = (sizeof (VkDeviceAddress))
}; };
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{ VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
@ -702,6 +736,12 @@ int main()
// acquire next image // acquire next image
VK_CHECK_SWAPCHAIN(vkAcquireNextImageKHR(device, swapchain, UINT64_MAX, presentSemaphores[frameIndex], VK_NULL_HANDLE, &imageIndex)); 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 // command buffer
VkCommandBuffer& commandBuffer = commandBuffers[frameIndex]; VkCommandBuffer& commandBuffer = commandBuffers[frameIndex];
VK_CHECK(vkResetCommandBuffer(commandBuffer, 0)); VK_CHECK(vkResetCommandBuffer(commandBuffer, 0));
@ -793,8 +833,8 @@ int main()
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexIndexBuffer, &vertexOffset); vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexIndexBuffer, &vertexOffset);
VkDeviceSize indexOffset{ vtxBufferSize }; VkDeviceSize indexOffset{ vtxBufferSize };
vkCmdBindIndexBuffer(commandBuffer, vertexIndexBuffer, indexOffset, VK_INDEX_TYPE_UINT32); vkCmdBindIndexBuffer(commandBuffer, vertexIndexBuffer, indexOffset, VK_INDEX_TYPE_UINT32);
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VkDeviceAddress), &shaderDataBuffers[frameIndex].deviceAddress); vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, (sizeof (VkDeviceAddress)), &shaderDataBuffers[frameIndex].deviceAddress);
VkDeviceSize indexCount{ 3 }; VkDeviceSize indexCount{ 9216 };
vkCmdDrawIndexed(commandBuffer, indexCount, 3, 0, 0, 0); vkCmdDrawIndexed(commandBuffer, indexCount, 3, 0, 0, 0);
vkCmdEndRendering(commandBuffer); vkCmdEndRendering(commandBuffer);