1//
2// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// renderer11_utils.h: Conversion functions and other utility routines
8// specific to the D3D11 renderer.
9
10#ifndef LIBGLESV2_RENDERER_RENDERER11_UTILS_H
11#define LIBGLESV2_RENDERER_RENDERER11_UTILS_H
12
13#include "libGLESv2/angletypes.h"
14#include "libGLESv2/Caps.h"
15
16#include <vector>
17
18namespace gl
19{
20class FramebufferAttachment;
21}
22
23namespace rx
24{
25class RenderTarget11;
26
27namespace gl_d3d11
28{
29
30D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha);
31D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp);
32UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha);
33
34D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode);
35
36D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison);
37D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled);
38UINT8 ConvertStencilMask(GLuint stencilmask);
39D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp);
40
41D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode);
42D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap);
43
44D3D11_QUERY ConvertQueryType(GLenum queryType);
45
46}
47
48namespace d3d11_gl
49{
50
51void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions);
52
53}
54
55namespace d3d11
56{
57
58void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
59
60void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth,
61                                GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
62                                std::vector< std::vector<BYTE> > *outData);
63
64struct PositionTexCoordVertex
65{
66    float x, y;
67    float u, v;
68};
69void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v);
70
71struct PositionLayerTexCoord3DVertex
72{
73    float x, y;
74    unsigned int l;
75    float u, v, s;
76};
77void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y,
78                                      unsigned int layer, float u, float v, float s);
79
80template <typename T>
81struct PositionDepthColorVertex
82{
83    float x, y, z;
84    T r, g, b, a;
85};
86
87template <typename T>
88void SetPositionDepthColorVertex(PositionDepthColorVertex<T>* vertex, float x, float y, float z,
89                                 const gl::Color<T> &color)
90{
91    vertex->x = x;
92    vertex->y = y;
93    vertex->z = z;
94    vertex->r = color.red;
95    vertex->g = color.green;
96    vertex->b = color.blue;
97    vertex->a = color.alpha;
98}
99
100HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name);
101
102template <typename outType>
103outType* DynamicCastComObject(IUnknown* object)
104{
105    outType *outObject = NULL;
106    HRESULT result = object->QueryInterface(__uuidof(outType), reinterpret_cast<void**>(&outObject));
107    if (SUCCEEDED(result))
108    {
109        return outObject;
110    }
111    else
112    {
113        SafeRelease(outObject);
114        return NULL;
115    }
116}
117
118inline bool isDeviceLostError(HRESULT errorCode)
119{
120    switch (errorCode)
121    {
122      case DXGI_ERROR_DEVICE_HUNG:
123      case DXGI_ERROR_DEVICE_REMOVED:
124      case DXGI_ERROR_DEVICE_RESET:
125      case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
126      case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
127        return true;
128      default:
129        return false;
130    }
131}
132
133template <unsigned int N>
134inline ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
135{
136    ID3D11VertexShader *vs = NULL;
137    HRESULT result = device->CreateVertexShader(byteCode, N, NULL, &vs);
138    UNUSED_ASSERTION_VARIABLE(result);
139    ASSERT(SUCCEEDED(result));
140    SetDebugName(vs, name);
141    return vs;
142}
143
144template <unsigned int N>
145inline ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
146{
147    ID3D11GeometryShader *gs = NULL;
148    HRESULT result = device->CreateGeometryShader(byteCode, N, NULL, &gs);
149    UNUSED_ASSERTION_VARIABLE(result);
150    ASSERT(SUCCEEDED(result));
151    SetDebugName(gs, name);
152    return gs;
153}
154
155template <unsigned int N>
156inline ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
157{
158    ID3D11PixelShader *ps = NULL;
159    HRESULT result = device->CreatePixelShader(byteCode, N, NULL, &ps);
160    UNUSED_ASSERTION_VARIABLE(result);
161    ASSERT(SUCCEEDED(result));
162    SetDebugName(ps, name);
163    return ps;
164}
165
166// Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to
167// represent an entire buffer.
168template <class T>
169inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value)
170{
171    D3D11_MAPPED_SUBRESOURCE mappedResource;
172    context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
173
174    memcpy(mappedResource.pData, &value, sizeof(T));
175
176    context->Unmap(constantBuffer, 0);
177}
178
179RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
180
181}
182
183}
184
185#endif // LIBGLESV2_RENDERER_RENDERER11_UTILS_H
186