1 #include "precompiled.h"
3 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
8 // BufferStorage11.cpp Defines the BufferStorage11 class.
10 #include "libGLESv2/renderer/d3d11/BufferStorage11.h"
11 #include "libGLESv2/main.h"
12 #include "libGLESv2/renderer/d3d11/Renderer11.h"
13 #include "libGLESv2/renderer/d3d11/formatutils11.h"
14 #include "libGLESv2/Buffer.h"
19 PackPixelsParams::PackPixelsParams()
27 PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, GLenum formatIn, GLenum typeIn, GLuint outputPitchIn,
28 const gl::PixelPackState &packIn, ptrdiff_t offsetIn)
32 outputPitch(outputPitchIn),
33 packBuffer(packIn.pixelBuffer.get()),
34 pack(packIn.alignment, packIn.reverseRowOrder),
41 D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access)
43 bool readBit = ((access & GL_MAP_READ_BIT) != 0);
44 bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0);
46 ASSERT(readBit || writeBit);
48 // 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)
51 if (readBit && !writeBit)
53 return D3D11_MAP_READ;
55 else if (writeBit && !readBit)
57 return D3D11_MAP_WRITE;
59 else if (writeBit && readBit)
61 return D3D11_MAP_READ_WRITE;
66 return D3D11_MAP_READ;
72 // Each instance of BufferStorageD3DBuffer11 is specialized for a class of D3D binding points
73 // - vertex/transform feedback buffers
75 // - pixel unpack buffers
77 class BufferStorage11::TypedBufferStorage11
80 virtual ~TypedBufferStorage11() {}
82 DataRevision getDataRevision() const { return mRevision; }
83 BufferUsage getUsage() const { return mUsage; }
84 size_t getSize() const { return mBufferSize; }
85 bool isMappable() const { return (mUsage == BUFFER_USAGE_STAGING || mUsage == BUFFER_USAGE_PIXEL_PACK); }
87 void setDataRevision(DataRevision rev) { mRevision = rev; }
89 virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
90 size_t size, size_t destOffset) = 0;
91 virtual bool resize(size_t size, bool preserveData) = 0;
93 virtual void *map(GLbitfield access) = 0;
94 virtual void unmap() = 0;
97 TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage);
99 Renderer11 *mRenderer;
100 DataRevision mRevision;
101 const BufferUsage mUsage;
105 // A native buffer storage represents an underlying D3D11 buffer for a particular
107 class BufferStorage11::NativeBuffer11 : public BufferStorage11::TypedBufferStorage11
110 NativeBuffer11(Renderer11 *renderer, BufferUsage usage);
113 ID3D11Buffer *getNativeBuffer() const { return mNativeBuffer; }
115 virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
116 size_t size, size_t destOffset);
117 virtual bool resize(size_t size, bool preserveData);
119 virtual void *map(GLbitfield access);
120 virtual void unmap();
123 ID3D11Buffer *mNativeBuffer;
125 static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize);
128 // 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.
130 class BufferStorage11::PackStorage11 : public BufferStorage11::TypedBufferStorage11
133 PackStorage11(Renderer11 *renderer);
136 virtual bool copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
137 size_t size, size_t destOffset);
138 virtual bool resize(size_t size, bool preserveData);
140 virtual void *map(GLbitfield access);
141 virtual void unmap();
143 void packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms);
147 void flushQueuedPackCommand();
149 ID3D11Texture2D *mStagingTexture;
150 DXGI_FORMAT mTextureFormat;
151 gl::Extents mTextureSize;
152 std::vector<unsigned char> mMemoryBuffer;
153 PackPixelsParams *mQueuedPackCommand;
154 PackPixelsParams mPackParams;
158 BufferStorage11::BufferStorage11(Renderer11 *renderer)
159 : mRenderer(renderer),
160 mMappedStorage(NULL),
161 mResolvedDataRevision(0),
167 BufferStorage11::~BufferStorage11()
169 for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++)
171 SafeDelete(it->second);
175 BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage)
177 ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage));
178 return static_cast<BufferStorage11*>(bufferStorage);
181 void *BufferStorage11::getData()
183 NativeBuffer11 *stagingBuffer = getStagingBuffer();
191 if (stagingBuffer->getDataRevision() > mResolvedDataRevision)
193 if (stagingBuffer->getSize() > mResolvedData.size())
195 mResolvedData.resize(stagingBuffer->getSize());
198 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
200 D3D11_MAPPED_SUBRESOURCE mappedResource;
201 HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource);
204 return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
207 memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize());
209 context->Unmap(stagingBuffer->getNativeBuffer(), 0);
211 mResolvedDataRevision = stagingBuffer->getDataRevision();
216 return mResolvedData.data();
219 void BufferStorage11::setData(const void* data, size_t size, size_t offset)
221 size_t requiredSize = size + offset;
222 mSize = std::max(mSize, requiredSize);
226 NativeBuffer11 *stagingBuffer = getStagingBuffer();
234 // Explicitly resize the staging buffer, preserving data if the new data will not
235 // completely fill the buffer
236 if (stagingBuffer->getSize() < requiredSize)
238 bool preserveData = (offset > 0);
239 if (!stagingBuffer->resize(requiredSize, preserveData))
246 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
248 D3D11_MAPPED_SUBRESOURCE mappedResource;
249 HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_WRITE, 0, &mappedResource);
252 return gl::error(GL_OUT_OF_MEMORY);
255 unsigned char *offsetBufferPointer = reinterpret_cast<unsigned char *>(mappedResource.pData) + offset;
256 memcpy(offsetBufferPointer, data, size);
258 context->Unmap(stagingBuffer->getNativeBuffer(), 0);
260 stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
264 void BufferStorage11::copyData(BufferStorage* sourceStorage, size_t size, size_t sourceOffset, size_t destOffset)
266 BufferStorage11* sourceStorage11 = makeBufferStorage11(sourceStorage);
269 TypedBufferStorage11 *dest = getLatestStorage();
272 dest = getStagingBuffer();
275 TypedBufferStorage11 *source = sourceStorage11->getLatestStorage();
278 // 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())
282 source = sourceStorage11->getStagingBuffer();
284 else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable())
286 dest = getStagingBuffer();
289 dest->copyFromStorage(source, sourceOffset, size, destOffset);
290 dest->setDataRevision(dest->getDataRevision() + 1);
293 mSize = std::max<size_t>(mSize, destOffset + size);
297 void BufferStorage11::clear()
300 mResolvedDataRevision = 0;
303 void BufferStorage11::markTransformFeedbackUsage()
305 TypedBufferStorage11 *transformFeedbackStorage = getStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
307 if (transformFeedbackStorage)
309 transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1);
313 size_t BufferStorage11::getSize() const
318 bool BufferStorage11::supportsDirectBinding() const
323 void BufferStorage11::markBufferUsage()
327 const unsigned int usageLimit = 5;
329 if (mReadUsageCount > usageLimit && mResolvedData.size() > 0)
331 mResolvedData.resize(0);
332 mResolvedDataRevision = 0;
336 ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage)
340 TypedBufferStorage11 *typedBuffer = getStorage(usage);
344 // Storage out-of-memory
348 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, typedBuffer));
350 return static_cast<NativeBuffer11*>(typedBuffer)->getNativeBuffer();
353 ID3D11ShaderResourceView *BufferStorage11::getSRV(DXGI_FORMAT srvFormat)
355 TypedBufferStorage11 *storage = getStorage(BUFFER_USAGE_PIXEL_UNPACK);
359 // Storage out-of-memory
363 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, storage));
364 ID3D11Buffer *buffer = static_cast<NativeBuffer11*>(storage)->getNativeBuffer();
366 auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
368 if (bufferSRVIt != mBufferResourceViews.end())
370 if (bufferSRVIt->second.first == buffer)
372 return bufferSRVIt->second.second;
376 // The underlying buffer has changed since the SRV was created: recreate the SRV.
377 SafeRelease(bufferSRVIt->second.second);
381 ID3D11Device *device = mRenderer->getDevice();
382 ID3D11ShaderResourceView *bufferSRV = NULL;
384 D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc;
385 bufferSRVDesc.Buffer.ElementOffset = 0;
386 bufferSRVDesc.Buffer.ElementWidth = mSize / d3d11::GetFormatPixelBytes(srvFormat);
387 bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
388 bufferSRVDesc.Format = srvFormat;
390 HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV);
391 UNUSED_ASSERTION_VARIABLE(result);
392 ASSERT(SUCCEEDED(result));
394 mBufferResourceViews[srvFormat] = BufferSRVPair(buffer, bufferSRV);
399 void BufferStorage11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams ¶ms)
401 PackStorage11 *packStorage = getPackStorage();
403 TypedBufferStorage11 *latestStorage = getLatestStorage();
407 packStorage->packPixels(srcTexture, srcSubresource, params);
408 packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1);
412 BufferStorage11::TypedBufferStorage11 *BufferStorage11::getStorage(BufferUsage usage)
414 TypedBufferStorage11 *directBuffer = NULL;
415 auto directBufferIt = mTypedBuffers.find(usage);
416 if (directBufferIt != mTypedBuffers.end())
418 directBuffer = directBufferIt->second;
423 if (usage == BUFFER_USAGE_PIXEL_PACK)
425 directBuffer = new PackStorage11(mRenderer);
429 // buffer is not allocated, create it
430 directBuffer = new NativeBuffer11(mRenderer, usage);
433 mTypedBuffers.insert(std::make_pair(usage, directBuffer));
437 if (directBuffer->getSize() < mSize)
439 if (!directBuffer->resize(mSize, true))
441 // Out of memory error
446 TypedBufferStorage11 *latestBuffer = getLatestStorage();
447 if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision())
449 // 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())
453 NativeBuffer11 *stagingBuffer = getStagingBuffer();
455 stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0);
456 directBuffer->setDataRevision(latestBuffer->getDataRevision());
458 latestBuffer = stagingBuffer;
461 // 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))
467 directBuffer->setDataRevision(latestBuffer->getDataRevision());
473 BufferStorage11::TypedBufferStorage11 *BufferStorage11::getLatestStorage() const
475 // Even though we iterate over all the direct buffers, it is expected that only
476 // 1 or 2 will be present.
477 TypedBufferStorage11 *latestStorage = NULL;
478 DataRevision latestRevision = 0;
479 for (auto it = mTypedBuffers.begin(); it != mTypedBuffers.end(); it++)
481 TypedBufferStorage11 *storage = it->second;
482 if (!latestStorage || storage->getDataRevision() > latestRevision)
484 latestStorage = storage;
485 latestRevision = storage->getDataRevision();
489 return latestStorage;
492 bool BufferStorage11::isMapped() const
494 return mMappedStorage != NULL;
497 void *BufferStorage11::map(GLbitfield access)
499 ASSERT(!mMappedStorage);
501 TypedBufferStorage11 *latestStorage = getLatestStorage();
502 ASSERT(latestStorage);
504 if (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
505 latestStorage->getUsage() == BUFFER_USAGE_STAGING)
507 mMappedStorage = latestStorage;
511 mMappedStorage = getStagingBuffer();
520 return mMappedStorage->map(access);
523 void BufferStorage11::unmap()
525 ASSERT(mMappedStorage);
526 mMappedStorage->unmap();
527 mMappedStorage = NULL;
530 BufferStorage11::NativeBuffer11 *BufferStorage11::getStagingBuffer()
532 TypedBufferStorage11 *stagingStorage = getStorage(BUFFER_USAGE_STAGING);
540 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, stagingStorage));
541 return static_cast<NativeBuffer11*>(stagingStorage);
544 BufferStorage11::PackStorage11 *BufferStorage11::getPackStorage()
546 TypedBufferStorage11 *packStorage = getStorage(BUFFER_USAGE_PIXEL_PACK);
554 ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, packStorage));
555 return static_cast<PackStorage11*>(packStorage);
558 BufferStorage11::TypedBufferStorage11::TypedBufferStorage11(Renderer11 *renderer, BufferUsage usage)
559 : mRenderer(renderer),
566 BufferStorage11::NativeBuffer11::NativeBuffer11(Renderer11 *renderer, BufferUsage usage)
567 : TypedBufferStorage11(renderer, usage),
572 BufferStorage11::NativeBuffer11::~NativeBuffer11()
574 SafeRelease(mNativeBuffer);
577 // Returns true if it recreates the direct buffer
578 bool BufferStorage11::NativeBuffer11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
579 size_t size, size_t destOffset)
581 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
583 size_t requiredSize = sourceOffset + size;
584 bool createBuffer = !mNativeBuffer || mBufferSize < requiredSize;
586 // (Re)initialize D3D buffer if needed
589 bool preserveData = (destOffset > 0);
590 resize(source->getSize(), preserveData);
593 if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK)
595 ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, source));
597 unsigned char *sourcePointer = static_cast<unsigned char *>(source->map(GL_MAP_READ_BIT)) + sourceOffset;
599 D3D11_MAPPED_SUBRESOURCE mappedResource;
600 HRESULT hr = context->Map(mNativeBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
601 UNUSED_ASSERTION_VARIABLE(hr);
602 ASSERT(SUCCEEDED(hr));
604 unsigned char *destPointer = static_cast<unsigned char *>(mappedResource.pData) + destOffset;
606 // Offset bounds are validated at the API layer
607 ASSERT(sourceOffset + size <= destOffset + mBufferSize);
608 memcpy(destPointer, sourcePointer, size);
612 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, source));
615 srcBox.left = sourceOffset;
616 srcBox.right = sourceOffset + size;
622 ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, source));
623 ID3D11Buffer *sourceBuffer = static_cast<NativeBuffer11*>(source)->getNativeBuffer();
625 context->CopySubresourceRegion(mNativeBuffer, 0, destOffset, 0, 0, sourceBuffer, 0, &srcBox);
631 bool BufferStorage11::NativeBuffer11::resize(size_t size, bool preserveData)
633 ID3D11Device *device = mRenderer->getDevice();
634 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
636 D3D11_BUFFER_DESC bufferDesc;
637 fillBufferDesc(&bufferDesc, mRenderer, mUsage, size);
639 ID3D11Buffer *newBuffer;
640 HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
644 return gl::error(GL_OUT_OF_MEMORY, false);
647 if (mNativeBuffer && preserveData)
649 // We don't call resize if the buffer is big enough already.
650 ASSERT(mBufferSize <= size);
654 srcBox.right = mBufferSize;
660 context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mNativeBuffer, 0, &srcBox);
663 // No longer need the old buffer
664 SafeRelease(mNativeBuffer);
665 mNativeBuffer = newBuffer;
667 mBufferSize = bufferDesc.ByteWidth;
672 void BufferStorage11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer,
673 BufferUsage usage, unsigned int bufferSize)
675 bufferDesc->ByteWidth = bufferSize;
676 bufferDesc->MiscFlags = 0;
677 bufferDesc->StructureByteStride = 0;
681 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;
687 case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
688 bufferDesc->Usage = D3D11_USAGE_DEFAULT;
689 bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
690 bufferDesc->CPUAccessFlags = 0;
693 case BUFFER_USAGE_INDEX:
694 bufferDesc->Usage = D3D11_USAGE_DEFAULT;
695 bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER;
696 bufferDesc->CPUAccessFlags = 0;
699 case BUFFER_USAGE_PIXEL_UNPACK:
700 bufferDesc->Usage = D3D11_USAGE_DEFAULT;
701 bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
702 bufferDesc->CPUAccessFlags = 0;
705 case BUFFER_USAGE_UNIFORM:
706 bufferDesc->Usage = D3D11_USAGE_DYNAMIC;
707 bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
708 bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
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);
713 bufferDesc->ByteWidth = std::min(bufferDesc->ByteWidth, renderer->getMaxUniformBufferSize());
721 void *BufferStorage11::NativeBuffer11::map(GLbitfield access)
723 ASSERT(mUsage == BUFFER_USAGE_STAGING);
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);
730 HRESULT result = context->Map(mNativeBuffer, 0, d3dMapType, d3dMapFlag, &mappedResource);
731 UNUSED_ASSERTION_VARIABLE(result);
732 ASSERT(SUCCEEDED(result));
734 return mappedResource.pData;
737 void BufferStorage11::NativeBuffer11::unmap()
739 ASSERT(mUsage == BUFFER_USAGE_STAGING);
740 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
741 context->Unmap(mNativeBuffer, 0);
744 BufferStorage11::PackStorage11::PackStorage11(Renderer11 *renderer)
745 : TypedBufferStorage11(renderer, BUFFER_USAGE_PIXEL_PACK),
746 mStagingTexture(NULL),
747 mTextureFormat(DXGI_FORMAT_UNKNOWN),
748 mQueuedPackCommand(NULL),
753 BufferStorage11::PackStorage11::~PackStorage11()
755 SafeRelease(mStagingTexture);
756 SafeDelete(mQueuedPackCommand);
759 bool BufferStorage11::PackStorage11::copyFromStorage(TypedBufferStorage11 *source, size_t sourceOffset,
760 size_t size, size_t destOffset)
766 bool BufferStorage11::PackStorage11::resize(size_t size, bool preserveData)
768 if (size != mBufferSize)
770 mMemoryBuffer.resize(size, 0);
777 void *BufferStorage11::PackStorage11::map(GLbitfield access)
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.
784 flushQueuedPackCommand();
785 mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
787 return &mMemoryBuffer[0];
790 void BufferStorage11::PackStorage11::unmap()
795 void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms)
797 flushQueuedPackCommand();
798 mQueuedPackCommand = new PackPixelsParams(params);
800 D3D11_TEXTURE2D_DESC textureDesc;
801 srcTexure->GetDesc(&textureDesc);
803 if (mStagingTexture != NULL &&
804 (mTextureFormat != textureDesc.Format ||
805 mTextureSize.width != params.area.width ||
806 mTextureSize.height != params.area.height))
808 SafeRelease(mStagingTexture);
809 mTextureSize.width = 0;
810 mTextureSize.height = 0;
811 mTextureFormat = DXGI_FORMAT_UNKNOWN;
814 if (mStagingTexture == NULL)
816 ID3D11Device *device = mRenderer->getDevice();
819 mTextureSize.width = params.area.width;
820 mTextureSize.height = params.area.height;
821 mTextureFormat = textureDesc.Format;
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;
836 hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture);
837 ASSERT(SUCCEEDED(hr));
840 if (textureDesc.SampleDesc.Count > 1)
845 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
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;
855 immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox);
858 void BufferStorage11::PackStorage11::flushQueuedPackCommand()
860 ASSERT(!mMemoryBuffer.empty());
862 if (mQueuedPackCommand)
864 mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, &mMemoryBuffer[0]);
865 SafeDelete(mQueuedPackCommand);