blob: 2f47ec0a671fc36b5b98ff172ea47c541ec755e9 [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +00002//
shannon.woods@transgaming.com07765502013-02-28 23:06:43 +00003// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +00004// 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 Jonesc7a41042014-06-23 12:03:25 -070010#include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
Brandon Jonesd38f9262014-06-18 16:26:45 -070011#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +000012
13#include "libGLESv2/Buffer.h"
Brandon Jonesc7a41042014-06-23 12:03:25 -070014#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
Jamie Madill87939712013-07-02 11:57:01 -040015#include "libGLESv2/VertexAttribute.h"
Brandon Jonesc7a41042014-06-23 12:03:25 -070016#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
Jamie Madilla857c362013-07-02 11:57:02 -040017
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +000018namespace rx
19{
20
21VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer)
22{
23 mBuffer = NULL;
24 mBufferSize = 0;
25 mDynamicUsage = false;
26}
27
28VertexBuffer11::~VertexBuffer11()
29{
Geoff Langea228632013-07-30 15:17:12 -040030 SafeRelease(mBuffer);
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +000031}
32
33bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
34{
Geoff Langea228632013-07-30 15:17:12 -040035 SafeRelease(mBuffer);
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +000036
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
63VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
64{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +000065 ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer));
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +000066 return static_cast<VertexBuffer11*>(vetexBuffer);
67}
68
Jamie Madilla857c362013-07-02 11:57:02 -040069bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
70 GLint start, GLsizei count, GLsizei instances, unsigned int offset)
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +000071{
72 if (mBuffer)
73 {
Brandon Jones5bf98292014-06-06 17:19:38 -070074 gl::Buffer *buffer = attrib.buffer.get();
75 int inputStride = ComputeVertexAttributeStride(attrib);
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +000076 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 Jones5bf98292014-06-06 17:19:38 -070089 if (attrib.enabled)
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +000090 {
shannon.woods%transgaming.com@gtempaccount.comcf8d2f82013-04-13 03:37:34 +000091 if (buffer)
92 {
Brandon Jonesd38f9262014-06-18 16:26:45 -070093 Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation());
Brandon Jones5bf98292014-06-06 17:19:38 -070094 input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.offset);
shannon.woods%transgaming.com@gtempaccount.comcf8d2f82013-04-13 03:37:34 +000095 }
96 else
97 {
Brandon Jones5bf98292014-06-06 17:19:38 -070098 input = static_cast<const char*>(attrib.pointer);
shannon.woods%transgaming.com@gtempaccount.comcf8d2f82013-04-13 03:37:34 +000099 }
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +0000100 }
101 else
102 {
Jamie Madilla857c362013-07-02 11:57:02 -0400103 input = reinterpret_cast<const char*>(currentValue.FloatValues);
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +0000104 }
105
Brandon Jones5bf98292014-06-06 17:19:38 -0700106 if (instances == 0 || attrib.divisor == 0)
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +0000107 {
108 input += inputStride * start;
109 }
110
Jamie Madill7ab02fa2014-02-04 16:04:08 -0500111 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.com2c4d0702012-12-20 21:08:51 +0000115
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 Langa36ead42013-08-02 11:54:08 -0400127bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
128 GLsizei instances, unsigned int *outSpaceRequired) const
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +0000129{
Geoff Langa36ead42013-08-02 11:54:08 -0400130 unsigned int elementCount = 0;
Brandon Jones5bf98292014-06-06 17:19:38 -0700131 if (attrib.enabled)
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +0000132 {
Brandon Jones5bf98292014-06-06 17:19:38 -0700133 if (instances == 0 || attrib.divisor == 0)
shannon.woods%transgaming.com@gtempaccount.comcf8d2f82013-04-13 03:37:34 +0000134 {
Geoff Langa36ead42013-08-02 11:54:08 -0400135 elementCount = count;
shannon.woods%transgaming.com@gtempaccount.comcf8d2f82013-04-13 03:37:34 +0000136 }
137 else
138 {
Brandon Jones5bf98292014-06-06 17:19:38 -0700139 if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.divisor - 1))
Geoff Langa36ead42013-08-02 11:54:08 -0400140 {
141 // Round up
Brandon Jones5bf98292014-06-06 17:19:38 -0700142 elementCount = rx::roundUp(static_cast<unsigned int>(instances), attrib.divisor);
Geoff Langa36ead42013-08-02 11:54:08 -0400143 }
144 else
145 {
Brandon Jones5bf98292014-06-06 17:19:38 -0700146 elementCount = instances / attrib.divisor;
Geoff Langa36ead42013-08-02 11:54:08 -0400147 }
148 }
149
Jamie Madill7ab02fa2014-02-04 16:04:08 -0500150 gl::VertexFormat vertexFormat(attrib);
151 unsigned int elementSize = static_cast<unsigned int>(gl_d3d11::GetVertexElementSize(vertexFormat));
Geoff Langa36ead42013-08-02 11:54:08 -0400152 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.comcf8d2f82013-04-13 03:37:34 +0000163 }
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +0000164 }
165 else
166 {
Geoff Langa36ead42013-08-02 11:54:08 -0400167 const unsigned int elementSize = 4;
168 if (outSpaceRequired)
169 {
170 *outSpaceRequired = elementSize * 4;
171 }
172 return true;
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +0000173 }
174}
175
176unsigned int VertexBuffer11::getBufferSize() const
177{
178 return mBufferSize;
179}
180
181bool 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
193bool 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.com2c4d0702012-12-20 21:08:51 +0000218ID3D11Buffer *VertexBuffer11::getBuffer() const
219{
220 return mBuffer;
221}
222
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +0000223}