1 //
2 // Copyright (c) 2002-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 // Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
8
9 #include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h"
10 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
11
12 namespace rx
13 {
14
IndexBuffer9(Renderer9 * const renderer)15 IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
16 {
17 mIndexBuffer = nullptr;
18 mBufferSize = 0;
19 mIndexType = 0;
20 mDynamic = false;
21 }
22
~IndexBuffer9()23 IndexBuffer9::~IndexBuffer9()
24 {
25 SafeRelease(mIndexBuffer);
26 }
27
initialize(unsigned int bufferSize,GLenum indexType,bool dynamic)28 gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
29 {
30 SafeRelease(mIndexBuffer);
31
32 updateSerial();
33
34 if (bufferSize > 0)
35 {
36 D3DFORMAT format = D3DFMT_UNKNOWN;
37 if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
38 {
39 format = D3DFMT_INDEX16;
40 }
41 else if (indexType == GL_UNSIGNED_INT)
42 {
43 ASSERT(mRenderer->getNativeExtensions().elementIndexUint);
44 format = D3DFMT_INDEX32;
45 }
46 else UNREACHABLE();
47
48 DWORD usageFlags = D3DUSAGE_WRITEONLY;
49 if (dynamic)
50 {
51 usageFlags |= D3DUSAGE_DYNAMIC;
52 }
53
54 HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
55 if (FAILED(result))
56 {
57 return gl::OutOfMemory()
58 << "Failed to allocate internal index buffer of size " << bufferSize;
59 }
60 }
61
62 mBufferSize = bufferSize;
63 mIndexType = indexType;
64 mDynamic = dynamic;
65
66 return gl::NoError();
67 }
68
mapBuffer(unsigned int offset,unsigned int size,void ** outMappedMemory)69 gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
70 {
71 if (!mIndexBuffer)
72 {
73 return gl::OutOfMemory() << "Internal index buffer is not initialized.";
74 }
75
76 DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
77
78 void *mapPtr = nullptr;
79 HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
80 if (FAILED(result))
81 {
82 return gl::OutOfMemory() << "Failed to lock internal index buffer, " << gl::FmtHR(result);
83 }
84
85 *outMappedMemory = mapPtr;
86 return gl::NoError();
87 }
88
unmapBuffer()89 gl::Error IndexBuffer9::unmapBuffer()
90 {
91 if (!mIndexBuffer)
92 {
93 return gl::OutOfMemory() << "Internal index buffer is not initialized.";
94 }
95
96 HRESULT result = mIndexBuffer->Unlock();
97 if (FAILED(result))
98 {
99 return gl::OutOfMemory() << "Failed to unlock internal index buffer, " << gl::FmtHR(result);
100 }
101
102 return gl::NoError();
103 }
104
getIndexType() const105 GLenum IndexBuffer9::getIndexType() const
106 {
107 return mIndexType;
108 }
109
getBufferSize() const110 unsigned int IndexBuffer9::getBufferSize() const
111 {
112 return mBufferSize;
113 }
114
setSize(unsigned int bufferSize,GLenum indexType)115 gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
116 {
117 if (bufferSize > mBufferSize || indexType != mIndexType)
118 {
119 return initialize(bufferSize, indexType, mDynamic);
120 }
121 else
122 {
123 return gl::NoError();
124 }
125 }
126
discard()127 gl::Error IndexBuffer9::discard()
128 {
129 if (!mIndexBuffer)
130 {
131 return gl::OutOfMemory() << "Internal index buffer is not initialized.";
132 }
133
134 void *dummy;
135 HRESULT result;
136
137 result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
138 if (FAILED(result))
139 {
140 return gl::OutOfMemory() << "Failed to lock internal index buffer, " << gl::FmtHR(result);
141 }
142
143 result = mIndexBuffer->Unlock();
144 if (FAILED(result))
145 {
146 return gl::OutOfMemory() << "Failed to unlock internal index buffer, " << gl::FmtHR(result);
147 }
148
149 return gl::NoError();
150 }
151
getIndexFormat() const152 D3DFORMAT IndexBuffer9::getIndexFormat() const
153 {
154 switch (mIndexType)
155 {
156 case GL_UNSIGNED_BYTE: return D3DFMT_INDEX16;
157 case GL_UNSIGNED_SHORT: return D3DFMT_INDEX16;
158 case GL_UNSIGNED_INT: return D3DFMT_INDEX32;
159 default: UNREACHABLE(); return D3DFMT_UNKNOWN;
160 }
161 }
162
getBuffer() const163 IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const
164 {
165 return mIndexBuffer;
166 }
167
168 }
169