• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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