Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / d3d / d3d11 / IndexBuffer11.cpp
1 //
2 // Copyright (c) 2012 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 // IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
8
9 #include "libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h"
10 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
11
12 namespace rx
13 {
14
15 IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
16 {
17     mBuffer = NULL;
18     mBufferSize = 0;
19     mDynamicUsage = false;
20 }
21
22 IndexBuffer11::~IndexBuffer11()
23 {
24     SafeRelease(mBuffer);
25 }
26
27 gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
28 {
29     SafeRelease(mBuffer);
30
31     updateSerial();
32
33     if (bufferSize > 0)
34     {
35         ID3D11Device* dxDevice = mRenderer->getDevice();
36
37         D3D11_BUFFER_DESC bufferDesc;
38         bufferDesc.ByteWidth = bufferSize;
39         bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
40         bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
41         bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
42         bufferDesc.MiscFlags = 0;
43         bufferDesc.StructureByteStride = 0;
44
45         HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
46         if (FAILED(result))
47         {
48             return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize);
49         }
50     }
51
52     mBufferSize = bufferSize;
53     mIndexType = indexType;
54     mDynamicUsage = dynamic;
55
56     return gl::Error(GL_NO_ERROR);
57 }
58
59 IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
60 {
61     ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer));
62     return static_cast<IndexBuffer11*>(indexBuffer);
63 }
64
65 gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
66 {
67     if (!mBuffer)
68     {
69         return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
70     }
71
72     // Check for integer overflows and out-out-bounds map requests
73     if (offset + size < offset || offset + size > mBufferSize)
74     {
75         return gl::Error(GL_OUT_OF_MEMORY, "Index buffer map range is not inside the buffer.");
76     }
77
78     ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
79
80     D3D11_MAPPED_SUBRESOURCE mappedResource;
81     HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
82     if (FAILED(result))
83     {
84         return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result);
85     }
86
87     *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
88     return gl::Error(GL_NO_ERROR);
89 }
90
91 gl::Error IndexBuffer11::unmapBuffer()
92 {
93     if (!mBuffer)
94     {
95         return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
96     }
97
98     ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
99     dxContext->Unmap(mBuffer, 0);
100     return gl::Error(GL_NO_ERROR);
101 }
102
103 GLenum IndexBuffer11::getIndexType() const
104 {
105     return mIndexType;
106 }
107
108 unsigned int IndexBuffer11::getBufferSize() const
109 {
110     return mBufferSize;
111 }
112
113 gl::Error IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
114 {
115     if (bufferSize > mBufferSize || indexType != mIndexType)
116     {
117         return initialize(bufferSize, indexType, mDynamicUsage);
118     }
119     else
120     {
121         return gl::Error(GL_NO_ERROR);
122     }
123 }
124
125 gl::Error IndexBuffer11::discard()
126 {
127     if (!mBuffer)
128     {
129         return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized.");
130     }
131
132     ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
133
134     D3D11_MAPPED_SUBRESOURCE mappedResource;
135     HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
136     if (FAILED(result))
137     {
138         return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result);
139     }
140
141     dxContext->Unmap(mBuffer, 0);
142
143     return gl::Error(GL_NO_ERROR);
144 }
145
146 DXGI_FORMAT IndexBuffer11::getIndexFormat() const
147 {
148     switch (mIndexType)
149     {
150       case GL_UNSIGNED_BYTE:    return DXGI_FORMAT_R16_UINT;
151       case GL_UNSIGNED_SHORT:   return DXGI_FORMAT_R16_UINT;
152       case GL_UNSIGNED_INT:     return DXGI_FORMAT_R32_UINT;
153       default: UNREACHABLE();   return DXGI_FORMAT_UNKNOWN;
154     }
155 }
156
157 ID3D11Buffer *IndexBuffer11::getBuffer() const
158 {
159     return mBuffer;
160 }
161
162 }