From 0bf18892ef92766b388ffef1b11083bb16151a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Wed, 1 Jan 2025 16:03:26 +0100 Subject: [PATCH] gpu driver crash workarounds --- WickedEngine/wiRenderer.cpp | 75 ++++++++++++++++++++++++++++--------- WickedEngine/wiVersion.cpp | 2 +- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 2d39c0b34..7e5edae89 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -198,6 +198,12 @@ Texture texture_weatherMap; // See: https://github.com/turanszkij/WickedEngine/issues/450 GPUBuffer luminance_dummy; +// Dummy buffers preinitialized to invalid scene structs, avoids possible GPU crash when +// shader compiler is incorrectly pulling buffer desciptor load outside valid branch +GPUBuffer instance_dummy; +GPUBuffer geometry_dummy; +GPUBuffer material_dummy; + // Direct reference to a renderable instance: struct RenderBatch { @@ -2124,6 +2130,45 @@ void LoadBuffers() static_assert(LUMINANCE_BUFFER_OFFSET_EXPOSURE == 0); } + { + ShaderMeshInstance data; + data.init(); + + GPUBufferDesc desc; + desc.stride = sizeof(data); + desc.size = desc.stride; + desc.bind_flags = BindFlag::SHADER_RESOURCE; + desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; + device->CreateBuffer(&desc, &data, &instance_dummy); + device->SetName(&instance_dummy, "instance_dummy"); + } + + { + ShaderGeometry data; + data.init(); + + GPUBufferDesc desc; + desc.stride = sizeof(data); + desc.size = desc.stride; + desc.bind_flags = BindFlag::SHADER_RESOURCE; + desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; + device->CreateBuffer(&desc, &data, &geometry_dummy); + device->SetName(&geometry_dummy, "geometry_dummy"); + } + + { + ShaderMaterial data; + data.init(); + + GPUBufferDesc desc; + desc.stride = sizeof(data); + desc.size = desc.stride; + desc.bind_flags = BindFlag::SHADER_RESOURCE; + desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; + device->CreateBuffer(&desc, &data, &material_dummy); + device->SetName(&material_dummy, "material_dummy"); + } + { TextureDesc desc; desc.type = TextureDesc::Type::TEXTURE_3D; @@ -4593,6 +4638,19 @@ void UpdatePerFrameData( frameCB.decals = ShaderEntityIterator(decalarray_offset, decalarray_count); frameCB.forces = ShaderEntityIterator(forcefieldarray_offset, forcefieldarray_count); + // GPU crash workarounds, setting buffers with invalid data: + if (frameCB.scene.instancebuffer < 0) + { + frameCB.scene.instancebuffer = device->GetDescriptorIndex(&instance_dummy, SubresourceType::SRV); + } + if (frameCB.scene.geometrybuffer < 0) + { + frameCB.scene.geometrybuffer = device->GetDescriptorIndex(&geometry_dummy, SubresourceType::SRV); + } + if (frameCB.scene.materialbuffer < 0) + { + frameCB.scene.materialbuffer = device->GetDescriptorIndex(&material_dummy, SubresourceType::SRV); + } } void UpdateRenderData( const Visibility& vis, @@ -16189,23 +16247,7 @@ void Postprocess_VolumetricClouds_Upsample( device->BindResource(&res.texture_reproject[temporal_output], 0, cmd); device->BindResource(&res.texture_reproject_depth[temporal_output], 1, cmd); - { - GPUBarrier barriers[] = { - GPUBarrier::Image(&res.texture_reproject[temporal_output], res.texture_reproject[temporal_output].desc.layout, ResourceState::SHADER_RESOURCE), - GPUBarrier::Image(&res.texture_reproject_depth[temporal_output], res.texture_reproject_depth[temporal_output].desc.layout, ResourceState::SHADER_RESOURCE), - }; - device->Barrier(barriers, arraysize(barriers), cmd); - } - device->Draw(3, 0, cmd); - - { - GPUBarrier barriers[] = { - GPUBarrier::Image(&res.texture_reproject[temporal_output], ResourceState::SHADER_RESOURCE, res.texture_reproject[temporal_output].desc.layout), - GPUBarrier::Image(&res.texture_reproject_depth[temporal_output], ResourceState::SHADER_RESOURCE, res.texture_reproject_depth[temporal_output].desc.layout), - }; - device->Barrier(barriers, arraysize(barriers), cmd); - } } wi::profiler::EndRange(range); @@ -16351,7 +16393,6 @@ void Postprocess_TemporalAA( { GPUBarrier barriers[] = { - GPUBarrier::Memory(), GPUBarrier::Image(output, ResourceState::UNORDERED_ACCESS, output->GetDesc().layout), }; device->Barrier(barriers, arraysize(barriers), cmd); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 180e3c2fc..18c24eff8 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -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 = 643; + const int revision = 644; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);