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 "libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h" 10 #include "libGLESv2/renderer/d3d/d3d9/Renderer9.h" 11 12 namespace rx 13 { 14 15 IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer) 16 { 17 mIndexBuffer = NULL; 18 mBufferSize = 0; 19 mIndexType = 0; 20 mDynamic = false; 21 } 22 23 IndexBuffer9::~IndexBuffer9() 24 { 25 SafeRelease(mIndexBuffer); 26 } 27 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->getRendererExtensions().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::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); 58 } 59 } 60 61 mBufferSize = bufferSize; 62 mIndexType = indexType; 63 mDynamic = dynamic; 64 65 return gl::Error(GL_NO_ERROR); 66 } 67 68 IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer) 69 { 70 ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer)); 71 return static_cast<IndexBuffer9*>(indexBuffer); 72 } 73 74 gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) 75 { 76 if (!mIndexBuffer) 77 { 78 return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); 79 } 80 81 DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; 82 83 void *mapPtr = NULL; 84 HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); 85 if (FAILED(result)) 86 { 87 return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); 88 } 89 90 *outMappedMemory = mapPtr; 91 return gl::Error(GL_NO_ERROR); 92 } 93 94 gl::Error IndexBuffer9::unmapBuffer() 95 { 96 if (!mIndexBuffer) 97 { 98 return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); 99 } 100 101 HRESULT result = mIndexBuffer->Unlock(); 102 if (FAILED(result)) 103 { 104 return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); 105 } 106 107 return gl::Error(GL_NO_ERROR); 108 } 109 110 GLenum IndexBuffer9::getIndexType() const 111 { 112 return mIndexType; 113 } 114 115 unsigned int IndexBuffer9::getBufferSize() const 116 { 117 return mBufferSize; 118 } 119 120 gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) 121 { 122 if (bufferSize > mBufferSize || indexType != mIndexType) 123 { 124 return initialize(bufferSize, indexType, mDynamic); 125 } 126 else 127 { 128 return gl::Error(GL_NO_ERROR); 129 } 130 } 131 132 gl::Error IndexBuffer9::discard() 133 { 134 if (!mIndexBuffer) 135 { 136 return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); 137 } 138 139 void *dummy; 140 HRESULT result; 141 142 result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); 143 if (FAILED(result)) 144 { 145 return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); 146 } 147 148 result = mIndexBuffer->Unlock(); 149 if (FAILED(result)) 150 { 151 return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); 152 } 153 154 return gl::Error(GL_NO_ERROR); 155 } 156 157 D3DFORMAT IndexBuffer9::getIndexFormat() const 158 { 159 switch (mIndexType) 160 { 161 case GL_UNSIGNED_BYTE: return D3DFMT_INDEX16; 162 case GL_UNSIGNED_SHORT: return D3DFMT_INDEX16; 163 case GL_UNSIGNED_INT: return D3DFMT_INDEX32; 164 default: UNREACHABLE(); return D3DFMT_UNKNOWN; 165 } 166 } 167 168 IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const 169 { 170 return mIndexBuffer; 171 } 172 173 } 174