1 //
2 // Copyright 2002 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
11 #include "libANGLE/Context.h"
12 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
13
14 namespace rx
15 {
16
IndexBuffer9(Renderer9 * const renderer)17 IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
18 {
19 mIndexBuffer = nullptr;
20 mBufferSize = 0;
21 mIndexType = gl::DrawElementsType::InvalidEnum;
22 mDynamic = false;
23 }
24
~IndexBuffer9()25 IndexBuffer9::~IndexBuffer9()
26 {
27 SafeRelease(mIndexBuffer);
28 }
29
initialize(const gl::Context * context,unsigned int bufferSize,gl::DrawElementsType indexType,bool dynamic)30 angle::Result IndexBuffer9::initialize(const gl::Context *context,
31 unsigned int bufferSize,
32 gl::DrawElementsType indexType,
33 bool dynamic)
34 {
35 SafeRelease(mIndexBuffer);
36
37 updateSerial();
38
39 if (bufferSize > 0)
40 {
41 D3DFORMAT format = D3DFMT_UNKNOWN;
42 if (indexType == gl::DrawElementsType::UnsignedShort ||
43 indexType == gl::DrawElementsType::UnsignedByte)
44 {
45 format = D3DFMT_INDEX16;
46 }
47 else if (indexType == gl::DrawElementsType::UnsignedInt)
48 {
49 ASSERT(mRenderer->getNativeExtensions().elementIndexUintOES);
50 format = D3DFMT_INDEX32;
51 }
52 else
53 UNREACHABLE();
54
55 DWORD usageFlags = D3DUSAGE_WRITEONLY;
56 if (dynamic)
57 {
58 usageFlags |= D3DUSAGE_DYNAMIC;
59 }
60
61 HRESULT result =
62 mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
63 ANGLE_TRY_HR(GetImplAs<Context9>(context), result,
64 "Failed to allocate internal index buffer");
65 }
66
67 mBufferSize = bufferSize;
68 mIndexType = indexType;
69 mDynamic = dynamic;
70
71 return angle::Result::Continue;
72 }
73
mapBuffer(const gl::Context * context,unsigned int offset,unsigned int size,void ** outMappedMemory)74 angle::Result IndexBuffer9::mapBuffer(const gl::Context *context,
75 unsigned int offset,
76 unsigned int size,
77 void **outMappedMemory)
78 {
79 ASSERT(mIndexBuffer);
80
81 DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
82
83 void *mapPtr = nullptr;
84 HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
85 ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to lock internal index buffer");
86
87 *outMappedMemory = mapPtr;
88 return angle::Result::Continue;
89 }
90
unmapBuffer(const gl::Context * context)91 angle::Result IndexBuffer9::unmapBuffer(const gl::Context *context)
92 {
93 ASSERT(mIndexBuffer);
94 HRESULT result = mIndexBuffer->Unlock();
95 ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to unlock internal index buffer");
96
97 return angle::Result::Continue;
98 }
99
getIndexType() const100 gl::DrawElementsType IndexBuffer9::getIndexType() const
101 {
102 return mIndexType;
103 }
104
getBufferSize() const105 unsigned int IndexBuffer9::getBufferSize() const
106 {
107 return mBufferSize;
108 }
109
setSize(const gl::Context * context,unsigned int bufferSize,gl::DrawElementsType indexType)110 angle::Result IndexBuffer9::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, mDynamic);
117 }
118
119 return angle::Result::Continue;
120 }
121
discard(const gl::Context * context)122 angle::Result IndexBuffer9::discard(const gl::Context *context)
123 {
124 ASSERT(mIndexBuffer);
125
126 void *mock;
127 HRESULT result;
128
129 Context9 *context9 = GetImplAs<Context9>(context);
130
131 result = mIndexBuffer->Lock(0, 1, &mock, D3DLOCK_DISCARD);
132 ANGLE_TRY_HR(context9, result, "Failed to lock internal index buffer");
133
134 result = mIndexBuffer->Unlock();
135 ANGLE_TRY_HR(context9, result, "Failed to unlock internal index buffer");
136
137 return angle::Result::Continue;
138 }
139
getIndexFormat() const140 D3DFORMAT IndexBuffer9::getIndexFormat() const
141 {
142 switch (mIndexType)
143 {
144 case gl::DrawElementsType::UnsignedByte:
145 return D3DFMT_INDEX16;
146 case gl::DrawElementsType::UnsignedShort:
147 return D3DFMT_INDEX16;
148 case gl::DrawElementsType::UnsignedInt:
149 return D3DFMT_INDEX32;
150 default:
151 UNREACHABLE();
152 return D3DFMT_UNKNOWN;
153 }
154 }
155
getBuffer() const156 IDirect3DIndexBuffer9 *IndexBuffer9::getBuffer() const
157 {
158 return mIndexBuffer;
159 }
160
161 } // namespace rx
162