shannon.woods@transgaming.com | bdf2d80 | 2013-02-28 23:16:20 +0000 | [diff] [blame] | 1 | #include "precompiled.h" |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 2 | // |
shannon.woods@transgaming.com | 0776550 | 2013-02-28 23:06:43 +0000 | [diff] [blame] | 3 | // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 4 | // Use of this source code is governed by a BSD-style license that can be |
| 5 | // found in the LICENSE file. |
| 6 | // |
| 7 | |
| 8 | // VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. |
| 9 | |
Brandon Jones | c7a4104 | 2014-06-23 12:03:25 -0700 | [diff] [blame] | 10 | #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h" |
Brandon Jones | d38f926 | 2014-06-18 16:26:45 -0700 | [diff] [blame] | 11 | #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 12 | |
| 13 | #include "libGLESv2/Buffer.h" |
Brandon Jones | c7a4104 | 2014-06-23 12:03:25 -0700 | [diff] [blame] | 14 | #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" |
Jamie Madill | 8793971 | 2013-07-02 11:57:01 -0400 | [diff] [blame] | 15 | #include "libGLESv2/VertexAttribute.h" |
Brandon Jones | c7a4104 | 2014-06-23 12:03:25 -0700 | [diff] [blame] | 16 | #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" |
Jamie Madill | a857c36 | 2013-07-02 11:57:02 -0400 | [diff] [blame] | 17 | |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 18 | namespace rx |
| 19 | { |
| 20 | |
| 21 | VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) |
| 22 | { |
| 23 | mBuffer = NULL; |
| 24 | mBufferSize = 0; |
| 25 | mDynamicUsage = false; |
| 26 | } |
| 27 | |
| 28 | VertexBuffer11::~VertexBuffer11() |
| 29 | { |
Geoff Lang | ea22863 | 2013-07-30 15:17:12 -0400 | [diff] [blame] | 30 | SafeRelease(mBuffer); |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 31 | } |
| 32 | |
| 33 | bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) |
| 34 | { |
Geoff Lang | ea22863 | 2013-07-30 15:17:12 -0400 | [diff] [blame] | 35 | SafeRelease(mBuffer); |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 36 | |
| 37 | updateSerial(); |
| 38 | |
| 39 | if (size > 0) |
| 40 | { |
| 41 | ID3D11Device* dxDevice = mRenderer->getDevice(); |
| 42 | |
| 43 | D3D11_BUFFER_DESC bufferDesc; |
| 44 | bufferDesc.ByteWidth = size; |
| 45 | bufferDesc.Usage = D3D11_USAGE_DYNAMIC; |
| 46 | bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; |
| 47 | bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; |
| 48 | bufferDesc.MiscFlags = 0; |
| 49 | bufferDesc.StructureByteStride = 0; |
| 50 | |
| 51 | HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); |
| 52 | if (FAILED(result)) |
| 53 | { |
| 54 | return false; |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | mBufferSize = size; |
| 59 | mDynamicUsage = dynamicUsage; |
| 60 | return true; |
| 61 | } |
| 62 | |
| 63 | VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) |
| 64 | { |
apatrick@chromium.org | 8b400b1 | 2013-01-30 21:53:40 +0000 | [diff] [blame] | 65 | ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer)); |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 66 | return static_cast<VertexBuffer11*>(vetexBuffer); |
| 67 | } |
| 68 | |
Jamie Madill | a857c36 | 2013-07-02 11:57:02 -0400 | [diff] [blame] | 69 | bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, |
| 70 | GLint start, GLsizei count, GLsizei instances, unsigned int offset) |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 71 | { |
| 72 | if (mBuffer) |
| 73 | { |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 74 | gl::Buffer *buffer = attrib.buffer.get(); |
| 75 | int inputStride = ComputeVertexAttributeStride(attrib); |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 76 | ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); |
| 77 | |
| 78 | D3D11_MAPPED_SUBRESOURCE mappedResource; |
| 79 | HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); |
| 80 | if (FAILED(result)) |
| 81 | { |
| 82 | ERR("Vertex buffer map failed with error 0x%08x", result); |
| 83 | return false; |
| 84 | } |
| 85 | |
| 86 | char* output = reinterpret_cast<char*>(mappedResource.pData) + offset; |
| 87 | |
| 88 | const char *input = NULL; |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 89 | if (attrib.enabled) |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 90 | { |
shannon.woods%transgaming.com@gtempaccount.com | cf8d2f8 | 2013-04-13 03:37:34 +0000 | [diff] [blame] | 91 | if (buffer) |
| 92 | { |
Brandon Jones | d38f926 | 2014-06-18 16:26:45 -0700 | [diff] [blame] | 93 | Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation()); |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 94 | input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset); |
shannon.woods%transgaming.com@gtempaccount.com | cf8d2f8 | 2013-04-13 03:37:34 +0000 | [diff] [blame] | 95 | } |
| 96 | else |
| 97 | { |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 98 | input = static_cast<const char*>(attrib.pointer); |
shannon.woods%transgaming.com@gtempaccount.com | cf8d2f8 | 2013-04-13 03:37:34 +0000 | [diff] [blame] | 99 | } |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 100 | } |
| 101 | else |
| 102 | { |
Jamie Madill | a857c36 | 2013-07-02 11:57:02 -0400 | [diff] [blame] | 103 | input = reinterpret_cast<const char*>(currentValue.FloatValues); |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 104 | } |
| 105 | |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 106 | if (instances == 0 || attrib.divisor == 0) |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 107 | { |
| 108 | input += inputStride * start; |
| 109 | } |
| 110 | |
Jamie Madill | 7ab02fa | 2014-02-04 16:04:08 -0500 | [diff] [blame] | 111 | gl::VertexFormat vertexFormat(attrib, currentValue.Type); |
| 112 | VertexCopyFunction conversionFunc = gl_d3d11::GetVertexCopyFunction(vertexFormat); |
| 113 | ASSERT(conversionFunc != NULL); |
| 114 | conversionFunc(input, inputStride, count, output); |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 115 | |
| 116 | dxContext->Unmap(mBuffer, 0); |
| 117 | |
| 118 | return true; |
| 119 | } |
| 120 | else |
| 121 | { |
| 122 | ERR("Vertex buffer not initialized."); |
| 123 | return false; |
| 124 | } |
| 125 | } |
| 126 | |
Geoff Lang | a36ead4 | 2013-08-02 11:54:08 -0400 | [diff] [blame] | 127 | bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, |
| 128 | GLsizei instances, unsigned int *outSpaceRequired) const |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 129 | { |
Geoff Lang | a36ead4 | 2013-08-02 11:54:08 -0400 | [diff] [blame] | 130 | unsigned int elementCount = 0; |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 131 | if (attrib.enabled) |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 132 | { |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 133 | if (instances == 0 || attrib.divisor == 0) |
shannon.woods%transgaming.com@gtempaccount.com | cf8d2f8 | 2013-04-13 03:37:34 +0000 | [diff] [blame] | 134 | { |
Geoff Lang | a36ead4 | 2013-08-02 11:54:08 -0400 | [diff] [blame] | 135 | elementCount = count; |
shannon.woods%transgaming.com@gtempaccount.com | cf8d2f8 | 2013-04-13 03:37:34 +0000 | [diff] [blame] | 136 | } |
| 137 | else |
| 138 | { |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 139 | if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.divisor - 1)) |
Geoff Lang | a36ead4 | 2013-08-02 11:54:08 -0400 | [diff] [blame] | 140 | { |
| 141 | // Round up |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 142 | elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.divisor); |
Geoff Lang | a36ead4 | 2013-08-02 11:54:08 -0400 | [diff] [blame] | 143 | } |
| 144 | else |
| 145 | { |
Brandon Jones | 5bf9829 | 2014-06-06 17:19:38 -0700 | [diff] [blame] | 146 | elementCount = instances / attrib.divisor; |
Geoff Lang | a36ead4 | 2013-08-02 11:54:08 -0400 | [diff] [blame] | 147 | } |
| 148 | } |
| 149 | |
Jamie Madill | 7ab02fa | 2014-02-04 16:04:08 -0500 | [diff] [blame] | 150 | gl::VertexFormat vertexFormat(attrib); |
| 151 | unsigned int elementSize = static_cast<unsigned int>(gl_d3d11::GetVertexElementSize(vertexFormat)); |
Geoff Lang | a36ead4 | 2013-08-02 11:54:08 -0400 | [diff] [blame] | 152 | if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount) |
| 153 | { |
| 154 | if (outSpaceRequired) |
| 155 | { |
| 156 | *outSpaceRequired = elementSize * elementCount; |
| 157 | } |
| 158 | return true; |
| 159 | } |
| 160 | else |
| 161 | { |
| 162 | return false; |
shannon.woods%transgaming.com@gtempaccount.com | cf8d2f8 | 2013-04-13 03:37:34 +0000 | [diff] [blame] | 163 | } |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 164 | } |
| 165 | else |
| 166 | { |
Geoff Lang | a36ead4 | 2013-08-02 11:54:08 -0400 | [diff] [blame] | 167 | const unsigned int elementSize = 4; |
| 168 | if (outSpaceRequired) |
| 169 | { |
| 170 | *outSpaceRequired = elementSize * 4; |
| 171 | } |
| 172 | return true; |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 173 | } |
| 174 | } |
| 175 | |
| 176 | unsigned int VertexBuffer11::getBufferSize() const |
| 177 | { |
| 178 | return mBufferSize; |
| 179 | } |
| 180 | |
| 181 | bool VertexBuffer11::setBufferSize(unsigned int size) |
| 182 | { |
| 183 | if (size > mBufferSize) |
| 184 | { |
| 185 | return initialize(size, mDynamicUsage); |
| 186 | } |
| 187 | else |
| 188 | { |
| 189 | return true; |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | bool VertexBuffer11::discard() |
| 194 | { |
| 195 | if (mBuffer) |
| 196 | { |
| 197 | ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); |
| 198 | |
| 199 | D3D11_MAPPED_SUBRESOURCE mappedResource; |
| 200 | HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); |
| 201 | if (FAILED(result)) |
| 202 | { |
| 203 | ERR("Vertex buffer map failed with error 0x%08x", result); |
| 204 | return false; |
| 205 | } |
| 206 | |
| 207 | dxContext->Unmap(mBuffer, 0); |
| 208 | |
| 209 | return true; |
| 210 | } |
| 211 | else |
| 212 | { |
| 213 | ERR("Vertex buffer not initialized."); |
| 214 | return false; |
| 215 | } |
| 216 | } |
| 217 | |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 218 | ID3D11Buffer *VertexBuffer11::getBuffer() const |
| 219 | { |
| 220 | return mBuffer; |
| 221 | } |
| 222 | |
daniel@transgaming.com | 2c4d070 | 2012-12-20 21:08:51 +0000 | [diff] [blame] | 223 | } |