Implemented Renderer11::copyImage.

TRAC #22358

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Author: Geoff Lang

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1749 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 8edc9e4..e478ff3 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -26,6 +26,12 @@
 #include "libGLESv2/renderer/IndexDataManager.h"
 #include "libGLESv2/renderer/TextureStorage11.h"
 
+#include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h"
+
 #include <sstream>
 
 namespace rx
@@ -48,6 +54,16 @@
     mLineLoopIB = NULL;
     mTriangleFanIB = NULL;
 
+    mCopyResourcesInitialized = false;
+    mCopyVB = NULL;
+    mCopySampler = NULL;
+    mCopyIL = NULL;
+    mCopyVS = NULL;
+    mCopyRGBAPS = NULL;
+    mCopyRGBPS = NULL;
+    mCopyLumPS = NULL;
+    mCopyLumAlphaPS = NULL;
+
     mD3d11Module = NULL;
     mDxgiModule = NULL;
 
@@ -1341,6 +1357,56 @@
 
     delete mTriangleFanIB;
     mTriangleFanIB = NULL;
+
+    if (mCopyVB)
+    {
+        mCopyVB->Release();
+        mCopyVB = NULL;
+    }
+
+    if (mCopySampler)
+    {
+        mCopySampler->Release();
+        mCopySampler = NULL;
+    }
+
+    if (mCopyIL)
+    {
+        mCopyIL->Release();
+        mCopyIL = NULL;
+    }
+
+    if (mCopyVS)
+    {
+        mCopyVS->Release();
+        mCopyVS = NULL;
+    }
+
+    if (mCopyRGBAPS)
+    {
+        mCopyRGBAPS->Release();
+        mCopyRGBAPS = NULL;
+    }
+
+    if (mCopyRGBPS)
+    {
+        mCopyRGBPS->Release();
+        mCopyRGBPS = NULL;
+    }
+
+    if (mCopyLumPS)
+    {
+        mCopyLumPS->Release();
+        mCopyLumPS = NULL;
+    }
+
+    if (mCopyLumAlphaPS)
+    {
+        mCopyLumAlphaPS->Release();
+        mCopyLumAlphaPS = NULL;
+    }
+
+    mCopyResourcesInitialized = false;
 }
 
 void Renderer11::markDeviceLost()
@@ -1672,17 +1738,306 @@
 bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
                            GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
 {
-    // TODO
-    UNIMPLEMENTED();
-    return false;
+    gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
+    if (!colorbuffer)
+    {
+        ERR("Failed to retrieve the color buffer from the frame buffer.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+    if (!sourceRenderTarget)
+    {
+        ERR("Failed to retrieve the render target from the frame buffer.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
+    if (!source)
+    {
+        ERR("Failed to retrieve the render target view from the render target.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
+    if (!storage11)
+    {
+        source->Release();
+        ERR("Failed to retrieve the texture storage from the destination.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level));
+    if (!destRenderTarget)
+    {
+        source->Release();
+        ERR("Failed to retrieve the render target from the destination storage.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
+    if (!dest)
+    {
+        source->Release();
+        ERR("Failed to retrieve the render target view from the destination render target.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    gl::Rectangle destRect;
+    destRect.x = xoffset;
+    destRect.y = yoffset;
+    destRect.width = sourceRect.width;
+    destRect.height = sourceRect.height;
+
+    bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(),
+                           dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat);
+
+    source->Release();
+    dest->Release();
+
+    return ret;
 }
 
 bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
                            GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
 {
-    // TODO
-    UNIMPLEMENTED();
-    return false;
+    gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
+    if (!colorbuffer)
+    {
+        ERR("Failed to retrieve the color buffer from the frame buffer.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+    if (!sourceRenderTarget)
+    {
+        ERR("Failed to retrieve the render target from the frame buffer.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
+    if (!source)
+    {
+        ERR("Failed to retrieve the render target view from the render target.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
+    if (!storage11)
+    {
+        source->Release();
+        ERR("Failed to retrieve the texture storage from the destination.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(target, level));
+    if (!destRenderTarget)
+    {
+        source->Release();
+        ERR("Failed to retrieve the render target from the destination storage.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
+    if (!dest)
+    {
+        source->Release();
+        ERR("Failed to retrieve the render target view from the destination render target.");
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    gl::Rectangle destRect;
+    destRect.x = xoffset;
+    destRect.y = yoffset;
+    destRect.width = sourceRect.width;
+    destRect.height = sourceRect.height;
+
+    bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(),
+                           dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat);
+
+    source->Release();
+    dest->Release();
+
+    return ret;
+}
+
+bool Renderer11::copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight,
+                             ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat)
+{
+    HRESULT result;
+
+    if (!mCopyResourcesInitialized)
+    {
+        ASSERT(!mCopyVB && !mCopySampler && !mCopyIL && !mCopyVS && !mCopyRGBAPS && !mCopyRGBPS && !mCopyLumPS && !mCopyLumAlphaPS);
+
+        D3D11_BUFFER_DESC vbDesc;
+        vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
+        vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+        vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+        vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        vbDesc.MiscFlags = 0;
+        vbDesc.StructureByteStride = 0;
+
+        result = mDevice->CreateBuffer(&vbDesc, NULL, &mCopyVB);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyVB, "Renderer11 copy texture vertex buffer");
+
+        D3D11_SAMPLER_DESC samplerDesc;
+        samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+        samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+        samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+        samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+        samplerDesc.MipLODBias = 0.0f;
+        samplerDesc.MaxAnisotropy = 0;
+        samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+        samplerDesc.BorderColor[0] = 0.0f;
+        samplerDesc.BorderColor[1] = 0.0f;
+        samplerDesc.BorderColor[2] = 0.0f;
+        samplerDesc.BorderColor[3] = 0.0f;
+        samplerDesc.MinLOD = 0.0f;
+        samplerDesc.MaxLOD = 0.0f;
+
+        result = mDevice->CreateSamplerState(&samplerDesc, &mCopySampler);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopySampler, "Renderer11 copy sampler");
+
+        D3D11_INPUT_ELEMENT_DESC quadLayout[] =
+        {
+            { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+            { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        };
+
+        result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mCopyIL);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyIL, "Renderer11 copy texture input layout");
+
+        result = mDevice->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mCopyVS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyVS, "Renderer11 copy texture vertex shader");
+
+        result = mDevice->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mCopyRGBAPS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyRGBAPS, "Renderer11 copy texture RGBA pixel shader");
+
+        result = mDevice->CreatePixelShader(g_PS_PassthroughRGB, sizeof(g_PS_PassthroughRGB), NULL, &mCopyRGBPS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyRGBPS, "Renderer11 copy texture RGB pixel shader");
+
+        result = mDevice->CreatePixelShader(g_PS_PassthroughLum, sizeof(g_PS_PassthroughLum), NULL, &mCopyLumPS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyLumPS, "Renderer11 copy texture luminance pixel shader");
+
+        result = mDevice->CreatePixelShader(g_PS_PassthroughLumAlpha, sizeof(g_PS_PassthroughLumAlpha), NULL, &mCopyLumAlphaPS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyLumAlphaPS, "Renderer11 copy texture luminance alpha pixel shader");
+
+        mCopyResourcesInitialized = true;
+    }
+
+    // Verify the source and destination area sizes
+    if (sourceArea.x < 0 || sourceArea.x + sourceArea.width > static_cast<int>(sourceWidth) ||
+        sourceArea.y < 0 || sourceArea.y + sourceArea.height > static_cast<int>(sourceHeight) ||
+        destArea.x < 0 || destArea.x + destArea.width > static_cast<int>(destWidth) ||
+        destArea.y < 0 || destArea.y + destArea.height > static_cast<int>(destHeight))
+    {
+        return error(GL_INVALID_VALUE, false);
+    }
+
+    // Set vertices
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    result = mDeviceContext->Map(mCopyVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+    if (FAILED(result))
+    {
+        ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
+        return error(GL_OUT_OF_MEMORY, false);
+    }
+
+    d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
+
+    // Create a quad in homogeneous coordinates
+    float x1 = (destArea.x / destWidth) * 2.0f - 1.0f;
+    float y1 = (destArea.y / destHeight) * 2.0f - 1.0f;
+    float x2 = ((destArea.x + destArea.width) / destWidth) * 2.0f - 1.0f;
+    float y2 = ((destArea.y + destArea.height) / destHeight) * 2.0f - 1.0f;
+
+    float u1 = sourceArea.x / float(sourceWidth);
+    float v1 = sourceArea.y / float(sourceHeight);
+    float u2 = (sourceArea.x + sourceArea.width) / float(sourceWidth);
+    float v2 = (sourceArea.y + sourceArea.height) / float(sourceHeight);
+
+    d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
+    d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
+    d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
+    d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
+
+    mDeviceContext->Unmap(mCopyVB, 0);
+
+    static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
+    static UINT startIdx = 0;
+    mDeviceContext->IASetVertexBuffers(0, 1, &mCopyVB, &stride, &startIdx);
+
+    // Apply state
+    static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+    mDeviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF);
+    mDeviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
+    mDeviceContext->RSSetState(NULL);
+
+    // Apply shaders
+    mDeviceContext->IASetInputLayout(mCopyIL);
+    mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+    mDeviceContext->VSSetShader(mCopyVS, NULL, 0);
+
+    ID3D11PixelShader *ps = NULL;
+    switch(destFormat)
+    {
+      case GL_RGBA:            ps = mCopyRGBAPS;     break;
+      case GL_RGB:             ps = mCopyRGBPS;      break;
+      case GL_ALPHA:           ps = mCopyRGBAPS;     break;
+      case GL_BGRA_EXT:        ps = mCopyRGBAPS;     break;
+      case GL_LUMINANCE:       ps = mCopyLumPS;      break;
+      case GL_LUMINANCE_ALPHA: ps = mCopyLumAlphaPS; break;
+      default: UNREACHABLE();  ps = NULL;            break;
+    }
+
+    mDeviceContext->PSSetShader(ps, NULL, 0);
+
+    // Unset the currently bound shader resource to avoid conflicts
+    static ID3D11ShaderResourceView *const nullSRV = NULL;
+    mDeviceContext->PSSetShaderResources(0, 1, &nullSRV);
+
+    // Apply render targets
+    mDeviceContext->OMSetRenderTargets(1, &dest, NULL);
+
+    // Set the viewport
+    D3D11_VIEWPORT viewport;
+    viewport.TopLeftX = 0;
+    viewport.TopLeftY = 0;
+    viewport.Width = destWidth;
+    viewport.Height = destHeight;
+    viewport.MinDepth = 0.0f;
+    viewport.MaxDepth = 1.0f;
+    mDeviceContext->RSSetViewports(1, &viewport);
+
+    // Apply textures
+    mDeviceContext->PSSetShaderResources(0, 1, &source);
+    mDeviceContext->PSSetSamplers(0, 1, &mCopySampler);
+
+    // Draw the quad
+    mDeviceContext->Draw(4, 0);
+
+    // Unbind textures and render targets and vertex buffer
+    mDeviceContext->PSSetShaderResources(0, 1, &nullSRV);
+
+    static ID3D11RenderTargetView *const nullRTV = NULL;
+    mDeviceContext->OMSetRenderTargets(1, &nullRTV, NULL);
+
+    static UINT zero = 0;
+    static ID3D11Buffer *const nullBuffer = NULL;
+    mDeviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
+
+    markAllStateDirty();
+
+    return true;
 }
 
 RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
@@ -2242,4 +2597,4 @@
     stagingTex = NULL;
 }
 
-}
\ No newline at end of file
+}
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 0262612..cfa09f8 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -126,6 +126,9 @@
     virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
                            GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
 
+    bool copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight,
+                     ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat);
+
     virtual bool blitRect(gl::Framebuffer *readTarget, gl::Rectangle *readRect, gl::Framebuffer *drawTarget, gl::Rectangle *drawRect,
                           bool blitRenderTarget, bool blitDepthStencil);
     virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
@@ -242,6 +245,17 @@
     StreamingIndexBufferInterface *mLineLoopIB;
     StreamingIndexBufferInterface *mTriangleFanIB;
 
+    // Texture copy resources
+    bool mCopyResourcesInitialized;
+    ID3D11Buffer *mCopyVB;
+    ID3D11SamplerState *mCopySampler;
+    ID3D11InputLayout *mCopyIL;
+    ID3D11VertexShader *mCopyVS;
+    ID3D11PixelShader *mCopyRGBAPS;
+    ID3D11PixelShader *mCopyRGBPS;
+    ID3D11PixelShader *mCopyLumPS;
+    ID3D11PixelShader *mCopyLumAlphaPS;
+
     ID3D11Device *mDevice;
     D3D_FEATURE_LEVEL mFeatureLevel;
     ID3D11DeviceContext *mDeviceContext;
diff --git a/src/libGLESv2/renderer/shaders/Passthrough11.hlsl b/src/libGLESv2/renderer/shaders/Passthrough11.hlsl
index 20deb48..43b7801 100644
--- a/src/libGLESv2/renderer/shaders/Passthrough11.hlsl
+++ b/src/libGLESv2/renderer/shaders/Passthrough11.hlsl
@@ -12,3 +12,18 @@
 {
     return Texture.Sample(Sampler, inTexCoord).rgba;
 }
+
+float4 PS_PassthroughRGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+    return float4(Texture.Sample(Sampler, inTexCoord).rgb, 1.0f);
+}
+
+float4 PS_PassthroughLum(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+    return float4(Texture.Sample(Sampler, inTexCoord).rrr, 1.0f);
+}
+
+float4 PS_PassthroughLumAlpha(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+    return Texture.Sample(Sampler, inTexCoord).rrra;
+}
diff --git a/src/libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h b/src/libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h
new file mode 100644
index 0000000..0d5c8eb
--- /dev/null
+++ b/src/libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h
@@ -0,0 +1,155 @@
+#if 0

+//

+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111

+//

+//

+//   fxc /E PS_PassthroughLum /T ps_4_0 /Fh compiled/passthroughlum11ps.h

+//    Passthrough11.hlsl

+//

+//

+// Resource Bindings:

+//

+// Name                                 Type  Format         Dim Slot Elements

+// ------------------------------ ---------- ------- ----------- ---- --------

+// Sampler                           sampler      NA          NA    0        1

+// Texture                           texture  float4          2d    0        1

+//

+//

+//

+// Input signature:

+//

+// Name                 Index   Mask Register SysValue Format   Used

+// -------------------- ----- ------ -------- -------- ------ ------

+// SV_POSITION              0   xyzw        0      POS  float       

+// TEXCOORD                 0   xy          1     NONE  float   xy  

+//

+//

+// Output signature:

+//

+// Name                 Index   Mask Register SysValue Format   Used

+// -------------------- ----- ------ -------- -------- ------ ------

+// SV_TARGET                0   xyzw        0   TARGET  float   xyzw

+//

+ps_4_0

+dcl_sampler s0, mode_default

+dcl_resource_texture2d (float,float,float,float) t0

+dcl_input_ps linear v1.xy

+dcl_output o0.xyzw

+dcl_temps 1

+sample r0.xyzw, v1.xyxx, t0.xyzw, s0

+mov o0.xyz, r0.xxxx

+mov o0.w, l(1.000000)

+ret 

+// Approximately 4 instruction slots used

+#endif

+

+const BYTE g_PS_PassthroughLum[] =

+{

+     68,  88,  66,  67,  97,  41, 

+     37, 154,   0, 174, 137, 157, 

+     76, 219, 230,  26, 227, 174, 

+    187,  66,   1,   0,   0,   0, 

+    128,   2,   0,   0,   5,   0, 

+      0,   0,  52,   0,   0,   0, 

+    220,   0,   0,   0,  52,   1, 

+      0,   0, 104,   1,   0,   0, 

+      4,   2,   0,   0,  82,  68, 

+     69,  70, 160,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   2,   0,   0,   0, 

+     28,   0,   0,   0,   0,   4, 

+    255, 255,   0,   1,   0,   0, 

+    108,   0,   0,   0,  92,   0, 

+      0,   0,   3,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   1,   0,   0,   0, 

+    100,   0,   0,   0,   2,   0, 

+      0,   0,   5,   0,   0,   0, 

+      4,   0,   0,   0, 255, 255, 

+    255, 255,   0,   0,   0,   0, 

+      1,   0,   0,   0,  13,   0, 

+      0,   0,  83,  97, 109, 112, 

+    108, 101, 114,   0,  84, 101, 

+    120, 116, 117, 114, 101,   0, 

+     77, 105,  99, 114, 111, 115, 

+    111, 102, 116,  32,  40,  82, 

+     41,  32,  72,  76,  83,  76, 

+     32,  83, 104,  97, 100, 101, 

+    114,  32,  67, 111, 109, 112, 

+    105, 108, 101, 114,  32,  57, 

+     46,  50,  57,  46,  57,  53, 

+     50,  46,  51,  49,  49,  49, 

+      0, 171, 171, 171,  73,  83, 

+     71,  78,  80,   0,   0,   0, 

+      2,   0,   0,   0,   8,   0, 

+      0,   0,  56,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   3,   0,   0,   0, 

+      0,   0,   0,   0,  15,   0, 

+      0,   0,  68,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   3,   0,   0,   0, 

+      1,   0,   0,   0,   3,   3, 

+      0,   0,  83,  86,  95,  80, 

+     79,  83,  73,  84,  73,  79, 

+     78,   0,  84,  69,  88,  67, 

+     79,  79,  82,  68,   0, 171, 

+    171, 171,  79,  83,  71,  78, 

+     44,   0,   0,   0,   1,   0, 

+      0,   0,   8,   0,   0,   0, 

+     32,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      3,   0,   0,   0,   0,   0, 

+      0,   0,  15,   0,   0,   0, 

+     83,  86,  95,  84,  65,  82, 

+     71,  69,  84,   0, 171, 171, 

+     83,  72,  68,  82, 148,   0, 

+      0,   0,  64,   0,   0,   0, 

+     37,   0,   0,   0,  90,   0, 

+      0,   3,   0,  96,  16,   0, 

+      0,   0,   0,   0,  88,  24, 

+      0,   4,   0, 112,  16,   0, 

+      0,   0,   0,   0,  85,  85, 

+      0,   0,  98,  16,   0,   3, 

+     50,  16,  16,   0,   1,   0, 

+      0,   0, 101,   0,   0,   3, 

+    242,  32,  16,   0,   0,   0, 

+      0,   0, 104,   0,   0,   2, 

+      1,   0,   0,   0,  69,   0, 

+      0,   9, 242,   0,  16,   0, 

+      0,   0,   0,   0,  70,  16, 

+     16,   0,   1,   0,   0,   0, 

+     70, 126,  16,   0,   0,   0, 

+      0,   0,   0,  96,  16,   0, 

+      0,   0,   0,   0,  54,   0, 

+      0,   5, 114,  32,  16,   0, 

+      0,   0,   0,   0,   6,   0, 

+     16,   0,   0,   0,   0,   0, 

+     54,   0,   0,   5, 130,  32, 

+     16,   0,   0,   0,   0,   0, 

+      1,  64,   0,   0,   0,   0, 

+    128,  63,  62,   0,   0,   1, 

+     83,  84,  65,  84, 116,   0, 

+      0,   0,   4,   0,   0,   0, 

+      1,   0,   0,   0,   0,   0, 

+      0,   0,   2,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      1,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      2,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0

+};

diff --git a/src/libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h b/src/libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h
new file mode 100644
index 0000000..6f9c14d
--- /dev/null
+++ b/src/libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h
@@ -0,0 +1,151 @@
+#if 0

+//

+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111

+//

+//

+//   fxc /E PS_PassthroughLumAlpha /T ps_4_0 /Fh

+//    compiled/passthroughlumalpha11ps.h Passthrough11.hlsl

+//

+//

+// Resource Bindings:

+//

+// Name                                 Type  Format         Dim Slot Elements

+// ------------------------------ ---------- ------- ----------- ---- --------

+// Sampler                           sampler      NA          NA    0        1

+// Texture                           texture  float4          2d    0        1

+//

+//

+//

+// Input signature:

+//

+// Name                 Index   Mask Register SysValue Format   Used

+// -------------------- ----- ------ -------- -------- ------ ------

+// SV_POSITION              0   xyzw        0      POS  float       

+// TEXCOORD                 0   xy          1     NONE  float   xy  

+//

+//

+// Output signature:

+//

+// Name                 Index   Mask Register SysValue Format   Used

+// -------------------- ----- ------ -------- -------- ------ ------

+// SV_TARGET                0   xyzw        0   TARGET  float   xyzw

+//

+ps_4_0

+dcl_sampler s0, mode_default

+dcl_resource_texture2d (float,float,float,float) t0

+dcl_input_ps linear v1.xy

+dcl_output o0.xyzw

+dcl_temps 1

+sample r0.xyzw, v1.xyxx, t0.xyzw, s0

+mov o0.xyzw, r0.xxxw

+ret 

+// Approximately 3 instruction slots used

+#endif

+

+const BYTE g_PS_PassthroughLumAlpha[] =

+{

+     68,  88,  66,  67, 197,  72, 

+    251, 236,  53, 107, 182, 146, 

+    196, 219, 130, 187, 140, 159, 

+    211, 123,   1,   0,   0,   0, 

+    108,   2,   0,   0,   5,   0, 

+      0,   0,  52,   0,   0,   0, 

+    220,   0,   0,   0,  52,   1, 

+      0,   0, 104,   1,   0,   0, 

+    240,   1,   0,   0,  82,  68, 

+     69,  70, 160,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   2,   0,   0,   0, 

+     28,   0,   0,   0,   0,   4, 

+    255, 255,   0,   1,   0,   0, 

+    108,   0,   0,   0,  92,   0, 

+      0,   0,   3,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   1,   0,   0,   0, 

+    100,   0,   0,   0,   2,   0, 

+      0,   0,   5,   0,   0,   0, 

+      4,   0,   0,   0, 255, 255, 

+    255, 255,   0,   0,   0,   0, 

+      1,   0,   0,   0,  13,   0, 

+      0,   0,  83,  97, 109, 112, 

+    108, 101, 114,   0,  84, 101, 

+    120, 116, 117, 114, 101,   0, 

+     77, 105,  99, 114, 111, 115, 

+    111, 102, 116,  32,  40,  82, 

+     41,  32,  72,  76,  83,  76, 

+     32,  83, 104,  97, 100, 101, 

+    114,  32,  67, 111, 109, 112, 

+    105, 108, 101, 114,  32,  57, 

+     46,  50,  57,  46,  57,  53, 

+     50,  46,  51,  49,  49,  49, 

+      0, 171, 171, 171,  73,  83, 

+     71,  78,  80,   0,   0,   0, 

+      2,   0,   0,   0,   8,   0, 

+      0,   0,  56,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   3,   0,   0,   0, 

+      0,   0,   0,   0,  15,   0, 

+      0,   0,  68,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   3,   0,   0,   0, 

+      1,   0,   0,   0,   3,   3, 

+      0,   0,  83,  86,  95,  80, 

+     79,  83,  73,  84,  73,  79, 

+     78,   0,  84,  69,  88,  67, 

+     79,  79,  82,  68,   0, 171, 

+    171, 171,  79,  83,  71,  78, 

+     44,   0,   0,   0,   1,   0, 

+      0,   0,   8,   0,   0,   0, 

+     32,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      3,   0,   0,   0,   0,   0, 

+      0,   0,  15,   0,   0,   0, 

+     83,  86,  95,  84,  65,  82, 

+     71,  69,  84,   0, 171, 171, 

+     83,  72,  68,  82, 128,   0, 

+      0,   0,  64,   0,   0,   0, 

+     32,   0,   0,   0,  90,   0, 

+      0,   3,   0,  96,  16,   0, 

+      0,   0,   0,   0,  88,  24, 

+      0,   4,   0, 112,  16,   0, 

+      0,   0,   0,   0,  85,  85, 

+      0,   0,  98,  16,   0,   3, 

+     50,  16,  16,   0,   1,   0, 

+      0,   0, 101,   0,   0,   3, 

+    242,  32,  16,   0,   0,   0, 

+      0,   0, 104,   0,   0,   2, 

+      1,   0,   0,   0,  69,   0, 

+      0,   9, 242,   0,  16,   0, 

+      0,   0,   0,   0,  70,  16, 

+     16,   0,   1,   0,   0,   0, 

+     70, 126,  16,   0,   0,   0, 

+      0,   0,   0,  96,  16,   0, 

+      0,   0,   0,   0,  54,   0, 

+      0,   5, 242,  32,  16,   0, 

+      0,   0,   0,   0,   6,  12, 

+     16,   0,   0,   0,   0,   0, 

+     62,   0,   0,   1,  83,  84, 

+     65,  84, 116,   0,   0,   0, 

+      3,   0,   0,   0,   1,   0, 

+      0,   0,   0,   0,   0,   0, 

+      2,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   1,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0

+};

diff --git a/src/libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h b/src/libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h
new file mode 100644
index 0000000..da9ff63
--- /dev/null
+++ b/src/libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h
@@ -0,0 +1,155 @@
+#if 0

+//

+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111

+//

+//

+//   fxc /E PS_PassthroughRGB /T ps_4_0 /Fh compiled/passthroughrgb11ps.h

+//    Passthrough11.hlsl

+//

+//

+// Resource Bindings:

+//

+// Name                                 Type  Format         Dim Slot Elements

+// ------------------------------ ---------- ------- ----------- ---- --------

+// Sampler                           sampler      NA          NA    0        1

+// Texture                           texture  float4          2d    0        1

+//

+//

+//

+// Input signature:

+//

+// Name                 Index   Mask Register SysValue Format   Used

+// -------------------- ----- ------ -------- -------- ------ ------

+// SV_POSITION              0   xyzw        0      POS  float       

+// TEXCOORD                 0   xy          1     NONE  float   xy  

+//

+//

+// Output signature:

+//

+// Name                 Index   Mask Register SysValue Format   Used

+// -------------------- ----- ------ -------- -------- ------ ------

+// SV_TARGET                0   xyzw        0   TARGET  float   xyzw

+//

+ps_4_0

+dcl_sampler s0, mode_default

+dcl_resource_texture2d (float,float,float,float) t0

+dcl_input_ps linear v1.xy

+dcl_output o0.xyzw

+dcl_temps 1

+sample r0.xyzw, v1.xyxx, t0.xyzw, s0

+mov o0.xyz, r0.xyzx

+mov o0.w, l(1.000000)

+ret 

+// Approximately 4 instruction slots used

+#endif

+

+const BYTE g_PS_PassthroughRGB[] =

+{

+     68,  88,  66,  67, 253,  45, 

+     13,  34, 125, 194,  95, 149, 

+      1,  95, 194, 252, 118, 228, 

+    178, 200,   1,   0,   0,   0, 

+    128,   2,   0,   0,   5,   0, 

+      0,   0,  52,   0,   0,   0, 

+    220,   0,   0,   0,  52,   1, 

+      0,   0, 104,   1,   0,   0, 

+      4,   2,   0,   0,  82,  68, 

+     69,  70, 160,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   2,   0,   0,   0, 

+     28,   0,   0,   0,   0,   4, 

+    255, 255,   0,   1,   0,   0, 

+    108,   0,   0,   0,  92,   0, 

+      0,   0,   3,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   1,   0,   0,   0, 

+    100,   0,   0,   0,   2,   0, 

+      0,   0,   5,   0,   0,   0, 

+      4,   0,   0,   0, 255, 255, 

+    255, 255,   0,   0,   0,   0, 

+      1,   0,   0,   0,  13,   0, 

+      0,   0,  83,  97, 109, 112, 

+    108, 101, 114,   0,  84, 101, 

+    120, 116, 117, 114, 101,   0, 

+     77, 105,  99, 114, 111, 115, 

+    111, 102, 116,  32,  40,  82, 

+     41,  32,  72,  76,  83,  76, 

+     32,  83, 104,  97, 100, 101, 

+    114,  32,  67, 111, 109, 112, 

+    105, 108, 101, 114,  32,  57, 

+     46,  50,  57,  46,  57,  53, 

+     50,  46,  51,  49,  49,  49, 

+      0, 171, 171, 171,  73,  83, 

+     71,  78,  80,   0,   0,   0, 

+      2,   0,   0,   0,   8,   0, 

+      0,   0,  56,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   3,   0,   0,   0, 

+      0,   0,   0,   0,  15,   0, 

+      0,   0,  68,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   3,   0,   0,   0, 

+      1,   0,   0,   0,   3,   3, 

+      0,   0,  83,  86,  95,  80, 

+     79,  83,  73,  84,  73,  79, 

+     78,   0,  84,  69,  88,  67, 

+     79,  79,  82,  68,   0, 171, 

+    171, 171,  79,  83,  71,  78, 

+     44,   0,   0,   0,   1,   0, 

+      0,   0,   8,   0,   0,   0, 

+     32,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      3,   0,   0,   0,   0,   0, 

+      0,   0,  15,   0,   0,   0, 

+     83,  86,  95,  84,  65,  82, 

+     71,  69,  84,   0, 171, 171, 

+     83,  72,  68,  82, 148,   0, 

+      0,   0,  64,   0,   0,   0, 

+     37,   0,   0,   0,  90,   0, 

+      0,   3,   0,  96,  16,   0, 

+      0,   0,   0,   0,  88,  24, 

+      0,   4,   0, 112,  16,   0, 

+      0,   0,   0,   0,  85,  85, 

+      0,   0,  98,  16,   0,   3, 

+     50,  16,  16,   0,   1,   0, 

+      0,   0, 101,   0,   0,   3, 

+    242,  32,  16,   0,   0,   0, 

+      0,   0, 104,   0,   0,   2, 

+      1,   0,   0,   0,  69,   0, 

+      0,   9, 242,   0,  16,   0, 

+      0,   0,   0,   0,  70,  16, 

+     16,   0,   1,   0,   0,   0, 

+     70, 126,  16,   0,   0,   0, 

+      0,   0,   0,  96,  16,   0, 

+      0,   0,   0,   0,  54,   0, 

+      0,   5, 114,  32,  16,   0, 

+      0,   0,   0,   0,  70,   2, 

+     16,   0,   0,   0,   0,   0, 

+     54,   0,   0,   5, 130,  32, 

+     16,   0,   0,   0,   0,   0, 

+      1,  64,   0,   0,   0,   0, 

+    128,  63,  62,   0,   0,   1, 

+     83,  84,  65,  84, 116,   0, 

+      0,   0,   4,   0,   0,   0, 

+      1,   0,   0,   0,   0,   0, 

+      0,   0,   2,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      1,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   1,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      2,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0,   0,   0, 

+      0,   0,   0,   0

+};

diff --git a/src/libGLESv2/renderer/shaders/generate_shaders.bat b/src/libGLESv2/renderer/shaders/generate_shaders.bat
index 09ec517..17bd13c 100644
--- a/src/libGLESv2/renderer/shaders/generate_shaders.bat
+++ b/src/libGLESv2/renderer/shaders/generate_shaders.bat
@@ -15,3 +15,6 @@
 

 fxc /E VS_Passthrough /T vs_4_0 /Fh compiled/passthrough11vs.h Passthrough11.hlsl

 fxc /E PS_PassthroughRGBA /T ps_4_0 /Fh compiled/passthroughrgba11ps.h Passthrough11.hlsl

+fxc /E PS_PassthroughRGB /T ps_4_0 /Fh compiled/passthroughrgb11ps.h Passthrough11.hlsl

+fxc /E PS_PassthroughLum /T ps_4_0 /Fh compiled/passthroughlum11ps.h Passthrough11.hlsl

+fxc /E PS_PassthroughLumAlpha /T ps_4_0 /Fh compiled/passthroughlumalpha11ps.h Passthrough11.hlsl