reduced gpu memory usage

This commit is contained in:
Turánszki János
2022-09-29 17:15:03 +02:00
parent 574b27ce9b
commit 768ad1fdca
12 changed files with 542 additions and 326 deletions
+1
View File
@@ -283,6 +283,7 @@ void TerrainWindow::Create(EditorComponent* _editor)
archive << EditorComponent::HISTORYOP_COMPONENT_DATA;
editor->RecordEntity(archive, entity);
terrain->BakeVirtualTexturesToFiles();
editor->GetCurrentScene().terrains.Remove(entity);
editor->RecordEntity(archive, entity);
+5
View File
@@ -1667,6 +1667,7 @@ using namespace dx12_internal;
uploadBufferDesc.usage = Usage::UPLOAD;
bool upload_success = device->CreateBuffer(&uploadBufferDesc, nullptr, &cmd.uploadbuffer);
assert(upload_success);
device->SetName(&cmd.uploadbuffer, "CopyAllocator::uploadBuffer");
}
// begin command list in valid state:
@@ -2417,6 +2418,10 @@ using namespace dx12_internal;
D3D12MA::ALLOCATOR_DESC allocatorDesc = {};
allocatorDesc.pDevice = device.Get();
allocatorDesc.pAdapter = dxgiAdapter.Get();
//allocatorDesc.PreferredBlockSize = 256 * 1024 * 1024;
//allocatorDesc.Flags |= D3D12MA::ALLOCATOR_FLAG_ALWAYS_COMMITTED;
allocatorDesc.Flags |= D3D12MA::ALLOCATOR_FLAG_DEFAULT_POOLS_NOT_ZEROED;
allocatorDesc.Flags |= D3D12MA::ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED;
allocationhandler = std::make_shared<AllocationHandler>();
allocationhandler->device = device;
+1
View File
@@ -1417,6 +1417,7 @@ using namespace vulkan_internal;
uploaddesc.usage = Usage::UPLOAD;
bool upload_success = device->CreateBuffer(&uploaddesc, nullptr, &cmd.uploadbuffer);
assert(upload_success);
device->SetName(&cmd.uploadbuffer, "CopyAllocator::uploadBuffer");
}
// begin command list in valid state:
+3 -2
View File
@@ -70,9 +70,10 @@ namespace wi::primitive
XMFLOAT3 _max = getMax();
return (_max.x - _min.x) * (_max.y - _min.y) * (_max.z - _min.z);
}
float AABB::getRadius() const {
float AABB::getRadius() const
{
XMFLOAT3 abc = getHalfWidth();
return std::max(std::max(abc.x, abc.y), abc.z);
return std::sqrt(std::pow(std::sqrt(std::pow(abc.x, 2.0f) + std::pow(abc.y, 2.0f)), 2.0f) + std::pow(abc.z, 2.0f));
}
AABB::INTERSECTION_TYPE AABB::intersects(const AABB& b) const
{
File diff suppressed because it is too large Load Diff
+8 -9
View File
@@ -111,7 +111,6 @@ namespace wi
wi::graphics::RenderPass renderpass_transparent;
wi::graphics::RenderPass renderpass_reflection_depthprepass;
wi::graphics::RenderPass renderpass_reflection;
wi::graphics::RenderPass renderpass_downsamplescene;
wi::graphics::RenderPass renderpass_lightshafts;
wi::graphics::RenderPass renderpass_volumetriclight;
wi::graphics::RenderPass renderpass_particledistortion;
@@ -261,19 +260,19 @@ namespace wi
void setSSREnabled(bool value);
void setRaytracedReflectionsEnabled(bool value);
void setRaytracedDiffuseEnabled(bool value);
void setMotionBlurEnabled(bool value);
void setDepthOfFieldEnabled(bool value);
void setEyeAdaptionEnabled(bool value);
void setReflectionsEnabled(bool value);
void setBloomEnabled(bool value);
void setVolumeLightsEnabled(bool value);
void setLightShaftsEnabled(bool value);
void setOutlineEnabled(bool value);
constexpr void setShadowsEnabled(bool value) { shadowsEnabled = value; }
constexpr void setReflectionsEnabled(bool value) { reflectionsEnabled = value; }
constexpr void setFXAAEnabled(bool value) { fxaaEnabled = value; }
constexpr void setBloomEnabled(bool value) { bloomEnabled = value; }
constexpr void setColorGradingEnabled(bool value) { colorGradingEnabled = value; }
constexpr void setVolumeLightsEnabled(bool value) { volumeLightsEnabled = value; }
constexpr void setLightShaftsEnabled(bool value) { lightShaftsEnabled = value; }
constexpr void setLensFlareEnabled(bool value) { lensFlareEnabled = value; }
constexpr void setMotionBlurEnabled(bool value) { motionBlurEnabled = value; }
constexpr void setDepthOfFieldEnabled(bool value) { depthOfFieldEnabled = value; }
constexpr void setEyeAdaptionEnabled(bool value) { eyeAdaptionEnabled = value; }
constexpr void setSharpenFilterEnabled(bool value) { sharpenFilterEnabled = value; }
constexpr void setOutlineEnabled(bool value) { outlineEnabled = value; }
constexpr void setChromaticAberrationEnabled(bool value) { chromaticAberrationEnabled = value; }
constexpr void setDitherEnabled(bool value) { ditherEnabled = value; }
constexpr void setOcclusionCullingEnabled(bool value) { occlusionCullingEnabled = value; }
+62 -64
View File
@@ -1771,61 +1771,6 @@ void LoadBuffers()
device->SetName(&textures[TEXTYPE_2D_SHEENLUT], "textures[TEXTYPE_2D_SHEENLUT]");
}
{
TextureDesc desc;
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 512;
desc.height = 512;
desc.format = Format::R11G11B10_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_VOLUMETRICCLOUDS_SHADOW]);
device->SetName(&textures[TEXTYPE_2D_VOLUMETRICCLOUDS_SHADOW], "textures[TEXTYPE_2D_VOLUMETRICCLOUDS_SHADOW]");
}
{
TextureDesc desc;
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 256;
desc.height = 64;
desc.format = Format::R16G16B16A16_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_SKYATMOSPHERE_TRANSMITTANCELUT]);
device->SetName(&textures[TEXTYPE_2D_SKYATMOSPHERE_TRANSMITTANCELUT], "textures[TEXTYPE_2D_SKYATMOSPHERE_TRANSMITTANCELUT]");
}
{
TextureDesc desc;
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 32;
desc.height = 32;
desc.format = Format::R16G16B16A16_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_SKYATMOSPHERE_MULTISCATTEREDLUMINANCELUT]);
device->SetName(&textures[TEXTYPE_2D_SKYATMOSPHERE_MULTISCATTEREDLUMINANCELUT], "textures[TEXTYPE_2D_SKYATMOSPHERE_MULTISCATTEREDLUMINANCELUT]");
}
{
TextureDesc desc;
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 192;
desc.height = 104;
desc.format = Format::R16G16B16A16_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_SKYATMOSPHERE_SKYVIEWLUT]);
device->SetName(&textures[TEXTYPE_2D_SKYATMOSPHERE_SKYVIEWLUT], "textures[TEXTYPE_2D_SKYATMOSPHERE_SKYVIEWLUT]");
}
{
TextureDesc desc;
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 1;
desc.height = 1;
desc.format = Format::R16G16B16A16_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_SKYATMOSPHERE_SKYLUMINANCELUT]);
device->SetName(&textures[TEXTYPE_2D_SKYATMOSPHERE_SKYLUMINANCELUT], "textures[TEXTYPE_2D_SKYATMOSPHERE_SKYLUMINANCELUT]");
}
{
// the dummy buffer is read-only so only the first 'exposure' value is needed,
// not the luminance or histogram values in the full version of the buffer used
@@ -2877,16 +2822,17 @@ void UpdateVisibility(Visibility& vis)
if (vis.flags & Visibility::ALLOW_OCCLUSION_CULLING)
{
if (object.IsRenderable() && object.occlusionQueries[vis.scene->queryheap_idx] < 0)
Scene::OcclusionResult& occlusion_result = vis.scene->occlusion_results_objects[args.jobIndex];
if (object.IsRenderable() && occlusion_result.occlusionQueries[vis.scene->queryheap_idx] < 0)
{
if (aabb.intersects(vis.camera->Eye))
{
// camera is inside the instance, mark it as visible in this frame:
object.occlusionHistory |= 1;
occlusion_result.occlusionHistory |= 1;
}
else
{
object.occlusionQueries[vis.scene->queryheap_idx] = vis.scene->queryAllocator.fetch_add(1); // allocate new occlusion query from heap
occlusion_result.occlusionQueries[vis.scene->queryheap_idx] = vis.scene->queryAllocator.fetch_add(1); // allocate new occlusion query from heap
}
}
}
@@ -3213,6 +3159,19 @@ void UpdatePerFrameData(
// Calculate volumetric cloud shadow data:
if (vis.scene->weather.IsVolumetricClouds() && vis.scene->weather.IsVolumetricCloudsShadows())
{
if (!textures[TEXTYPE_2D_VOLUMETRICCLOUDS_SHADOW].IsValid())
{
TextureDesc desc;
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 512;
desc.height = 512;
desc.format = Format::R11G11B10_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_VOLUMETRICCLOUDS_SHADOW]);
device->SetName(&textures[TEXTYPE_2D_VOLUMETRICCLOUDS_SHADOW], "textures[TEXTYPE_2D_VOLUMETRICCLOUDS_SHADOW]");
}
const float cloudShadowSnapLength = 5000.0f;
const float cloudShadowExtent = 35000.0f; // The cloud shadow bounding box size
const float cloudShadowNearPlane = 0.0f;
@@ -3249,6 +3208,46 @@ void UpdatePerFrameData(
frameCB.texture_volumetricclouds_shadow_index = device->GetDescriptorIndex(&textures[TEXTYPE_2D_VOLUMETRICCLOUDS_SHADOW], SubresourceType::SRV);
}
if (scene.weather.IsRealisticSky() && !textures[TEXTYPE_2D_SKYATMOSPHERE_TRANSMITTANCELUT].IsValid())
{
TextureDesc desc;
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 256;
desc.height = 64;
desc.format = Format::R16G16B16A16_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_SKYATMOSPHERE_TRANSMITTANCELUT]);
device->SetName(&textures[TEXTYPE_2D_SKYATMOSPHERE_TRANSMITTANCELUT], "textures[TEXTYPE_2D_SKYATMOSPHERE_TRANSMITTANCELUT]");
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 32;
desc.height = 32;
desc.format = Format::R16G16B16A16_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_SKYATMOSPHERE_MULTISCATTEREDLUMINANCELUT]);
device->SetName(&textures[TEXTYPE_2D_SKYATMOSPHERE_MULTISCATTEREDLUMINANCELUT], "textures[TEXTYPE_2D_SKYATMOSPHERE_MULTISCATTEREDLUMINANCELUT]");
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 192;
desc.height = 104;
desc.format = Format::R16G16B16A16_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_SKYATMOSPHERE_SKYVIEWLUT]);
device->SetName(&textures[TEXTYPE_2D_SKYATMOSPHERE_SKYVIEWLUT], "textures[TEXTYPE_2D_SKYATMOSPHERE_SKYVIEWLUT]");
desc.type = TextureDesc::Type::TEXTURE_2D;
desc.width = 1;
desc.height = 1;
desc.format = Format::R16G16B16A16_FLOAT;
desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS;
desc.layout = ResourceState::SHADER_RESOURCE_COMPUTE;
device->CreateTexture(&desc, nullptr, &textures[TEXTYPE_2D_SKYATMOSPHERE_SKYLUMINANCELUT]);
device->SetName(&textures[TEXTYPE_2D_SKYATMOSPHERE_SKYLUMINANCELUT], "textures[TEXTYPE_2D_SKYATMOSPHERE_SKYLUMINANCELUT]");
}
// Update CPU-side frame constant buffer:
frameCB.delta_time = dt * GetGameSpeed();
frameCB.time_previous = frameCB.time;
@@ -3400,7 +3399,6 @@ void UpdatePerFrameData(
frameCB.shadow_atlas_resolution_rcp.x = 1.0f / frameCB.shadow_atlas_resolution.x;
frameCB.shadow_atlas_resolution_rcp.y = 1.0f / frameCB.shadow_atlas_resolution.y;
// Create volumetric cloud static resources if needed:
if (scene.weather.IsVolumetricClouds() && !texture_shapeNoise.IsValid())
{
@@ -3461,6 +3459,7 @@ void UpdatePerFrameData(
texture_desc.format = Format::R8G8B8A8_UNORM;
device->CreateTexture(&texture_desc, nullptr, &texture_weatherMap);
device->SetName(&texture_weatherMap, "texture_weatherMap");
}
}
void UpdateRenderData(
@@ -4377,9 +4376,9 @@ void OcclusionCulling_Render(const CameraComponent& camera, const Visibility& vi
for (uint32_t instanceIndex : vis.visibleObjects)
{
const ObjectComponent& object = vis.scene->objects[instanceIndex];
const Scene::OcclusionResult& occlusion_result = vis.scene->occlusion_results_objects[instanceIndex];
int queryIndex = object.occlusionQueries[query_write];
int queryIndex = occlusion_result.occlusionQueries[query_write];
if (queryIndex >= 0)
{
const AABB& aabb = vis.scene->aabb_objects[instanceIndex];
@@ -5132,11 +5131,10 @@ void DrawScene(
renderQueue.init();
for (uint32_t instanceIndex : vis.visibleObjects)
{
const ObjectComponent& object = vis.scene->objects[instanceIndex];
if (occlusion && object.IsOccluded())
if (occlusion && vis.scene->occlusion_results_objects[instanceIndex].IsOccluded())
continue;
const ObjectComponent& object = vis.scene->objects[instanceIndex];
if (object.IsRenderable() && (object.GetFilterMask() & filterMask))
{
const float distance = wi::math::Distance(vis.camera->Eye, object.center);
+12 -6
View File
@@ -125,7 +125,11 @@ namespace wi::scene
// Occlusion culling read:
if(wi::renderer::GetOcclusionCullingEnabled() && !wi::renderer::GetFreezeCullingCameraEnabled())
{
uint32_t minQueryCount = uint32_t(objects.GetCount() + lights.GetCount() + 1); // +1 : ocean
uint32_t minQueryCount = uint32_t(objects.GetCount() + lights.GetCount());
if (weather.IsOceanEnabled())
{
minQueryCount += 1;
}
if (queryHeap.desc.query_count < minQueryCount)
{
GPUQueryHeapDesc desc;
@@ -3108,6 +3112,7 @@ namespace wi::scene
aabb_objects.resize(objects.GetCount());
matrix_objects.resize(objects.GetCount());
matrix_objects_prev.resize(objects.GetCount());
occlusion_results_objects.resize(objects.GetCount());
meshletAllocator.store(0u);
@@ -3121,24 +3126,25 @@ namespace wi::scene
AABB& aabb = aabb_objects[args.jobIndex];
// Update occlusion culling status:
OcclusionResult& occlusion_result = occlusion_results_objects[args.jobIndex];
if (!wi::renderer::GetFreezeCullingCameraEnabled())
{
object.occlusionHistory <<= 1u; // advance history by 1 frame
int query_id = object.occlusionQueries[queryheap_idx];
occlusion_result.occlusionHistory <<= 1u; // advance history by 1 frame
int query_id = occlusion_result.occlusionQueries[queryheap_idx];
if (queryResultBuffer[queryheap_idx].mapped_data != nullptr && query_id >= 0)
{
uint64_t visible = ((uint64_t*)queryResultBuffer[queryheap_idx].mapped_data)[query_id];
if (visible)
{
object.occlusionHistory |= 1; // visible
occlusion_result.occlusionHistory |= 1; // visible
}
}
else
{
object.occlusionHistory |= 1; // visible
occlusion_result.occlusionHistory |= 1; // visible
}
}
object.occlusionQueries[queryheap_idx] = -1; // invalidate query
occlusion_result.occlusionQueries[queryheap_idx] = -1; // invalidate query
const LayerComponent* layer = layers.GetComponent(entity);
uint32_t layerMask;
+17 -1
View File
@@ -123,8 +123,24 @@ namespace wi::scene
std::atomic<uint32_t> meshletAllocator{ 0 };
// Occlusion query state:
struct OcclusionResult
{
int occlusionQueries[wi::graphics::GraphicsDevice::GetBufferCount() + 1];
// occlusion result history bitfield (32 bit->32 frame history)
uint32_t occlusionHistory = ~0u;
constexpr bool IsOccluded() const
{
// Perform a conservative occlusion test:
// If it is visible in any frames in the history, it is determined visible in this frame
// But if all queries failed in the history, it is occluded.
// If it pops up for a frame after occluded, it is visible again for some frames
return occlusionHistory == 0;
}
};
mutable wi::vector<OcclusionResult> occlusion_results_objects;
wi::graphics::GPUQueryHeap queryHeap;
wi::graphics::GPUBuffer queryResultBuffer[arraysize(ObjectComponent::occlusionQueries)];
wi::graphics::GPUBuffer queryResultBuffer[arraysize(OcclusionResult::occlusionQueries)];
wi::graphics::GPUBuffer queryPredicationBuffer;
int queryheap_idx = 0;
mutable std::atomic<uint32_t> queryAllocator{ 0 };
-13
View File
@@ -668,19 +668,6 @@ namespace wi::scene
// these will only be valid for a single frame:
uint32_t mesh_index = ~0u;
// occlusion result history bitfield (32 bit->32 frame history)
mutable uint32_t occlusionHistory = ~0u;
mutable int occlusionQueries[wi::graphics::GraphicsDevice::GetBufferCount() + 1];
inline bool IsOccluded() const
{
// Perform a conservative occlusion test:
// If it is visible in any frames in the history, it is determined visible in this frame
// But if all queries failed in the history, it is occluded.
// If it pops up for a frame after occluded, it is visible again for some frames
return occlusionHistory == 0;
}
inline void SetRenderable(bool value) { if (value) { _flags |= RENDERABLE; } else { _flags &= ~RENDERABLE; } }
inline void SetCastShadow(bool value) { if (value) { _flags |= CAST_SHADOW; } else { _flags &= ~CAST_SHADOW; } }
inline void SetDynamic(bool value) { if (value) { _flags |= DYNAMIC; } else { _flags &= ~DYNAMIC; } }
+20 -15
View File
@@ -342,6 +342,7 @@ namespace wi::terrain
{
const Chunk& chunk = it->first;
ChunkData& chunk_data = it->second;
const bool chunk_visible = camera.frustum.CheckSphere(chunk_data.sphere.center, chunk_data.sphere.radius);
const int dist = std::max(std::abs(center_chunk.x - chunk.x), std::abs(center_chunk.z - chunk.z));
// pointer refresh:
@@ -443,24 +444,30 @@ namespace wi::terrain
// Collect virtual texture update requests:
if (virtual_texture_any)
{
uint32_t texture_lod = 0;
const float distsq = wi::math::DistanceSquared(camera.Eye, chunk_data.sphere.center);
const float radius = chunk_data.sphere.radius;
const float radiussq = radius * radius;
if (distsq < radiussq)
if (chunk_visible)
{
texture_lod = 0;
uint32_t texture_lod = 0;
const float distsq = wi::math::DistanceSquared(camera.Eye, chunk_data.sphere.center);
const float radius = chunk_data.sphere.radius;
const float radiussq = radius * radius;
if (distsq < radiussq)
{
texture_lod = 0;
}
else
{
const float dist = std::sqrt(distsq);
const float dist_to_sphere = dist - radius;
texture_lod = uint32_t(dist_to_sphere * texlodMultiplier);
}
chunk_data.required_texture_resolution = uint32_t(target_texture_resolution / std::pow(2.0f, (float)std::max(0u, texture_lod)));
chunk_data.required_texture_resolution = AlignTo(chunk_data.required_texture_resolution, 8u);
chunk_data.required_texture_resolution = std::max(8u, chunk_data.required_texture_resolution);
}
else
{
const float dist = std::sqrt(distsq);
const float dist_to_sphere = dist - radius;
texture_lod = uint32_t(dist_to_sphere * texlodMultiplier);
chunk_data.required_texture_resolution = 8u;
}
chunk_data.required_texture_resolution = uint32_t(target_texture_resolution / std::pow(2.0f, (float)std::max(0u, texture_lod)));
chunk_data.required_texture_resolution = AlignTo(chunk_data.required_texture_resolution, 8u);
chunk_data.required_texture_resolution = std::max(8u, chunk_data.required_texture_resolution);
MaterialComponent* material = scene->materials.GetComponent(chunk_data.entity);
if (material != nullptr)
@@ -1160,8 +1167,6 @@ namespace wi::terrain
}
else
{
BakeVirtualTexturesToFiles();
archive << _flags;
archive << lod_multiplier;
archive << texlod;
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 59;
const int revision = 60;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);