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 "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
10
11 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
12 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
13
14 namespace rx
15 {
16
IndexBuffer11(Renderer11 * const renderer)17 IndexBuffer11::IndexBuffer11(Renderer11 *const renderer)
18 : mRenderer(renderer), mBuffer(), mBufferSize(0), mIndexType(GL_NONE), mDynamicUsage(false)
19 {
20 }
21
~IndexBuffer11()22 IndexBuffer11::~IndexBuffer11()
23 {
24 }
25
initialize(unsigned int bufferSize,GLenum indexType,bool dynamic)26 gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
27 {
28 mBuffer.reset();
29
30 updateSerial();
31
32 if (bufferSize > 0)
33 {
34 D3D11_BUFFER_DESC bufferDesc;
35 bufferDesc.ByteWidth = bufferSize;
36 bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
37 bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
38 bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
39 bufferDesc.MiscFlags = 0;
40 bufferDesc.StructureByteStride = 0;
41
42 ANGLE_TRY(mRenderer->allocateResource(bufferDesc, &mBuffer));
43
44 if (dynamic)
45 {
46 mBuffer.setDebugName("IndexBuffer11 (dynamic)");
47 }
48 else
49 {
50 mBuffer.setDebugName("IndexBuffer11 (static)");
51 }
52 }
53
54 mBufferSize = bufferSize;
55 mIndexType = indexType;
56 mDynamicUsage = dynamic;
57
58 return gl::NoError();
59 }
60
mapBuffer(unsigned int offset,unsigned int size,void ** outMappedMemory)61 gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
62 {
63 if (!mBuffer.valid())
64 {
65 return gl::OutOfMemory() << "Internal index buffer is not initialized.";
66 }
67
68 // Check for integer overflows and out-out-bounds map requests
69 if (offset + size < offset || offset + size > mBufferSize)
70 {
71 return gl::OutOfMemory() << "Index buffer map range is not inside the buffer.";
72 }
73
74 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
75
76 D3D11_MAPPED_SUBRESOURCE mappedResource;
77 HRESULT result =
78 dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
79 if (FAILED(result))
80 {
81 return gl::OutOfMemory() << "Failed to map internal index buffer, " << gl::FmtHR(result);
82 }
83
84 *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
85 return gl::NoError();
86 }
87
unmapBuffer()88 gl::Error IndexBuffer11::unmapBuffer()
89 {
90 if (!mBuffer.valid())
91 {
92 return gl::OutOfMemory() << "Internal index buffer is not initialized.";
93 }
94
95 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
96 dxContext->Unmap(mBuffer.get(), 0);
97 return gl::NoError();
98 }
99
getIndexType() const100 GLenum IndexBuffer11::getIndexType() const
101 {
102 return mIndexType;
103 }
104
getBufferSize() const105 unsigned int IndexBuffer11::getBufferSize() const
106 {
107 return mBufferSize;
108 }
109
setSize(unsigned int bufferSize,GLenum indexType)110 gl::Error IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
111 {
112 if (bufferSize > mBufferSize || indexType != mIndexType)
113 {
114 return initialize(bufferSize, indexType, mDynamicUsage);
115 }
116 else
117 {
118 return gl::NoError();
119 }
120 }
121
discard()122 gl::Error IndexBuffer11::discard()
123 {
124 if (!mBuffer.valid())
125 {
126 return gl::OutOfMemory() << "Internal index buffer is not initialized.";
127 }
128
129 ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
130
131 D3D11_MAPPED_SUBRESOURCE mappedResource;
132 HRESULT result = dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
133 if (FAILED(result))
134 {
135 return gl::OutOfMemory() << "Failed to map internal index buffer, " << gl::FmtHR(result);
136 }
137
138 dxContext->Unmap(mBuffer.get(), 0);
139
140 return gl::NoError();
141 }
142
getIndexFormat() const143 DXGI_FORMAT IndexBuffer11::getIndexFormat() const
144 {
145 switch (mIndexType)
146 {
147 case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT;
148 case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT;
149 case GL_UNSIGNED_INT: return DXGI_FORMAT_R32_UINT;
150 default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN;
151 }
152 }
153
getBuffer() const154 const d3d11::Buffer &IndexBuffer11::getBuffer() const
155 {
156 return mBuffer;
157 }
158
159 } // namespace rx
160