diff --git a/Content/terrain/licenses.txt b/Content/terrain/licenses.txt index 7073063f5..f4b731c98 100644 --- a/Content/terrain/licenses.txt +++ b/Content/terrain/licenses.txt @@ -17,7 +17,7 @@ Snow texture: https://www.sharetextures.com/textures/ground/snow_ground_3/ Sand texture: -https://www.cgbookcase.com/textures/sandy-gravel-01/?source=3dassets.one +https://ambientcg.com/view?id=Ground033 Stone texture: ambientCG (ambientCG.com) diff --git a/Content/terrain/low_altitude.jpg b/Content/terrain/low_altitude.jpg index 8e7b21576..7b4eab4be 100644 Binary files a/Content/terrain/low_altitude.jpg and b/Content/terrain/low_altitude.jpg differ diff --git a/Content/terrain/low_altitude_nor.jpg b/Content/terrain/low_altitude_nor.jpg index 4b6671a2f..dbb96626b 100644 Binary files a/Content/terrain/low_altitude_nor.jpg and b/Content/terrain/low_altitude_nor.jpg differ diff --git a/WickedEngine/shaders/ShaderInterop_Renderer.h b/WickedEngine/shaders/ShaderInterop_Renderer.h index 016f72eae..9e1c13596 100644 --- a/WickedEngine/shaders/ShaderInterop_Renderer.h +++ b/WickedEngine/shaders/ShaderInterop_Renderer.h @@ -1382,7 +1382,13 @@ struct TerrainVirtualTexturePush uint write_size; float resolution_rcp; + int blendmap_buffer; uint blendmap_buffer_offset; + + int blendmap_texture; + uint blendmap_layers; + int output_texture; + int padding0; }; struct VirtualTextureResidencyUpdateCB { diff --git a/WickedEngine/shaders/terrainVirtualTextureUpdateCS.hlsl b/WickedEngine/shaders/terrainVirtualTextureUpdateCS.hlsl index ae0ea33a5..cb3a04c08 100644 --- a/WickedEngine/shaders/terrainVirtualTextureUpdateCS.hlsl +++ b/WickedEngine/shaders/terrainVirtualTextureUpdateCS.hlsl @@ -4,19 +4,10 @@ PUSHCONSTANT(push, TerrainVirtualTexturePush); -Texture2DArray blendmap : register(t0); -ByteAddressBuffer blendmap_buffer : register(t1); - #if !defined(UPDATE_NORMALMAP) && !defined(UPDATE_SURFACEMAP) && !defined(UPDATE_EMISSIVEMAP) #define UPDATE_BASECOLORMAP #endif -#if defined(UPDATE_BASECOLORMAP) || defined(UPDATE_EMISSIVEMAP) -RWTexture2D output : register(u0); -#else -RWTexture2D output : register(u0); -#endif - static const uint2 block_offsets[16] = { uint2(0, 0), uint2(1, 0), uint2(2, 0), uint2(3, 0), uint2(0, 1), uint2(1, 1), uint2(2, 1), uint2(3, 1), @@ -30,9 +21,14 @@ void main(uint3 DTid : SV_DispatchThreadID) if (DTid.x >= push.write_size || DTid.y >= push.write_size) return; - uint2 dim; - uint array_size; - blendmap.GetDimensions(dim.x, dim.y, array_size); + Texture2DArray blendmap = bindless_textures2DArray[push.blendmap_texture]; + ByteAddressBuffer blendmap_buffer = bindless_buffers[push.blendmap_buffer]; + +#if defined(UPDATE_BASECOLORMAP) || defined(UPDATE_EMISSIVEMAP) + RWTexture2D output = bindless_rwtextures_uint2[push.output_texture]; +#else + RWTexture2D output = bindless_rwtextures_uint4[push.output_texture]; +#endif #ifdef UPDATE_BASECOLORMAP float3 block_rgb[16]; @@ -63,9 +59,9 @@ void main(uint3 DTid : SV_DispatchThreadID) float accumulation = 0; // Note: blending is front-to back with early exit like decals - for(int blendmap_index = array_size - 1; blendmap_index >= 0; blendmap_index--) + for(int blendmap_index = push.blendmap_layers - 1; blendmap_index >= 0; blendmap_index--) { - float weight = blendmap.SampleLevel(sampler_linear_clamp, float3(uv, blendmap_index), 0); + float weight = blendmap.SampleLevel(sampler_linear_clamp, float3(uv, blendmap_index), 0).r; if(weight == 0) continue; diff --git a/WickedEngine/wiTerrain.cpp b/WickedEngine/wiTerrain.cpp index 07e05399f..6067e8672 100644 --- a/WickedEngine/wiTerrain.cpp +++ b/WickedEngine/wiTerrain.cpp @@ -229,6 +229,7 @@ namespace wi::terrain bool success = device->CreateTexture(&td, nullptr, &residencyMap); assert(success); device->SetName(&residencyMap, "VirtualTexture::residencyMap"); + residency_cleared = false; for (uint32_t i = 0; i < lod_count; ++i) { @@ -304,6 +305,7 @@ namespace wi::terrain data_available_CPU[i] = false; } cpu_resource_id = 0; + residency_cleared = false; } void VirtualTexture::init(VirtualTextureAtlas& atlas, uint resolution) @@ -1351,9 +1353,11 @@ namespace wi::terrain bool success = device->CreateTexture(&desc, nullptr, &atlas.maps[map_type].texture); assert(success); + device->SetName(&atlas.maps[map_type].texture, "VirtualTextureAtlas::texture"); success = device->CreateTexture(&desc_raw_block, nullptr, &atlas.maps[map_type].texture_raw_block); assert(success); + device->SetName(&atlas.maps[map_type].texture_raw_block, "VirtualTextureAtlas::texture_raw_block"); assert(atlas.maps[map_type].texture.sparse_properties->total_tile_count == atlas.maps[map_type].texture_raw_block.sparse_properties->total_tile_count); assert(atlas.maps[map_type].texture.sparse_page_size == atlas.maps[map_type].texture_raw_block.sparse_page_size); @@ -1674,9 +1678,16 @@ namespace wi::terrain device->ClearUAV(&vt->residency->feedbackMap, 0xFF, cmd); device->ClearUAV(&vt->residency->requestBuffer, 0xFF, cmd); device->ClearUAV(&vt->residency->allocationBuffer, 0, cmd); + if (!vt->residency->residency_cleared) + { + vt->residency->residency_cleared = true; + device->ClearUAV(&vt->residency->residencyMap, 0, cmd); + } } device->EventEnd(cmd); + device->Barrier(GPUBarrier::Memory(), cmd); + device->EventBegin("Update Residency Maps", cmd); device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_VIRTUALTEXTURE_RESIDENCYUPDATE), cmd); for (const VirtualTexture* vt : virtual_textures_in_use) @@ -1719,28 +1730,37 @@ namespace wi::terrain continue; for (uint32_t map_type = 0; map_type < arraysize(atlas.maps); map_type++) { + TerrainVirtualTexturePush push = {}; + switch (map_type) { case MaterialComponent::BASECOLORMAP: device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_TERRAIN_VIRTUALTEXTURE_UPDATE_BASECOLORMAP), cmd); - device->BindUAV(&atlas.maps[MaterialComponent::BASECOLORMAP].texture_raw_block, 0, cmd); + push.output_texture = device->GetDescriptorIndex(&atlas.maps[MaterialComponent::BASECOLORMAP].texture_raw_block, SubresourceType::UAV); break; case MaterialComponent::NORMALMAP: device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_TERRAIN_VIRTUALTEXTURE_UPDATE_NORMALMAP), cmd); - device->BindUAV(&atlas.maps[MaterialComponent::NORMALMAP].texture_raw_block, 0, cmd); + push.output_texture = device->GetDescriptorIndex(&atlas.maps[MaterialComponent::NORMALMAP].texture_raw_block, SubresourceType::UAV); break; case MaterialComponent::SURFACEMAP: device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_TERRAIN_VIRTUALTEXTURE_UPDATE_SURFACEMAP), cmd); - device->BindUAV(&atlas.maps[MaterialComponent::SURFACEMAP].texture_raw_block, 0, cmd); + push.output_texture = device->GetDescriptorIndex(&atlas.maps[MaterialComponent::SURFACEMAP].texture_raw_block, SubresourceType::UAV); break; case MaterialComponent::EMISSIVEMAP: device->BindComputeShader(wi::renderer::GetShader(wi::enums::CSTYPE_TERRAIN_VIRTUALTEXTURE_UPDATE_EMISSIVEMAP), cmd); - device->BindUAV(&atlas.maps[MaterialComponent::EMISSIVEMAP].texture_raw_block, 0, cmd); + push.output_texture = device->GetDescriptorIndex(&atlas.maps[MaterialComponent::EMISSIVEMAP].texture_raw_block, SubresourceType::UAV); break; default: assert(0); break; } + if (push.output_texture < 0) + continue; + + push.blendmap_texture = device->GetDescriptorIndex(&vt->blendmap, SubresourceType::SRV); + push.blendmap_layers = vt->blendmap.desc.array_size; + if (push.blendmap_texture < 0) + continue; auto mem = device->AllocateGPU(sizeof(uint) * vt->blendmap.desc.array_size, cmd); const uint blendcount = std::min(vt->blendmap.desc.array_size, uint(materialEntities.size())); @@ -1749,9 +1769,11 @@ namespace wi::terrain const uint material_index = (uint)scene->materials.GetIndex(materialEntities[i]); std::memcpy((uint*)mem.data + i, &material_index, sizeof(uint)); // force memcpy to avoid uncached write into GPU pointer! } - const uint blendmap_buffer_offset = (uint)mem.offset; - device->BindResource(&vt->blendmap, 0, cmd); - device->BindResource(&mem.buffer, 1, cmd); + + push.blendmap_buffer = device->GetDescriptorIndex(&mem.buffer, SubresourceType::SRV); + if (push.blendmap_buffer < 0) + continue; + push.blendmap_buffer_offset = (uint)mem.offset; for (auto& request : vt->update_requests) { @@ -1761,17 +1783,14 @@ namespace wi::terrain request.tile_y * SVT_TILE_SIZE_PADDED / 4 ); - TerrainVirtualTexturePush push; push.offset = int2( int(request.x * SVT_TILE_SIZE) - int(SVT_TILE_BORDER), int(request.y * SVT_TILE_SIZE) - int(SVT_TILE_BORDER) ); - push.blendmap_buffer_offset = blendmap_buffer_offset; if (request_lod_resolution < SVT_TILE_SIZE) { // packed mips - uint32_t tail_mip_idx = 0; while (request_lod_resolution >= 4u) { @@ -1866,8 +1885,7 @@ namespace wi::terrain device->EventEnd(cmd); } - GPUBarrier memory_barrier = GPUBarrier::Memory(); - device->Barrier(&memory_barrier, 1, cmd); + device->Barrier(GPUBarrier::Memory(), cmd); { device->EventBegin("Tile Allocation Requests", cmd); diff --git a/WickedEngine/wiTerrain.h b/WickedEngine/wiTerrain.h index 9b1acf8b4..d531f9ecd 100644 --- a/WickedEngine/wiTerrain.h +++ b/WickedEngine/wiTerrain.h @@ -97,6 +97,7 @@ namespace wi::terrain bool data_available_CPU[wi::graphics::GraphicsDevice::GetBufferCount() + 1] = {}; int cpu_resource_id = 0; uint32_t resolution = 0; + bool residency_cleared = false; void init(uint32_t resolution); void reset(); @@ -132,7 +133,7 @@ namespace wi::terrain uint64_t get_tile_frames(const Tile& tile) const { if (!tile.IsValid()) - return false; + return ~0ull; return physical_tiles[tile.x + tile.y * physical_tile_count_x].free_frames; } std::shared_ptr allocate_residency(uint32_t resolution) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 08fbf0649..5df15330e 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 = 466; + const int revision = 467; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);