VertexBuffer9.cpp (4592B)
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 // VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation. 8 9 #include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" 10 11 #include "libANGLE/Buffer.h" 12 #include "libANGLE/Context.h" 13 #include "libANGLE/VertexAttribute.h" 14 #include "libANGLE/renderer/d3d/BufferD3D.h" 15 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" 16 #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" 17 #include "libANGLE/renderer/d3d/d3d9/vertexconversion.h" 18 19 namespace rx 20 { 21 22 VertexBuffer9::VertexBuffer9(Renderer9 *renderer) : mRenderer(renderer) 23 { 24 mVertexBuffer = nullptr; 25 mBufferSize = 0; 26 mDynamicUsage = false; 27 } 28 29 VertexBuffer9::~VertexBuffer9() 30 { 31 SafeRelease(mVertexBuffer); 32 } 33 34 angle::Result VertexBuffer9::initialize(const gl::Context *context, 35 unsigned int size, 36 bool dynamicUsage) 37 { 38 SafeRelease(mVertexBuffer); 39 40 updateSerial(); 41 42 if (size > 0) 43 { 44 DWORD flags = D3DUSAGE_WRITEONLY; 45 if (dynamicUsage) 46 { 47 flags |= D3DUSAGE_DYNAMIC; 48 } 49 50 HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer); 51 ANGLE_TRY_HR(GetImplAs<Context9>(context), result, 52 "Failed to allocate internal vertex buffer"); 53 } 54 55 mBufferSize = size; 56 mDynamicUsage = dynamicUsage; 57 return angle::Result::Continue; 58 } 59 60 angle::Result VertexBuffer9::storeVertexAttributes(const gl::Context *context, 61 const gl::VertexAttribute &attrib, 62 const gl::VertexBinding &binding, 63 gl::VertexAttribType currentValueType, 64 GLint start, 65 size_t count, 66 GLsizei instances, 67 unsigned int offset, 68 const uint8_t *sourceData) 69 { 70 ASSERT(mVertexBuffer); 71 72 size_t inputStride = gl::ComputeVertexAttributeStride(attrib, binding); 73 size_t elementSize = gl::ComputeVertexAttributeTypeSize(attrib); 74 75 DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; 76 77 uint8_t *mapPtr = nullptr; 78 79 unsigned int mapSize = 0; 80 ANGLE_TRY( 81 mRenderer->getVertexSpaceRequired(context, attrib, binding, count, instances, 0, &mapSize)); 82 83 HRESULT result = 84 mVertexBuffer->Lock(offset, mapSize, reinterpret_cast<void **>(&mapPtr), lockFlags); 85 ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to lock internal vertex buffer"); 86 87 const uint8_t *input = sourceData; 88 89 if (instances == 0 || binding.getDivisor() == 0) 90 { 91 input += inputStride * start; 92 } 93 94 angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, currentValueType); 95 const d3d9::VertexFormat &d3dVertexInfo = 96 d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatID); 97 bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0; 98 99 if (!needsConversion && inputStride == elementSize) 100 { 101 size_t copySize = count * inputStride; 102 memcpy(mapPtr, input, copySize); 103 } 104 else 105 { 106 d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr); 107 } 108 109 mVertexBuffer->Unlock(); 110 111 return angle::Result::Continue; 112 } 113 114 unsigned int VertexBuffer9::getBufferSize() const 115 { 116 return mBufferSize; 117 } 118 119 angle::Result VertexBuffer9::setBufferSize(const gl::Context *context, unsigned int size) 120 { 121 if (size > mBufferSize) 122 { 123 return initialize(context, size, mDynamicUsage); 124 } 125 else 126 { 127 return angle::Result::Continue; 128 } 129 } 130 131 angle::Result VertexBuffer9::discard(const gl::Context *context) 132 { 133 ASSERT(mVertexBuffer); 134 135 void *mock; 136 HRESULT result; 137 138 Context9 *context9 = GetImplAs<Context9>(context); 139 140 result = mVertexBuffer->Lock(0, 1, &mock, D3DLOCK_DISCARD); 141 ANGLE_TRY_HR(context9, result, "Failed to lock internal vertex buffer for discarding"); 142 143 result = mVertexBuffer->Unlock(); 144 ANGLE_TRY_HR(context9, result, "Failed to unlock internal vertex buffer for discarding"); 145 146 return angle::Result::Continue; 147 } 148 149 IDirect3DVertexBuffer9 *VertexBuffer9::getBuffer() const 150 { 151 return mVertexBuffer; 152 } 153 } // namespace rx