14ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com//
24ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
34ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
44ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com// found in the LICENSE file.
54ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com//
64ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
74ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com// Image9.cpp: Implements the rx::Image9 class, which acts as the interface to
84ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com// the actual underlying surfaces of a Texture.
94ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
10c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d9/Image9.h"
110b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
120b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
130b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
140b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
150b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
164ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com#include "libGLESv2/main.h"
174ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com#include "libGLESv2/Framebuffer.h"
18e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill#include "libGLESv2/FramebufferAttachment.h"
19486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/Renderbuffer.h"
204ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
214ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
224ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comnamespace rx
234ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
244ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2512e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.comImage9::Image9()
264ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
2712e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.com    mSurface = NULL;
2812e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.com    mRenderer = NULL;
294ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3012e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.com    mD3DPool = D3DPOOL_SYSTEMMEM;
3112e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.com    mD3DFormat = D3DFMT_UNKNOWN;
3212e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.com}
334ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3412e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.comImage9::~Image9()
354ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
36ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(mSurface);
374ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
384ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3912e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.comvoid Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
404ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
414ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DSURFACE_DESC destDesc;
424ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    HRESULT result = destSurface->GetDesc(&destDesc);
434ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(SUCCEEDED(result));
444ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
454ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DSURFACE_DESC sourceDesc;
464ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    result = sourceSurface->GetDesc(&sourceDesc);
474ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(SUCCEEDED(result));
484ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
494ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(sourceDesc.Format == destDesc.Format);
504ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
514ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height);
524ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5391fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format);
5491fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    ASSERT(d3dFormatInfo.mipGenerationFunction != NULL);
55cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org
564ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DLOCKED_RECT sourceLocked = {0};
574ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
584ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(SUCCEEDED(result));
594ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
604ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DLOCKED_RECT destLocked = {0};
614ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    result = destSurface->LockRect(&destLocked, NULL, 0);
624ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(SUCCEEDED(result));
634ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
6457f9b6d56bec5e2040909b9dc0c68ddb7ac4a978Geoff Lang    const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(sourceLocked.pBits);
6557f9b6d56bec5e2040909b9dc0c68ddb7ac4a978Geoff Lang    uint8_t *destData = reinterpret_cast<uint8_t*>(destLocked.pBits);
664ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
674ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (sourceData && destData)
684ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
6991fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
7091fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang                                            destData, destLocked.Pitch, 0);
714ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
72cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org
73cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    destSurface->UnlockRect();
74cead8ad71769f28cbf8df829f60952999d3df602shannonwoods@chromium.org    sourceSurface->UnlockRect();
754ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
764ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
774ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comImage9 *Image9::makeImage9(Image *img)
784ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
798b400b1e8d84c5b93dd151807504a3e4b90d1b21apatrick@chromium.org    ASSERT(HAS_DYNAMIC_TYPE(rx::Image9*, img));
804ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    return static_cast<rx::Image9*>(img);
814ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
824ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
834ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comvoid Image9::generateMipmap(Image9 *dest, Image9 *source)
844ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
854ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    IDirect3DSurface9 *sourceSurface = source->getSurface();
864ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (sourceSurface == NULL)
87779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
884ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
894ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    IDirect3DSurface9 *destSurface = dest->getSurface();
9012e02218fe8a0a8ff962463a4f185d276421195bdaniel@transgaming.com    generateMip(destSurface, sourceSurface);
914ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
925dd4502f2fdc5a832bb23997348b82c16d2537c3daniel@transgaming.com    dest->markDirty();
934ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
944ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
954ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comvoid Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
964ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
974ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DLOCKED_RECT sourceLock = {0};
984ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DLOCKED_RECT destLock = {0};
9991fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang
1004ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    source->LockRect(&sourceLock, NULL, 0);
1014ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    dest->LockRect(&destLock, NULL, 0);
10291fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang
1034ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (sourceLock.pBits && destLock.pBits)
1044ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
1054ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        D3DSURFACE_DESC desc;
1064ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        source->GetDesc(&desc);
1074ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
10891fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
10991fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
110803be0a97a07688190ea977251959467e7f94daeshannonwoods@chromium.org
11191fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
11291fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
11391fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang               bytes <= static_cast<unsigned int>(destLock.Pitch));
1144ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
11591fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        for(unsigned int i = 0; i < rows; i++)
1164ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        {
1174ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
1184ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        }
1194ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1204ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        source->UnlockRect();
1214ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        dest->UnlockRect();
1224ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
1234ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    else UNREACHABLE();
1244ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
1254ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
126005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langbool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
1274ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
1284760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com    // 3D textures are not supported by the D3D9 backend.
1294760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com    ASSERT(depth <= 1);
1304760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com
13156074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com    // Only 2D and cube texture are supported by the D3D9 backend.
13256074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com    ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP);
13356074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com
1344ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (mWidth != width ||
1354ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mHeight != height ||
1364760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com        mDepth != depth ||
1374ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mInternalFormat != internalformat ||
1384ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        forceRelease)
1394ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
1404ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mRenderer = Renderer9::makeRenderer9(renderer);
1414ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1424ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mWidth = width;
1434ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mHeight = height;
1444760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com        mDepth = depth;
1454ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mInternalFormat = internalformat;
146803be0a97a07688190ea977251959467e7f94daeshannonwoods@chromium.org
1474ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        // compute the d3d format that will be used
14891fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat);
14991fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat);
15091fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        mD3DFormat = d3d9FormatInfo.texFormat;
15191fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        mActualFormat = d3dFormatInfo.internalFormat;
15291fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN);
1534ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
154ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(mSurface);
15591fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        mDirty = (d3d9FormatInfo.dataInitializerFunction != NULL);
1564ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1574ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        return true;
1584ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
1594ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1604ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    return false;
1614ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
1624ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1634ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comvoid Image9::createSurface()
1644ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
1654ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if(mSurface)
1664ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
1674ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        return;
1684ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
1694ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1704ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    IDirect3DTexture9 *newTexture = NULL;
1714ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    IDirect3DSurface9 *newSurface = NULL;
1724ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM;
1734ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    const D3DFORMAT d3dFormat = getD3DFormat();
1744ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1754ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (mWidth != 0 && mHeight != 0)
1764ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
1774ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        int levelToFetch = 0;
1784ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        GLsizei requestWidth = mWidth;
1794ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        GLsizei requestHeight = mHeight;
180803be0a97a07688190ea977251959467e7f94daeshannonwoods@chromium.org        d3d9::MakeValidSize(true, d3dFormat, &requestWidth, &requestHeight, &levelToFetch);
1814ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
182204677af271502bb1f91d4abd0cf8ab4ab5b49d0daniel@transgaming.com        IDirect3DDevice9 *device = mRenderer->getDevice();
1834ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1844ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, d3dFormat,
1854ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                                                    poolToUse, &newTexture, NULL);
1864ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1874ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        if (FAILED(result))
1884ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        {
1894ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
1904ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            ERR("Creating image surface failed.");
191779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com            return gl::error(GL_OUT_OF_MEMORY);
1924ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        }
1934ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
1944ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
195ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(newTexture);
19634256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang
19791fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
19891fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang        if (d3dFormatInfo.dataInitializerFunction != NULL)
19934256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang        {
20034256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            RECT entireRect;
20134256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            entireRect.left = 0;
20234256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            entireRect.right = mWidth;
20334256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            entireRect.top = 0;
20434256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            entireRect.bottom = mHeight;
20534256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang
20634256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            D3DLOCKED_RECT lockedRect;
20734256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            result = newSurface->LockRect(&lockedRect, &entireRect, 0);
20834256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            ASSERT(SUCCEEDED(result));
20934256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang
21091fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang            d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits),
21191fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang                                                  lockedRect.Pitch, 0);
21234256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang
21334256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            result = newSurface->UnlockRect();
21434256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang            ASSERT(SUCCEEDED(result));
21534256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang        }
2164ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
2174ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2184ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    mSurface = newSurface;
2194ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    mDirty = false;
2204ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    mD3DPool = poolToUse;
2214ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
2224ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2234ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comHRESULT Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect)
2244ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
2254ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    createSurface();
2264ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2274ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    HRESULT result = D3DERR_INVALIDCALL;
2284ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2294ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (mSurface)
2304ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
2314ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        result = mSurface->LockRect(lockedRect, rect, 0);
2324ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        ASSERT(SUCCEEDED(result));
2334ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2344ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mDirty = true;
2354ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
2364ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2374ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    return result;
2384ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
2394ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2404ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comvoid Image9::unlock()
2414ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
2424ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (mSurface)
2434ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
2444ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        HRESULT result = mSurface->UnlockRect();
2459cd1915c96800fc998ec25b88b0e3081f0aa6109Geoff Lang        UNUSED_ASSERTION_VARIABLE(result);
2464ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        ASSERT(SUCCEEDED(result));
2474ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
2484ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
2494ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2504ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comD3DFORMAT Image9::getD3DFormat() const
2514ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
2524ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    // this should only happen if the image hasn't been redefined first
2534ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    // which would be a bug by the caller
2544ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(mD3DFormat != D3DFMT_UNKNOWN);
2554ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2564ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    return mD3DFormat;
2574ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
2584ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
25934256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Langbool Image9::isDirty() const
26034256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang{
26134256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang    // Make sure to that this image is marked as dirty even if the staging texture hasn't been created yet
26234256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang    // if initialization is required before use.
26391fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty;
26434256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang}
26534256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang
2664ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comIDirect3DSurface9 *Image9::getSurface()
2674ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
2684ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    createSurface();
2694ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2704ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    return mSurface;
2714ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
2724ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2732f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillvoid Image9::setManagedSurface2D(TextureStorage *storage, int level)
2744ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
2752f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
27634da397e13a101d6157619bfbd6c2f33efbd1a31daniel@transgaming.com    setManagedSurface(storage9->getSurfaceLevel(level, false));
2774ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
2784ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2792f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillvoid Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level)
2804ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
2812f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
28234da397e13a101d6157619bfbd6c2f33efbd1a31daniel@transgaming.com    setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
2834ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
2844ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2854ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.comvoid Image9::setManagedSurface(IDirect3DSurface9 *surface)
2864ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
2874ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DSURFACE_DESC desc;
2884ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    surface->GetDesc(&desc);
2894ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(desc.Pool == D3DPOOL_MANAGED);
2904ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2914ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if ((GLsizei)desc.Width == mWidth && (GLsizei)desc.Height == mHeight)
2924ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
2934ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        if (mSurface)
2944ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        {
2954ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            copyLockableSurfaces(surface, mSurface);
296ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang            SafeRelease(mSurface);
2974ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        }
2984ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
2994ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mSurface = surface;
3004ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        mD3DPool = desc.Pool;
3014ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
3024ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
3034ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3042f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillbool Image9::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
3054ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
3064ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(getSurface() != NULL);
3072f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
308169d11186cb1fdef8920668169682cf84749606dJamie Madill    return copyToSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
3094ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
3104ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3112f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillbool Image9::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
3124ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
3134ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    ASSERT(getSurface() != NULL);
3142f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
315169d11186cb1fdef8920668169682cf84749606dJamie Madill    return copyToSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
3164ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
3174ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3182f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillbool Image9::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
3192058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
3202058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    // 3D textures are not supported by the D3D9 backend.
3212058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    UNREACHABLE();
3222058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    return false;
3232058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
3242058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
3252f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madillbool Image9::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height)
3266c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com{
3276c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    // 2D array textures are not supported by the D3D9 backend.
3286c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    UNREACHABLE();
3296c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    return false;
3306c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com}
3316c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
332169d11186cb1fdef8920668169682cf84749606dJamie Madillbool Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
3334ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
334c41e42d49626e1527c9e049b48d7c9fb30b0b9d6Geoff Lang    ASSERT(width > 0 && height > 0);
335c41e42d49626e1527c9e049b48d7c9fb30b0b9d6Geoff Lang
3364ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (!destSurface)
3374ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        return false;
3384ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3394ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    IDirect3DSurface9 *sourceSurface = getSurface();
3404ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3414ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (sourceSurface && sourceSurface != destSurface)
3424ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
3434ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        RECT rect;
3444ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        rect.left = xoffset;
3454ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        rect.top = yoffset;
3464ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        rect.right = xoffset + width;
3474ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        rect.bottom = yoffset + height;
3484ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3494ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        POINT point = {rect.left, rect.top};
3504ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
351204677af271502bb1f91d4abd0cf8ab4ab5b49d0daniel@transgaming.com        IDirect3DDevice9 *device = mRenderer->getDevice();
3524ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3534ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        if (mD3DPool == D3DPOOL_MANAGED)
3544ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        {
3554ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            D3DSURFACE_DESC desc;
3564ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            sourceSurface->GetDesc(&desc);
3574ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3584ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            IDirect3DSurface9 *surf = 0;
3594ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
3604ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3614ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            if (SUCCEEDED(result))
3624ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            {
3634ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                copyLockableSurfaces(surf, sourceSurface);
3644ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                result = device->UpdateSurface(surf, &rect, destSurface, &point);
3654ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                ASSERT(SUCCEEDED(result));
366ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang                SafeRelease(surf);
3674ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            }
3684ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        }
3694ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        else
3704ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        {
3719f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill            // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
3724ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point);
3739cd1915c96800fc998ec25b88b0e3081f0aa6109Geoff Lang            UNUSED_ASSERTION_VARIABLE(result);
3744ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            ASSERT(SUCCEEDED(result));
3754ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        }
3764ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
3774ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
378ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(destSurface);
3794ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    return true;
3804ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
3814ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
3824ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
3834ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com// into the target pixel rectangle.
3844760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.comvoid Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
385557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org                      GLint unpackAlignment, GLenum type, const void *input)
3864ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
3874760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com    // 3D textures are not supported by the D3D9 backend.
3884760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com    ASSERT(zoffset == 0 && depth == 1);
3894760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com
3905d601382b51c29d1670b58c01360416bd929842dGeoff Lang    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
3915d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
392557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org
39391fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
39491fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    ASSERT(d3dFormatInfo.loadFunction != NULL);
395557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org
3964ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    RECT lockRect =
3974ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
3984ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        xoffset, yoffset,
3994ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        xoffset + width, yoffset + height
4004ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    };
4014ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4024ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DLOCKED_RECT locked;
4034ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    HRESULT result = lock(&locked, &lockRect);
4044ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (FAILED(result))
4054ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
4064ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        return;
4074ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
4084ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
40991fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    d3dFormatInfo.loadFunction(width, height, depth,
41091fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang                               reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0,
41191fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang                               reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
4124ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4134ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    unlock();
4144ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
4154ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4164760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.comvoid Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
4174ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                                const void *input)
4184ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
4194760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com    // 3D textures are not supported by the D3D9 backend.
4204760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com    ASSERT(zoffset == 0 && depth == 1);
4214760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com
4225d601382b51c29d1670b58c01360416bd929842dGeoff Lang    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
4235d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
4245d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
425b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org
42691fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
42791fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang
42891fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    ASSERT(xoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0);
42991fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    ASSERT(yoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0);
430b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org
43191fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    ASSERT(d3d9FormatInfo.loadFunction != NULL);
432b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org
433b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org    RECT lockRect =
434b8cabd593cf162be44fb1c0f3c8fbe72c1f45b75shannonwoods@chromium.org    {
4354ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        xoffset, yoffset,
4364ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        xoffset + width, yoffset + height
4374ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    };
4384ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4394ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DLOCKED_RECT locked;
4404ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    HRESULT result = lock(&locked, &lockRect);
4414ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (FAILED(result))
4424ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
4434ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        return;
4444ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
4454ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
44691fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang    d3d9FormatInfo.loadFunction(width, height, depth,
44791fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang                                reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
44891fa9ce47649057c5b15113ea31c5ed4b7bd8fceGeoff Lang                                reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
4494ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4504ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    unlock();
4514ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
4524ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4534ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
454e5dcce75bb08208387723a4e0494ca19073e05a7shannon.woods%transgaming.com@gtempaccount.comvoid Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
4554ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com{
456e5dcce75bb08208387723a4e0494ca19073e05a7shannon.woods%transgaming.com@gtempaccount.com    // ES3.0 only behaviour to copy into a 3d texture
457e5dcce75bb08208387723a4e0494ca19073e05a7shannon.woods%transgaming.com@gtempaccount.com    ASSERT(zoffset == 0);
458e5dcce75bb08208387723a4e0494ca19073e05a7shannon.woods%transgaming.com@gtempaccount.com
4594ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    RenderTarget9 *renderTarget = NULL;
4604ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    IDirect3DSurface9 *surface = NULL;
4613c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *colorbuffer = source->getColorbuffer(0);
4624ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4634ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (colorbuffer)
4644ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
4659f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill        renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
4664ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
4679f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill
4684ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (renderTarget)
4694ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
4704ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        surface = renderTarget->getSurface();
4714ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
4724ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4734ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (!surface)
4744ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
4754ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        ERR("Failed to retrieve the render target.");
476779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
4774ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
4784ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
479204677af271502bb1f91d4abd0cf8ab4ab5b49d0daniel@transgaming.com    IDirect3DDevice9 *device = mRenderer->getDevice();
4804ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4814ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    IDirect3DSurface9 *renderTargetData = NULL;
4824ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DSURFACE_DESC description;
4834ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    surface->GetDesc(&description);
4849f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill
4854ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL);
4864ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4874ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (FAILED(result))
4884ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
4894ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        ERR("Could not create matching destination surface.");
490ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(surface);
491779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
4924ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
4934ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4944ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    result = device->GetRenderTargetData(surface, renderTargetData);
4954ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
4964ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (FAILED(result))
4974ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
4984ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        ERR("GetRenderTargetData unexpectedly failed.");
499ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(renderTargetData);
500ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(surface);
501779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
5024ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
5034ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5044ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    RECT sourceRect = {x, y, x + width, y + height};
5054ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
5064ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5074ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DLOCKED_RECT sourceLock = {0};
5084ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0);
5094ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5104ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (FAILED(result))
5114ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
5124ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        ERR("Failed to lock the source surface (rectangle might be invalid).");
513ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(renderTargetData);
514ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(surface);
515779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
5164ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
5174ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5184ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    D3DLOCKED_RECT destLock = {0};
5194ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    result = lock(&destLock, &destRect);
5209f0b42a6ab87ae2b2f065cf022497ac6deabf3fdJamie Madill
5214ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (FAILED(result))
5224ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
5234ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        ERR("Failed to lock the destination surface (rectangle might be invalid).");
5244ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        renderTargetData->UnlockRect();
525ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(renderTargetData);
526ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(surface);
527779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
5284ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
5294ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5304ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    if (destLock.pBits && sourceLock.pBits)
5314ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    {
5324ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        unsigned char *source = (unsigned char*)sourceLock.pBits;
5334ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        unsigned char *dest = (unsigned char*)destLock.pBits;
5344ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5354ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        switch (description.Format)
5364ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        {
5374ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com          case D3DFMT_X8R8G8B8:
5384ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com          case D3DFMT_A8R8G8B8:
5394ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            switch(getD3DFormat())
5404ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            {
5414ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_X8R8G8B8:
5424ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_A8R8G8B8:
5434ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
5444ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
5454ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    memcpy(dest, source, 4 * width);
5464ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5474ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
5484ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
5494ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
5504ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
5514ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_L8:
5524ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
5534ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
5544ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    for(int x = 0; x < width; x++)
5554ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    {
5564ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x] = source[x * 4 + 2];
5574ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    }
5584ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5594ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
5604ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
5614ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
5624ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
5634ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_A8L8:
5644ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
5654ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
5664ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    for(int x = 0; x < width; x++)
5674ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    {
5684ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x * 2 + 0] = source[x * 4 + 2];
5694ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x * 2 + 1] = source[x * 4 + 3];
5704ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    }
5714ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5724ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
5734ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
5744ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
5754ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
5764ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              default:
5774ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                UNREACHABLE();
5784ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            }
5794ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            break;
5804ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com          case D3DFMT_R5G6B5:
5814ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            switch(getD3DFormat())
5824ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            {
5834ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_X8R8G8B8:
5844ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
5854ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
5864ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    for(int x = 0; x < width; x++)
5874ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    {
5884ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned short rgb = ((unsigned short*)source)[x];
5894ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char red = (rgb & 0xF800) >> 8;
5904ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char green = (rgb & 0x07E0) >> 3;
5914ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char blue = (rgb & 0x001F) << 3;
5924ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 0] = blue | (blue >> 5);
5934ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 1] = green | (green >> 6);
5944ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 2] = red | (red >> 5);
5954ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 3] = 0xFF;
5964ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    }
5974ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
5984ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
5994ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
6004ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
6014ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
6024ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_L8:
6034ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
6044ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
6054ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    for(int x = 0; x < width; x++)
6064ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    {
6074ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char red = source[x * 2 + 1] & 0xF8;
6084ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x] = red | (red >> 5);
6094ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    }
6104ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
6114ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
6124ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
6134ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
6144ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
6154ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              default:
6164ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                UNREACHABLE();
6174ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            }
6184ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            break;
6194ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com          case D3DFMT_A1R5G5B5:
6204ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            switch(getD3DFormat())
6214ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            {
6224ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_X8R8G8B8:
6234ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
6244ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
6254ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    for(int x = 0; x < width; x++)
6264ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    {
6274ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned short argb = ((unsigned short*)source)[x];
6284ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char red = (argb & 0x7C00) >> 7;
6294ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char green = (argb & 0x03E0) >> 2;
6304ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char blue = (argb & 0x001F) << 3;
6314ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 0] = blue | (blue >> 5);
6324ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 1] = green | (green >> 5);
6334ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 2] = red | (red >> 5);
6344ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 3] = 0xFF;
6354ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    }
6364ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
6374ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
6384ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
6394ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
6404ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
6414ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_A8R8G8B8:
6424ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
6434ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
6444ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    for(int x = 0; x < width; x++)
6454ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    {
6464ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned short argb = ((unsigned short*)source)[x];
6474ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char red = (argb & 0x7C00) >> 7;
6484ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char green = (argb & 0x03E0) >> 2;
6494ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char blue = (argb & 0x001F) << 3;
6504ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char alpha = (signed short)argb >> 15;
6514ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 0] = blue | (blue >> 5);
6524ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 1] = green | (green >> 5);
6534ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 2] = red | (red >> 5);
6544ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x + 3] = alpha;
6554ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    }
6564ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
6574ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
6584ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
6594ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
6604ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
6614ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_L8:
6624ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
6634ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
6644ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    for(int x = 0; x < width; x++)
6654ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    {
6664ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char red = source[x * 2 + 1] & 0x7C;
6674ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x] = (red << 1) | (red >> 4);
6684ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    }
6694ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
6704ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
6714ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
6724ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
6734ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
6744ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              case D3DFMT_A8L8:
6754ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                for(int y = 0; y < height; y++)
6764ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                {
6774ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    for(int x = 0; x < width; x++)
6784ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    {
6794ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        unsigned char red = source[x * 2 + 1] & 0x7C;
6804ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x * 2 + 0] = (red << 1) | (red >> 4);
6814ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                        dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
6824ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    }
6834ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
6844ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    source += sourceLock.Pitch;
6854ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                    dest += destLock.Pitch;
6864ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                }
6874ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                break;
6884ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com              default:
6894ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com                UNREACHABLE();
6904ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            }
6914ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            break;
6924ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com          default:
6934ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com            UNREACHABLE();
6944ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com        }
6954ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    }
6964ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
6974ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    unlock();
6984ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    renderTargetData->UnlockRect();
6994ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
700ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(renderTargetData);
701ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(surface);
7024ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
7034ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com    mDirty = true;
7044ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com}
7054ba2406781174627e817ca547a6e9f6b1a196ff0daniel@transgaming.com
70634256ed8593f6d7fff6b7536979c95afc28ae2d3Geoff Lang}
707