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