Use buffer device address.

This commit is contained in:
Anish Bhobe 2025-06-28 15:44:28 +02:00
parent 9a2a6a3340
commit 00d5e1476c
9 changed files with 285 additions and 51 deletions

View File

@ -2,8 +2,8 @@ import Bindless;
struct VertexOut { struct VertexOut {
float4 outPosition : SV_Position; float4 outPosition : SV_Position;
float4 screenPosition : ScreenPosition; float4 worldPosition : WorldPosition;
float4 normal : CoarseNormal; float4 normal : WorldNormal;
float2 texCoord0 : TexCoord0; float2 texCoord0 : TexCoord0;
float2 texCoord1 : TexCoord1; float2 texCoord1 : TexCoord1;
float4 vertexColor0 : VertexColor; float4 vertexColor0 : VertexColor;
@ -12,9 +12,46 @@ struct VertexOut {
struct CameraData { struct CameraData {
float4x4 view; float4x4 view;
float4x4 proj; float4x4 proj;
float4 position;
}; };
uniform ParameterBlock<CameraData> camera; struct PointLight {
float3 position;
float range;
float3 color;
float attenuation;
};
struct DirectionalLight {
float3 direction;
float _padding0;
float3 color;
float _padding1;
};
struct LightData {
PointLight* pointLights;
DirectionalLight* dirLights;
uint pointLightCount;
uint dirLightCount;
PointLight getPointLight(uint idx) {
if (idx >= pointLightCount) return pointLights[0];
return pointLights[idx];
}
DirectionalLight getDirectionalLight(uint idx) {
if (idx >= dirLightCount) return dirLights[0];
return dirLights[idx];
}
};
struct PerFrameData {
CameraData camera;
LightData lightData;
};
uniform ParameterBlock<PerFrameData> pfd;
struct PerInstanceData { struct PerInstanceData {
float4x4 transform; float4x4 transform;
@ -37,9 +74,11 @@ VertexOut VertexMain(
float2 texCoord1, float2 texCoord1,
float4 vertexColor0, float4 vertexColor0,
) { ) {
float4 worldPosition = mul(pcb.transform, float4(position, 1.0f));
VertexOut output; VertexOut output;
output.outPosition = mul(camera.proj, mul(camera.view, mul(pcb.transform, float4(position, 1.0f)))); output.outPosition = mul(pfd.camera.proj, mul(pfd.camera.view, worldPosition));
output.screenPosition = mul(camera.proj, mul(camera.view, mul(pcb.transform, float4(position, 1.0f)))); output.worldPosition = worldPosition;
output.normal = mul(pcb.transform, float4(normalize(normal.rgb), 0.0f)); output.normal = mul(pcb.transform, float4(normalize(normal.rgb), 0.0f));
output.texCoord0 = texCoord0; output.texCoord0 = texCoord0;
output.texCoord1 = texCoord1; output.texCoord1 = texCoord1;
@ -49,20 +88,40 @@ VertexOut VertexMain(
[shader("fragment")] [shader("fragment")]
float4 FragmentMain( float4 FragmentMain(
float4 interpolatePosition : ScreenPosition, float4 worldPosition : WorldPosition,
float4 interpolatedNormal : CoarseNormal, float4 normal : WorldNormal,
float2 uv0 : TexCoord0, float2 uv0 : TexCoord0,
float2 uv1 : TexCoord1, float2 uv1 : TexCoord1,
float4 interpolatedColor : VertexColor, float4 color : VertexColor,
) : SV_Target0 { ) : SV_Target0 {
let N = interpolatedNormal.xyz; float3 diffuse = 0.0f.xxx;
let L = dot(normalize(N), float3(1.0f, 1.0f, -1.0f)); float3 specular = 0.0f.xxx;
for (uint i = 0; i < pfd.lightData.pointLightCount; ++i) {
PointLight pointlight = pfd.lightData.pointLights[i];
let lightPosition = pointlight.position;
let lightDisplace = worldPosition.xyz - lightPosition;
let lightDistance = length(lightDisplace);
let lightDirection = normalize(lightDisplace);
let viewDirection = normalize(worldPosition.xyz - pfd.camera.position.xyz);
let halfWayVector = normalize(-lightDirection + viewDirection);
let attenuation = (1.0f / lightDistance);
let diffuseFactor = pcb.roughness * dot(-lightDirection, normalize(normal.xyz));
diffuse += pointlight.color * diffuseFactor;
let specularFactor = (1.0f - pcb.roughness) * pow(max(dot(halfWayVector, viewDirection), 0.0f), 32.0f) * attenuation;
specular += pointlight.color * specularFactor;
}
if (let texture = pcb.textureID) { if (let texture = pcb.textureID) {
return float4(texture.Sample(uv0).rgb, 1.0f) * pcb.baseColor * interpolatedColor * L; return float4(texture.Sample(uv0).rgb, 1.0f) * pcb.baseColor * color * float4((diffuse + specular), 0.0f);
} else { } else {
return pcb.baseColor * interpolatedColor * L; return pcb.baseColor * color * float4((diffuse + specular), 0.0f);
} }
} }

View File

@ -119,7 +119,7 @@
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\Eon\source\repos\Blaze\vcpkg_installed\x64-windows\x64-windows\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -144,7 +144,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\Eon\source\repos\Blaze\vcpkg_installed\x64-windows\x64-windows\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -50,6 +50,37 @@ SDL_AppResult SDL_AppInit( void** appstate, int, char** )
LoadModel( appState.renderDevice, appState.entityManager, "Assets/Models/OrientationTest.glb" ); LoadModel( appState.renderDevice, appState.entityManager, "Assets/Models/OrientationTest.glb" );
ASSERT( entity ); ASSERT( entity );
std::array pointLight = {
MiscData::PointLight{
.position = { 12.0f, 0.0f, 0.0f },
.range = 12,
.color = { 1.0f, 0.0f, 0.0f },
.attenuation = 1.0f,
},
MiscData::PointLight{
.position = { 0.0f, 12.0f, 0.0f },
.range = 12,
.color = { 0.0f, 1.0f, 0.0f },
.attenuation = 1.0f,
},
MiscData::PointLight{
.position = { 0.0f, 0.0f, -12.0f },
.range = 6,
.color = { 0.0f, 0.0f, 1.0f },
.attenuation = 1.0f,
},
};
appState.miscData->lightData.pointLightCount = static_cast<uint32_t>( pointLight.size() );
appState.renderDevice->bufferManager->writeToBuffer(
appState.miscData->pointLights, std::span{ pointLight.begin(), pointLight.end() } );
memcpy(
appState.miscData->cameraUniformBufferPtr + sizeof( MiscData::CameraData ),
&appState.miscData->lightData,
sizeof appState.miscData->lightData );
return SDL_APP_CONTINUE; return SDL_APP_CONTINUE;
} }
@ -260,7 +291,6 @@ SDL_AppResult SDL_AppIterate( void* appstate )
materialData ); materialData );
vkCmdDrawIndexed( cmd, primitive.indexCount, 1, primitive.indexStart, primitive.vertexOffset, 0 ); vkCmdDrawIndexed( cmd, primitive.indexCount, 1, primitive.indexStart, primitive.vertexOffset, 0 );
// vkCmdDrawIndexed( cmd, primitive.count, 1, primitive.start, 0 );
} }
} }

View File

@ -46,7 +46,7 @@ void BufferManager::writeToBufferImpl( BufferID const& rid, void const* data, si
Buffer const& buffer = fetchBufferUnchecked( rid ); Buffer const& buffer = fetchBufferUnchecked( rid );
ASSERT( buffer.size <= size ); ASSERT( size <= buffer.size );
memcpy( buffer.mappedData, data, size ); memcpy( buffer.mappedData, data, size );
} }
@ -115,6 +115,7 @@ std::optional<BufferID> BufferManager::createVertexBuffer( size_t const size )
.buffer = vertexBuffer, .buffer = vertexBuffer,
.allocation = vertexBufferAllocation, .allocation = vertexBufferAllocation,
.mappedData = static_cast<std::byte*>( allocationInfo.pMappedData ), .mappedData = static_cast<std::byte*>( allocationInfo.pMappedData ),
.deviceAddress = 0,
.size = size, .size = size,
.index = index, .index = index,
}; };
@ -177,6 +178,78 @@ std::optional<BufferID> BufferManager::createIndexBuffer( size_t size )
.buffer = indexBuffer, .buffer = indexBuffer,
.allocation = indexBufferAllocation, .allocation = indexBufferAllocation,
.mappedData = static_cast<std::byte*>( allocationInfo.pMappedData ), .mappedData = static_cast<std::byte*>( allocationInfo.pMappedData ),
.deviceAddress = 0,
.size = size,
.index = index,
};
// NOTE: Memory hackery to create BufferID;
return std::move( *reinterpret_cast<BufferID*>( &index ) );
}
std::optional<BufferID> BufferManager::createStorageBuffer( size_t size )
{
if ( m_freeList.empty() )
{
return std::nullopt;
}
Buffer* bufferSlot = reinterpret_cast<Buffer*>( m_freeList.popFront() );
++m_count;
ASSERT( m_pRenderDevice );
RenderDevice const& renderDevice = *m_pRenderDevice;
VkBufferCreateInfo const bufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = size,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = nullptr,
};
VmaAllocationCreateInfo constexpr allocationCreateInfo = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.preferredFlags = 0,
.memoryTypeBits = 0,
.pool = nullptr,
.pUserData = nullptr,
.priority = 1.0f,
};
VmaAllocationInfo allocationInfo;
VkBuffer storageBuffer;
VmaAllocation storageBufferAllocation;
VK_CHECK( vmaCreateBuffer(
renderDevice.gpuAllocator,
&bufferCreateInfo,
&allocationCreateInfo,
&storageBuffer,
&storageBufferAllocation,
&allocationInfo ) );
VkBufferDeviceAddressInfo const deviceAddressInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.pNext = nullptr,
.buffer = storageBuffer,
};
VkDeviceAddress const deviceAddress = vkGetBufferDeviceAddress( renderDevice.device, &deviceAddressInfo );
// NOTE: bufferSlot preserves index between uses.
uint32_t index = bufferSlot->index;
new ( bufferSlot ) Buffer{
.buffer = storageBuffer,
.allocation = storageBufferAllocation,
.mappedData = static_cast<std::byte*>( allocationInfo.pMappedData ),
.deviceAddress = deviceAddress,
.size = size, .size = size,
.index = index, .index = index,
}; };
@ -203,6 +276,16 @@ std::optional<VkBuffer> BufferManager::fetchBuffer( BufferID const& rid )
return fetchBufferUnchecked( rid ).buffer; return fetchBufferUnchecked( rid ).buffer;
} }
std::optional<VkDeviceAddress> BufferManager::fetchDeviceAddress( BufferID const& rid )
{
if ( not isValidID( rid ) ) return std::nullopt;
Buffer const& buffer = fetchBufferUnchecked( rid );
if ( buffer.deviceAddress == 0 ) return std::nullopt;
return buffer.deviceAddress;
}
BufferManager::BufferManager( RenderDevice* pRenderDevice, Buffer* aBuffers, uint32_t const capacity ) BufferManager::BufferManager( RenderDevice* pRenderDevice, Buffer* aBuffers, uint32_t const capacity )
: m_pRenderDevice{ pRenderDevice }, m_aBuffers{ aBuffers }, m_count{ 0 }, m_capacity{ capacity } : m_pRenderDevice{ pRenderDevice }, m_aBuffers{ aBuffers }, m_count{ 0 }, m_capacity{ capacity }
{ {

View File

@ -17,6 +17,7 @@ struct Buffer
VkBuffer buffer; VkBuffer buffer;
VmaAllocation allocation; VmaAllocation allocation;
std::byte* mappedData; // Assume the system has ReBAR/SAM enabled. std::byte* mappedData; // Assume the system has ReBAR/SAM enabled.
VkDeviceAddress deviceAddress;
size_t size; size_t size;
uint32_t index; uint32_t index;
}; };
@ -55,18 +56,21 @@ public:
[[nodiscard]] bool isValidID( BufferID const& rid ) const; [[nodiscard]] bool isValidID( BufferID const& rid ) const;
std::optional<BufferID> createVertexBuffer( size_t size ); std::optional<BufferID> createVertexBuffer( size_t size );
std::optional<BufferID> createIndexBuffer( size_t size ); std::optional<BufferID> createIndexBuffer( size_t size );
std::optional<BufferID> createStorageBuffer( size_t size );
void freeBuffer( BufferID&& rid ); void freeBuffer( BufferID&& rid );
DEPRECATE_JULY_2025 DEPRECATE_JULY_2025
std::optional<VkBuffer> fetchBuffer( BufferID const& rid ); std::optional<VkBuffer> fetchBuffer( BufferID const& rid );
std::optional<VkDeviceAddress> fetchDeviceAddress( BufferID const& rid );
template <typename T> void writeToBuffer( BufferID const& rid, std::ranges::contiguous_range auto const& data )
void writeToBuffer( BufferID const& rid, std::span<T> const& data )
{ {
writeToBufferImpl( rid, data.data(), data.size_bytes() ); writeToBufferImpl(
rid,
std::ranges::data( data ),
std::ranges::size( data ) * sizeof( std::ranges::range_value_t<decltype( data )> ) );
} }
// //

View File

@ -43,7 +43,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
.binding = 0, .binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT, .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
.pImmutableSamplers = nullptr, .pImmutableSamplers = nullptr,
}; };
@ -60,7 +60,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
VkPushConstantRange const pushConstantRange = { VkPushConstantRange const pushConstantRange = {
.stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS, .stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS,
.offset = 0, .offset = 0,
.size = sizeof( DirectX::XMMATRIX ) + Material::GPU_DATA_SIZE .size = sizeof( DirectX::XMMATRIX ) + Material::GPU_DATA_SIZE,
}; };
std::array const descriptorSetLayouts = { std::array const descriptorSetLayouts = {
@ -289,14 +289,37 @@ bool MiscData::init( RenderDevice const& renderDevice )
// Camera // Camera
{ {
cameraPosition = DirectX::XMVectorSet( 0.0f, 20.0f, -20.0f, 1.0f ); cameraData.cameraPosition = DirectX::XMVectorSet( 0.0f, 20.0f, -20.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.viewMatrix = DirectX::XMMatrixLookAtLH( cameraPosition, cameraTarget, cameraUp ); cameraData.viewMatrix = DirectX::XMMatrixLookAtLH( cameraData.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 );
cameraUniformBufferSize = sizeof( CameraData ); cameraUniformBufferSize = sizeof( CameraData ) + sizeof( LightData );
}
// Lights
{
auto pointLightsValue = renderDevice.bufferManager->createStorageBuffer( 10 * sizeof( PointLight ) );
if ( !pointLightsValue ) return false;
pointLights = std::move( pointLightsValue.value() );
auto dirLightsValue = renderDevice.bufferManager->createStorageBuffer( 10 * sizeof( DirectionalLight ) );
if ( !dirLightsValue ) return false;
directionalLights = std::move( dirLightsValue.value() );
lightData.pointLights = renderDevice.bufferManager->fetchDeviceAddress( pointLights ).value();
lightData.directionalLights = renderDevice.bufferManager->fetchDeviceAddress( directionalLights ).value();
lightData.dirLightCount = 0;
lightData.pointLightCount = 0;
}
// Uniform Buffer
{
VkBufferCreateInfo const bufferCreateInfo = { VkBufferCreateInfo const bufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@ -332,8 +355,9 @@ bool MiscData::init( RenderDevice const& renderDevice )
if ( allocationInfo.pMappedData ) if ( allocationInfo.pMappedData )
{ {
memcpy( allocationInfo.pMappedData, &cameraData, sizeof cameraData );
cameraUniformBufferPtr = static_cast<uint8_t*>( allocationInfo.pMappedData ); cameraUniformBufferPtr = static_cast<uint8_t*>( allocationInfo.pMappedData );
memcpy( cameraUniformBufferPtr, &cameraData, sizeof cameraData );
memcpy( cameraUniformBufferPtr + sizeof cameraData, &lightData, sizeof lightData );
} }
} }
@ -373,7 +397,7 @@ bool MiscData::init( RenderDevice const& renderDevice )
VkDescriptorBufferInfo const descriptorBufferInfo = { VkDescriptorBufferInfo const descriptorBufferInfo = {
.buffer = cameraUniformBuffer, .buffer = cameraUniformBuffer,
.offset = 0, .offset = 0,
.range = sizeof CameraData, .range = cameraUniformBufferSize,
}; };
std::array writeDescriptorSets = { std::array writeDescriptorSets = {
@ -474,6 +498,9 @@ void MiscData::destroy( RenderDevice const& renderDevice )
vkDestroyDescriptorPool( device, Take( descriptorPool ), nullptr ); vkDestroyDescriptorPool( device, Take( descriptorPool ), nullptr );
vmaDestroyBuffer( renderDevice.gpuAllocator, Take( cameraUniformBuffer ), Take( cameraUniformBufferAllocation ) ); vmaDestroyBuffer( renderDevice.gpuAllocator, Take( cameraUniformBuffer ), Take( cameraUniformBufferAllocation ) );
renderDevice.bufferManager->freeBuffer( std::move( pointLights ) );
renderDevice.bufferManager->freeBuffer( std::move( directionalLights ) );
vkDestroyPipeline( device, Take( meshPipeline ), nullptr ); vkDestroyPipeline( device, Take( meshPipeline ), nullptr );
vkDestroyPipelineLayout( device, Take( pipelineLayout ), nullptr ); vkDestroyPipelineLayout( device, Take( pipelineLayout ), nullptr );
vkDestroyDescriptorSetLayout( device, Take( descriptorSetLayout ), nullptr ); vkDestroyDescriptorSetLayout( device, Take( descriptorSetLayout ), nullptr );

View File

@ -6,6 +6,8 @@
#include <DirectXMath.h> #include <DirectXMath.h>
#include "BufferManager.h"
struct GlobalMemory; struct GlobalMemory;
struct RenderDevice; struct RenderDevice;
@ -15,6 +17,31 @@ struct MiscData
{ {
DirectX::XMMATRIX viewMatrix; DirectX::XMMATRIX viewMatrix;
DirectX::XMMATRIX projectionMatrix; DirectX::XMMATRIX projectionMatrix;
DirectX::XMVECTOR cameraPosition;
};
struct PointLight
{
DirectX::XMFLOAT3 position;
float range;
DirectX::XMFLOAT3 color;
float attenuation;
};
struct DirectionalLight
{
DirectX::XMFLOAT3 direction;
float _padding0;
DirectX::XMFLOAT3 color;
float _padding1;
};
struct LightData
{
VkDeviceAddress pointLights;
VkDeviceAddress directionalLights;
uint32_t pointLightCount;
uint32_t dirLightCount;
}; };
uint64_t previousCounter; uint64_t previousCounter;
@ -23,10 +50,14 @@ struct MiscData
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
VkPipeline meshPipeline; VkPipeline meshPipeline;
DirectX::XMVECTOR cameraPosition;
DirectX::XMVECTOR cameraTarget; DirectX::XMVECTOR cameraTarget;
DirectX::XMVECTOR cameraUp; DirectX::XMVECTOR cameraUp;
CameraData cameraData; CameraData cameraData;
BufferID pointLights;
BufferID directionalLights;
LightData lightData;
VkBuffer cameraUniformBuffer; VkBuffer cameraUniformBuffer;
VmaAllocation cameraUniformBufferAllocation; VmaAllocation cameraUniformBufferAllocation;
size_t cameraUniformBufferSize; size_t cameraUniformBufferSize;

View File

@ -31,7 +31,6 @@ uint32_t ProcessMaterial( RenderDevice* renderDevice, Model* model, cgltf_materi
cgltf_image* baseColorImage = material.pbr_metallic_roughness.base_color_texture.texture->image; cgltf_image* baseColorImage = material.pbr_metallic_roughness.base_color_texture.texture->image;
{ {
byte* data; byte* data;
if ( baseColorImage->buffer_view->data ) if ( baseColorImage->buffer_view->data )
{ {
@ -740,7 +739,7 @@ Entity* LoadModel( RenderDevice* renderDevice, EntityManager* entityManager, con
} }
entity->model.vertexBuffer = std::move( vertexBuffer.value() ); entity->model.vertexBuffer = std::move( vertexBuffer.value() );
renderDevice->bufferManager->writeToBuffer( entity->model.vertexBuffer, std::span{ vertices } ); renderDevice->bufferManager->writeToBuffer( entity->model.vertexBuffer, vertices );
auto indexBuffer = renderDevice->bufferManager->createIndexBuffer( indices.size() * sizeof indices[0] ); auto indexBuffer = renderDevice->bufferManager->createIndexBuffer( indices.size() * sizeof indices[0] );
if ( not indexBuffer ) if ( not indexBuffer )

View File

@ -192,6 +192,7 @@ RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo c
.descriptorBindingPartiallyBound = true, .descriptorBindingPartiallyBound = true,
.descriptorBindingVariableDescriptorCount = true, .descriptorBindingVariableDescriptorCount = true,
.runtimeDescriptorArray = true, .runtimeDescriptorArray = true,
.bufferDeviceAddress = true,
}; };
VkPhysicalDeviceFeatures features = { VkPhysicalDeviceFeatures features = {
@ -218,7 +219,7 @@ RenderDevice* RenderDevice_Create( GlobalMemory* mem, RenderDevice::CreateInfo c
volkLoadDevice( device ); volkLoadDevice( device );
VmaAllocatorCreateInfo allocatorCreateInfo = { VmaAllocatorCreateInfo allocatorCreateInfo = {
.flags = 0, .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
.physicalDevice = physicalDeviceInUse, .physicalDevice = physicalDeviceInUse,
.device = device, .device = device,
.preferredLargeHeapBlockSize = 0, .preferredLargeHeapBlockSize = 0,