1b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang#include "precompiled.h"
2b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang//
3b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
4b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang// Use of this source code is governed by a BSD-style license that can be
5b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang// found in the LICENSE file.
6b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang//
7b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
8b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang// Blit11.cpp: Texture copy utility class.
9b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
10b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang#include "libGLESv2/main.h"
11b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang#include "libGLESv2/formatutils.h"
12d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/Blit11.h"
13d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/Renderer11.h"
14d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
15d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/formatutils11.h"
16b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
17d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough2d11vs.h"
18d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
19d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
20d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2dui11ps.h"
21d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba2di11ps.h"
22d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2d11ps.h"
23d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2dui11ps.h"
24d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb2di11ps.h"
25d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2d11ps.h"
26d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2dui11ps.h"
27d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg2di11ps.h"
28d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2d11ps.h"
29d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2dui11ps.h"
30d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr2di11ps.h"
31d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum2d11ps.h"
32d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h"
33b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
34d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11vs.h"
35d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough3d11gs.h"
36d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3d11ps.h"
37d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3dui11ps.h"
38d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba3di11ps.h"
39d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3d11ps.h"
40d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3dui11ps.h"
41d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb3di11ps.h"
42d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3d11ps.h"
43d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3dui11ps.h"
44d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrg3di11ps.h"
45d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3d11ps.h"
46d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3dui11ps.h"
47d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughr3di11ps.h"
48d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum3d11ps.h"
49d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h"
50b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
51ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2dps.h"
52ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2dps.h"
53ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2dps.h"
54ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef3dps.h"
55ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei3dps.h"
56ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui3dps.h"
57ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlef2darrayps.h"
58ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzlei2darrayps.h"
59ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang#include "libGLESv2/renderer/d3d11/shaders/compiled/swizzleui2darrayps.h"
60ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
61b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Langnamespace rx
62b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang{
63b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
64bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madillstatic DXGI_FORMAT GetTextureFormat(ID3D11Resource *resource)
65bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill{
66bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    ID3D11Texture2D *texture = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
67bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    if (!texture)
68bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    {
69bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        return DXGI_FORMAT_UNKNOWN;
70bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    }
71bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
72bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    D3D11_TEXTURE2D_DESC desc;
73bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    texture->GetDesc(&desc);
74bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
75bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    SafeRelease(texture);
76bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
77bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    return desc.Format;
78bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill}
79bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
80bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madillstatic ID3D11Resource *CreateStagingTexture(ID3D11Device *device, ID3D11DeviceContext *context,
81bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                                            ID3D11Resource *source, unsigned int subresource,
82bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                                            const gl::Extents &size, unsigned int cpuAccessFlags)
83bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill{
84bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    D3D11_TEXTURE2D_DESC stagingDesc;
85bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.Width = size.width;
86bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.Height = size.height;
87bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.MipLevels = 1;
88bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.ArraySize = 1;
89bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.Format = GetTextureFormat(source);
90bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.SampleDesc.Count = 1;
91bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.SampleDesc.Quality = 0;
92bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.Usage = D3D11_USAGE_STAGING;
93bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.CPUAccessFlags = cpuAccessFlags;
94bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.MiscFlags = 0;
95bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    stagingDesc.BindFlags = 0;
96bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
97bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    ID3D11Texture2D *stagingTexture = NULL;
98bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    HRESULT result = device->CreateTexture2D(&stagingDesc, NULL, &stagingTexture);
99bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    if (FAILED(result))
100bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    {
101bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        ERR("Failed to create staging texture for depth stencil blit. HRESULT: 0x%X.", result);
102bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        return NULL;
103bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    }
104bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
105bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    context->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, source, subresource, NULL);
106bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
107bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    return stagingTexture;
108bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill}
109bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
110bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madillinline static void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Extents &sourceSize,
111bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                                        const gl::Box &destArea, const gl::Extents &destSize,
112bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                                        float *x1, float *y1, float *x2, float *y2,
113bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                                        float *u1, float *v1, float *u2, float *v2)
114bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill{
115bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
116bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f;
117bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *x2 = ((destArea.x + destArea.width) / float(destSize.width)) * 2.0f - 1.0f;
118bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *y2 = ((destSize.height - destArea.y) / float(destSize.height)) * 2.0f - 1.0f;
119bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
120bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *u1 = sourceArea.x / float(sourceSize.width);
121bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *v1 = sourceArea.y / float(sourceSize.height);
122bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *u2 = (sourceArea.x + sourceArea.width) / float(sourceSize.width);
123bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height);
124bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill}
125bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
126bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madillstatic void Write2DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize,
127bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                            const gl::Box &destArea, const gl::Extents &destSize,
128bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                            void *outVertices, unsigned int *outStride, unsigned int *outVertexCount,
129bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                            D3D11_PRIMITIVE_TOPOLOGY *outTopology)
130bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill{
131bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    float x1, y1, x2, y2, u1, v1, u2, v2;
132bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2);
133bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
134bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(outVertices);
135bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
136bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
137bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
138bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
139bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
140bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
141bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *outStride = sizeof(d3d11::PositionTexCoordVertex);
142bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *outVertexCount = 4;
143bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
144bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill}
145bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
146bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madillstatic void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize,
147bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                            const gl::Box &destArea, const gl::Extents &destSize,
148bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                            void *outVertices, unsigned int *outStride, unsigned int *outVertexCount,
149bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill                            D3D11_PRIMITIVE_TOPOLOGY *outTopology)
150bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill{
151ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    ASSERT(sourceSize.depth > 0 && destSize.depth > 0);
152ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
153bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    float x1, y1, x2, y2, u1, v1, u2, v2;
154bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2);
155bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
156bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    d3d11::PositionLayerTexCoord3DVertex *vertices = static_cast<d3d11::PositionLayerTexCoord3DVertex*>(outVertices);
157bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
158bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    for (int i = 0; i < destSize.depth; i++)
159bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    {
160ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        float readDepth = (float)i / std::max(destSize.depth - 1, 1);
161bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
162bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 0], x1, y1, i, u1, v2, readDepth);
163bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 1], x1, y2, i, u1, v1, readDepth);
164bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 2], x2, y1, i, u2, v2, readDepth);
165bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
166bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 3], x1, y2, i, u1, v1, readDepth);
167bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 4], x2, y2, i, u2, v1, readDepth);
168bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth);
169bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    }
170bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
171bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *outStride = sizeof(d3d11::PositionLayerTexCoord3DVertex);
172bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *outVertexCount = destSize.depth * 6;
173bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
174bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill}
175bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill
176b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff LangBlit11::Blit11(rx::Renderer11 *renderer)
177ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    : mRenderer(renderer), mBlitShaderMap(compareBlitParameters), mSwizzleShaderMap(compareSwizzleParameters),
178ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      mVertexBuffer(NULL), mPointSampler(NULL), mLinearSampler(NULL), mScissorEnabledRasterizerState(NULL),
179125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang      mScissorDisabledRasterizerState(NULL), mDepthStencilState(NULL),
180975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang      mQuad2DIL(NULL), mQuad2DVS(NULL), mDepthPS(NULL),
181ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      mQuad3DIL(NULL), mQuad3DVS(NULL), mQuad3DGS(NULL),
182ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      mSwizzleCB(NULL)
183b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang{
184b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    HRESULT result;
185b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ID3D11Device *device = mRenderer->getDevice();
186b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
187b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    D3D11_BUFFER_DESC vbDesc;
188ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    vbDesc.ByteWidth = std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex), sizeof(d3d11::PositionTexCoordVertex)) *
189ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang                       6 * renderer->getMaxTextureDepth();
190b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    vbDesc.Usage = D3D11_USAGE_DYNAMIC;
191b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
192b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
193b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    vbDesc.MiscFlags = 0;
194b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    vbDesc.StructureByteStride = 0;
195b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
196b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer);
197b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(SUCCEEDED(result));
198b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    d3d11::SetDebugName(mVertexBuffer, "Blit11 vertex buffer");
199b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
200b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    D3D11_SAMPLER_DESC pointSamplerDesc;
201b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
202b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
203b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
204b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
205b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.MipLODBias = 0.0f;
206b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.MaxAnisotropy = 0;
207b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
208b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.BorderColor[0] = 0.0f;
209b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.BorderColor[1] = 0.0f;
210b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.BorderColor[2] = 0.0f;
211b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.BorderColor[3] = 0.0f;
212b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.MinLOD = 0.0f;
213b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    pointSamplerDesc.MaxLOD = 0.0f;
214b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
215b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler);
216b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(SUCCEEDED(result));
217b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    d3d11::SetDebugName(mPointSampler, "Blit11 point sampler");
218b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
219b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    D3D11_SAMPLER_DESC linearSamplerDesc;
220b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
221b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
222b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
223b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
224b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.MipLODBias = 0.0f;
225b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.MaxAnisotropy = 0;
226b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
227b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.BorderColor[0] = 0.0f;
228b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.BorderColor[1] = 0.0f;
229b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.BorderColor[2] = 0.0f;
230b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.BorderColor[3] = 0.0f;
231b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.MinLOD = 0.0f;
232b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    linearSamplerDesc.MaxLOD = 0.0f;
233b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
234b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler);
235b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(SUCCEEDED(result));
236b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    d3d11::SetDebugName(mLinearSampler, "Blit11 linear sampler");
237b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
23877e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    // Use a rasterizer state that will not cull so that inverted quads will not be culled
23977e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    D3D11_RASTERIZER_DESC rasterDesc;
24077e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.FillMode = D3D11_FILL_SOLID;
24177e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.CullMode = D3D11_CULL_NONE;
24277e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.FrontCounterClockwise = FALSE;
24377e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.DepthBias = 0;
24477e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.SlopeScaledDepthBias = 0.0f;
24577e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.DepthBiasClamp = 0.0f;
24677e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.DepthClipEnable = TRUE;
24777e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.MultisampleEnable = FALSE;
24877e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    rasterDesc.AntialiasedLineEnable = FALSE;
24977e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang
250125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    rasterDesc.ScissorEnable = TRUE;
251125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    result = device->CreateRasterizerState(&rasterDesc, &mScissorEnabledRasterizerState);
25277e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang    ASSERT(SUCCEEDED(result));
253125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    d3d11::SetDebugName(mScissorEnabledRasterizerState, "Blit11 scissoring rasterizer state");
254125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
255125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    rasterDesc.ScissorEnable = FALSE;
256125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    result = device->CreateRasterizerState(&rasterDesc, &mScissorDisabledRasterizerState);
257125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    ASSERT(SUCCEEDED(result));
258125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    d3d11::SetDebugName(mScissorDisabledRasterizerState, "Blit11 no scissoring rasterizer state");
25977e3900a6821fb89bfa5fa166f2832b407f38111Geoff Lang
260975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
261975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.DepthEnable = true;
262975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
263975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
264975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.StencilEnable = FALSE;
265975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
266975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
267975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
268975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
269975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
270975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
271975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
272975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
273975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
274975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
275975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
276975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    result = device->CreateDepthStencilState(&depthStencilDesc, &mDepthStencilState);
277975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    ASSERT(SUCCEEDED(result));
278975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    d3d11::SetDebugName(mDepthStencilState, "Blit11 depth stencil state");
279975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
280b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    D3D11_INPUT_ELEMENT_DESC quad2DLayout[] =
281b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    {
282b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
283b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
284b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    };
285b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
286b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = device->CreateInputLayout(quad2DLayout, ArraySize(quad2DLayout), g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), &mQuad2DIL);
287b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(SUCCEEDED(result));
288b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    d3d11::SetDebugName(mQuad2DIL, "Blit11 2D input layout");
289b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
290b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = device->CreateVertexShader(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), NULL, &mQuad2DVS);
291b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(SUCCEEDED(result));
292b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader");
293b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
294975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS);
295975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    ASSERT(SUCCEEDED(result));
296975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    d3d11::SetDebugName(mDepthPS, "Blit11 2D depth pixel shader");
297975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
298b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    D3D11_INPUT_ELEMENT_DESC quad3DLayout[] =
299b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    {
300b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT,    0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
301b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        { "LAYER",    0, DXGI_FORMAT_R32_UINT,        0,  8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
302b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
303b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    };
304b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
305b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL);
306b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(SUCCEEDED(result));
307b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout");
308b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
309b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS);
310b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(SUCCEEDED(result));
311b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader");
312b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
313b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS);
314b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(SUCCEEDED(result));
315b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader");
316b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
317b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    buildShaderMap();
318ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
319ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    D3D11_BUFFER_DESC swizzleBufferDesc;
320ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4;
321ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
322ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
323ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
324ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleBufferDesc.MiscFlags = 0;
325ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleBufferDesc.StructureByteStride = 0;
326ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
327ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    result = device->CreateBuffer(&swizzleBufferDesc, NULL, &mSwizzleCB);
328ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    ASSERT(SUCCEEDED(result));
329ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    d3d11::SetDebugName(mSwizzleCB, "Blit11 swizzle constant buffer");
330b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang}
331b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
332b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff LangBlit11::~Blit11()
333b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang{
334b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    SafeRelease(mVertexBuffer);
335b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    SafeRelease(mPointSampler);
336b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    SafeRelease(mLinearSampler);
337125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    SafeRelease(mScissorEnabledRasterizerState);
338125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    SafeRelease(mScissorDisabledRasterizerState);
339975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    SafeRelease(mDepthStencilState);
340b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
341b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    SafeRelease(mQuad2DIL);
342b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    SafeRelease(mQuad2DVS);
343975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    SafeRelease(mDepthPS);
344b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
345b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    SafeRelease(mQuad3DIL);
346b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    SafeRelease(mQuad3DVS);
347b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    SafeRelease(mQuad3DGS);
348b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
349ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    SafeRelease(mSwizzleCB);
350ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
351b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    clearShaderMap();
352b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang}
353b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
354ed883f5416ad89f727674b096c247f668ae64cf7Geoff Langstatic inline unsigned int GetSwizzleIndex(GLenum swizzle)
355ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang{
356ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    unsigned int colorIndex = 0;
357ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
358ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    switch (swizzle)
359ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    {
360ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_RED:   colorIndex = 0; break;
361ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_GREEN: colorIndex = 1; break;
362ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_BLUE:  colorIndex = 2; break;
363ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_ALPHA: colorIndex = 3; break;
364ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_ZERO:  colorIndex = 4; break;
365ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_ONE:   colorIndex = 5; break;
366ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      default:       UNREACHABLE();  break;
367ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    }
368ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
369ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    return colorIndex;
370ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang}
371ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
372ed883f5416ad89f727674b096c247f668ae64cf7Geoff Langbool Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size,
373ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang                            GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
374ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang{
375ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    HRESULT result;
376ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
377ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
378ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
379ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    source->GetDesc(&sourceSRVDesc);
380ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceSRVDesc.Format, mRenderer->getCurrentClientVersion());
381ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
382ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    GLenum shaderType = GL_NONE;
383ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    switch (gl::GetComponentType(sourceInternalFormat, mRenderer->getCurrentClientVersion()))
384ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    {
385ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_UNSIGNED_NORMALIZED:
386ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_SIGNED_NORMALIZED:
387ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_FLOAT:
388ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shaderType = GL_FLOAT;
389ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        break;
390ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_INT:
391ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shaderType = GL_INT;
392ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        break;
393ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case GL_UNSIGNED_INT:
394ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shaderType = GL_UNSIGNED_INT;
395ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        break;
396ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      default:
397ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        UNREACHABLE();
398ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        break;
399ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    }
400ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
401ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    SwizzleParameters parameters = { 0 };
402ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    parameters.mDestinationType = shaderType;
403ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    parameters.mViewDimension = sourceSRVDesc.ViewDimension;
404ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
405ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    SwizzleShaderMap::const_iterator i = mSwizzleShaderMap.find(parameters);
406ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    if (i == mSwizzleShaderMap.end())
407ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    {
408ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        UNREACHABLE();
409ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        return false;
410ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    }
411ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
412ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    const Shader &shader = i->second;
413ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
414ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Set vertices
415ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    D3D11_MAPPED_SUBRESOURCE mappedResource;
416ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
417ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    if (FAILED(result))
418ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    {
419ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        ERR("Failed to map vertex buffer for texture swizzle, HRESULT: 0x%X.", result);
420ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        return false;
421ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    }
422ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
423ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    UINT stride = 0;
424ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    UINT startIdx = 0;
425ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    UINT drawCount = 0;
426ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    D3D11_PRIMITIVE_TOPOLOGY topology;
427ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
428ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    gl::Box area(0, 0, 0, size.width, size.height, size.depth);
429ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    shader.mVertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, &topology);
430ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
431ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->Unmap(mVertexBuffer, 0);
432ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
433ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Set constant buffer
434ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    result = deviceContext->Map(mSwizzleCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
435ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    if (FAILED(result))
436ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    {
437ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        ERR("Failed to map constant buffer for texture swizzle, HRESULT: 0x%X.", result);
438ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        return false;
439ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    }
440ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
441ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    unsigned int *swizzleIndices = reinterpret_cast<unsigned int*>(mappedResource.pData);
442ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleIndices[0] = GetSwizzleIndex(swizzleRed);
443ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleIndices[1] = GetSwizzleIndex(swizzleGreen);
444ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleIndices[2] = GetSwizzleIndex(swizzleBlue);
445ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    swizzleIndices[3] = GetSwizzleIndex(swizzleAlpha);
446ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
447ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->Unmap(mSwizzleCB, 0);
448ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
449ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Apply vertex buffer
450ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx);
451ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
452ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Apply constant buffer
453ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->PSSetConstantBuffers(0, 1, &mSwizzleCB);
454ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
455ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Apply state
456ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
457ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
458ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->RSSetState(mScissorDisabledRasterizerState);
459ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
460ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Apply shaders
461ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->IASetInputLayout(shader.mInputLayout);
462ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->IASetPrimitiveTopology(topology);
463ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->VSSetShader(shader.mVertexShader, NULL, 0);
464ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
465ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->PSSetShader(shader.mPixelShader, NULL, 0);
466ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
467ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
468ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Unset the currently bound shader resource to avoid conflicts
469ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    ID3D11ShaderResourceView *const nullSRV = NULL;
470ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->PSSetShaderResources(0, 1, &nullSRV);
471ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
472ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Apply render target
473ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    mRenderer->setOneTimeRenderTarget(dest);
474ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
475ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Set the viewport
476ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    D3D11_VIEWPORT viewport;
477ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    viewport.TopLeftX = 0;
478ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    viewport.TopLeftY = 0;
479ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    viewport.Width = size.width;
480ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    viewport.Height = size.height;
481ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    viewport.MinDepth = 0.0f;
482ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    viewport.MaxDepth = 1.0f;
483ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->RSSetViewports(1, &viewport);
484ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
485ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Apply textures
486ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->PSSetShaderResources(0, 1, &source);
487ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
488ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Apply samplers
489ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->PSSetSamplers(0, 1, &mPointSampler);
490ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
491ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Draw the quad
492ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->Draw(drawCount, 0);
493ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
494ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    // Unbind textures and render targets and vertex buffer
495ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->PSSetShaderResources(0, 1, &nullSRV);
496ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
497ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    mRenderer->unapplyRenderTargets();
498ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
499ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    UINT zero = 0;
500ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    ID3D11Buffer *const nullBuffer = NULL;
501ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
502ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
503ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    mRenderer->markAllStateDirty();
504ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
505ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    return true;
506ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang}
507ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
508b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Langbool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
509b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang                         ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
510125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                         const gl::Rectangle *scissor, GLenum destFormat, GLenum filter)
511b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang{
512b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    HRESULT result;
513b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
514b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
515b0c75cc92655ce8e7df2d5e0b239662be852b52eGeoff Lang    // Determine if the source format is a signed integer format, the destFormat will already
516b0c75cc92655ce8e7df2d5e0b239662be852b52eGeoff Lang    // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned.
517b0c75cc92655ce8e7df2d5e0b239662be852b52eGeoff Lang    D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
518b0c75cc92655ce8e7df2d5e0b239662be852b52eGeoff Lang    source->GetDesc(&sourceSRVDesc);
519005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceSRVDesc.Format, mRenderer->getCurrentClientVersion());
520b0c75cc92655ce8e7df2d5e0b239662be852b52eGeoff Lang
521b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    BlitParameters parameters = { 0 };
522b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    parameters.mDestinationFormat = destFormat;
523b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang    parameters.mSignedInteger = gl::GetComponentType(sourceInternalFormat, mRenderer->getCurrentClientVersion()) == GL_INT;
524b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    parameters.m3DBlit = sourceArea.depth > 1;
525b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
52626533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    BlitShaderMap::const_iterator i = mBlitShaderMap.find(parameters);
52726533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    if (i == mBlitShaderMap.end())
528b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    {
529b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        UNREACHABLE();
530b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        return false;
531b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    }
532b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
53326533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    const Shader& shader = i->second;
534b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
535b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Set vertices
536b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    D3D11_MAPPED_SUBRESOURCE mappedResource;
537b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
538b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    if (FAILED(result))
539b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    {
540b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
541b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        return false;
542b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    }
543b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
544b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    UINT stride = 0;
545b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    UINT startIdx = 0;
546b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    UINT drawCount = 0;
547b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    D3D11_PRIMITIVE_TOPOLOGY topology;
548b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
549b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mVertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
550b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang                                &stride, &drawCount, &topology);
551b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
552b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->Unmap(mVertexBuffer, 0);
553b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
554b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Apply vertex buffer
555b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx);
556b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
557b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Apply state
558b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
559b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
560125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
561125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    if (scissor)
562125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
563125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        D3D11_RECT scissorRect;
564125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        scissorRect.left = scissor->x;
565125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        scissorRect.right = scissor->x + scissor->width;
566125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        scissorRect.top = scissor->y;
567125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        scissorRect.bottom = scissor->y + scissor->height;
568125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
569125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        deviceContext->RSSetScissorRects(1, &scissorRect);
570125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        deviceContext->RSSetState(mScissorEnabledRasterizerState);
571125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
572125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    else
573125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
574125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        deviceContext->RSSetState(mScissorDisabledRasterizerState);
575125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
576b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
577b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Apply shaders
578b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->IASetInputLayout(shader.mInputLayout);
579b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->IASetPrimitiveTopology(topology);
580b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->VSSetShader(shader.mVertexShader, NULL, 0);
581b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
582b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->PSSetShader(shader.mPixelShader, NULL, 0);
583b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
584b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
585b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Unset the currently bound shader resource to avoid conflicts
586b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ID3D11ShaderResourceView *const nullSRV = NULL;
587b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->PSSetShaderResources(0, 1, &nullSRV);
588b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
589b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Apply render target
590b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    mRenderer->setOneTimeRenderTarget(dest);
591b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
592b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Set the viewport
593b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    D3D11_VIEWPORT viewport;
594b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    viewport.TopLeftX = 0;
595b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    viewport.TopLeftY = 0;
596b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    viewport.Width = destSize.width;
597b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    viewport.Height = destSize.height;
598b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    viewport.MinDepth = 0.0f;
599b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    viewport.MaxDepth = 1.0f;
600b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->RSSetViewports(1, &viewport);
601b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
602b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Apply textures
603b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->PSSetShaderResources(0, 1, &source);
604b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
605b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Apply samplers
606b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ID3D11SamplerState *sampler = NULL;
607b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    switch (filter)
608b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    {
609b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang      case GL_NEAREST: sampler = mPointSampler;  break;
610b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang      case GL_LINEAR:  sampler = mLinearSampler; break;
611b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang      default:         UNREACHABLE(); return false;
612b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    }
613b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->PSSetSamplers(0, 1, &sampler);
614b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
615b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Draw the quad
616b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->Draw(drawCount, 0);
617b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
618b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Unbind textures and render targets and vertex buffer
619b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->PSSetShaderResources(0, 1, &nullSRV);
620b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
621b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    mRenderer->unapplyRenderTargets();
622b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
623b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    UINT zero = 0;
624b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ID3D11Buffer *const nullBuffer = NULL;
625b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
626b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
627b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    mRenderer->markAllStateDirty();
628b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
629b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    return true;
630b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang}
631b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
632975af378b32445c4c0595de0ff3a64cb931c139aGeoff Langbool Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
633125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                         ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
634125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                         const gl::Rectangle *scissor)
635975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang{
636975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize,
637975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                            dest, destSubresource, destArea, destSize,
638125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                            scissor, true);
639975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang}
640975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
641975af378b32445c4c0595de0ff3a64cb931c139aGeoff Langbool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
642125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                       ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
643125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                       const gl::Rectangle *scissor)
644975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang{
645975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    HRESULT result;
646975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
647975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
648975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Set vertices
649975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    D3D11_MAPPED_SUBRESOURCE mappedResource;
650975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
651975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    if (FAILED(result))
652975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    {
653975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
654975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        return false;
655975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    }
656975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
657975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    UINT stride = 0;
658975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    UINT startIdx = 0;
659975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    UINT drawCount = 0;
660975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    D3D11_PRIMITIVE_TOPOLOGY topology;
661975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
662bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
663975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                    &stride, &drawCount, &topology);
664975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
665975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->Unmap(mVertexBuffer, 0);
666975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
667975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Apply vertex buffer
668975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx);
669975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
670975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Apply state
671975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
672975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->OMSetDepthStencilState(mDepthStencilState, 0xFFFFFFFF);
673125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
674125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    if (scissor)
675125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
676125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        D3D11_RECT scissorRect;
677125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        scissorRect.left = scissor->x;
678125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        scissorRect.right = scissor->x + scissor->width;
679125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        scissorRect.top = scissor->y;
680125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        scissorRect.bottom = scissor->y + scissor->height;
681125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
682125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        deviceContext->RSSetScissorRects(1, &scissorRect);
683125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        deviceContext->RSSetState(mScissorEnabledRasterizerState);
684125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
685125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    else
686125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
687125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        deviceContext->RSSetState(mScissorDisabledRasterizerState);
688125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
689975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
690975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Apply shaders
691975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->IASetInputLayout(mQuad2DIL);
692975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->IASetPrimitiveTopology(topology);
693975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->VSSetShader(mQuad2DVS, NULL, 0);
694975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
695975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->PSSetShader(mDepthPS, NULL, 0);
696975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->GSSetShader(NULL, NULL, 0);
697975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
698975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Unset the currently bound shader resource to avoid conflicts
699975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    ID3D11ShaderResourceView *const nullSRV = NULL;
700975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->PSSetShaderResources(0, 1, &nullSRV);
701975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
702975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Apply render target
703975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->OMSetRenderTargets(0, NULL, dest);
704975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
705975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Set the viewport
706975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    D3D11_VIEWPORT viewport;
707975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    viewport.TopLeftX = 0;
708975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    viewport.TopLeftY = 0;
709975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    viewport.Width = destSize.width;
710975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    viewport.Height = destSize.height;
711975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    viewport.MinDepth = 0.0f;
712975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    viewport.MaxDepth = 1.0f;
713975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->RSSetViewports(1, &viewport);
714975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
715975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Apply textures
716975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->PSSetShaderResources(0, 1, &source);
717975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
718975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Apply samplers
719975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->PSSetSamplers(0, 1, &mPointSampler);
720975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
721975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Draw the quad
722975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->Draw(drawCount, 0);
723975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
724975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Unbind textures and render targets and vertex buffer
725975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->PSSetShaderResources(0, 1, &nullSRV);
726975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
727975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    mRenderer->unapplyRenderTargets();
728975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
729975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    UINT zero = 0;
730975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    ID3D11Buffer *const nullBuffer = NULL;
731975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
732975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
733975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    mRenderer->markAllStateDirty();
734975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
735975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    return true;
736975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang}
737975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
738975af378b32445c4c0595de0ff3a64cb931c139aGeoff Langbool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
739125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                              ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
740125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                              const gl::Rectangle *scissor)
741975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang{
742975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize,
743975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                            dest, destSubresource, destArea, destSize,
744125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                            scissor, false);
745975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang}
746975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
747975af378b32445c4c0595de0ff3a64cb931c139aGeoff Langbool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
748975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                              ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
749125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                              const gl::Rectangle *scissor, bool stencilOnly)
750975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang{
751975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    ID3D11Device *device = mRenderer->getDevice();
752975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
753975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
754bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    ID3D11Resource *sourceStaging = CreateStagingTexture(device, deviceContext, source, sourceSubresource, sourceSize, D3D11_CPU_ACCESS_READ);
755921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang    // HACK: Create the destination staging buffer as a read/write texture so ID3D11DevicContext::UpdateSubresource can be called
756921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang    //       using it's mapped data as a source
757bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    ID3D11Resource *destStaging = CreateStagingTexture(device, deviceContext, dest, destSubresource, destSize, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE);
758975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
759125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    if (!sourceStaging || !destStaging)
760125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
761125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        SafeRelease(sourceStaging);
762125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        SafeRelease(destStaging);
763125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        return false;
764125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
765125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
766bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    DXGI_FORMAT format = GetTextureFormat(source);
767bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    ASSERT(format == GetTextureFormat(dest));
768975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
7699eeecfc20be089b62310787895870e0284cfb383Jamie Madill    unsigned int pixelSize = d3d11::GetFormatPixelBytes(format);
770975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    unsigned int copyOffset = 0;
771975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    unsigned int copySize = pixelSize;
772975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    if (stencilOnly)
773975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    {
774975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        copyOffset = d3d11::GetStencilOffset(format) / 8;
775975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        copySize = d3d11::GetStencilBits(format) / 8;
776975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
777975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        // It would be expensive to have non-byte sized stencil sizes since it would
778125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        // require reading from the destination, currently there aren't any though.
779975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        ASSERT(d3d11::GetStencilBits(format)   % 8 == 0 &&
780975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang               d3d11::GetStencilOffset(format) % 8 == 0);
781975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    }
782975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
783975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping;
784975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping);
785975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping);
786975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
787125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    if (!sourceMapping.pData || !destMapping.pData)
788125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
789125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        if (!sourceMapping.pData)
790125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        {
791125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            deviceContext->Unmap(sourceStaging, 0);
792125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        }
793125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        if (!destMapping.pData)
794125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        {
795125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            deviceContext->Unmap(destStaging, 0);
796125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        }
797125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        SafeRelease(sourceStaging);
798125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        SafeRelease(destStaging);
799125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        return false;
800125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
801125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
802125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
803975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
804125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    // Clip dest area to the destination size
805125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    gl::ClipRectangle(clippedDestArea, gl::Rectangle(0, 0, destSize.width, destSize.height), &clippedDestArea);
806975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
807125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    // Clip dest area to the scissor
808125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    if (scissor)
809975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    {
810125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        gl::ClipRectangle(clippedDestArea, *scissor, &clippedDestArea);
811125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
812125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
813125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    // Determine if entire rows can be copied at once instead of each individual pixel, requires that there is
814125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    // no out of bounds lookups required, the entire pixel is copied and no stretching
815125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool wholeRowCopy = sourceArea.width == clippedDestArea.width &&
816125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                        sourceArea.x >= 0 && sourceArea.x + sourceArea.width <= sourceSize.width &&
817125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                        copySize == pixelSize;
818125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
819125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++)
820125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
821125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1);
822125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
823125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        // Interpolate using the original source rectangle to determine which row to sample from while clamping to the edges
824125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        unsigned int readRow = gl::clamp(sourceArea.y + floor(yPerc * (sourceArea.height - 1) + 0.5f), 0, sourceSize.height - 1);
825975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        unsigned int writeRow = y;
826975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
827125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        if (wholeRowCopy)
828975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        {
829975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang            void *sourceRow = reinterpret_cast<char*>(sourceMapping.pData) +
830125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                              readRow * sourceMapping.RowPitch +
831125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                              sourceArea.x * pixelSize;
832975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
833975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang            void *destRow = reinterpret_cast<char*>(destMapping.pData) +
834125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                            writeRow * destMapping.RowPitch +
835125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                            destArea.x * pixelSize;
836975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
837975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang            memcpy(destRow, sourceRow, pixelSize * destArea.width);
838975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        }
839975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        else
840975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        {
841125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            for (int x = clippedDestArea.x; x < clippedDestArea.x + clippedDestArea.width; x++)
842975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang            {
843125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                float xPerc = static_cast<float>(x - destArea.x) / (destArea.width - 1);
844125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
845125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                // Interpolate the original source rectangle to determine which column to sample from while clamping to the edges
846125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                unsigned int readColumn = gl::clamp(sourceArea.x + floor(xPerc * (sourceArea.width - 1) + 0.5f), 0, sourceSize.width - 1);
847975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                unsigned int writeColumn = x;
848975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
849975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                void *sourcePixel = reinterpret_cast<char*>(sourceMapping.pData) +
850975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                                    readRow * sourceMapping.RowPitch +
851975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                                    readColumn * pixelSize +
852975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                                    copyOffset;
853975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
854975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                void *destPixel = reinterpret_cast<char*>(destMapping.pData) +
855975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                                  writeRow * destMapping.RowPitch +
856975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                                  writeColumn * pixelSize +
857975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                                  copyOffset;
858975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
859975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang                memcpy(destPixel, sourcePixel, copySize);
860975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang            }
861975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        }
862975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    }
863975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
864921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang    // HACK: Use ID3D11DevicContext::UpdateSubresource which causes an extra copy compared to ID3D11DevicContext::CopySubresourceRegion
865921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang    //       according to MSDN.
866921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang    deviceContext->UpdateSubresource(dest, destSubresource, NULL, destMapping.pData, destMapping.RowPitch, destMapping.DepthPitch);
867921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang
868975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->Unmap(sourceStaging, 0);
869975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    deviceContext->Unmap(destStaging, 0);
870975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
871921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang    // TODO: Determine why this call to ID3D11DevicContext::CopySubresourceRegion causes a TDR timeout on some
872921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang    //       systems when called repeatedly.
873921968ca3082bc9e1554c665c142c24b475107eeGeoff Lang    // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, NULL);
874975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
875975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    SafeRelease(sourceStaging);
876975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    SafeRelease(destStaging);
877975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
878975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    return true;
879975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang}
880975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
881975af378b32445c4c0595de0ff3a64cb931c139aGeoff Langbool Blit11::compareBlitParameters(const Blit11::BlitParameters &a, const Blit11::BlitParameters &b)
882975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang{
883975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    return memcmp(&a, &b, sizeof(Blit11::BlitParameters)) < 0;
884975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang}
885975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
886ed883f5416ad89f727674b096c247f668ae64cf7Geoff Langbool Blit11::compareSwizzleParameters(const SwizzleParameters &a, const SwizzleParameters &b)
887ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang{
888ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    return memcmp(&a, &b, sizeof(Blit11::SwizzleParameters)) < 0;
889ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang}
890ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
89126533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Langvoid Blit11::add2DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps)
892b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang{
893b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    BlitParameters params = { 0 };
894b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    params.mDestinationFormat = destFormat;
895b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    params.mSignedInteger = signedInteger;
896b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    params.m3DBlit = false;
897b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
89826533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    ASSERT(mBlitShaderMap.find(params) == mBlitShaderMap.end());
899b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(ps);
900b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
90126533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    Shader shader;
902bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    shader.mVertexWriteFunction = Write2DVertices;
903b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mInputLayout = mQuad2DIL;
904b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mVertexShader = mQuad2DVS;
905b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mGeometryShader = NULL;
906b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mPixelShader = ps;
907b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
90826533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    mBlitShaderMap[params] = shader;
909b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang}
910b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
91126533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Langvoid Blit11::add3DBlitShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps)
912b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang{
913b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    BlitParameters params = { 0 };
914b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    params.mDestinationFormat = destFormat;
915b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    params.mSignedInteger = signedInteger;
916b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    params.m3DBlit = true;
917b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
91826533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    ASSERT(mBlitShaderMap.find(params) == mBlitShaderMap.end());
919b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(ps);
920b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
92126533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    Shader shader;
922bdfa22896df1b5271e0c6dfbeb76c0d55d6520f0Jamie Madill    shader.mVertexWriteFunction = Write3DVertices;
923b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mInputLayout = mQuad3DIL;
924b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mVertexShader = mQuad3DVS;
925b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mGeometryShader = mQuad3DGS;
926b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    shader.mPixelShader = ps;
927b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
92826533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    mBlitShaderMap[params] = shader;
929b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang}
930b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
931ed883f5416ad89f727674b096c247f668ae64cf7Geoff Langvoid Blit11::addSwizzleShaderToMap(GLenum destType, D3D11_SRV_DIMENSION viewDimension, ID3D11PixelShader *ps)
932ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang{
933ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    SwizzleParameters params = { 0 };
934ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    params.mDestinationType = destType;
935ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    params.mViewDimension = viewDimension;
936ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
937ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    ASSERT(mSwizzleShaderMap.find(params) == mSwizzleShaderMap.end());
938ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    ASSERT(ps);
939ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
940ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    Shader shader;
941ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    switch (viewDimension)
942ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    {
943ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case D3D_SRV_DIMENSION_TEXTURE2D:
944ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shader.mVertexWriteFunction = Write2DVertices;
945ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shader.mInputLayout = mQuad2DIL;
946ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shader.mVertexShader = mQuad2DVS;
947ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shader.mGeometryShader = NULL;
948ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        break;
949ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
950ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case D3D_SRV_DIMENSION_TEXTURE3D:
951ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case D3D_SRV_DIMENSION_TEXTURE2DARRAY:
952ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      case D3D_SRV_DIMENSION_TEXTURECUBE:
953ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shader.mVertexWriteFunction = Write3DVertices;
954ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shader.mInputLayout = mQuad3DIL;
955ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shader.mVertexShader = mQuad3DVS;
956ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        shader.mGeometryShader = mQuad3DGS;
957ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        break;
958ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
959ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang      default:
960ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        UNREACHABLE();
961ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        break;
962ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    }
963ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    shader.mPixelShader = ps;
964ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
965ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    mSwizzleShaderMap[params] = shader;
966ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang}
967ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
968b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Langvoid Blit11::buildShaderMap()
969b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang{
970b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ID3D11Device *device = mRenderer->getDevice();
971b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
97226533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RGBA,            false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D,     "Blit11 2D RGBA pixel shader"           ));
97326533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RGBA_INTEGER,    false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI,   "Blit11 2D RGBA UI pixel shader"        ));
97426533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RGBA_INTEGER,    true,  d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI,    "Blit11 2D RGBA I pixel shader"         ));
97526533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_BGRA_EXT,        false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D,     "Blit11 2D BGRA pixel shader"           ));
97626533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RGB,             false, d3d11::CompilePS(device, g_PS_PassthroughRGB2D,      "Blit11 2D RGB pixel shader"            ));
97726533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RGB_INTEGER,     false, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI,    "Blit11 2D RGB UI pixel shader"         ));
97826533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RGB_INTEGER,     true,  d3d11::CompilePS(device, g_PS_PassthroughRGB2DI,     "Blit11 2D RGB I pixel shader"          ));
97926533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RG,              false, d3d11::CompilePS(device, g_PS_PassthroughRG2D,       "Blit11 2D RG pixel shader"             ));
98026533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RG_INTEGER,      false, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI,     "Blit11 2D RG UI pixel shader"          ));
98126533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RG_INTEGER,      true,  d3d11::CompilePS(device, g_PS_PassthroughRG2DI,      "Blit11 2D RG I pixel shader"           ));
98226533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RED,             false, d3d11::CompilePS(device, g_PS_PassthroughR2D,        "Blit11 2D R pixel shader"              ));
98326533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RED_INTEGER,     false, d3d11::CompilePS(device, g_PS_PassthroughR2DUI,      "Blit11 2D R UI pixel shader"           ));
98426533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_RED_INTEGER,     true,  d3d11::CompilePS(device, g_PS_PassthroughR2DI,       "Blit11 2D R I pixel shader"            ));
98526533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_ALPHA,           false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D,     "Blit11 2D alpha pixel shader"          ));
98626533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_LUMINANCE,       false, d3d11::CompilePS(device, g_PS_PassthroughLum2D,      "Blit11 2D lum pixel shader"            ));
98726533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add2DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader"));
98826533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang
98926533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RGBA,            false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D,     "Blit11 3D RGBA pixel shader"           ));
99026533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RGBA_INTEGER,    false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI,   "Blit11 3D UI RGBA pixel shader"        ));
99126533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RGBA_INTEGER,    true,  d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI,    "Blit11 3D I RGBA pixel shader"         ));
99226533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_BGRA_EXT,        false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D,     "Blit11 3D BGRA pixel shader"           ));
99326533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RGB,             false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D,      "Blit11 3D RGB pixel shader"            ));
99426533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RGB_INTEGER,     false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI,    "Blit11 3D RGB UI pixel shader"         ));
99526533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RGB_INTEGER,     true,  d3d11::CompilePS(device, g_PS_PassthroughRGB3DI,     "Blit11 3D RGB I pixel shader"          ));
99626533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RG,              false, d3d11::CompilePS(device, g_PS_PassthroughRG3D,       "Blit11 3D RG pixel shader"             ));
99726533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RG_INTEGER,      false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI,     "Blit11 3D RG UI pixel shader"          ));
99826533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RG_INTEGER,      true,  d3d11::CompilePS(device, g_PS_PassthroughRG3DI,      "Blit11 3D RG I pixel shader"           ));
99926533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RED,             false, d3d11::CompilePS(device, g_PS_PassthroughR3D,        "Blit11 3D R pixel shader"              ));
100026533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RED_INTEGER,     false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI,      "Blit11 3D R UI pixel shader"           ));
100126533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_RED_INTEGER,     true,  d3d11::CompilePS(device, g_PS_PassthroughR3DI,       "Blit11 3D R I pixel shader"            ));
100226533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_ALPHA,           false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D,     "Blit11 3D alpha pixel shader"          ));
100326533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_LUMINANCE,       false, d3d11::CompilePS(device, g_PS_PassthroughLum3D,      "Blit11 3D luminance pixel shader"      ));
100426533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    add3DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader"));
1005ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
1006ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_FLOAT,        D3D_SRV_DIMENSION_TEXTURE2D,      d3d11::CompilePS(device, g_PS_SwizzleF2D,       "Blit11 2D F swizzle pixel shader" ));
1007ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2D,      d3d11::CompilePS(device, g_PS_SwizzleUI2D,      "Blit11 2D UI swizzle pixel shader"));
1008ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_INT,          D3D_SRV_DIMENSION_TEXTURE2D,      d3d11::CompilePS(device, g_PS_SwizzleI2D,       "Blit11 2D I swizzle pixel shader" ));
1009ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
1010ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_FLOAT,        D3D_SRV_DIMENSION_TEXTURECUBE,    d3d11::CompilePS(device, g_PS_SwizzleF2DArray,  "Blit11 2D Cube F swizzle pixel shader" ));
1011ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURECUBE,    d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader"));
1012ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_INT,          D3D_SRV_DIMENSION_TEXTURECUBE,    d3d11::CompilePS(device, g_PS_SwizzleI2DArray,  "Blit11 2D Cube I swizzle pixel shader" ));
1013ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
1014ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_FLOAT,        D3D_SRV_DIMENSION_TEXTURE3D,      d3d11::CompilePS(device, g_PS_SwizzleF3D,       "Blit11 3D F swizzle pixel shader" ));
1015ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE3D,      d3d11::CompilePS(device, g_PS_SwizzleUI3D,      "Blit11 3D UI swizzle pixel shader"));
1016ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_INT,          D3D_SRV_DIMENSION_TEXTURE3D,      d3d11::CompilePS(device, g_PS_SwizzleI3D,       "Blit11 3D I swizzle pixel shader" ));
1017ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
1018ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_FLOAT,        D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleF2DArray,  "Blit11 2D Array F swizzle pixel shader" ));
1019ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader"));
1020ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    addSwizzleShaderToMap(GL_INT,          D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleI2DArray,  "Blit11 2D Array I swizzle pixel shader" ));
1021b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang}
1022b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
1023b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Langvoid Blit11::clearShaderMap()
1024b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang{
102526533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    for (BlitShaderMap::iterator i = mBlitShaderMap.begin(); i != mBlitShaderMap.end(); ++i)
1026b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    {
102726533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang        Shader &shader = i->second;
1028b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang        SafeRelease(shader.mPixelShader);
1029b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    }
103026533604d5f1dfb099e7e173bf7dfb91b349b8d3Geoff Lang    mBlitShaderMap.clear();
1031ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang
1032ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    for (SwizzleShaderMap::iterator i = mSwizzleShaderMap.begin(); i != mSwizzleShaderMap.end(); ++i)
1033ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    {
1034ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        Shader &shader = i->second;
1035ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang        SafeRelease(shader.mPixelShader);
1036ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    }
1037ed883f5416ad89f727674b096c247f668ae64cf7Geoff Lang    mSwizzleShaderMap.clear();
1038b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang}
1039b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
1040b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang}
1041