blob: 5109779eab038d1781f624a791e9281d5857d379 [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +00002//
Geoff Langeeba6e12014-02-03 13:12:30 -05003// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// BufferStorage11.cpp Defines the BufferStorage11 class.
9
Geoff Langd47e0fc2013-08-29 11:40:43 -040010#include "libGLESv2/renderer/d3d11/BufferStorage11.h"
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +000011#include "libGLESv2/main.h"
Geoff Langd47e0fc2013-08-29 11:40:43 -040012#include "libGLESv2/renderer/d3d11/Renderer11.h"
Jamie Madill4461f092013-10-10 15:10:39 -040013#include "libGLESv2/renderer/d3d11/formatutils11.h"
Jamie Madill7538f7f2014-04-17 11:53:39 -040014#include "libGLESv2/Buffer.h"
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +000015
16namespace rx
17{
18
Jamie Madill7538f7f2014-04-17 11:53:39 -040019PackPixelsParams::PackPixelsParams()
20 : format(GL_NONE),
21 type(GL_NONE),
22 outputPitch(0),
23 packBuffer(NULL),
24 offset(0)
25{}
26
27PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, GLenum formatIn, GLenum typeIn, GLuint outputPitchIn,
28 const gl::PixelPackState &packIn, ptrdiff_t offsetIn)
29 : area(areaIn),
30 format(formatIn),
31 type(typeIn),
32 outputPitch(outputPitchIn),
33 packBuffer(packIn.pixelBuffer.get()),
34 pack(packIn.alignment, packIn.reverseRowOrder),
35 offset(offsetIn)
36{}
37
Jamie Madill9533dcd2014-02-24 15:27:20 -050038namespace gl_d3d11
39{
40
41D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access)
42{
43 bool readBit = ((access & GL_MAP_READ_BIT) != 0);
44 bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0);
Jamie Madill9533dcd2014-02-24 15:27:20 -050045
Jamie Madill9533dcd2014-02-24 15:27:20 -050046 ASSERT(readBit || writeBit);
47
Jamie Madille708fc02014-03-17 10:23:18 -040048 // Note : we ignore the discard bit, because in D3D11, staging buffers
49 // don't accept the map-discard flag (discard only works for DYNAMIC usage)
50
Jamie Madill9533dcd2014-02-24 15:27:20 -050051 if (readBit && !writeBit)
52 {
53 return D3D11_MAP_READ;
54 }
55 else if (writeBit && !readBit)
56 {
Jamie Madille708fc02014-03-17 10:23:18 -040057 return D3D11_MAP_WRITE;
Jamie Madill9533dcd2014-02-24 15:27:20 -050058 }
59 else if (writeBit && readBit)
60 {
61 return D3D11_MAP_READ_WRITE;
62 }
63 else
64 {
65 UNREACHABLE();
66 return D3D11_MAP_READ;
67 }
68}
69
70}
71
Jamie Madill15cba8b2014-04-08 10:26:34 -040072// Each instance of BufferStorageD3DBuffer11 is specialized for a class of D3D binding points
73// - vertex/transform feedback buffers
74// - index buffers
75// - pixel unpack buffers
76// - uniform buffers
77class BufferStorage11::TypedBufferStorage11
78{
79 public:
80 virtual ~TypedBufferStorage11() {}
81
82 DataRevision getDataRevision() const { return mRevision; }
83 BufferUsage getUsage() const { return mUsage; }
84 size_t getSize() const { return mBufferSize; }
Jamie Madill5fedd012014-05-08 10:19:36 -040085 bool isMappable() const { return (mUsage == BUFFER_USAGE_STAGING || mUsage == BUFFER_USAGE_PIXEL_PACK); }
Jamie Madill15cba8b2014-04-08 10:26:34 -040086
87 void setDataRevision(DataRevision rev) { mRevision = rev; }
88
89 virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
90 size_t size, size_t destOffset) = 0;
Jamie Madill80b95282014-05-06 13:57:43 -040091 virtual bool resize(size_t size, bool preserveData) = 0;
Jamie Madill15cba8b2014-04-08 10:26:34 -040092
Jamie Madill948f5572014-04-08 10:26:35 -040093 virtual void *map(GLbitfield access) = 0;
94 virtual void unmap() = 0;
95
Jamie Madill4305fea2014-04-16 15:12:35 -040096 protected:
Jamie Madill15cba8b2014-04-08 10:26:34 -040097 TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage);
98
99 Renderer11 *mRenderer;
100 DataRevision mRevision;
101 const BufferUsage mUsage;
102 size_t mBufferSize;
103};
104
105// A native buffer storage represents an underlying D3D11 buffer for a particular
106// type of storage.
107class BufferStorage11::NativeBuffer11 : public BufferStorage11::TypedBufferStorage11
108{
109 public:
110 NativeBuffer11(Renderer11 *renderer, BufferUsage usage);
111 ~NativeBuffer11();
112
113 ID3D11Buffer *getNativeBuffer() const { return mNativeBuffer; }
114
115 virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
116 size_t size, size_t destOffset);
Jamie Madill80b95282014-05-06 13:57:43 -0400117 virtual bool resize(size_t size, bool preserveData);
Jamie Madill15cba8b2014-04-08 10:26:34 -0400118
Jamie Madill948f5572014-04-08 10:26:35 -0400119 virtual void *map(GLbitfield access);
120 virtual void unmap();
121
Jamie Madill4305fea2014-04-16 15:12:35 -0400122 private:
Jamie Madill15cba8b2014-04-08 10:26:34 -0400123 ID3D11Buffer *mNativeBuffer;
124
125 static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize);
126};
127
Jamie Madill4305fea2014-04-16 15:12:35 -0400128// Pack storage represents internal storage for pack buffers. We implement pack buffers
129// as CPU memory, tied to a staging texture, for asynchronous texture readback.
130class BufferStorage11::PackStorage11 : public BufferStorage11::TypedBufferStorage11
131{
132 public:
133 PackStorage11(Renderer11 *renderer);
134 ~PackStorage11();
135
136 virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
137 size_t size, size_t destOffset);
Jamie Madill80b95282014-05-06 13:57:43 -0400138 virtual bool resize(size_t size, bool preserveData);
Jamie Madill4305fea2014-04-16 15:12:35 -0400139
140 virtual void *map(GLbitfield access);
141 virtual void unmap();
142
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400143 void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
144
Jamie Madill4305fea2014-04-16 15:12:35 -0400145 private:
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400146
147 void flushQueuedPackCommand();
148
Jamie Madill4305fea2014-04-16 15:12:35 -0400149 ID3D11Texture2D *mStagingTexture;
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400150 DXGI_FORMAT mTextureFormat;
151 gl::Extents mTextureSize;
Jamie Madill80b95282014-05-06 13:57:43 -0400152 std::vector<unsigned char> mMemoryBuffer;
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400153 PackPixelsParams *mQueuedPackCommand;
Jamie Madill80b95282014-05-06 13:57:43 -0400154 PackPixelsParams mPackParams;
Jamie Madill73571e62014-04-24 14:50:56 -0400155 bool mDataModified;
Jamie Madill4305fea2014-04-16 15:12:35 -0400156};
157
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000158BufferStorage11::BufferStorage11(Renderer11 *renderer)
Geoff Langecc8b6f2014-01-30 10:44:23 -0500159 : mRenderer(renderer),
Jamie Madill73571e62014-04-24 14:50:56 -0400160 mMappedStorage(NULL),
Geoff Langecc8b6f2014-01-30 10:44:23 -0500161 mResolvedDataRevision(0),
162 mReadUsageCount(0),
Geoff Langecc8b6f2014-01-30 10:44:23 -0500163 mSize(0)
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000164{
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000165}
166
167BufferStorage11::~BufferStorage11()
168{
Jamie Madill15cba8b2014-04-08 10:26:34 -0400169 for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++)
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000170 {
Geoff Lang9c53f1e2014-01-08 13:41:47 -0500171 SafeDelete(it->second);
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000172 }
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000173}
174
175BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage)
176{
177 ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage));
178 return static_cast<BufferStorage11*>(bufferStorage);
179}
180
181void *BufferStorage11::getData()
182{
Jamie Madill15cba8b2014-04-08 10:26:34 -0400183 NativeBuffer11 *stagingBuffer = getStagingBuffer();
Jamie Madill80b95282014-05-06 13:57:43 -0400184
185 if (!stagingBuffer)
186 {
187 // Out-of-memory
188 return NULL;
189 }
190
Geoff Langecc8b6f2014-01-30 10:44:23 -0500191 if (stagingBuffer->getDataRevision() > mResolvedDataRevision)
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000192 {
Geoff Langecc8b6f2014-01-30 10:44:23 -0500193 if (stagingBuffer->getSize() > mResolvedData.size())
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000194 {
Geoff Langecc8b6f2014-01-30 10:44:23 -0500195 mResolvedData.resize(stagingBuffer->getSize());
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000196 }
197
Geoff Langecc8b6f2014-01-30 10:44:23 -0500198 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
199
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000200 D3D11_MAPPED_SUBRESOURCE mappedResource;
Jamie Madill15cba8b2014-04-08 10:26:34 -0400201 HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource);
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000202 if (FAILED(result))
203 {
204 return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
205 }
206
Geoff Langecc8b6f2014-01-30 10:44:23 -0500207 memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize());
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000208
Jamie Madill15cba8b2014-04-08 10:26:34 -0400209 context->Unmap(stagingBuffer->getNativeBuffer(), 0);
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000210
Geoff Langecc8b6f2014-01-30 10:44:23 -0500211 mResolvedDataRevision = stagingBuffer->getDataRevision();
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000212 }
213
Nicolas Capens3b35e4d2014-04-22 11:34:31 -0400214 mReadUsageCount = 0;
215
Geoff Langecc8b6f2014-01-30 10:44:23 -0500216 return mResolvedData.data();
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000217}
218
Geoff Lang876dc722014-05-01 17:10:24 -0400219void BufferStorage11::setData(const void* data, size_t size, size_t offset)
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000220{
Geoff Langecc8b6f2014-01-30 10:44:23 -0500221 size_t requiredSize = size + offset;
Jamie Madille7a453a2014-04-24 14:50:57 -0400222 mSize = std::max(mSize, requiredSize);
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000223
Geoff Langecc8b6f2014-01-30 10:44:23 -0500224 if (data)
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000225 {
Jamie Madille7a453a2014-04-24 14:50:57 -0400226 NativeBuffer11 *stagingBuffer = getStagingBuffer();
227
Jamie Madill80b95282014-05-06 13:57:43 -0400228 if (!stagingBuffer)
229 {
230 // Out-of-memory
231 return;
232 }
233
Jamie Madille7a453a2014-04-24 14:50:57 -0400234 // Explicitly resize the staging buffer, preserving data if the new data will not
235 // completely fill the buffer
236 if (stagingBuffer->getSize() < requiredSize)
237 {
238 bool preserveData = (offset > 0);
Jamie Madill80b95282014-05-06 13:57:43 -0400239 if (!stagingBuffer->resize(requiredSize, preserveData))
240 {
241 // Out-of-memory
242 return;
243 }
Jamie Madille7a453a2014-04-24 14:50:57 -0400244 }
245
Geoff Langecc8b6f2014-01-30 10:44:23 -0500246 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
247
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000248 D3D11_MAPPED_SUBRESOURCE mappedResource;
Jamie Madill15cba8b2014-04-08 10:26:34 -0400249 HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_WRITE, 0, &mappedResource);
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000250 if (FAILED(result))
251 {
252 return gl::error(GL_OUT_OF_MEMORY);
253 }
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000254
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000255 unsigned char *offsetBufferPointer = reinterpret_cast<unsigned char *>(mappedResource.pData) + offset;
256 memcpy(offsetBufferPointer, data, size);
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000257
Jamie Madill15cba8b2014-04-08 10:26:34 -0400258 context->Unmap(stagingBuffer->getNativeBuffer(), 0);
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000259
Jamie Madille7a453a2014-04-24 14:50:57 -0400260 stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
261 }
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000262}
263
Geoff Lang876dc722014-05-01 17:10:24 -0400264void BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset)
shannon.woods%transgaming.com@gtempaccount.comab30bab2013-04-13 03:39:24 +0000265{
Geoff Langecc8b6f2014-01-30 10:44:23 -0500266 BufferStorage11* sourceStorage11 = makeBufferStorage11(sourceStorage);
267 if (sourceStorage11)
shannon.woods%transgaming.com@gtempaccount.comab30bab2013-04-13 03:39:24 +0000268 {
Jamie Madill15cba8b2014-04-08 10:26:34 -0400269 TypedBufferStorage11 *dest = getLatestStorage();
Geoff Langecc8b6f2014-01-30 10:44:23 -0500270 if (!dest)
271 {
Jamie Madill9533dcd2014-02-24 15:27:20 -0500272 dest = getStagingBuffer();
Geoff Langecc8b6f2014-01-30 10:44:23 -0500273 }
shannon.woods%transgaming.com@gtempaccount.comab30bab2013-04-13 03:39:24 +0000274
Jamie Madill15cba8b2014-04-08 10:26:34 -0400275 TypedBufferStorage11 *source = sourceStorage11->getLatestStorage();
Geoff Langecc8b6f2014-01-30 10:44:23 -0500276 if (source && dest)
277 {
Jamie Madill5fedd012014-05-08 10:19:36 -0400278 // If copying to/from a pixel pack buffer, we must have a staging or
279 // pack buffer partner, because other native buffers can't be mapped
280 if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable())
281 {
282 source = sourceStorage11->getStagingBuffer();
283 }
284 else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable())
285 {
286 dest = getStagingBuffer();
287 }
288
Geoff Langecc8b6f2014-01-30 10:44:23 -0500289 dest->copyFromStorage(source, sourceOffset, size, destOffset);
290 dest->setDataRevision(dest->getDataRevision() + 1);
291 }
shannon.woods%transgaming.com@gtempaccount.comab30bab2013-04-13 03:39:24 +0000292
Geoff Lang876dc722014-05-01 17:10:24 -0400293 mSize = std::max<size_t>(mSize, destOffset + size);
shannon.woods%transgaming.com@gtempaccount.comab30bab2013-04-13 03:39:24 +0000294 }
295}
296
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000297void BufferStorage11::clear()
298{
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000299 mSize = 0;
Geoff Langecc8b6f2014-01-30 10:44:23 -0500300 mResolvedDataRevision = 0;
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000301}
302
Geoff Langeeba6e12014-02-03 13:12:30 -0500303void BufferStorage11::markTransformFeedbackUsage()
304{
Jamie Madill15cba8b2014-04-08 10:26:34 -0400305 TypedBufferStorage11 *transformFeedbackStorage = getStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
Jamie Madill80b95282014-05-06 13:57:43 -0400306
307 if (transformFeedbackStorage)
308 {
309 transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
310 }
Geoff Langeeba6e12014-02-03 13:12:30 -0500311}
312
Geoff Lang876dc722014-05-01 17:10:24 -0400313size_t BufferStorage11::getSize() const
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000314{
315 return mSize;
316}
317
318bool BufferStorage11::supportsDirectBinding() const
319{
320 return true;
321}
322
323void BufferStorage11::markBufferUsage()
324{
325 mReadUsageCount++;
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000326
shannonwoods@chromium.org29233b22013-05-30 00:04:57 +0000327 const unsigned int usageLimit = 5;
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000328
Geoff Langecc8b6f2014-01-30 10:44:23 -0500329 if (mReadUsageCount > usageLimit && mResolvedData.size() > 0)
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000330 {
Geoff Langecc8b6f2014-01-30 10:44:23 -0500331 mResolvedData.resize(0);
332 mResolvedDataRevision = 0;
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000333 }
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000334}
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000335
Geoff Lang9c53f1e2014-01-08 13:41:47 -0500336ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage)
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000337{
shannonwoods@chromium.org29233b22013-05-30 00:04:57 +0000338 markBufferUsage();
Jamie Madill15cba8b2014-04-08 10:26:34 -0400339
340 TypedBufferStorage11 *typedBuffer = getStorage(usage);
Jamie Madill80b95282014-05-06 13:57:43 -0400341
342 if (!typedBuffer)
343 {
344 // Storage out-of-memory
345 return NULL;
346 }
347
Geoff Lang6cec8502014-04-19 12:39:25 -0400348 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, typedBuffer));
Jamie Madill15cba8b2014-04-08 10:26:34 -0400349
350 return static_cast<NativeBuffer11*>(typedBuffer)->getNativeBuffer();
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000351}
352
Jamie Madill89a0bf52013-09-18 14:36:24 -0400353ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
354{
Jamie Madill15cba8b2014-04-08 10:26:34 -0400355 TypedBufferStorage11 *storage = getStorage(BUFFER_USAGE_PIXEL_UNPACK);
Jamie Madill80b95282014-05-06 13:57:43 -0400356
357 if (!storage)
358 {
359 // Storage out-of-memory
360 return NULL;
361 }
362
Geoff Lang6cec8502014-04-19 12:39:25 -0400363 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, storage));
Jamie Madill15cba8b2014-04-08 10:26:34 -0400364 ID3D11Buffer *buffer = static_cast<NativeBuffer11*>(storage)->getNativeBuffer();
Jamie Madill4461f092013-10-10 15:10:39 -0400365
366 auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
367
368 if (bufferSRVIt != mBufferResourceViews.end())
369 {
370 if (bufferSRVIt->second.first == buffer)
371 {
372 return bufferSRVIt->second.second;
373 }
374 else
375 {
376 // The underlying buffer has changed since the SRV was created: recreate the SRV.
377 SafeRelease(bufferSRVIt->second.second);
378 }
379 }
380
381 ID3D11Device *device = mRenderer->getDevice();
382 ID3D11ShaderResourceView *bufferSRV = NULL;
383
384 D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc;
385 bufferSRVDesc.Buffer.ElementOffset = 0;
Jamie Madill9eeecfc2014-01-29 09:26:48 -0500386 bufferSRVDesc.Buffer.ElementWidth = mSize / d3d11::GetFormatPixelBytes(srvFormat);
Jamie Madill4461f092013-10-10 15:10:39 -0400387 bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
388 bufferSRVDesc.Format = srvFormat;
389
390 HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV);
Geoff Lang9cd19152014-05-28 15:54:34 -0400391 UNUSED_ASSERTION_VARIABLE(result);
Jamie Madill4461f092013-10-10 15:10:39 -0400392 ASSERT(SUCCEEDED(result));
393
394 mBufferResourceViews[srvFormat] = BufferSRVPair(buffer, bufferSRV);
395
396 return bufferSRV;
Jamie Madill89a0bf52013-09-18 14:36:24 -0400397}
398
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400399void BufferStorage11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
400{
401 PackStorage11 *packStorage = getPackStorage();
402
403 TypedBufferStorage11 *latestStorage = getLatestStorage();
404
Jamie Madill235a6ab2014-05-08 10:44:20 -0400405 if (packStorage)
Jamie Madill80b95282014-05-06 13:57:43 -0400406 {
407 packStorage->packPixels(srcTexture, srcSubresource, params);
408 packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1);
409 }
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400410}
411
Jamie Madill15cba8b2014-04-08 10:26:34 -0400412BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage usage)
Geoff Langecc8b6f2014-01-30 10:44:23 -0500413{
Jamie Madill15cba8b2014-04-08 10:26:34 -0400414 TypedBufferStorage11 *directBuffer = NULL;
415 auto directBufferIt = mTypedBuffers.find(usage);
416 if (directBufferIt != mTypedBuffers.end())
Geoff Langecc8b6f2014-01-30 10:44:23 -0500417 {
418 directBuffer = directBufferIt->second;
419 }
420
421 if (!directBuffer)
422 {
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400423 if (usage == BUFFER_USAGE_PIXEL_PACK)
424 {
425 directBuffer = new PackStorage11(mRenderer);
426 }
427 else
428 {
429 // buffer is not allocated, create it
430 directBuffer = new NativeBuffer11(mRenderer, usage);
431 }
432
Jamie Madill15cba8b2014-04-08 10:26:34 -0400433 mTypedBuffers.insert(std::make_pair(usage, directBuffer));
Geoff Langecc8b6f2014-01-30 10:44:23 -0500434 }
435
Jamie Madille7a453a2014-04-24 14:50:57 -0400436 // resize buffer
437 if (directBuffer->getSize() < mSize)
438 {
Jamie Madill80b95282014-05-06 13:57:43 -0400439 if (!directBuffer->resize(mSize, true))
440 {
441 // Out of memory error
442 return NULL;
443 }
Jamie Madille7a453a2014-04-24 14:50:57 -0400444 }
445
Jamie Madill15cba8b2014-04-08 10:26:34 -0400446 TypedBufferStorage11 *latestBuffer = getLatestStorage();
Geoff Langecc8b6f2014-01-30 10:44:23 -0500447 if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision())
448 {
Jamie Madill5fedd012014-05-08 10:19:36 -0400449 // if copying from a pack buffer to a non-staging native buffer, we must first
450 // copy through the staging buffer, because other native buffers can't be mapped
451 if (latestBuffer->getUsage() == BUFFER_USAGE_PIXEL_PACK && !directBuffer->isMappable())
452 {
453 NativeBuffer11 *stagingBuffer = getStagingBuffer();
454
455 stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0);
456 directBuffer->setDataRevision(latestBuffer->getDataRevision());
457
458 latestBuffer = stagingBuffer;
459 }
460
Geoff Langecc8b6f2014-01-30 10:44:23 -0500461 // if copyFromStorage returns true, the D3D buffer has been recreated
462 // and we should update our serial
463 if (directBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
464 {
465 updateSerial();
466 }
467 directBuffer->setDataRevision(latestBuffer->getDataRevision());
468 }
469
470 return directBuffer;
471}
472
Jamie Madill15cba8b2014-04-08 10:26:34 -0400473BufferStorage11::TypedBufferStorage11 *BufferStorage11::getLatestStorage() const
Geoff Langecc8b6f2014-01-30 10:44:23 -0500474{
475 // Even though we iterate over all the direct buffers, it is expected that only
476 // 1 or 2 will be present.
Jamie Madill15cba8b2014-04-08 10:26:34 -0400477 TypedBufferStorage11 *latestStorage = NULL;
Geoff Langecc8b6f2014-01-30 10:44:23 -0500478 DataRevision latestRevision = 0;
Jamie Madill15cba8b2014-04-08 10:26:34 -0400479 for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++)
Geoff Langecc8b6f2014-01-30 10:44:23 -0500480 {
Jamie Madill15cba8b2014-04-08 10:26:34 -0400481 TypedBufferStorage11 *storage = it->second;
Geoff Lang7b827592014-05-08 11:12:26 -0400482 if (!latestStorage || storage->getDataRevision() > latestRevision)
Geoff Langecc8b6f2014-01-30 10:44:23 -0500483 {
484 latestStorage = storage;
485 latestRevision = storage->getDataRevision();
486 }
487 }
488
489 return latestStorage;
490}
491
Jamie Madilld9fa3b92014-02-19 10:30:51 -0500492bool BufferStorage11::isMapped() const
493{
Jamie Madill73571e62014-04-24 14:50:56 -0400494 return mMappedStorage != NULL;
Jamie Madilld9fa3b92014-02-19 10:30:51 -0500495}
496
497void *BufferStorage11::map(GLbitfield access)
498{
Jamie Madill73571e62014-04-24 14:50:56 -0400499 ASSERT(!mMappedStorage);
500
501 TypedBufferStorage11 *latestStorage = getLatestStorage();
Jamie Madill235a6ab2014-05-08 10:44:20 -0400502 ASSERT(latestStorage);
Jamie Madill73571e62014-04-24 14:50:56 -0400503
504 if (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
505 latestStorage->getUsage() == BUFFER_USAGE_STAGING)
506 {
507 mMappedStorage = latestStorage;
508 }
509 else
510 {
511 mMappedStorage = getStagingBuffer();
512 }
513
Jamie Madill80b95282014-05-06 13:57:43 -0400514 if (!mMappedStorage)
515 {
516 // Out-of-memory
517 return NULL;
518 }
519
Jamie Madill73571e62014-04-24 14:50:56 -0400520 return mMappedStorage->map(access);
Jamie Madilld9fa3b92014-02-19 10:30:51 -0500521}
522
523void BufferStorage11::unmap()
524{
Jamie Madill73571e62014-04-24 14:50:56 -0400525 ASSERT(mMappedStorage);
526 mMappedStorage->unmap();
527 mMappedStorage = NULL;
Jamie Madill9533dcd2014-02-24 15:27:20 -0500528}
529
Jamie Madill15cba8b2014-04-08 10:26:34 -0400530BufferStorage11::NativeBuffer11 *BufferStorage11::getStagingBuffer()
Jamie Madill9533dcd2014-02-24 15:27:20 -0500531{
Jamie Madill15cba8b2014-04-08 10:26:34 -0400532 TypedBufferStorage11 *stagingStorage = getStorage(BUFFER_USAGE_STAGING);
Jamie Madill80b95282014-05-06 13:57:43 -0400533
534 if (!stagingStorage)
535 {
536 // Out-of-memory
537 return NULL;
538 }
539
Jamie Madill15cba8b2014-04-08 10:26:34 -0400540 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, stagingStorage));
541 return static_cast<NativeBuffer11*>(stagingStorage);
Jamie Madilld9fa3b92014-02-19 10:30:51 -0500542}
543
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400544BufferStorage11::PackStorage11 *BufferStorage11::getPackStorage()
545{
546 TypedBufferStorage11 *packStorage = getStorage(BUFFER_USAGE_PIXEL_PACK);
Jamie Madill80b95282014-05-06 13:57:43 -0400547
548 if (!packStorage)
549 {
550 // Out-of-memory
551 return NULL;
552 }
553
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400554 ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, packStorage));
555 return static_cast<PackStorage11*>(packStorage);
556}
557
Jamie Madill15cba8b2014-04-08 10:26:34 -0400558BufferStorage11::TypedBufferStorage11::TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage)
Jamie Madill171ca0e2013-10-10 15:10:31 -0400559 : mRenderer(renderer),
Geoff Lang9c53f1e2014-01-08 13:41:47 -0500560 mUsage(usage),
Geoff Langecc8b6f2014-01-30 10:44:23 -0500561 mRevision(0),
Geoff Langecc8b6f2014-01-30 10:44:23 -0500562 mBufferSize(0)
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000563{
564}
565
Jamie Madill15cba8b2014-04-08 10:26:34 -0400566BufferStorage11::NativeBuffer11::NativeBuffer11(Renderer11 *renderer, BufferUsage usage)
567 : TypedBufferStorage11(renderer, usage),
568 mNativeBuffer(NULL)
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000569{
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000570}
571
Jamie Madill15cba8b2014-04-08 10:26:34 -0400572BufferStorage11::NativeBuffer11::~NativeBuffer11()
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000573{
Jamie Madill15cba8b2014-04-08 10:26:34 -0400574 SafeRelease(mNativeBuffer);
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000575}
576
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000577// Returns true if it recreates the direct buffer
Jamie Madill15cba8b2014-04-08 10:26:34 -0400578bool BufferStorage11::NativeBuffer11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
579 size_t size, size_t destOffset)
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000580{
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000581 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
582
Geoff Langecc8b6f2014-01-30 10:44:23 -0500583 size_t requiredSize = sourceOffset + size;
Jamie Madill15cba8b2014-04-08 10:26:34 -0400584 bool createBuffer = !mNativeBuffer || mBufferSize < requiredSize;
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000585
586 // (Re)initialize D3D buffer if needed
587 if (createBuffer)
588 {
Geoff Langecc8b6f2014-01-30 10:44:23 -0500589 bool preserveData = (destOffset > 0);
590 resize(source->getSize(), preserveData);
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000591 }
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000592
Jamie Madill14764a02014-05-08 10:19:20 -0400593 if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK)
594 {
595 ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, source));
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000596
Jamie Madill14764a02014-05-08 10:19:20 -0400597 unsigned char *sourcePointer = static_cast<unsigned char *>(source->map(GL_MAP_READ_BIT)) + sourceOffset;
Jamie Madill15cba8b2014-04-08 10:26:34 -0400598
Jamie Madill14764a02014-05-08 10:19:20 -0400599 D3D11_MAPPED_SUBRESOURCE mappedResource;
600 HRESULT hr = context->Map(mNativeBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
Geoff Lang9cd19152014-05-28 15:54:34 -0400601 UNUSED_ASSERTION_VARIABLE(hr);
Jamie Madill14764a02014-05-08 10:19:20 -0400602 ASSERT(SUCCEEDED(hr));
603
604 unsigned char *destPointer = static_cast<unsigned char *>(mappedResource.pData) + destOffset;
605
606 // Offset bounds are validated at the API layer
607 ASSERT(sourceOffset + size <= destOffset + mBufferSize);
608 memcpy(destPointer, sourcePointer, size);
609 }
610 else
611 {
612 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, source));
613
614 D3D11_BOX srcBox;
615 srcBox.left = sourceOffset;
616 srcBox.right = sourceOffset + size;
617 srcBox.top = 0;
618 srcBox.bottom = 1;
619 srcBox.front = 0;
620 srcBox.back = 1;
621
622 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, source));
623 ID3D11Buffer *sourceBuffer = static_cast<NativeBuffer11*>(source)->getNativeBuffer();
624
625 context->CopySubresourceRegion(mNativeBuffer, 0, destOffset, 0, 0, sourceBuffer, 0, &srcBox);
626 }
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000627
628 return createBuffer;
629}
630
Jamie Madill80b95282014-05-06 13:57:43 -0400631bool BufferStorage11::NativeBuffer11::resize(size_t size, bool preserveData)
Geoff Langecc8b6f2014-01-30 10:44:23 -0500632{
633 ID3D11Device *device = mRenderer->getDevice();
634 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
635
636 D3D11_BUFFER_DESC bufferDesc;
637 fillBufferDesc(&bufferDesc, mRenderer, mUsage, size);
638
639 ID3D11Buffer *newBuffer;
640 HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
641
642 if (FAILED(result))
643 {
Jamie Madill80b95282014-05-06 13:57:43 -0400644 return gl::error(GL_OUT_OF_MEMORY, false);
Geoff Langecc8b6f2014-01-30 10:44:23 -0500645 }
646
Jamie Madill15cba8b2014-04-08 10:26:34 -0400647 if (mNativeBuffer && preserveData)
Geoff Langecc8b6f2014-01-30 10:44:23 -0500648 {
Jamie Madillea77ce22014-06-16 13:20:17 -0400649 // We don't call resize if the buffer is big enough already.
650 ASSERT(mBufferSize <= size);
651
Geoff Langecc8b6f2014-01-30 10:44:23 -0500652 D3D11_BOX srcBox;
653 srcBox.left = 0;
Jamie Madillea77ce22014-06-16 13:20:17 -0400654 srcBox.right = mBufferSize;
Geoff Langecc8b6f2014-01-30 10:44:23 -0500655 srcBox.top = 0;
656 srcBox.bottom = 1;
657 srcBox.front = 0;
658 srcBox.back = 1;
659
Jamie Madill15cba8b2014-04-08 10:26:34 -0400660 context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mNativeBuffer, 0, &srcBox);
Geoff Langecc8b6f2014-01-30 10:44:23 -0500661 }
662
663 // No longer need the old buffer
Jamie Madill15cba8b2014-04-08 10:26:34 -0400664 SafeRelease(mNativeBuffer);
665 mNativeBuffer = newBuffer;
Geoff Langecc8b6f2014-01-30 10:44:23 -0500666
667 mBufferSize = bufferDesc.ByteWidth;
Jamie Madill80b95282014-05-06 13:57:43 -0400668
669 return true;
Geoff Langecc8b6f2014-01-30 10:44:23 -0500670}
671
Jamie Madill15cba8b2014-04-08 10:26:34 -0400672void BufferStorage11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer,
673 BufferUsage usage, unsigned int bufferSize)
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000674{
675 bufferDesc->ByteWidth = bufferSize;
676 bufferDesc->MiscFlags = 0;
677 bufferDesc->StructureByteStride = 0;
678
Geoff Lang9c53f1e2014-01-08 13:41:47 -0500679 switch (usage)
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000680 {
Geoff Langecc8b6f2014-01-30 10:44:23 -0500681 case BUFFER_USAGE_STAGING:
682 bufferDesc->Usage = D3D11_USAGE_STAGING;
683 bufferDesc->BindFlags = 0;
684 bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
685 break;
686
Geoff Langeeba6e12014-02-03 13:12:30 -0500687 case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000688 bufferDesc->Usage = D3D11_USAGE_DEFAULT;
Geoff Langeeba6e12014-02-03 13:12:30 -0500689 bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000690 bufferDesc->CPUAccessFlags = 0;
Geoff Lang9c53f1e2014-01-08 13:41:47 -0500691 break;
692
693 case BUFFER_USAGE_INDEX:
694 bufferDesc->Usage = D3D11_USAGE_DEFAULT;
695 bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER;
696 bufferDesc->CPUAccessFlags = 0;
697 break;
698
Geoff Langecc8b6f2014-01-30 10:44:23 -0500699 case BUFFER_USAGE_PIXEL_UNPACK:
Geoff Lang9c53f1e2014-01-08 13:41:47 -0500700 bufferDesc->Usage = D3D11_USAGE_DEFAULT;
701 bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
702 bufferDesc->CPUAccessFlags = 0;
703 break;
704
705 case BUFFER_USAGE_UNIFORM:
shannonwoods@chromium.orgce672482013-05-30 00:05:14 +0000706 bufferDesc->Usage = D3D11_USAGE_DYNAMIC;
707 bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
708 bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
709
710 // Constant buffers must be of a limited size, and aligned to 16 byte boundaries
711 // For our purposes we ignore any buffer data past the maximum constant buffer size
712 bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u);
Geoff Lang9c53f1e2014-01-08 13:41:47 -0500713 bufferDesc->ByteWidth = std::min(bufferDesc->ByteWidth, renderer->getMaxUniformBufferSize());
714 break;
715
716 default:
717 UNREACHABLE();
shannonwoods@chromium.org675526e2013-05-30 00:04:49 +0000718 }
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000719}
720
Jamie Madill948f5572014-04-08 10:26:35 -0400721void *BufferStorage11::NativeBuffer11::map(GLbitfield access)
722{
723 ASSERT(mUsage == BUFFER_USAGE_STAGING);
724
725 D3D11_MAPPED_SUBRESOURCE mappedResource;
726 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
727 D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access);
728 UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0);
729
730 HRESULT result = context->Map(mNativeBuffer, 0, d3dMapType, d3dMapFlag, &mappedResource);
Geoff Lang9cd19152014-05-28 15:54:34 -0400731 UNUSED_ASSERTION_VARIABLE(result);
Jamie Madill948f5572014-04-08 10:26:35 -0400732 ASSERT(SUCCEEDED(result));
733
734 return mappedResource.pData;
735}
736
737void BufferStorage11::NativeBuffer11::unmap()
738{
739 ASSERT(mUsage == BUFFER_USAGE_STAGING);
740 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
741 context->Unmap(mNativeBuffer, 0);
742}
743
Jamie Madill4305fea2014-04-16 15:12:35 -0400744BufferStorage11::PackStorage11::PackStorage11(Renderer11 *renderer)
745 : TypedBufferStorage11(renderer, BUFFER_USAGE_PIXEL_PACK),
746 mStagingTexture(NULL),
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400747 mTextureFormat(DXGI_FORMAT_UNKNOWN),
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400748 mQueuedPackCommand(NULL),
Jamie Madill73571e62014-04-24 14:50:56 -0400749 mDataModified(false)
Jamie Madill4305fea2014-04-16 15:12:35 -0400750{
751}
752
753BufferStorage11::PackStorage11::~PackStorage11()
754{
755 SafeRelease(mStagingTexture);
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400756 SafeDelete(mQueuedPackCommand);
Jamie Madill4305fea2014-04-16 15:12:35 -0400757}
758
759bool BufferStorage11::PackStorage11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
760 size_t size, size_t destOffset)
761{
762 UNIMPLEMENTED();
763 return false;
764}
765
Jamie Madill80b95282014-05-06 13:57:43 -0400766bool BufferStorage11::PackStorage11::resize(size_t size, bool preserveData)
Jamie Madill4305fea2014-04-16 15:12:35 -0400767{
Jamie Madill19811d02014-05-01 14:51:04 -0400768 if (size != mBufferSize)
769 {
Jamie Madill80b95282014-05-06 13:57:43 -0400770 mMemoryBuffer.resize(size, 0);
Jamie Madill19811d02014-05-01 14:51:04 -0400771 mBufferSize = size;
772 }
Jamie Madill80b95282014-05-06 13:57:43 -0400773
774 return true;
Jamie Madill4305fea2014-04-16 15:12:35 -0400775}
776
777void *BufferStorage11::PackStorage11::map(GLbitfield access)
778{
Jamie Madill73571e62014-04-24 14:50:56 -0400779 // TODO: fast path
780 // We might be able to optimize out one or more memcpy calls by detecting when
781 // and if D3D packs the staging texture memory identically to how we would fill
782 // the pack buffer according to the current pack state.
783
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400784 flushQueuedPackCommand();
Jamie Madill73571e62014-04-24 14:50:56 -0400785 mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
Jamie Madill80b95282014-05-06 13:57:43 -0400786
787 return &mMemoryBuffer[0];
Jamie Madill4305fea2014-04-16 15:12:35 -0400788}
789
790void BufferStorage11::PackStorage11::unmap()
791{
Jamie Madill19811d02014-05-01 14:51:04 -0400792 // No-op
Jamie Madill4305fea2014-04-16 15:12:35 -0400793}
794
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400795void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
796{
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400797 flushQueuedPackCommand();
798 mQueuedPackCommand = new PackPixelsParams(params);
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400799
800 D3D11_TEXTURE2D_DESC textureDesc;
801 srcTexure->GetDesc(&textureDesc);
802
803 if (mStagingTexture != NULL &&
804 (mTextureFormat != textureDesc.Format ||
805 mTextureSize.width != params.area.width ||
806 mTextureSize.height != params.area.height))
807 {
808 SafeRelease(mStagingTexture);
809 mTextureSize.width = 0;
810 mTextureSize.height = 0;
811 mTextureFormat = DXGI_FORMAT_UNKNOWN;
812 }
813
814 if (mStagingTexture == NULL)
815 {
816 ID3D11Device *device = mRenderer->getDevice();
817 HRESULT hr;
818
819 mTextureSize.width = params.area.width;
820 mTextureSize.height = params.area.height;
821 mTextureFormat = textureDesc.Format;
822
823 D3D11_TEXTURE2D_DESC stagingDesc;
824 stagingDesc.Width = params.area.width;
825 stagingDesc.Height = params.area.height;
826 stagingDesc.MipLevels = 1;
827 stagingDesc.ArraySize = 1;
828 stagingDesc.Format = mTextureFormat;
829 stagingDesc.SampleDesc.Count = 1;
830 stagingDesc.SampleDesc.Quality = 0;
831 stagingDesc.Usage = D3D11_USAGE_STAGING;
832 stagingDesc.BindFlags = 0;
833 stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
834 stagingDesc.MiscFlags = 0;
835
836 hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture);
837 ASSERT(SUCCEEDED(hr));
838 }
839
Jamie Madillc9fa6ed2014-04-17 11:53:40 -0400840 if (textureDesc.SampleDesc.Count > 1)
841 {
842 UNIMPLEMENTED();
843 }
844
845 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
846 D3D11_BOX srcBox;
847 srcBox.left = params.area.x;
848 srcBox.right = params.area.x + params.area.width;
849 srcBox.top = params.area.y;
850 srcBox.bottom = params.area.y + params.area.height;
851 srcBox.front = 0;
852 srcBox.back = 1;
853
854 // Asynchronous copy
855 immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox);
856}
857
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400858void BufferStorage11::PackStorage11::flushQueuedPackCommand()
859{
Jamie Madill80b95282014-05-06 13:57:43 -0400860 ASSERT(!mMemoryBuffer.empty());
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400861
862 if (mQueuedPackCommand)
863 {
Jamie Madill80b95282014-05-06 13:57:43 -0400864 mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, &mMemoryBuffer[0]);
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400865 SafeDelete(mQueuedPackCommand);
866 }
867}
868
shannon.woods@transgaming.com70c856f2013-02-28 23:07:53 +0000869}