Mipmapping implemented.

This commit is contained in:
Anish Bhobe 2025-06-15 22:09:08 +02:00
parent 98c5f28146
commit 6da0250c81
5 changed files with 295 additions and 80 deletions

View File

@ -70,10 +70,14 @@ SDL_AppResult SDL_AppIterate( void* appstate )
SDL_SetWindowTitle( appState.window, appState.sprintfBuffer ); SDL_SetWindowTitle( appState.window, appState.sprintfBuffer );
} }
misc.cameraData.modelMatrix = DirectX::XMMatrixMultiply( for ( Transform& transform : misc.modelTransform )
misc.cameraData.modelMatrix, {
DirectX::XMMatrixRotationY( DirectX::XMConvertToRadians( 60.0f ) * static_cast<float>( deltaTime ) ) ); transform.rotation = DirectX::XMQuaternionMultiply(
memcpy( misc.cameraUniformBufferPtr, &misc.cameraData, sizeof misc.cameraData ); DirectX::XMQuaternionRotationAxis(
DirectX::XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ),
DirectX::XMConvertToRadians( 60.0f ) * static_cast<float>( deltaTime ) ),
transform.rotation );
}
uint32_t currentImageIndex; uint32_t currentImageIndex;
VK_CHECK( vkAcquireNextImageKHR( VK_CHECK( vkAcquireNextImageKHR(
@ -155,7 +159,20 @@ SDL_AppResult SDL_AppIterate( void* appstate )
vkCmdBindVertexBuffers( cmd, 0, 1, &misc.vertexBuffer, &offset ); vkCmdBindVertexBuffers( cmd, 0, 1, &misc.vertexBuffer, &offset );
vkCmdBindDescriptorSets( vkCmdBindDescriptorSets(
cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.pipelineLayout, 0, 1, &misc.descriptorSet, 0, nullptr ); cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, misc.pipelineLayout, 0, 1, &misc.descriptorSet, 0, nullptr );
vkCmdDraw( cmd, static_cast<uint32_t>( misc.vertices.size() ), 1, 0, 0 ); for ( Transform& localTransform : misc.modelTransform )
{
DirectX::XMMATRIX worldTransform;
{
auto [x, y, z] = localTransform.position;
auto scale = localTransform.scale;
worldTransform = DirectX::XMMatrixScaling( scale, scale, scale ) *
DirectX::XMMatrixRotationQuaternion( localTransform.rotation ) *
DirectX::XMMatrixTranslation( x, y, z );
}
vkCmdPushConstants(
cmd, misc.pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, sizeof worldTransform, &worldTransform );
vkCmdDraw( cmd, static_cast<uint32_t>( misc.vertices.size() ), 1, 0, 0 );
}
} }
vkCmdEndRendering( cmd ); vkCmdEndRendering( cmd );
vkCmdPipelineBarrier2( cmd, &misc.renderToPresentDependency ); vkCmdPipelineBarrier2( cmd, &misc.renderToPresentDependency );

View File

@ -103,13 +103,13 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel> <WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<RuntimeTypeInfo>false</RuntimeTypeInfo> <RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>false</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ExceptionHandling>Sync</ExceptionHandling> <ExceptionHandling>Sync</ExceptionHandling>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
@ -124,7 +124,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<WarningLevel>EnableAllWarnings</WarningLevel> <WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
@ -132,7 +132,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<RuntimeTypeInfo>false</RuntimeTypeInfo> <RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>false</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<ExceptionHandling>/EH-</ExceptionHandling> <ExceptionHandling>/EH-</ExceptionHandling>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>

View File

@ -1,12 +1,12 @@
struct VertexOut { struct VertexOut {
float4 outPosition : SV_Position; float4 outPosition : SV_Position;
float4 screenPosition : ScreenPosition;
float4 vertexColor : CoarseColor; float4 vertexColor : CoarseColor;
float2 texCoord0 : TexCoord0; float2 texCoord0 : TexCoord0;
}; };
struct CameraData { struct CameraData {
float4x4 model;
float4x4 view; float4x4 view;
float4x4 proj; float4x4 proj;
}; };
@ -18,6 +18,13 @@ struct PerFrameData {
ParameterBlock<PerFrameData> perFrameData; ParameterBlock<PerFrameData> perFrameData;
struct PerInstanceData {
float4x4 transform;
}
[[vk::push_constant]]
uniform ConstantBuffer<PerInstanceData> pcb;
[shader("vertex")] [shader("vertex")]
VertexOut VertexMain( VertexOut VertexMain(
uint vertexId: SV_VertexID, uint vertexId: SV_VertexID,
@ -26,7 +33,8 @@ VertexOut VertexMain(
float2 texCoord0, float2 texCoord0,
) { ) {
VertexOut output; VertexOut output;
output.outPosition = mul(perFrameData.camera.proj, mul(perFrameData.camera.view, mul(perFrameData.camera.model, float4(position, 1.0f)))); output.outPosition = mul(perFrameData.camera.proj, mul(perFrameData.camera.view, mul(pcb.transform, float4(position, 1.0f))));
output.screenPosition = mul(perFrameData.camera.proj, mul(perFrameData.camera.view, mul(pcb.transform, float4(position, 1.0f))));
output.vertexColor = float4(color, 1.0f); output.vertexColor = float4(color, 1.0f);
output.texCoord0 = texCoord0 * 2.0f; output.texCoord0 = texCoord0 * 2.0f;
return output; return output;
@ -34,9 +42,16 @@ VertexOut VertexMain(
[shader("fragment")] [shader("fragment")]
float4 FragmentMain( float4 FragmentMain(
float4 interpolatePosition : ScreenPosition,
float4 interpolatedColors : CoarseColor, float4 interpolatedColors : CoarseColor,
float2 uv0 : TexCoord0, float2 uv0 : TexCoord0,
) : SV_Target0 { ) : SV_Target0 {
return float4(perFrameData.texture.Sample(uv0).rgb, 1.0f) * interpolatedColors; float4 outColor;
if (interpolatePosition.x < 0) {
outColor = float4(perFrameData.texture.SampleLevel(uv0, 0).rgb, 1.0f) * interpolatedColors;
} else {
outColor = float4(perFrameData.texture.Sample(uv0).rgb, 1.0f) * interpolatedColors;
}
return outColor;
} }

View File

@ -67,14 +67,20 @@ bool MiscData::init( RenderDevice const& renderDevice )
}; };
VK_CHECK( vkCreateDescriptorSetLayout( device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout ) ); VK_CHECK( vkCreateDescriptorSetLayout( device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayout ) );
VkPushConstantRange const pushConstantRange = {
.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS,
.offset = 0,
.size = sizeof( DirectX::XMMATRIX ),
};
VkPipelineLayoutCreateInfo const pipelineLayoutCreateInfo = { VkPipelineLayoutCreateInfo const pipelineLayoutCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.setLayoutCount = 1, .setLayoutCount = 1,
.pSetLayouts = &descriptorSetLayout, .pSetLayouts = &descriptorSetLayout,
.pushConstantRangeCount = 0, .pushConstantRangeCount = 1,
.pPushConstantRanges = nullptr, .pPushConstantRanges = &pushConstantRange,
}; };
VK_CHECK( vkCreatePipelineLayout( device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout ) ); VK_CHECK( vkCreatePipelineLayout( device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout ) );
@ -228,7 +234,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }, .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
}; };
std::array constexpr dynamicStates{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; std::array constexpr dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VkPipelineDynamicStateCreateInfo const dynamicStateCreateInfo = { VkPipelineDynamicStateCreateInfo const dynamicStateCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
@ -378,19 +384,23 @@ bool MiscData::init( RenderDevice const& renderDevice )
height = static_cast<uint32_t>( h ); height = static_cast<uint32_t>( h );
} }
// Calculate mips
uint32_t mipLevels =
1 + static_cast<uint32_t>( floorf( log2f( static_cast<float>( std::max( width, height ) ) ) ) );
VkImageCreateInfo const imageCreateInfo = { VkImageCreateInfo const imageCreateInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = 0,
.imageType = VK_IMAGE_TYPE_2D, .imageType = VK_IMAGE_TYPE_2D,
.format = VK_FORMAT_R8G8B8A8_SRGB, .format = VK_FORMAT_R8G8B8A8_SRGB,
.extent = { .width = width, .height = height, .depth = 1 }, .extent = { .width = width, .height = height, .depth = 1 },
.mipLevels = 1, .mipLevels = mipLevels,
.arrayLayers = 1, .arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL, .tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0, .queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr, .pQueueFamilyIndices = nullptr,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
@ -410,10 +420,10 @@ bool MiscData::init( RenderDevice const& renderDevice )
VK_CHECK( vmaCreateImage( VK_CHECK( vmaCreateImage(
renderDevice.gpuAllocator, &imageCreateInfo, &allocationCreateInfo, &texture, &textureAllocation, nullptr ) ); renderDevice.gpuAllocator, &imageCreateInfo, &allocationCreateInfo, &texture, &textureAllocation, nullptr ) );
VkImageSubresourceRange constexpr subresourceRange = { VkImageSubresourceRange const subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = 1, .levelCount = mipLevels,
.baseArrayLayer = 0, .baseArrayLayer = 0,
.layerCount = 1, .layerCount = 1,
}; };
@ -454,7 +464,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.compareEnable = false, .compareEnable = false,
.compareOp = VK_COMPARE_OP_NEVER, .compareOp = VK_COMPARE_OP_NEVER,
.minLod = 0.0f, .minLod = 0.0f,
.maxLod = 0.0f, .maxLod = VK_LOD_CLAMP_NONE,
.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
.unnormalizedCoordinates = false, .unnormalizedCoordinates = false,
}; };
@ -506,6 +516,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
// All data is copied to stagingBuffer, don't need this. // All data is copied to stagingBuffer, don't need this.
stbi_image_free( textureData ); stbi_image_free( textureData );
// Staging -> Texture transfer
{ {
Frame& frameInUse = renderDevice.frames[0]; Frame& frameInUse = renderDevice.frames[0];
@ -547,19 +558,48 @@ bool MiscData::init( RenderDevice const& renderDevice )
.pImageMemoryBarriers = &creationToTransferImageBarrier, .pImageMemoryBarriers = &creationToTransferImageBarrier,
}; };
VkImageMemoryBarrier2 const transferToReadyImageBarrier = { std::array transferToReadyImageBarriers{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, // transferToReadyImageBarrier
.pNext = nullptr, VkImageMemoryBarrier2{
.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT, .pNext = nullptr,
.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, .srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT, .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, .dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
.image = texture, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.subresourceRange = subresourceRange, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = texture,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = mipLevels-1,
.baseArrayLayer = 0,
.layerCount = 1,
},
},
VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = texture,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = mipLevels-1,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
}
}; };
VkDependencyInfo const transferToReadyDependency = { VkDependencyInfo const transferToReadyDependency = {
@ -570,10 +610,64 @@ bool MiscData::init( RenderDevice const& renderDevice )
.pMemoryBarriers = nullptr, .pMemoryBarriers = nullptr,
.bufferMemoryBarrierCount = 0, .bufferMemoryBarrierCount = 0,
.pBufferMemoryBarriers = nullptr, .pBufferMemoryBarriers = nullptr,
.imageMemoryBarrierCount = 1, .imageMemoryBarrierCount = static_cast<uint32_t>( transferToReadyImageBarriers.size() ),
.pImageMemoryBarriers = &transferToReadyImageBarrier, .pImageMemoryBarriers = transferToReadyImageBarriers.data(),
}; };
VkImageSubresourceRange const mipLevelSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
};
std::array prepareNextMipLevelBarriers{
// prepareNextMipLevelSrcImageBarrier
VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT,
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = texture,
.subresourceRange = mipLevelSubresource,
},
// prepareNextMipLevelDstImageBarrier
VkImageMemoryBarrier2{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr,
.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT,
.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_2_BLIT_BIT,
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = texture,
.subresourceRange = mipLevelSubresource,
}
};
VkDependencyInfo const prepareNextMipLevelDependency = {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
.pNext = nullptr,
.dependencyFlags = 0,
.memoryBarrierCount = 0,
.pMemoryBarriers = nullptr,
.bufferMemoryBarrierCount = 0,
.pBufferMemoryBarriers = nullptr,
.imageMemoryBarrierCount = static_cast<uint32_t>( prepareNextMipLevelBarriers.size() ),
.pImageMemoryBarriers = prepareNextMipLevelBarriers.data(),
};
vkBeginCommandBuffer( frameInUse.commandBuffer, &beginInfo ); vkBeginCommandBuffer( frameInUse.commandBuffer, &beginInfo );
{ {
VkImageSubresourceLayers imageSubresourceLayers = { VkImageSubresourceLayers imageSubresourceLayers = {
@ -593,11 +687,82 @@ bool MiscData::init( RenderDevice const& renderDevice )
.imageExtent = imageCreateInfo.extent .imageExtent = imageCreateInfo.extent
}; };
// Start
vkCmdPipelineBarrier2( frameInUse.commandBuffer, &creationToTransferDependency ); vkCmdPipelineBarrier2( frameInUse.commandBuffer, &creationToTransferDependency );
// Staging -> Image L0
vkCmdCopyBufferToImage( vkCmdCopyBufferToImage(
frameInUse.commandBuffer, stagingBuffer, texture, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copyRegion ); frameInUse.commandBuffer, stagingBuffer, texture, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copyRegion );
prepareNextMipLevelBarriers[0].subresourceRange.baseMipLevel = 0;
prepareNextMipLevelBarriers[1].subresourceRange.baseMipLevel = 1;
int32_t mipSrcWidth = static_cast<int32_t>( width );
int32_t mipSrcHeight = static_cast<int32_t>( height );
int32_t mipDstWidth = std::max( mipSrcWidth / 2, 1 );
int32_t mipDstHeight = std::max( mipSrcHeight / 2, 1 );
VkImageSubresourceLayers constexpr mipSubresourceLayers = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
};
VkImageBlit2 imageBlit = {
.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
.pNext = nullptr,
.srcSubresource = mipSubresourceLayers,
.srcOffsets = { { 0, 0, 0 }, { mipSrcWidth, mipSrcHeight, 1 } },
.dstSubresource = mipSubresourceLayers,
.dstOffsets = { { 0, 0, 0 }, { mipDstWidth, mipDstHeight, 1 } },
};
imageBlit.srcSubresource.mipLevel = 0;
imageBlit.dstSubresource.mipLevel = 1;
imageBlit.srcOffsets[1].x = mipSrcWidth;
imageBlit.srcOffsets[1].y = mipSrcHeight;
imageBlit.dstOffsets[1].x = mipDstWidth;
imageBlit.dstOffsets[1].y = mipDstHeight;
VkBlitImageInfo2 blitInfo = {
.sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2,
.pNext = nullptr,
.srcImage = texture,
.srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.dstImage = texture,
.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.regionCount = 1,
.pRegions = &imageBlit,
.filter = VK_FILTER_LINEAR,
};
// MipMapping
for ( uint32_t dstMipLevel = 1; dstMipLevel < mipLevels; ++dstMipLevel )
{
vkCmdPipelineBarrier2( frameInUse.commandBuffer, &prepareNextMipLevelDependency );
vkCmdBlitImage2( frameInUse.commandBuffer, &blitInfo );
// Prep for NEXT iteration
mipSrcWidth = mipDstWidth;
mipSrcHeight = mipDstHeight;
mipDstWidth = std::max( mipSrcWidth / 2, 1 );
mipDstHeight = std::max( mipSrcHeight / 2, 1 );
imageBlit.srcSubresource.mipLevel = dstMipLevel;
imageBlit.dstSubresource.mipLevel = dstMipLevel + 1;
imageBlit.srcOffsets[1].x = mipSrcWidth;
imageBlit.srcOffsets[1].y = mipSrcHeight;
imageBlit.dstOffsets[1].x = mipDstWidth;
imageBlit.dstOffsets[1].y = mipDstHeight;
// Prep current mip level as source
prepareNextMipLevelBarriers[0].subresourceRange.baseMipLevel = dstMipLevel;
prepareNextMipLevelBarriers[1].subresourceRange.baseMipLevel = dstMipLevel + 1;
}
// End
vkCmdPipelineBarrier2( frameInUse.commandBuffer, &transferToReadyDependency ); vkCmdPipelineBarrier2( frameInUse.commandBuffer, &transferToReadyDependency );
} }
vkEndCommandBuffer( frameInUse.commandBuffer ); vkEndCommandBuffer( frameInUse.commandBuffer );
@ -622,13 +787,23 @@ bool MiscData::init( RenderDevice const& renderDevice )
vmaDestroyBuffer( renderDevice.gpuAllocator, stagingBuffer, stagingAllocation ); vmaDestroyBuffer( renderDevice.gpuAllocator, stagingBuffer, stagingAllocation );
} }
// Model Setup
modelTransform[0].position = { 1.0f, 0.0f, 0.0f };
modelTransform[0].scale = 1.0f;
modelTransform[0].rotation =
DirectX::XMQuaternionRotationAxis( DirectX::XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ), 0.0f );
modelTransform[1].position = { -1.0f, 0.0f, 0.0f };
modelTransform[1].scale = 1.0f;
modelTransform[1].rotation =
DirectX::XMQuaternionRotationAxis( DirectX::XMVectorSet( 1.0f, 0.0f, 0.0f, 0.0f ), 0.0f );
// Camera // Camera
{ {
cameraPosition = DirectX::XMVectorSet( 0.0f, 0.0f, -5.0f, 1.0f ); cameraPosition = DirectX::XMVectorSet( 0.0f, 0.0f, -4.0f, 1.0f );
cameraTarget = DirectX::XMVectorSet( 0.0f, 0.0f, 0.0f, 1.0f ); cameraTarget = DirectX::XMVectorSet( 0.0f, 0.0f, 0.0f, 1.0f );
cameraUp = DirectX::XMVectorSet( 0.0f, 1.0f, 0.0f, 1.0f ); cameraUp = DirectX::XMVectorSet( 0.0f, 1.0f, 0.0f, 1.0f );
cameraData.modelMatrix = DirectX::XMMatrixIdentity(); cameraData.viewMatrix = DirectX::XMMatrixLookAtLH( cameraPosition, cameraTarget, cameraUp );
cameraData.viewMatrix = DirectX::XMMatrixLookAtLH( cameraPosition, cameraTarget, cameraUp );
cameraData.projectionMatrix = cameraData.projectionMatrix =
DirectX::XMMatrixPerspectiveFovLH( DirectX::XMConvertToRadians( 70.0f ), 16.0f / 9.0f, 0.1f, 1000.0f ); DirectX::XMMatrixPerspectiveFovLH( DirectX::XMConvertToRadians( 70.0f ), 16.0f / 9.0f, 0.1f, 1000.0f );

View File

@ -17,49 +17,57 @@ struct Vertex
DirectX::XMFLOAT2 texCoord0; DirectX::XMFLOAT2 texCoord0;
}; };
struct Transform
{
DirectX::XMFLOAT3 position;
float scale;
DirectX::XMVECTOR rotation;
};
struct MiscData struct MiscData
{ {
struct CameraData struct CameraData
{ {
DirectX::XMMATRIX modelMatrix;
DirectX::XMMATRIX viewMatrix; DirectX::XMMATRIX viewMatrix;
DirectX::XMMATRIX projectionMatrix; DirectX::XMMATRIX projectionMatrix;
}; };
uint64_t previousCounter; uint64_t previousCounter;
VkDescriptorSetLayout descriptorSetLayout; VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
VkPipeline meshPipeline; VkPipeline meshPipeline;
VkBuffer vertexBuffer; VkBuffer vertexBuffer;
VmaAllocation vertexBufferAllocation; VmaAllocation vertexBufferAllocation;
size_t vertexBufferSize; size_t vertexBufferSize;
std::array<Vertex, 4> vertices; std::array<Vertex, 4> vertices;
VkImage texture; VkImage texture;
VmaAllocation textureAllocation; VmaAllocation textureAllocation;
VkImageView textureView; VkImageView textureView;
VkSampler sampler; VkSampler sampler;
uint64_t _padding; // TODO: Optimize out? uint64_t _padding; // TODO: Optimize out?
DirectX::XMVECTOR cameraPosition; std::array<Transform, 2> modelTransform;
DirectX::XMVECTOR cameraTarget;
DirectX::XMVECTOR cameraUp;
CameraData cameraData;
VkBuffer cameraUniformBuffer;
VmaAllocation cameraUniformBufferAllocation;
size_t cameraUniformBufferSize;
uint8_t* cameraUniformBufferPtr;
VkDescriptorPool descriptorPool;
VkDescriptorSet descriptorSet;
VkImageMemoryBarrier2 acquireToRenderBarrier; DirectX::XMVECTOR cameraPosition;
VkDependencyInfo acquireToRenderDependency; DirectX::XMVECTOR cameraTarget;
VkImageMemoryBarrier2 renderToPresentBarrier; DirectX::XMVECTOR cameraUp;
VkDependencyInfo renderToPresentDependency; CameraData cameraData;
VkBuffer cameraUniformBuffer;
VmaAllocation cameraUniformBufferAllocation;
size_t cameraUniformBufferSize;
uint8_t* cameraUniformBufferPtr;
VkDescriptorPool descriptorPool;
VkDescriptorSet descriptorSet;
bool init( RenderDevice const& renderDevice ); VkImageMemoryBarrier2 acquireToRenderBarrier;
void destroy( RenderDevice const& renderDevice ); VkDependencyInfo acquireToRenderDependency;
VkImageMemoryBarrier2 renderToPresentBarrier;
VkDependencyInfo renderToPresentDependency;
bool init( RenderDevice const& renderDevice );
void destroy( RenderDevice const& renderDevice );
}; };