Skip to content
This repository has been archived by the owner on Dec 25, 2023. It is now read-only.

Commit

Permalink
readme changes. misc.
Browse files Browse the repository at this point in the history
  • Loading branch information
allenhux-intel committed Nov 14, 2022
1 parent 58e21e7 commit 1b753fe
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 34 deletions.
23 changes: 11 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
# Sampler Feedback Streaming
# Sampler Feedback Streaming With DirectStorage

## Introduction

This repository contains an [MIT licensed](LICENSE) demo of _DirectX12 Sampler Feedback Streaming_, a technique using [DirectX12 Sampler Feedback](https://microsoft.github.io/DirectX-Specs/d3d/SamplerFeedback.html) to guide continuous loading and eviction of small regions (tiles) of textures - in other words, virtual texture streaming. Sampler Feedback Streaming can dramatically improve visual quality by enabling scenes consisting of 100s of gigabytes of resources to be drawn on GPUs containing much less physical memory. The scene below uses just ~200MB of a 1GB heap, despite over 350GB of total texture resources. It also uses DirectStorage for Windows for maximum file upload performance.

New: incorporated DirectStorage for Windows v1.1.0 with GPU decompression. Be sure to update your GPU drivers to access your vendor's optimized GPU decompression capabilities. See also:
- [Intel's blog](https://www.intel.com/content/www/us/en/developer/articles/news/directstorage-on-intel-gpus.html)
- [Microsoft's blog](https://devblogs.microsoft.com/directx/directstorage-1-1-now-available/)
- [Intel's 1.1 announcement blog](https://www.intel.com/content/www/us/en/developer/articles/news/directstorage-on-intel-gpus.html)
- [Microsoft's 1.1 announcement blog](https://devblogs.microsoft.com/directx/directstorage-1-1-now-available/)

See also:

- [GDC 2021 video](https://software.intel.com/content/www/us/en/develop/events/gdc.html?videoid=6264595860001) [(alternate link)](https://www.youtube.com/watch?v=VDDbrfZucpQ) which provides an overview of Sampler Feedback and discusses this sample [starting at about 15:30.](https://www.youtube.com/watch?v=VDDbrfZucpQ&t=936s)
- [GDC 2021 presentation](https://software.intel.com/content/dam/develop/external/us/en/documents/pdf/july-gdc-2021-sampler-feedback-texture-space-shading-direct-storage.pdf) in PDF form
- [Microsoft DirectStorage Landing Page](https://devblogs.microsoft.com/directx/directstorage-api-downloads/)

![Sample screenshot](./readme-images/sampler-feedback-streaming.jpg "Sample screenshot")
Textures derived from [Hubble Images](https://www.nasa.gov/mission_pages/hubble/multimedia/index.html), see the [Hubble Copyright](https://hubblesite.org/copyright)

Notes:
- while multiple objects can share the same DX texture and source file, this sample aims to demonstrate the possibility of every object having a unique resource. Hence, every texture is treated as though unique, though the same source file may be used multiple times.
- not all textures shown above, which total over 13GB, are not part of the repo. A few 16k x 16k textures are available as [release 1](https://github.com/GameTechDev/SamplerFeedbackStreaming/releases/tag/1) and [release 2](https://github.com/GameTechDev/SamplerFeedbackStreaming/releases/tag/2)
- the repo does not include all textures shown above (they total over 13GB). A few 16k x 16k textures are available as [release 1](https://github.com/GameTechDev/SamplerFeedbackStreaming/releases/tag/1) and [release 2](https://github.com/GameTechDev/SamplerFeedbackStreaming/releases/tag/2)
- the file format has changed since large textures were provided as "releases." See the [log](#log) below.
- this repository has been updated with DirectStorage 1.0.2 for Windows® from https://www.nuget.org/packages/Microsoft.Direct3D.DirectStorage/
- this repository depends on DirectStorage for Windows® version 1.1.0 from https://www.nuget.org/packages/Microsoft.Direct3D.DirectStorage/
- at build time, BCx textures (BC7 and BC1 tested) in the dds/ directory are converted into the custom .XET format and placed in the ($TargetDir)/media directory (e.g. x64/Release/media). A few dds files are included.

Requirements:
## Requirements:
- minimum:
- Windows 10 20H1 (aka May 2020 Update, build 19041)
- GPU with D3D12 Sampler Feedback Support such as Intel Iris Xe Graphics as found in 11th Generation Intel® Core™ processors and discrete GPUs (driver version **[30.0.100.9667](https://downloadcenter.intel.com/product/80939/Graphics) or later**)
Expand All @@ -28,12 +33,6 @@ Requirements:
- nvme SSD with PCIe gen4 or later
- Intel Arc A770 discrete GPU or later

See also:

* [GDC 2021 video](https://software.intel.com/content/www/us/en/develop/events/gdc.html?videoid=6264595860001) [(alternate link)](https://www.youtube.com/watch?v=VDDbrfZucpQ) which provides an overview of Sampler Feedback and discusses this sample starting at about 15:30.

* [GDC 2021 presentation](https://software.intel.com/content/dam/develop/external/us/en/documents/pdf/july-gdc-2021-sampler-feedback-texture-space-shading-direct-storage.pdf) in PDF form

## Build Instructions

Download the source. Build the appropriate solution file
Expand Down
61 changes: 61 additions & 0 deletions TileUpdateManager/BitVector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//*********************************************************
//
// Copyright 2020 Intel Corporation
//
// Permission is hereby granted, free of charge, to any
// person obtaining a copy of this software and associated
// documentation files(the "Software"), to deal in the Software
// without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to
// whom the Software is furnished to do so, subject to the
// following conditions :
// The above copyright notice and this permission notice shall
// be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
//*********************************************************
#pragma once

//==================================================
// vector of bits packed into standard type
// expected types: UINT64, UINT32, UINT16, UINT8
//==================================================
template<typename T> class BitVector
{
public:
BitVector(size_t in_size, UINT in_initialValue = 0) : m_size(in_size), m_bits((in_size + BIT_MASK) >> BIT_SHIFT, in_initialValue ? T(-1) : 0) {}
UINT Get(UINT i) { return GetVector(i) & GetBit(i); }
void Set(UINT i) { GetVector(i) |= GetBit(i); }
void Clear(UINT i) { GetVector(i) &= ~GetBit(i); }
size_t size() { return m_size; }

class Accessor // helper class so we can replace std::vector<>
{
public:
operator UINT() const { return m_b.Get(m_i); }
void operator=(UINT b) { b ? m_b.Set(m_i) : m_b.Clear(m_i); }
private:
Accessor(BitVector& b, UINT i) : m_b(b), m_i(i) {}
BitVector& m_b;
const UINT m_i{ 0 };
friend class BitVector;
};
Accessor operator[](UINT i) { return Accessor(*this, i); }
private:
const size_t m_size{ 0 };
// use the upper bits of the incoming index to get the array index (shift by log2, e.g. byte type is 3 bits)
static constexpr UINT BIT_SHIFT = (8 == sizeof(T)) ? 6 : (4 == sizeof(T)) ? 5 : (2 == sizeof(T)) ? 4 : 3;
static constexpr UINT BIT_MASK = (T(1) << BIT_SHIFT) - 1;
std::vector<T> m_bits;
UINT GetBit(UINT i) { return T(1) << (i & BIT_MASK); }
T& GetVector(UINT i) { return m_bits[i >> BIT_SHIFT]; }
};
3 changes: 2 additions & 1 deletion TileUpdateManager/TileUpdateManagerBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "StreamingResourceBase.h"
#include "XeTexture.h"
#include "StreamingHeap.h"
#include "BitVector.h"

//=============================================================================
// constructor for streaming library base class
Expand Down Expand Up @@ -156,7 +157,7 @@ void Streaming::TileUpdateManagerBase::ProcessFeedbackThread()
staleResources.reserve(m_streamingResources.size());

// flags to prevent duplicates in the staleResources array
std::vector<BYTE> pending(m_streamingResources.size(), 0);
BitVector<UINT32> pending(m_streamingResources.size(), 0);

UINT uploadsRequested = 0; // remember if any work was queued so we can signal afterwards
UINT64 previousFrameFenceValue = m_frameFenceValue;
Expand Down
1 change: 1 addition & 0 deletions TileUpdateManager/TileUpdateManager_vs2022.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
<ClCompile Include="XeTexture.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="BitVector.h" />
<ClInclude Include="SimpleAllocator.h" />
<ClInclude Include="DataUploader.h" />
<ClInclude Include="FileStreamer.h" />
Expand Down
3 changes: 3 additions & 0 deletions TileUpdateManager/TileUpdateManager_vs2022.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
<ClInclude Include="SimpleAllocator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BitVector.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="TileUpdateManagerBase.cpp">
Expand Down
2 changes: 1 addition & 1 deletion config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"maxFeedbackTime": 5.0, // maximum milliseconds for GPU to resolve feedback

"visualizeMinMip": false, // color overlayed onto texture by PS corresponding to mip level
"hideFeedback": true, // hide the terrain feedback windows
"hideFeedback": false, // hide the terrain feedback windows
"hideUI": false, // hide the UI
"miniUI": false, // use "lite" UI (bandwidth & heap occupancy only)

Expand Down
38 changes: 33 additions & 5 deletions src/Gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,22 @@ void Gui::ToggleDemoMode(CommandLineArgs& in_args)
static float bias = 0;
static float cameraRate = 0.4f;
static float animationRate = 0.4f;
static int numSpheres = (int)m_initialArgs.m_maxNumObjects;

if (m_demoMode)
{
bias = 0;
cameraRate = 0.4f;
animationRate = 0.4f;
numSpheres = (int)m_initialArgs.m_maxNumObjects;
}

std::swap(bias, in_args.m_lodBias);
std::swap(cameraRate, in_args.m_cameraAnimationRate);
std::swap(animationRate, in_args.m_animationRate);
std::swap(numSpheres, in_args.m_numSpheres);

in_args.m_showFeedbackMaps = false;
in_args.m_numSpheres = (int)m_initialArgs.m_maxNumObjects;
}

//-----------------------------------------------------------------------------
Expand All @@ -256,13 +266,24 @@ void Gui::ToggleBenchmarkMode(CommandLineArgs& in_args)
static float bias = -2;
static float cameraRate = 2;
static float animationRate = 2;
static int numSpheres = (int)m_initialArgs.m_maxNumObjects;

if (m_benchmarkMode)
{
paintmixer = true;
bias = -2;
cameraRate = 2;
animationRate = 2;
numSpheres = (int)m_initialArgs.m_maxNumObjects;
}

std::swap(paintmixer, in_args.m_cameraPaintMixer);
std::swap(bias, in_args.m_lodBias);
std::swap(cameraRate, in_args.m_cameraAnimationRate);
std::swap(animationRate, in_args.m_animationRate);
std::swap(numSpheres, in_args.m_numSpheres);

in_args.m_showFeedbackMaps = false;
in_args.m_numSpheres = (int)m_initialArgs.m_maxNumObjects;
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -341,7 +362,12 @@ void Gui::Draw(ID3D12GraphicsCommandList* in_pCommandList,
//---------------------------------------------------------------------
// terrain feedback viewer
//---------------------------------------------------------------------
in_args.m_showFeedbackMaps = ImGui::CollapsingHeader("Terrain Object Feedback Viewer");
ImGuiTreeNodeFlags feedbackNodeFlags = ImGuiTreeNodeFlags_None;
if (in_args.m_showFeedbackMaps)
{
feedbackNodeFlags = ImGuiTreeNodeFlags_DefaultOpen;
}
in_args.m_showFeedbackMaps = ImGui::CollapsingHeader("Terrain Object Feedback Viewer", feedbackNodeFlags);
if (in_args.m_showFeedbackMaps)
{
in_args.m_cameraUpLock = true;
Expand Down Expand Up @@ -400,7 +426,8 @@ void Gui::Draw(ID3D12GraphicsCommandList* in_pCommandList,
//---------------------------------------------------------------------
// demo mode
//---------------------------------------------------------------------
if (ImGui::Button("DEMO MODE", ImVec2(-1, 0)))
out_buttonChanges.m_toggleDemoMode = ImGui::Button("DEMO MODE", ImVec2(-1, 0));
if (out_buttonChanges.m_toggleDemoMode)
{
if (m_benchmarkMode) { ToggleBenchmarkMode(in_args); }
ToggleDemoMode(in_args);
Expand All @@ -409,7 +436,8 @@ void Gui::Draw(ID3D12GraphicsCommandList* in_pCommandList,
//---------------------------------------------------------------------
// benchmark mode
//---------------------------------------------------------------------
if (ImGui::Button("BENCHMARK MODE", ImVec2(-1, 0)))
out_buttonChanges.m_toggleBenchmarkMode = ImGui::Button("BENCHMARK MODE", ImVec2(-1, 0));
if (out_buttonChanges.m_toggleBenchmarkMode)
{
if (m_demoMode) { ToggleDemoMode(in_args); }
ToggleBenchmarkMode(in_args);
Expand Down
2 changes: 2 additions & 0 deletions src/Gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class Gui
bool m_directStorageToggle{ false };
bool m_frustumToggle{ false };
bool m_visualizationChange{ false };
bool m_toggleDemoMode{ false };
bool m_toggleBenchmarkMode{ false };
};

void Draw(ID3D12GraphicsCommandList* in_pCommandList,
Expand Down
45 changes: 34 additions & 11 deletions src/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,7 @@ Scene::Scene(const CommandLineArgs& in_args, HWND in_hwnd) :
XMVECTOR lookAt = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
XMVECTOR vUpVec = XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f);

m_viewMatrix = XMMatrixLookAtLH(vEyePt, lookAt, vUpVec);
m_viewMatrixInverse = XMMatrixInverse(nullptr, m_viewMatrix);
SetViewMatrix(XMMatrixLookAtLH(vEyePt, lookAt, vUpVec));

m_pGui = new Gui(m_hwnd, m_device.Get(), m_srvHeap.Get(), (UINT)DescriptorHeapOffsets::GUI, m_swapBufferCount, SharedConstants::SWAP_CHAIN_FORMAT, adapterDescription, m_args);

Expand Down Expand Up @@ -284,8 +283,7 @@ void Scene::MoveView(int in_x, int in_y, int in_z)
float z = in_z * -translationRate;
XMMATRIX translation = XMMatrixTranslation(x, y, z);

m_viewMatrix = XMMatrixMultiply(m_viewMatrix, translation);
m_viewMatrixInverse = XMMatrixInverse(nullptr, m_viewMatrix);
SetViewMatrix(XMMatrixMultiply(m_viewMatrix, translation));
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -314,9 +312,7 @@ void Scene::RotateView(float in_x, float in_y, float in_z)
rotation = XMMatrixRotationRollPitchYaw(in_x, in_y, in_z);
}

m_viewMatrix = XMMatrixMultiply(m_viewMatrix, rotation);

m_viewMatrixInverse = XMMatrixInverse(nullptr, m_viewMatrix);
SetViewMatrix(XMMatrixMultiply(m_viewMatrix, rotation));
}


Expand Down Expand Up @@ -1365,17 +1361,15 @@ void Scene::Animate()

XMVECTOR vUpVec = XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f);

m_viewMatrix = XMMatrixLookToLH(pos, lookTo, vUpVec);
SetViewMatrix(XMMatrixLookToLH(pos, lookTo, vUpVec));

previous = pos;
}
else
{
XMVECTOR pos = XMVectorSet(x, y, z, 1);
m_viewMatrix = XMMatrixLookAtLH(pos, XMVectorSet(0, 0, 0, 0), XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f));
SetViewMatrix(XMMatrixLookAtLH(pos, XMVectorSet(0, 0, 0, 0), XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f)));
}

m_viewMatrixInverse = XMMatrixInverse(nullptr, m_viewMatrix);
}

// spin objects
Expand Down Expand Up @@ -1638,6 +1632,22 @@ void Scene::HandleUiToggleFrustum()
}
}

//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
void Scene::SwapCameraForDemo(bool in_capture)
{
static XMMATRIX previousView = XMMatrixIdentity();

if (in_capture)
{
previousView = m_viewMatrix;
}
else
{
SetViewMatrix(previousView);
}
}

//-------------------------------------------------------------------------
// handle UI changes (outside of begin/end frame)
//-------------------------------------------------------------------------
Expand All @@ -1658,6 +1668,19 @@ void Scene::HandleUIchanges()
m_pTileUpdateManager->SetVisualizationMode((UINT)m_args.m_dataVisualizationMode);
}

if (m_uiButtonChanges.m_toggleBenchmarkMode)
{
m_benchmarkMode = !m_benchmarkMode;
if (!m_demoMode) { SwapCameraForDemo(m_benchmarkMode); }
else { m_demoMode = false; }
}
if (m_uiButtonChanges.m_toggleDemoMode)
{
m_demoMode = !m_demoMode;
if (!m_benchmarkMode) { SwapCameraForDemo(m_demoMode); }
else { m_benchmarkMode = false; }
}

m_uiButtonChanges = Gui::ButtonChanges(); // reset
}
}
Expand Down
12 changes: 8 additions & 4 deletions src/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class Scene
DirectX::XMMATRIX m_projection;
DirectX::XMMATRIX m_viewMatrix;
DirectX::XMMATRIX m_viewMatrixInverse;
void SetViewMatrix(const DirectX::XMMATRIX& m) { m_viewMatrix = m; m_viewMatrixInverse = XMMatrixInverse(nullptr, m_viewMatrix); }

float m_aspectRatio{ 0 };
const float m_fieldOfView{ DirectX::XM_PI / 6.0f };

Expand Down Expand Up @@ -183,6 +185,7 @@ class Scene
// startup sequence (constructor)
//-------------------------------
void InitDebugLayer();
void CreateDeviceWithName(std::wstring& out_adapterDescription);
void CreateDescriptorHeaps();
void CreateCommandQueue();
void CreateSwapChain();
Expand All @@ -206,6 +209,8 @@ class Scene
//-----------------------------------
// scene graph
//-----------------------------------
AssetUploader m_assetUploader;

std::vector<class SceneObjects::BaseObject*> m_objects;
UINT m_numSpheresLoaded{ 0 };

Expand Down Expand Up @@ -252,12 +257,11 @@ class Scene

void HandleUIchanges();
bool WaitForAssetLoad();

void StartScene();
void DrawUI();
void HandleUiToggleFrustum();

void CreateDeviceWithName(std::wstring& out_adapterDescription);

AssetUploader m_assetUploader;
bool m_demoMode{ false };
bool m_benchmarkMode{ false };
void SwapCameraForDemo(bool in_capture);
};

0 comments on commit 1b753fe

Please sign in to comment.