GteDX11StructuredBuffer.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
10 using namespace gte;
11 
13 {
17 }
18 
20  StructuredBuffer const* sbuffer)
21  :
22  DX11Buffer(sbuffer),
23  mSRView(nullptr),
24  mUAView(nullptr),
25  mCounterStaging(nullptr)
26 {
27  // Specify the buffer description.
28  D3D11_BUFFER_DESC desc;
29  desc.ByteWidth = sbuffer->GetNumBytes();
30  desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
31  desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
32  desc.StructureByteStride = sbuffer->GetElementSize();
33  Resource::Usage usage = sbuffer->GetUsage();
34  if (usage == Resource::IMMUTABLE)
35  {
36  desc.Usage = D3D11_USAGE_IMMUTABLE;
37  desc.CPUAccessFlags = D3D11_CPU_ACCESS_NONE;
38  }
39  else if (usage == Resource::DYNAMIC_UPDATE)
40  {
41  desc.Usage = D3D11_USAGE_DYNAMIC;
42  desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
43  }
44  else // usage == Resource::SHADER_OUTPUT
45  {
46  desc.Usage = D3D11_USAGE_DEFAULT;
47  desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
48  desc.CPUAccessFlags = D3D11_CPU_ACCESS_NONE;
49  }
50 
51  // Create the buffer.
52  ID3D11Buffer* buffer = nullptr;
53  HRESULT hr;
54  if (sbuffer->GetData())
55  {
56  D3D11_SUBRESOURCE_DATA data;
57  data.pSysMem = sbuffer->GetData();
58  data.SysMemPitch = 0;
59  data.SysMemSlicePitch = 0;
60  hr = device->CreateBuffer(&desc, &data, &buffer);
61  }
62  else
63  {
64  hr = device->CreateBuffer(&desc, nullptr, &buffer);
65  }
66  CHECK_HR_RETURN_NONE("Failed to create structured buffer");
67  mDXObject = buffer;
68 
69  // Create views of the buffer.
70  CreateSRView(device);
71  if (usage == Resource::SHADER_OUTPUT)
72  {
73  CreateUAView(device);
74  }
75 
76  // Create a staging buffer if requested.
77  if (sbuffer->GetCopyType() != Resource::COPY_NONE)
78  {
79  CreateStaging(device, desc);
80  }
81 
82  // Create a staging buffer for the internal counter.
83  if (sbuffer->GetCounterType() != StructuredBuffer::CT_NONE)
84  {
85  CreateCounterStaging(device);
86  }
87 }
88 
89 std::shared_ptr<GEObject> DX11StructuredBuffer::Create(void* device, GraphicsObject const* object)
90 {
91  if (object->GetType() == GT_STRUCTURED_BUFFER)
92  {
93  return std::make_shared<DX11StructuredBuffer>(
94  reinterpret_cast<ID3D11Device*>(device),
95  static_cast<StructuredBuffer const*>(object));
96  }
97 
98  LogError("Invalid object type.");
99  return nullptr;
100 }
101 
102 bool DX11StructuredBuffer::CopyGpuToCpu(ID3D11DeviceContext* context)
103 {
104  if (mCounterStaging)
105  {
106  if (!GetNumActiveElements(context))
107  {
108  return false;
109  }
110  }
111  return DX11Buffer::CopyGpuToCpu(context);
112 }
113 
115  ID3D11DeviceContext* context)
116 {
117  // Copy the number of active elements from GPU to staging buffer.
118  context->CopyStructureCount(mCounterStaging, 0, mUAView);
119 
120  // Map the staging buffer.
121  D3D11_MAPPED_SUBRESOURCE sub;
122  HRESULT hr = context->Map(mCounterStaging, 0, D3D11_MAP_READ, 0, &sub);
123  CHECK_HR_RETURN("Failed to map counter staging buffer", false);
124 
125  // Get the number of active elements in the buffer. The internal counter
126  // appears to increment even when the buffer is full, so it needs to be
127  // clamped to the maximum value. The clamping occurs in the call to
128  // SetNumActiveElements().
129  unsigned int numActive = *static_cast<unsigned int*>(sub.pData);
130  context->Unmap(mCounterStaging, 0);
131 
132  // Copy the number to the CPU.
134  return true;
135 }
136 
138 {
139  DX11Buffer::SetName(name);
140  HRESULT hr = SetPrivateName(mSRView, name);
141  CHECK_HR_RETURN_NONE("Failed to set private name");
142  hr = SetPrivateName(mUAView, name);
143  CHECK_HR_RETURN_NONE("Failed to set private name");
144  if (mCounterStaging)
145  {
146  hr = SetPrivateName(mCounterStaging, name);
147  CHECK_HR_RETURN_NONE("Failed to set private name");
148  }
149 }
150 
151 void DX11StructuredBuffer::CreateSRView(ID3D11Device* device)
152 {
153  ID3D11Buffer* buffer = GetDXBuffer();
155 
156  D3D11_SHADER_RESOURCE_VIEW_DESC desc;
157  desc.Format = DXGI_FORMAT_UNKNOWN;
158  desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
159  desc.Buffer.FirstElement = sbuffer->GetOffset();
160  desc.Buffer.NumElements = sbuffer->GetNumElements();
161 
162  HRESULT hr = device->CreateShaderResourceView(buffer, &desc, &mSRView);
163  CHECK_HR_RETURN_NONE("Failed to create shader resource view");
164 }
165 
166 void DX11StructuredBuffer::CreateUAView(ID3D11Device* device)
167 {
168  ID3D11Buffer* buffer = GetDXBuffer();
170 
171  D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
172  desc.Format = DXGI_FORMAT_UNKNOWN;
173  desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
174  desc.Buffer.FirstElement = sbuffer->GetOffset();
175  desc.Buffer.NumElements = sbuffer->GetNumElements();
176  desc.Buffer.Flags = msUAVFlag[sbuffer->GetCounterType()];
177 
178  HRESULT hr = device->CreateUnorderedAccessView(buffer, &desc, &mUAView);
179  CHECK_HR_RETURN_NONE("Failed to create unordered access view");
180 }
181 
183 {
184  // This allows us to read the internal counter of the buffer (if it
185  // has one).
186  D3D11_BUFFER_DESC desc;
187  desc.ByteWidth = 4; // sizeof(unsigned int)
188  desc.Usage = D3D11_USAGE_STAGING;
189  desc.BindFlags = D3D11_BIND_NONE;
190  desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
191  desc.MiscFlags = D3D11_RESOURCE_MISC_NONE;
192 
193  HRESULT hr = device->CreateBuffer(&desc, nullptr, &mCounterStaging);
194  CHECK_HR_RETURN_NONE("Failed to create counter staging buffer");
195 }
196 
197 
198 unsigned int const DX11StructuredBuffer::msUAVFlag[] =
199 {
201  D3D11_BUFFER_UAV_FLAG_APPEND,
202  D3D11_BUFFER_UAV_FLAG_COUNTER
203 };
StructuredBuffer * GetStructuredBuffer() const
DYNAMIC_UPDATE
Definition: GteResource.h:42
COPY_NONE
Definition: GteResource.h:55
void CreateSRView(ID3D11Device *device)
#define D3D11_BUFFER_UAV_FLAG_BASIC
unsigned int GetNumElements() const
Definition: GteResource.h:106
CounterType GetCounterType() const
void CreateCounterStaging(ID3D11Device *device)
#define D3D11_RESOURCE_MISC_NONE
#define CHECK_HR_RETURN_NONE(msg)
unsigned int GetOffset() const
Definition: GteResource.h:173
IMMUTABLE
Definition: GteResource.h:42
ID3D11Buffer * GetDXBuffer() const
Definition: GteDX11Buffer.h:74
HRESULT SetPrivateName(ID3D11DeviceChild *object, std::string const &name)
Usage GetUsage() const
Definition: GteResource.h:126
ID3D11UnorderedAccessView * mUAView
#define D3D11_BIND_NONE
GraphicsObjectType GetType() const
GLuint const GLchar * name
Definition: glcorearb.h:781
ULONG FinalRelease(T *&object)
virtual void SetName(std::string const &name)
unsigned int GetElementSize() const
Definition: GteResource.h:111
virtual bool CopyGpuToCpu(ID3D11DeviceContext *context)
GLsizei const GLchar *const * string
Definition: glcorearb.h:809
#define LogError(message)
Definition: GteLogger.h:92
GLboolean * data
Definition: glcorearb.h:126
ID3D11ShaderResourceView * mSRView
ID3D11DeviceChild * mDXObject
unsigned int GetNumBytes() const
Definition: GteResource.h:116
void CreateStaging(ID3D11Device *device, D3D11_BUFFER_DESC const &bf)
char const * GetData() const
Definition: GteResource.h:151
bool GetNumActiveElements(ID3D11DeviceContext *context)
GT_STRUCTURED_BUFFER
GLsizeiptr const void GLenum usage
Definition: glcorearb.h:659
#define D3D11_CPU_ACCESS_NONE
void SetNumActiveElements(unsigned int numActiveElements)
void CreateUAView(ID3D11Device *device)
static unsigned int const msUAVFlag[]
CopyType GetCopyType() const
Definition: GteResource.h:136
DX11StructuredBuffer(ID3D11Device *device, StructuredBuffer const *sbuffer)
#define CHECK_HR_RETURN(msg, value)
GLuint buffer
Definition: glcorearb.h:655
virtual bool CopyGpuToCpu(ID3D11DeviceContext *context) override
static std::shared_ptr< GEObject > Create(void *device, GraphicsObject const *object)
virtual void SetName(std::string const &name) override


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59