IndexBuffer11.cpp (5020B)
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 19 IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) 20 : mRenderer(renderer), 21 mBuffer(), 22 mBufferSize(0), 23 mIndexType(gl::DrawElementsType::InvalidEnum), 24 mDynamicUsage(false) 25 {} 26 27 IndexBuffer11::~IndexBuffer11() {} 28 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.setInternalName("IndexBuffer11(dynamic)"); 53 } 54 else 55 { 56 mBuffer.setInternalName("IndexBuffer11(static)"); 57 } 58 } 59 60 mBufferSize = bufferSize; 61 mIndexType = indexType; 62 mDynamicUsage = dynamic; 63 64 return angle::Result::Continue; 65 } 66 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 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 100 gl::DrawElementsType IndexBuffer11::getIndexType() const 101 { 102 return mIndexType; 103 } 104 105 unsigned int IndexBuffer11::getBufferSize() const 106 { 107 return mBufferSize; 108 } 109 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 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 139 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 155 const d3d11::Buffer &IndexBuffer11::getBuffer() const 156 { 157 return mBuffer; 158 } 159 160 } // namespace rx