blob: 53a726b1d71f0a0b86f4b874372699835dd2b6f6 [file] [log] [blame]
daniel@transgaming.coma8aac672012-12-20 21:08:00 +00001//
2// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Image11.h: Implements the rx::Image11 class, which acts as the interface to
8// the actual underlying resources of a Texture
9
10#include "libGLESv2/renderer/Renderer11.h"
11#include "libGLESv2/renderer/Image11.h"
daniel@transgaming.com46cf2492013-01-11 04:06:43 +000012#include "libGLESv2/renderer/TextureStorage11.h"
shannon.woods@transgaming.comc8cd7f62013-01-25 21:52:40 +000013#include "libGLESv2/Framebuffer.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000014#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.coma8aac672012-12-20 21:08:00 +000015
16#include "libGLESv2/main.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000017#include "libGLESv2/utilities.h"
daniel@transgaming.coma8aac672012-12-20 21:08:00 +000018#include "libGLESv2/renderer/renderer11_utils.h"
shannon.woods@transgaming.com2b132f42013-01-25 21:52:47 +000019#include "libGLESv2/renderer/generatemip.h"
daniel@transgaming.coma8aac672012-12-20 21:08:00 +000020
21namespace rx
22{
23
24Image11::Image11()
25{
26 mStagingTexture = NULL;
27 mRenderer = NULL;
28 mDXGIFormat = DXGI_FORMAT_UNKNOWN;
29}
30
31Image11::~Image11()
32{
33 if (mStagingTexture)
34 {
35 mStagingTexture->Release();
36 }
37}
38
39Image11 *Image11::makeImage11(Image *img)
40{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +000041 ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
daniel@transgaming.coma8aac672012-12-20 21:08:00 +000042 return static_cast<rx::Image11*>(img);
43}
44
shannon.woods@transgaming.com2b132f42013-01-25 21:52:47 +000045void Image11::generateMipmap(Image11 *dest, Image11 *src)
46{
47 ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
48 ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
49 ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight());
50
51 D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped;
52 dest->map(&destMapped);
53 src->map(&srcMapped);
54
55 const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(srcMapped.pData);
56 unsigned char *destData = reinterpret_cast<unsigned char*>(destMapped.pData);
57
58 if (sourceData && destData)
59 {
60 switch (src->getDXGIFormat())
61 {
62 case DXGI_FORMAT_R8G8B8A8_UNORM:
63 case DXGI_FORMAT_B8G8R8A8_UNORM:
64 GenerateMip<R8G8B8A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
65 break;
66 case DXGI_FORMAT_A8_UNORM:
67 GenerateMip<A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
68 break;
69 case DXGI_FORMAT_R8_UNORM:
70 GenerateMip<R8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
71 break;
72 case DXGI_FORMAT_R32G32B32A32_FLOAT:
73 GenerateMip<A32B32G32R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
74 break;
75 case DXGI_FORMAT_R32G32B32_FLOAT:
76 GenerateMip<R32G32B32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
77 break;
78 case DXGI_FORMAT_R16G16B16A16_FLOAT:
79 GenerateMip<A16B16G16R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
80 break;
81 case DXGI_FORMAT_R8G8_UNORM:
82 GenerateMip<R8G8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
83 break;
84 case DXGI_FORMAT_R16_FLOAT:
85 GenerateMip<R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
86 break;
87 case DXGI_FORMAT_R16G16_FLOAT:
88 GenerateMip<R16G16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
89 break;
90 case DXGI_FORMAT_R32_FLOAT:
91 GenerateMip<R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
92 break;
93 case DXGI_FORMAT_R32G32_FLOAT:
94 GenerateMip<R32G32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
95 break;
96 default:
97 UNREACHABLE();
98 break;
99 }
100
101 dest->unmap();
102 src->unmap();
103 }
104
105 dest->markDirty();
106}
107
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000108bool Image11::isDirty() const
109{
110 return (mStagingTexture && mDirty);
111}
112
daniel@transgaming.com5ea16ef2013-01-11 04:06:30 +0000113ID3D11Texture2D *Image11::getStagingTexture()
114{
115 createStagingTexture();
116
117 return mStagingTexture;
118}
119
daniel@transgaming.com87705f82012-12-20 21:10:45 +0000120bool Image11::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000121{
daniel@transgaming.com46cf2492013-01-11 04:06:43 +0000122 TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
123 return storage11->updateSubresourceLevel(getStagingTexture(), level, 0, xoffset, yoffset, width, height);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000124}
125
daniel@transgaming.com87705f82012-12-20 21:10:45 +0000126bool Image11::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000127{
daniel@transgaming.com46cf2492013-01-11 04:06:43 +0000128 TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
129 return storage11->updateSubresourceLevel(getStagingTexture(), level, face, xoffset, yoffset, width, height);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000130}
131
132bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
133{
134 if (mWidth != width ||
135 mHeight != height ||
136 mInternalFormat != internalformat ||
137 forceRelease)
138 {
139 mRenderer = Renderer11::makeRenderer11(renderer);
140
141 mWidth = width;
142 mHeight = height;
143 mInternalFormat = internalformat;
144 // compute the d3d format that will be used
145 mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat);
146 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat);
147
148 if (mStagingTexture)
149 {
150 mStagingTexture->Release();
151 mStagingTexture = NULL;
152 }
153
154 return true;
155 }
156
157 return false;
158}
159
160bool Image11::isRenderableFormat() const
161{
shannon.woods@transgaming.com2a0a39e2013-01-25 21:50:15 +0000162 return TextureStorage11::IsTextureFormatRenderable(mDXGIFormat);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000163}
164
165DXGI_FORMAT Image11::getDXGIFormat() const
166{
167 // this should only happen if the image hasn't been redefined first
168 // which would be a bug by the caller
169 ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN);
170
171 return mDXGIFormat;
172}
173
174// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
175// into the target pixel rectangle.
176void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
177 GLint unpackAlignment, const void *input)
178{
179 D3D11_MAPPED_SUBRESOURCE mappedImage;
180 HRESULT result = map(&mappedImage);
181 if (FAILED(result))
182 {
183 ERR("Could not map image for loading.");
184 return;
185 }
186
187 GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment);
188 size_t pixelSize = d3d11::ComputePixelSizeBits(mDXGIFormat) / 8;
189 void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * pixelSize));
190
191 switch (mInternalFormat)
192 {
193 case GL_ALPHA8_EXT:
daniel@transgaming.com26041c92013-01-11 04:08:58 +0000194 loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000195 break;
196 case GL_LUMINANCE8_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000197 loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000198 break;
199 case GL_ALPHA32F_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000200 loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000201 break;
202 case GL_LUMINANCE32F_EXT:
daniel@transgaming.com26041c92013-01-11 04:08:58 +0000203 loadLuminanceFloatDataToRGB(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000204 break;
205 case GL_ALPHA16F_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000206 loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000207 break;
208 case GL_LUMINANCE16F_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000209 loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000210 break;
211 case GL_LUMINANCE8_ALPHA8_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000212 loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000213 break;
214 case GL_LUMINANCE_ALPHA32F_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000215 loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000216 break;
217 case GL_LUMINANCE_ALPHA16F_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000218 loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000219 break;
220 case GL_RGB8_OES:
daniel@transgaming.com005979d2012-12-20 21:11:29 +0000221 loadRGBUByteDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000222 break;
223 case GL_RGB565:
daniel@transgaming.com005979d2012-12-20 21:11:29 +0000224 loadRGB565DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000225 break;
226 case GL_RGBA8_OES:
daniel@transgaming.com005979d2012-12-20 21:11:29 +0000227 loadRGBAUByteDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000228 break;
229 case GL_RGBA4:
daniel@transgaming.com005979d2012-12-20 21:11:29 +0000230 loadRGBA4444DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000231 break;
232 case GL_RGB5_A1:
daniel@transgaming.com005979d2012-12-20 21:11:29 +0000233 loadRGBA5551DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000234 break;
235 case GL_BGRA8_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000236 loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000237 break;
238 case GL_RGB32F_EXT:
daniel@transgaming.com005979d2012-12-20 21:11:29 +0000239 loadRGBFloatDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000240 break;
241 case GL_RGB16F_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000242 loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000243 break;
244 case GL_RGBA32F_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000245 loadRGBAFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000246 break;
247 case GL_RGBA16F_EXT:
daniel@transgaming.com8ca7d372012-12-20 21:11:22 +0000248 loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000249 break;
250 default: UNREACHABLE();
251 }
252
253 unmap();
254}
255
256void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
257 const void *input)
258{
259 ASSERT(xoffset % 4 == 0);
260 ASSERT(yoffset % 4 == 0);
261
262 D3D11_MAPPED_SUBRESOURCE mappedImage;
263 HRESULT result = map(&mappedImage);
264 if (FAILED(result))
265 {
266 ERR("Could not map image for loading.");
267 return;
268 }
269
270 // Size computation assumes a 4x4 block compressed texture format
271 size_t blockSize = d3d11::ComputeBlockSizeBits(mDXGIFormat) / 8;
272 void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + ((yoffset / 4) * mappedImage.RowPitch + (xoffset / 4) * blockSize));
273
274 GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat);
275 GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat);
276 int rows = inputSize / inputPitch;
277 for (int i = 0; i < rows; ++i)
278 {
279 memcpy((void*)((BYTE*)offsetMappedData + i * mappedImage.RowPitch), (void*)((BYTE*)input + i * inputPitch), inputPitch);
280 }
281
282 unmap();
283}
284
285void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
286{
shannon.woods@transgaming.com51cb88e2013-02-28 23:14:07 +0000287 if (source->getColorbuffer() && source->getColorbuffer()->getActualFormat() == (GLuint)mActualFormat)
shannon.woods@transgaming.comc8cd7f62013-01-25 21:52:40 +0000288 {
289 // No conversion needed-- use copyback fastpath
290 ID3D11Texture2D *colorBufferTexture = NULL;
291 unsigned int subresourceIndex = 0;
292
293 if (mRenderer->getRenderTargetResource(source, &subresourceIndex, &colorBufferTexture))
294 {
295 D3D11_TEXTURE2D_DESC textureDesc;
296 colorBufferTexture->GetDesc(&textureDesc);
297
298 ID3D11Device *device = mRenderer->getDevice();
299 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
300
301 ID3D11Texture2D* srcTex = NULL;
302 if (textureDesc.SampleDesc.Count > 1)
303 {
304 D3D11_TEXTURE2D_DESC resolveDesc;
305 resolveDesc.Width = textureDesc.Width;
306 resolveDesc.Height = textureDesc.Height;
307 resolveDesc.MipLevels = 1;
308 resolveDesc.ArraySize = 1;
309 resolveDesc.Format = textureDesc.Format;
310 resolveDesc.SampleDesc.Count = 1;
311 resolveDesc.SampleDesc.Quality = 0;
312 resolveDesc.Usage = D3D11_USAGE_DEFAULT;
313 resolveDesc.BindFlags = 0;
314 resolveDesc.CPUAccessFlags = 0;
315 resolveDesc.MiscFlags = 0;
316
317 HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
318 if (FAILED(result))
319 {
320 ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
321 return;
322 }
323
324 deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
325 subresourceIndex = 0;
326 }
327 else
328 {
329 srcTex = colorBufferTexture;
330 srcTex->AddRef();
331 }
332
333 D3D11_BOX srcBox;
334 srcBox.left = x;
335 srcBox.right = x + width;
336 srcBox.top = y;
337 srcBox.bottom = y + height;
338 srcBox.front = 0;
339 srcBox.back = 1;
340
341 deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, 0, srcTex, subresourceIndex, &srcBox);
342
343 srcTex->Release();
344 colorBufferTexture->Release();
345 }
346 }
347 else
348 {
349 // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
350 D3D11_MAPPED_SUBRESOURCE mappedImage;
351 HRESULT result = map(&mappedImage);
352
shannon.woods@transgaming.coma7c7bc42013-02-28 23:14:02 +0000353 // determine the offset coordinate into the destination buffer
354 GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset;
355 void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset;
356
shannon.woods@transgaming.comc8cd7f62013-01-25 21:52:40 +0000357 mRenderer->readPixels(source, x, y, width, height, gl::ExtractFormat(mInternalFormat),
shannon.woods@transgaming.coma7c7bc42013-02-28 23:14:02 +0000358 gl::ExtractType(mInternalFormat), mappedImage.RowPitch, false, 4, dataOffset);
shannon.woods@transgaming.comc8cd7f62013-01-25 21:52:40 +0000359
360 unmap();
361 }
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000362}
363
364void Image11::createStagingTexture()
365{
366 if (mStagingTexture)
367 {
368 return;
369 }
370
371 ID3D11Texture2D *newTexture = NULL;
372 const DXGI_FORMAT dxgiFormat = getDXGIFormat();
shannon.woods@transgaming.comeec5c632013-02-28 23:04:21 +0000373 ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000374
375 if (mWidth != 0 && mHeight != 0)
376 {
377 ID3D11Device *device = mRenderer->getDevice();
378
shannon.woods@transgaming.com7ae9e7f2013-02-28 23:13:27 +0000379 // Round up the width and height to the nearest multiple of dimension alignment
380 unsigned int dimensionAlignment = d3d11::GetTextureFormatDimensionAlignment(dxgiFormat);
381 unsigned int width = mWidth + dimensionAlignment - 1 - (mWidth - 1) % dimensionAlignment;
382 unsigned int height = mHeight + dimensionAlignment - 1 - (mHeight - 1) % dimensionAlignment;
383
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000384 D3D11_TEXTURE2D_DESC desc;
shannon.woods@transgaming.com7ae9e7f2013-02-28 23:13:27 +0000385 desc.Width = width;
386 desc.Height = height;
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000387 desc.MipLevels = desc.ArraySize = 1;
388 desc.Format = dxgiFormat;
389 desc.SampleDesc.Count = 1;
390 desc.SampleDesc.Quality = 0;
391 desc.Usage = D3D11_USAGE_STAGING;
392 desc.BindFlags = 0;
393 desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
394 desc.MiscFlags = 0;
395
396 HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture);
397
398 if (FAILED(result))
399 {
400 ASSERT(result == E_OUTOFMEMORY);
401 ERR("Creating image failed.");
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000402 return gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000403 }
404 }
405
406 mStagingTexture = newTexture;
407 mDirty = false;
408}
409
410HRESULT Image11::map(D3D11_MAPPED_SUBRESOURCE *map)
411{
412 createStagingTexture();
413
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +0000414 HRESULT result = E_FAIL;
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000415
416 if (mStagingTexture)
417 {
418 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
419 result = deviceContext->Map(mStagingTexture, 0, D3D11_MAP_WRITE, 0, map);
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000420
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +0000421 // this can fail if the device is removed (from TDR)
422 if (d3d11::isDeviceLostError(result))
423 {
424 mRenderer->notifyDeviceLost();
425 }
426 else if (SUCCEEDED(result))
427 {
428 mDirty = true;
429 }
daniel@transgaming.coma8aac672012-12-20 21:08:00 +0000430 }
431
432 return result;
433}
434
435void Image11::unmap()
436{
437 if (mStagingTexture)
438 {
439 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
440 deviceContext->Unmap(mStagingTexture, 0);
441 }
442}
443
444}