1a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com//
2a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
4a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com// found in the LICENSE file.
5a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com//
6a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
7a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com// Image11.h: Implements the rx::Image11 class, which acts as the interface to
8a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com// the actual underlying resources of a Texture
9a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
10c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
11c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
12c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
130b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
140b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
15c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com#include "libGLESv2/Framebuffer.h"
16e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill#include "libGLESv2/FramebufferAttachment.h"
17a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com#include "libGLESv2/main.h"
180b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang
19a2ecfcccf1d1a85e6054a7314ce1f9de0648ac7fshannonwoods@chromium.org#include "common/utilities.h"
20a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
21a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.comnamespace rx
22a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
23a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
24a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.comImage11::Image11()
25a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
26a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    mStagingTexture = NULL;
27a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    mRenderer = NULL;
28a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    mDXGIFormat = DXGI_FORMAT_UNKNOWN;
296982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    mRecoverFromStorage = false;
306982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    mAssociatedStorage = NULL;
316982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    mAssociatedStorageLevel = 0;
326982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    mAssociatedStorageLayerTarget = 0;
336982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    mRecoveredFromStorageCount = 0;
34a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
35a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
36a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.comImage11::~Image11()
37a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
386982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    disassociateStorage();
396982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    releaseStagingTexture();
40a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
41a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
42a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.comImage11 *Image11::makeImage11(Image *img)
43a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
448b400b1e8d84c5b93dd151807504a3e4b90d1b21apatrick@chromium.org    ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
45a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    return static_cast<rx::Image11*>(img);
46a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
47a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
48e4a492be45f39dffaea53c3523064844ee56e41bGeoff Langvoid Image11::generateMipmap(Image11 *dest, Image11 *src)
492b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com{
502b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com    ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
512b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com    ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
522b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com    ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight());
532b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com
549aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(src->getDXGIFormat());
559aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL);
562b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com
57cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    D3D11_MAPPED_SUBRESOURCE destMapped;
58cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped);
59cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    if (FAILED(destMapResult))
60cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    {
61cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org        ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult);
62cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org        return;
63cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    }
642b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com
65cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    D3D11_MAPPED_SUBRESOURCE srcMapped;
66cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped);
67cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    if (FAILED(srcMapResult))
682b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com    {
69cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org        ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult);
702b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com
712b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com        dest->unmap();
72cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org        return;
732b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com    }
742b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com
7557f9b6d56bec5e2040909b9dc0c68ddb7ac4a978Geoff Lang    const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData);
7657f9b6d56bec5e2040909b9dc0c68ddb7ac4a978Geoff Lang    uint8_t *destData = reinterpret_cast<uint8_t*>(destMapped.pData);
77cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org
789aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    dxgiFormatInfo.mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(),
799aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang                                         sourceData, srcMapped.RowPitch, srcMapped.DepthPitch,
809aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang                                         destData, destMapped.RowPitch, destMapped.DepthPitch);
81cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org
82cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    dest->unmap();
83cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    src->unmap();
84cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org
852b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com    dest->markDirty();
862b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com}
872b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com
88a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.combool Image11::isDirty() const
89a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
906982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // If mDirty is true
916982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be recovered from TextureStorage
926982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // AND the texture doesn't require init data (i.e. a blank new texture will suffice)
936982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // then isDirty should still return false.
946982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (mDirty && !mStagingTexture && !mRecoverFromStorage && !(d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL))
956982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
966982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        return false;
976982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
986982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
996982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return mDirty;
100a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
101a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
1022f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillbool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
103a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
1042f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
1056982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height);
106a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
107a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
1082f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillbool Image11::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
109a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
1102f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
1116982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height);
1122058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
1132058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
1142f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillbool Image11::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
1152058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
1162f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
1176982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height);
118a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
119a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
1202f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillbool Image11::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height)
1216c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com{
1222f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
1236982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return copyToStorageImpl(storage11, level, arrayLayer, xoffset, yoffset, width, height);
1246982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
1256982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1266982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossbool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
1276982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
1286982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // If an app's behavior results in an Image11 copying its data to/from to a TextureStorage multiple times,
1296982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // then we should just keep the staging texture around to prevent the copying from impacting perf.
1306982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // We allow the Image11 to copy its data to/from TextureStorage once.
1316982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // This accounts for an app making a late call to glGenerateMipmap.
1326982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    bool attemptToReleaseStagingTexture = (mRecoveredFromStorageCount < 2);
1336982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1346982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (attemptToReleaseStagingTexture)
1356982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
1366982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // If another image is relying on this Storage for its data, then we must let it recover its data before we overwrite it.
1376982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        storage11->releaseAssociatedImage(level, layerTarget, this);
1386982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
1396982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1406982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    bool updateSubresourceSuccess = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, layerTarget, xoffset, yoffset, 0, width, height, 1);
1416982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1426982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // Once the image data has been copied into the Storage, we can release it locally.
1436982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (attemptToReleaseStagingTexture && updateSubresourceSuccess)
1446982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
1456982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        storage11->associateImage(this, level, layerTarget);
1466982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        releaseStagingTexture();
1476982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mRecoverFromStorage = true;
1486982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedStorage = storage11;
1496982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedStorageLevel = level;
1506982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedStorageLayerTarget = layerTarget;
1516982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
1526982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1536982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return updateSubresourceSuccess;
1546982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
1556982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1566982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossbool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const
1576982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
1586982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return (mAssociatedStorage == textureStorage);
1596982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
1606982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1616982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossbool Image11::recoverFromAssociatedStorage()
1626982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
1636982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (mRecoverFromStorage)
1646982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
1656982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        createStagingTexture();
1666982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1676982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this);
1686982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1696982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // This means that the cached TextureStorage has been modified after this Image11 released its copy of its data.
1706982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // This should not have happened. The TextureStorage should have told this Image11 to recover its data before it was overwritten.
1716982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ASSERT(textureStorageCorrect);
1726982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1736982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (textureStorageCorrect)
1746982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
1756982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            // CopySubResource from the Storage to the Staging texture
1766982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedStorageLevel, mAssociatedStorageLayerTarget, 0, 0, 0, mWidth, mHeight, mDepth);
1776982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            mRecoveredFromStorageCount += 1;
1786982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
1796982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1806982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // Reset all the recovery parameters, even if the texture storage association is broken.
1816982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        disassociateStorage();
1826982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1836982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        return textureStorageCorrect;
1846982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
1856982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1866982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return false;
1876982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
1886982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1896982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid Image11::disassociateStorage()
1906982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
1916982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (mRecoverFromStorage)
1926982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
1936982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // Make the texturestorage release the Image11 too
1946982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedStorage->disassociateImage(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this);
1956982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1966982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mRecoverFromStorage = false;
1976982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedStorage = NULL;
1986982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedStorageLevel = 0;
1996982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedStorageLayerTarget = 0;
2006982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
2016c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com}
2026c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
203005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langbool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
204a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
205a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    if (mWidth != width ||
206a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        mHeight != height ||
207a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        mInternalFormat != internalformat ||
208a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        forceRelease)
209a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    {
2106982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // End the association with the TextureStorage, since that data will be out of date.
2116982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // Also reset mRecoveredFromStorageCount since this Image is getting completely redefined.
2126982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        disassociateStorage();
2136982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mRecoveredFromStorageCount = 0;
2146982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
215a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        mRenderer = Renderer11::makeRenderer11(renderer);
216a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
217a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        mWidth = width;
218a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        mHeight = height;
2194760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com        mDepth = depth;
220a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        mInternalFormat = internalformat;
22156074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        mTarget = target;
222803be0a97a07688190ea977251959467e7f94daeshannonwoods@chromium.org
223a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        // compute the d3d format that will be used
2249aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang        const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
2259aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang        const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
2269aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang        mDXGIFormat = formatInfo.texFormat;
2279aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang        mActualFormat = dxgiFormatInfo.internalFormat;
2289aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang        mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
229a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
230ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(mStagingTexture);
2319aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang        mDirty = (formatInfo.dataInitializerFunction != NULL);
232ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang
233a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        return true;
234a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    }
235a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
236a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    return false;
237a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
238a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
239a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.comDXGI_FORMAT Image11::getDXGIFormat() const
240a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
241a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    // this should only happen if the image hasn't been redefined first
242a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    // which would be a bug by the caller
243a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN);
244a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
245a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    return mDXGIFormat;
246a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
247a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
248a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
249a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com// into the target pixel rectangle.
2504760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.comvoid Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
251557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org                       GLint unpackAlignment, GLenum type, const void *input)
252a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
2535d601382b51c29d1670b58c01360416bd929842dGeoff Lang    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
2545d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
2555d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpackAlignment);
256557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org
2579aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
2589aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
2599aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang
2609aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat);
2619aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type);
262557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org
263a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    D3D11_MAPPED_SUBRESOURCE mappedImage;
26444b2768fcceb1989b268bb88698ac58cb33debcbshannonwoods@chromium.org    HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
265a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    if (FAILED(result))
266a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    {
267a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        ERR("Could not map image for loading.");
268a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        return;
269a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    }
2704760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com
27186846e242e61e16d19e7a07492c081ee29a59694Geoff Lang    uint8_t* offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch));
27286846e242e61e16d19e7a07492c081ee29a59694Geoff Lang    loadFunction(width, height, depth,
27386846e242e61e16d19e7a07492c081ee29a59694Geoff Lang                 reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
27486846e242e61e16d19e7a07492c081ee29a59694Geoff Lang                 offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
275a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
276a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    unmap();
277a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
278a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
2794760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.comvoid Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
2804760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com                                 const void *input)
281a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
2825d601382b51c29d1670b58c01360416bd929842dGeoff Lang    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
2835d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
2845d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
285b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org
2869aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
2879aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
2889aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    GLuint outputBlockWidth = dxgiFormatInfo.blockWidth;
2899aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    GLuint outputBlockHeight = dxgiFormatInfo.blockHeight;
290b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org
291b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org    ASSERT(xoffset % outputBlockWidth == 0);
292b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org    ASSERT(yoffset % outputBlockHeight == 0);
293b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org
2949aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat);
2959aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE);
296a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
297a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    D3D11_MAPPED_SUBRESOURCE mappedImage;
29844b2768fcceb1989b268bb88698ac58cb33debcbshannonwoods@chromium.org    HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
299a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    if (FAILED(result))
300a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    {
301a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        ERR("Could not map image for loading.");
302a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        return;
303a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    }
304a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
30586846e242e61e16d19e7a07492c081ee29a59694Geoff Lang    uint8_t* offsetMappedData = reinterpret_cast<uint8_t*>(mappedImage.pData) + ((yoffset / outputBlockHeight) * mappedImage.RowPitch +
30686846e242e61e16d19e7a07492c081ee29a59694Geoff Lang                                                                           (xoffset / outputBlockWidth) * outputPixelSize +
30786846e242e61e16d19e7a07492c081ee29a59694Geoff Lang                                                                           zoffset * mappedImage.DepthPitch);
308a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
30986846e242e61e16d19e7a07492c081ee29a59694Geoff Lang    loadFunction(width, height, depth,
31086846e242e61e16d19e7a07492c081ee29a59694Geoff Lang                 reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
311b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org                 offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
312a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
313a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    unmap();
314a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
315a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
316e5dcce75bb08208387723a4e0494ca19073e05a7shannon.woods%transgaming.com@gtempaccount.comvoid Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
317a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
3183c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
31900e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com
3207bee639532e50336f651ead7e1627e873ec48a00Geoff Lang    if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat)
321c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com    {
322c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com        // No conversion needed-- use copyback fastpath
323c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com        ID3D11Texture2D *colorBufferTexture = NULL;
324c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com        unsigned int subresourceIndex = 0;
325c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
32600e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com        if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
327c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com        {
328c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            D3D11_TEXTURE2D_DESC textureDesc;
329c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            colorBufferTexture->GetDesc(&textureDesc);
330c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
331c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            ID3D11Device *device = mRenderer->getDevice();
332c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
333c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
334c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            ID3D11Texture2D* srcTex = NULL;
335c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            if (textureDesc.SampleDesc.Count > 1)
336c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            {
337c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                D3D11_TEXTURE2D_DESC resolveDesc;
338c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.Width = textureDesc.Width;
339c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.Height = textureDesc.Height;
340c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.MipLevels = 1;
341c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.ArraySize = 1;
342c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.Format = textureDesc.Format;
343c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.SampleDesc.Count = 1;
344c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.SampleDesc.Quality = 0;
345c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.Usage = D3D11_USAGE_DEFAULT;
346c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.BindFlags = 0;
347c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.CPUAccessFlags = 0;
348c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                resolveDesc.MiscFlags = 0;
349c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
350c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
351c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                if (FAILED(result))
352c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                {
353c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                    ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
354c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                    return;
355c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                }
356c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
357c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
358c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                subresourceIndex = 0;
359c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            }
360c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            else
361c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            {
362c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                srcTex = colorBufferTexture;
363c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com                srcTex->AddRef();
364c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            }
365c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
366c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            D3D11_BOX srcBox;
367c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            srcBox.left = x;
368c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            srcBox.right = x + width;
369c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            srcBox.top = y;
370c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            srcBox.bottom = y + height;
371c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            srcBox.front = 0;
372c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com            srcBox.back = 1;
373c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
374e5dcce75bb08208387723a4e0494ca19073e05a7shannon.woods%transgaming.com@gtempaccount.com            deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox);
375c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
376ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang            SafeRelease(srcTex);
377ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang            SafeRelease(colorBufferTexture);
378c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com        }
379c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com    }
380c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com    else
381c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com    {
382c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com        // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
383c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com        D3D11_MAPPED_SUBRESOURCE mappedImage;
38444b2768fcceb1989b268bb88698ac58cb33debcbshannonwoods@chromium.org        HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
385cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang        if (FAILED(result))
386cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang        {
387cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result);
388cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            return;
389cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang        }
390803be0a97a07688190ea977251959467e7f94daeshannonwoods@chromium.org
391a7c7bc49da358414824abdd537fb4119a32b1b68shannon.woods@transgaming.com        // determine the offset coordinate into the destination buffer
3925d601382b51c29d1670b58c01360416bd929842dGeoff Lang        GLsizei rowOffset = gl::GetInternalFormatInfo(mActualFormat).pixelBytes * xoffset;
393268b6bcd5d415e2169228f4f082e546ac05aa899Geoff Lang        uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch;
394a7c7bc49da358414824abdd537fb4119a32b1b68shannon.woods@transgaming.com
3955d601382b51c29d1670b58c01360416bd929842dGeoff Lang        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
396eb9baabb73632231c8c1a26dc4d3647e17262ba7Jamie Madill
3975d601382b51c29d1670b58c01360416bd929842dGeoff Lang        mRenderer->readPixels(source, x, y, width, height, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
398c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com
399c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com        unmap();
400c8cd7f6139f018fe334831351b98cfc9060a5042shannon.woods@transgaming.com    }
401a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
402a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
4035d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.comID3D11Resource *Image11::getStagingTexture()
404cabb17c5675062b0b8adc2732663916ca8bab98cshannon.woods@transgaming.com{
405cabb17c5675062b0b8adc2732663916ca8bab98cshannon.woods@transgaming.com    createStagingTexture();
406cabb17c5675062b0b8adc2732663916ca8bab98cshannon.woods@transgaming.com
407cabb17c5675062b0b8adc2732663916ca8bab98cshannon.woods@transgaming.com    return mStagingTexture;
408cabb17c5675062b0b8adc2732663916ca8bab98cshannon.woods@transgaming.com}
409cabb17c5675062b0b8adc2732663916ca8bab98cshannon.woods@transgaming.com
4106982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid Image11::releaseStagingTexture()
4116982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
4126982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    SafeRelease(mStagingTexture);
4136982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
4146982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
41581ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.comunsigned int Image11::getStagingSubresource()
41681ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com{
41781ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com    createStagingTexture();
41881ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com
41981ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com    return mStagingSubresource;
42081ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com}
42181ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com
422a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.comvoid Image11::createStagingTexture()
423a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
424a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    if (mStagingTexture)
425a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    {
426a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        return;
427a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    }
428a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
429a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    const DXGI_FORMAT dxgiFormat = getDXGIFormat();
430a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
4315d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com    if (mWidth > 0 && mHeight > 0 && mDepth > 0)
432a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    {
4335d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com        ID3D11Device *device = mRenderer->getDevice();
43434256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang        HRESULT result;
4355d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com
43656074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        int lodOffset = 1;
43781ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com        GLsizei width = mWidth;
43881ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com        GLsizei height = mHeight;
439a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
44081ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com        // adjust size if needed for compressed textures
4419eeecfc20be089b62310787895870e0284cfb383Jamie Madill        d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
4427ae9e7fc1648f9c5b5231248e273ed203417cb35shannon.woods@transgaming.com
44356074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        if (mTarget == GL_TEXTURE_3D)
4445d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com        {
4455d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            ID3D11Texture3D *newTexture = NULL;
4465d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com
4475d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            D3D11_TEXTURE3D_DESC desc;
4485d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Width = width;
4495d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Height = height;
4505d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Depth = mDepth;
4515d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.MipLevels = lodOffset + 1;
4525d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Format = dxgiFormat;
4535d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Usage = D3D11_USAGE_STAGING;
4545d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.BindFlags = 0;
45544b2768fcceb1989b268bb88698ac58cb33debcbshannonwoods@chromium.org            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
4565d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.MiscFlags = 0;
4575d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com
4589aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang            if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
45934256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            {
46034256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang                std::vector<D3D11_SUBRESOURCE_DATA> initialData;
46134256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang                std::vector< std::vector<BYTE> > textureData;
462e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang                d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
463e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang                                                  lodOffset + 1, &initialData, &textureData);
46434256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang
46534256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang                result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
46634256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            }
46734256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            else
46834256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            {
46934256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang                result = device->CreateTexture3D(&desc, NULL, &newTexture);
47034256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            }
47134256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang
4725d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            if (FAILED(result))
4735d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            {
4745d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com                ASSERT(result == E_OUTOFMEMORY);
4755d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com                ERR("Creating image failed.");
4765d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com                return gl::error(GL_OUT_OF_MEMORY);
4775d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            }
4785d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com
4795d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            mStagingTexture = newTexture;
4805d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
4815d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com        }
48256074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
483a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        {
4845d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            ID3D11Texture2D *newTexture = NULL;
4855d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com
4865d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            D3D11_TEXTURE2D_DESC desc;
4875d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Width = width;
4885d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Height = height;
4895d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.MipLevels = lodOffset + 1;
4905d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.ArraySize = 1;
4915d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Format = dxgiFormat;
4925d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.SampleDesc.Count = 1;
4935d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.SampleDesc.Quality = 0;
4945d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.Usage = D3D11_USAGE_STAGING;
4955d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.BindFlags = 0;
49644b2768fcceb1989b268bb88698ac58cb33debcbshannonwoods@chromium.org            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
4975d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            desc.MiscFlags = 0;
4985d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com
4999aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang            if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
50034256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            {
50134256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang                std::vector<D3D11_SUBRESOURCE_DATA> initialData;
50234256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang                std::vector< std::vector<BYTE> > textureData;
503e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang                d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
504e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang                                                  lodOffset + 1, &initialData, &textureData);
50534256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang
50634256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang                result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
50734256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            }
50834256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            else
50934256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            {
51034256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang                result = device->CreateTexture2D(&desc, NULL, &newTexture);
51134256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            }
5125d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com
5135d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            if (FAILED(result))
5145d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            {
5155d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com                ASSERT(result == E_OUTOFMEMORY);
5165d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com                ERR("Creating image failed.");
5175d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com                return gl::error(GL_OUT_OF_MEMORY);
5185d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            }
5195d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com
5205d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            mStagingTexture = newTexture;
5215d009bb92f5a73130057bab196e171edb7a6792fshannon.woods%transgaming.com@gtempaccount.com            mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
522a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        }
52356074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        else
52456074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        {
52556074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com            UNREACHABLE();
52656074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        }
527a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    }
528a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
529a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    mDirty = false;
530a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
531a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
53244b2768fcceb1989b268bb88698ac58cb33debcbshannonwoods@chromium.orgHRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
533a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
534a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    createStagingTexture();
535a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
5366982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
5376982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    recoverFromAssociatedStorage();
5386982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
539ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    HRESULT result = E_FAIL;
540a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
541a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    if (mStagingTexture)
542a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    {
543a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
54444b2768fcceb1989b268bb88698ac58cb33debcbshannonwoods@chromium.org        result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map);
545a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
546ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        // this can fail if the device is removed (from TDR)
547ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        if (d3d11::isDeviceLostError(result))
548ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        {
549ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com            mRenderer->notifyDeviceLost();
550ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        }
551ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        else if (SUCCEEDED(result))
552ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        {
553ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com            mDirty = true;
554ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        }
555a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    }
556a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
557a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    return result;
558a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
559a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
560a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.comvoid Image11::unmap()
561a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com{
562a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    if (mStagingTexture)
563a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    {
564a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
56581ae58ac5438ed6059529115ea694f5ae1b649cashannon.woods@transgaming.com        deviceContext->Unmap(mStagingTexture, mStagingSubresource);
566a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    }
567a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
568a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com
569a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com}
570