gfx/angle/src/libGLESv2/renderer/VertexBuffer9.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 #include "precompiled.h"
michael@0 2 //
michael@0 3 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
michael@0 4 // Use of this source code is governed by a BSD-style license that can be
michael@0 5 // found in the LICENSE file.
michael@0 6 //
michael@0 7
michael@0 8 // VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation.
michael@0 9
michael@0 10 #include "libGLESv2/renderer/VertexBuffer9.h"
michael@0 11 #include "libGLESv2/renderer/vertexconversion.h"
michael@0 12 #include "libGLESv2/renderer/BufferStorage.h"
michael@0 13 #include "libGLESv2/Context.h"
michael@0 14 #include "libGLESv2/renderer/Renderer9.h"
michael@0 15
michael@0 16 #include "libGLESv2/Buffer.h"
michael@0 17
michael@0 18 namespace rx
michael@0 19 {
michael@0 20
michael@0 21 bool VertexBuffer9::mTranslationsInitialized = false;
michael@0 22 VertexBuffer9::FormatConverter VertexBuffer9::mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
michael@0 23
michael@0 24 VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer)
michael@0 25 {
michael@0 26 mVertexBuffer = NULL;
michael@0 27 mBufferSize = 0;
michael@0 28 mDynamicUsage = false;
michael@0 29
michael@0 30 if (!mTranslationsInitialized)
michael@0 31 {
michael@0 32 initializeTranslations(renderer->getCapsDeclTypes());
michael@0 33 mTranslationsInitialized = true;
michael@0 34 }
michael@0 35 }
michael@0 36
michael@0 37 VertexBuffer9::~VertexBuffer9()
michael@0 38 {
michael@0 39 if (mVertexBuffer)
michael@0 40 {
michael@0 41 mVertexBuffer->Release();
michael@0 42 mVertexBuffer = NULL;
michael@0 43 }
michael@0 44 }
michael@0 45
michael@0 46 bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage)
michael@0 47 {
michael@0 48 if (mVertexBuffer)
michael@0 49 {
michael@0 50 mVertexBuffer->Release();
michael@0 51 mVertexBuffer = NULL;
michael@0 52 }
michael@0 53
michael@0 54 updateSerial();
michael@0 55
michael@0 56 if (size > 0)
michael@0 57 {
michael@0 58 DWORD flags = D3DUSAGE_WRITEONLY;
michael@0 59 if (dynamicUsage)
michael@0 60 {
michael@0 61 flags |= D3DUSAGE_DYNAMIC;
michael@0 62 }
michael@0 63
michael@0 64 HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer);
michael@0 65
michael@0 66 if (FAILED(result))
michael@0 67 {
michael@0 68 ERR("Out of memory allocating a vertex buffer of size %lu.", size);
michael@0 69 return false;
michael@0 70 }
michael@0 71 }
michael@0 72
michael@0 73 mBufferSize = size;
michael@0 74 mDynamicUsage = dynamicUsage;
michael@0 75 return true;
michael@0 76 }
michael@0 77
michael@0 78 VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer)
michael@0 79 {
michael@0 80 ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer));
michael@0 81 return static_cast<VertexBuffer9*>(vertexBuffer);
michael@0 82 }
michael@0 83
michael@0 84 bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
michael@0 85 GLsizei instances, unsigned int offset)
michael@0 86 {
michael@0 87 if (mVertexBuffer)
michael@0 88 {
michael@0 89 gl::Buffer *buffer = attrib.mBoundBuffer.get();
michael@0 90
michael@0 91 int inputStride = attrib.stride();
michael@0 92 int elementSize = attrib.typeSize();
michael@0 93 const FormatConverter &converter = formatConverter(attrib);
michael@0 94
michael@0 95 DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
michael@0 96
michael@0 97 void *mapPtr = NULL;
michael@0 98
michael@0 99 unsigned int mapSize;
michael@0 100 if (!spaceRequired(attrib, count, instances, &mapSize))
michael@0 101 {
michael@0 102 return false;
michael@0 103 }
michael@0 104
michael@0 105 HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags);
michael@0 106
michael@0 107 if (FAILED(result))
michael@0 108 {
michael@0 109 ERR("Lock failed with error 0x%08x", result);
michael@0 110 return false;
michael@0 111 }
michael@0 112
michael@0 113 const char *input = NULL;
michael@0 114 if (buffer)
michael@0 115 {
michael@0 116 BufferStorage *storage = buffer->getStorage();
michael@0 117 input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset);
michael@0 118 }
michael@0 119 else
michael@0 120 {
michael@0 121 input = static_cast<const char*>(attrib.mPointer);
michael@0 122 }
michael@0 123
michael@0 124 if (instances == 0 || attrib.mDivisor == 0)
michael@0 125 {
michael@0 126 input += inputStride * start;
michael@0 127 }
michael@0 128
michael@0 129 if (converter.identity && inputStride == elementSize)
michael@0 130 {
michael@0 131 memcpy(mapPtr, input, count * inputStride);
michael@0 132 }
michael@0 133 else
michael@0 134 {
michael@0 135 converter.convertArray(input, inputStride, count, mapPtr);
michael@0 136 }
michael@0 137
michael@0 138 mVertexBuffer->Unlock();
michael@0 139
michael@0 140 return true;
michael@0 141 }
michael@0 142 else
michael@0 143 {
michael@0 144 ERR("Vertex buffer not initialized.");
michael@0 145 return false;
michael@0 146 }
michael@0 147 }
michael@0 148
michael@0 149 bool VertexBuffer9::storeRawData(const void* data, unsigned int size, unsigned int offset)
michael@0 150 {
michael@0 151 if (mVertexBuffer)
michael@0 152 {
michael@0 153 DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
michael@0 154
michael@0 155 void *mapPtr = NULL;
michael@0 156 HRESULT result = mVertexBuffer->Lock(offset, size, &mapPtr, lockFlags);
michael@0 157
michael@0 158 if (FAILED(result))
michael@0 159 {
michael@0 160 ERR("Lock failed with error 0x%08x", result);
michael@0 161 return false;
michael@0 162 }
michael@0 163
michael@0 164 memcpy(mapPtr, data, size);
michael@0 165
michael@0 166 mVertexBuffer->Unlock();
michael@0 167
michael@0 168 return true;
michael@0 169 }
michael@0 170 else
michael@0 171 {
michael@0 172 ERR("Vertex buffer not initialized.");
michael@0 173 return false;
michael@0 174 }
michael@0 175 }
michael@0 176
michael@0 177 bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
michael@0 178 unsigned int *outSpaceRequired) const
michael@0 179 {
michael@0 180 return spaceRequired(attrib, count, instances, outSpaceRequired);
michael@0 181 }
michael@0 182
michael@0 183 bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &attrib) const
michael@0 184 {
michael@0 185 return formatConverter(attrib).identity;
michael@0 186 }
michael@0 187
michael@0 188 unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &attrib) const
michael@0 189 {
michael@0 190 unsigned int spaceRequired;
michael@0 191 return getSpaceRequired(attrib, 1, 0, &spaceRequired) ? spaceRequired : 0;
michael@0 192 }
michael@0 193
michael@0 194 D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &attrib) const
michael@0 195 {
michael@0 196 return formatConverter(attrib).d3dDeclType;
michael@0 197 }
michael@0 198
michael@0 199 unsigned int VertexBuffer9::getBufferSize() const
michael@0 200 {
michael@0 201 return mBufferSize;
michael@0 202 }
michael@0 203
michael@0 204 bool VertexBuffer9::setBufferSize(unsigned int size)
michael@0 205 {
michael@0 206 if (size > mBufferSize)
michael@0 207 {
michael@0 208 return initialize(size, mDynamicUsage);
michael@0 209 }
michael@0 210 else
michael@0 211 {
michael@0 212 return true;
michael@0 213 }
michael@0 214 }
michael@0 215
michael@0 216 bool VertexBuffer9::discard()
michael@0 217 {
michael@0 218 if (mVertexBuffer)
michael@0 219 {
michael@0 220 void *dummy;
michael@0 221 HRESULT result;
michael@0 222
michael@0 223 result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
michael@0 224 if (FAILED(result))
michael@0 225 {
michael@0 226 ERR("Discard lock failed with error 0x%08x", result);
michael@0 227 return false;
michael@0 228 }
michael@0 229
michael@0 230 result = mVertexBuffer->Unlock();
michael@0 231 if (FAILED(result))
michael@0 232 {
michael@0 233 ERR("Discard unlock failed with error 0x%08x", result);
michael@0 234 return false;
michael@0 235 }
michael@0 236
michael@0 237 return true;
michael@0 238 }
michael@0 239 else
michael@0 240 {
michael@0 241 ERR("Vertex buffer not initialized.");
michael@0 242 return false;
michael@0 243 }
michael@0 244 }
michael@0 245
michael@0 246 IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const
michael@0 247 {
michael@0 248 return mVertexBuffer;
michael@0 249 }
michael@0 250
michael@0 251 // Mapping from OpenGL-ES vertex attrib type to D3D decl type:
michael@0 252 //
michael@0 253 // BYTE SHORT (Cast)
michael@0 254 // BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
michael@0 255 // UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast)
michael@0 256 // UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize)
michael@0 257 // SHORT SHORT (Identity)
michael@0 258 // SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize)
michael@0 259 // UNSIGNED_SHORT FLOAT (Cast)
michael@0 260 // UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize)
michael@0 261 // FIXED (not in WebGL) FLOAT (FixedToFloat)
michael@0 262 // FLOAT FLOAT (Identity)
michael@0 263
michael@0 264 // GLToCType maps from GL type (as GLenum) to the C typedef.
michael@0 265 template <GLenum GLType> struct GLToCType { };
michael@0 266
michael@0 267 template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; };
michael@0 268 template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; };
michael@0 269 template <> struct GLToCType<GL_SHORT> { typedef GLshort type; };
michael@0 270 template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; };
michael@0 271 template <> struct GLToCType<GL_FIXED> { typedef GLuint type; };
michael@0 272 template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; };
michael@0 273
michael@0 274 // This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
michael@0 275 enum D3DVertexType
michael@0 276 {
michael@0 277 D3DVT_FLOAT,
michael@0 278 D3DVT_SHORT,
michael@0 279 D3DVT_SHORT_NORM,
michael@0 280 D3DVT_UBYTE,
michael@0 281 D3DVT_UBYTE_NORM,
michael@0 282 D3DVT_USHORT_NORM
michael@0 283 };
michael@0 284
michael@0 285 // D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
michael@0 286 template <unsigned int D3DType> struct D3DToCType { };
michael@0 287
michael@0 288 template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
michael@0 289 template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
michael@0 290 template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
michael@0 291 template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
michael@0 292 template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
michael@0 293 template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
michael@0 294
michael@0 295 // Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
michael@0 296 template <unsigned int type, int size> struct WidenRule { };
michael@0 297
michael@0 298 template <int size> struct WidenRule<D3DVT_FLOAT, size> : NoWiden<size> { };
michael@0 299 template <int size> struct WidenRule<D3DVT_SHORT, size> : WidenToEven<size> { };
michael@0 300 template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : WidenToEven<size> { };
michael@0 301 template <int size> struct WidenRule<D3DVT_UBYTE, size> : WidenToFour<size> { };
michael@0 302 template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : WidenToFour<size> { };
michael@0 303 template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : WidenToEven<size> { };
michael@0 304
michael@0 305 // VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
michael@0 306 template <unsigned int d3dtype, int size> struct VertexTypeFlags { };
michael@0 307
michael@0 308 template <unsigned int _capflag, unsigned int _declflag>
michael@0 309 struct VertexTypeFlagsHelper
michael@0 310 {
michael@0 311 enum { capflag = _capflag };
michael@0 312 enum { declflag = _declflag };
michael@0 313 };
michael@0 314
michael@0 315 template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
michael@0 316 template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
michael@0 317 template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
michael@0 318 template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
michael@0 319 template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
michael@0 320 template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
michael@0 321 template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
michael@0 322 template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
michael@0 323 template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
michael@0 324 template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
michael@0 325 template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
michael@0 326 template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
michael@0 327
michael@0 328
michael@0 329 // VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
michael@0 330 template <GLenum GLtype, bool normalized> struct VertexTypeMapping { };
michael@0 331
michael@0 332 template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
michael@0 333 struct VertexTypeMappingBase
michael@0 334 {
michael@0 335 enum { preferred = Preferred };
michael@0 336 enum { fallback = Fallback };
michael@0 337 };
michael@0 338
michael@0 339 template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast
michael@0 340 template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize
michael@0 341 template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast
michael@0 342 template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize
michael@0 343 template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity
michael@0 344 template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
michael@0 345 template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast
michael@0 346 template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
michael@0 347 template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat
michael@0 348 template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity
michael@0 349
michael@0 350
michael@0 351 // Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
michael@0 352 // The conversion rules themselves are defined in vertexconversion.h.
michael@0 353
michael@0 354 // Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
michael@0 355 template <GLenum fromType, bool normalized, unsigned int toType>
michael@0 356 struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type> { };
michael@0 357
michael@0 358 // All conversions from normalized types to float use the Normalize operator.
michael@0 359 template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type> { };
michael@0 360
michael@0 361 // Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules.
michael@0 362 template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { };
michael@0 363 template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { };
michael@0 364
michael@0 365 // A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
michael@0 366 // whether it is normalized or not.
michael@0 367 template <class T, bool normalized> struct DefaultVertexValuesStage2 { };
michael@0 368
michael@0 369 template <class T> struct DefaultVertexValuesStage2<T, true> : NormalizedDefaultValues<T> { };
michael@0 370 template <class T> struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T> { };
michael@0 371
michael@0 372 // Work out the default value rule for a D3D type (expressed as the C type) and
michael@0 373 template <class T, bool normalized> struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized> { };
michael@0 374 template <bool normalized> struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float> { };
michael@0 375
michael@0 376 // Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
michael@0 377 // The fallback conversion produces an output that all D3D9 devices must support.
michael@0 378 template <class T> struct UsePreferred { enum { type = T::preferred }; };
michael@0 379 template <class T> struct UseFallback { enum { type = T::fallback }; };
michael@0 380
michael@0 381 // Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
michael@0 382 // it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
michael@0 383 // and the D3DDECLTYPE member needed for the vertex declaration in declflag.
michael@0 384 template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
michael@0 385 struct Converter
michael@0 386 : VertexDataConverter<typename GLToCType<fromType>::type,
michael@0 387 WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
michael@0 388 ConversionRule<fromType,
michael@0 389 normalized,
michael@0 390 PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
michael@0 391 DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
michael@0 392 {
michael@0 393 private:
michael@0 394 enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
michael@0 395 enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
michael@0 396
michael@0 397 public:
michael@0 398 enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
michael@0 399 enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
michael@0 400 };
michael@0 401
michael@0 402 // Initialize a TranslationInfo
michael@0 403 #define TRANSLATION(type, norm, size, preferred) \
michael@0 404 { \
michael@0 405 Converter<type, norm, size, preferred>::identity, \
michael@0 406 Converter<type, norm, size, preferred>::finalSize, \
michael@0 407 Converter<type, norm, size, preferred>::convertArray, \
michael@0 408 static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \
michael@0 409 }
michael@0 410
michael@0 411 #define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \
michael@0 412 { \
michael@0 413 Converter<type, norm, size, UsePreferred>::capflag, \
michael@0 414 TRANSLATION(type, norm, size, UsePreferred), \
michael@0 415 TRANSLATION(type, norm, size, UseFallback) \
michael@0 416 }
michael@0 417
michael@0 418 #define TRANSLATIONS_FOR_TYPE(type) \
michael@0 419 { \
michael@0 420 { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
michael@0 421 { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \
michael@0 422 }
michael@0 423
michael@0 424 #define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \
michael@0 425 { \
michael@0 426 { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
michael@0 427 { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
michael@0 428 }
michael@0 429
michael@0 430 const VertexBuffer9::TranslationDescription VertexBuffer9::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
michael@0 431 {
michael@0 432 TRANSLATIONS_FOR_TYPE(GL_BYTE),
michael@0 433 TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
michael@0 434 TRANSLATIONS_FOR_TYPE(GL_SHORT),
michael@0 435 TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
michael@0 436 TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED),
michael@0 437 TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)
michael@0 438 };
michael@0 439
michael@0 440 void VertexBuffer9::initializeTranslations(DWORD declTypes)
michael@0 441 {
michael@0 442 for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
michael@0 443 {
michael@0 444 for (unsigned int j = 0; j < 2; j++)
michael@0 445 {
michael@0 446 for (unsigned int k = 0; k < 4; k++)
michael@0 447 {
michael@0 448 if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0)
michael@0 449 {
michael@0 450 mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
michael@0 451 }
michael@0 452 else
michael@0 453 {
michael@0 454 mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
michael@0 455 }
michael@0 456 }
michael@0 457 }
michael@0 458 }
michael@0 459 }
michael@0 460
michael@0 461 unsigned int VertexBuffer9::typeIndex(GLenum type)
michael@0 462 {
michael@0 463 switch (type)
michael@0 464 {
michael@0 465 case GL_BYTE: return 0;
michael@0 466 case GL_UNSIGNED_BYTE: return 1;
michael@0 467 case GL_SHORT: return 2;
michael@0 468 case GL_UNSIGNED_SHORT: return 3;
michael@0 469 case GL_FIXED: return 4;
michael@0 470 case GL_FLOAT: return 5;
michael@0 471
michael@0 472 default: UNREACHABLE(); return 5;
michael@0 473 }
michael@0 474 }
michael@0 475
michael@0 476 const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::VertexAttribute &attribute)
michael@0 477 {
michael@0 478 return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1];
michael@0 479 }
michael@0 480
michael@0 481 bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
michael@0 482 unsigned int *outSpaceRequired)
michael@0 483 {
michael@0 484 unsigned int elementSize = formatConverter(attrib).outputElementSize;
michael@0 485
michael@0 486 if (instances == 0 || attrib.mDivisor == 0)
michael@0 487 {
michael@0 488 unsigned int elementCount = 0;
michael@0 489 if (instances == 0 || attrib.mDivisor == 0)
michael@0 490 {
michael@0 491 elementCount = count;
michael@0 492 }
michael@0 493 else
michael@0 494 {
michael@0 495 if (static_cast<unsigned int>(instances) < std::numeric_limits<unsigned int>::max() - (attrib.mDivisor - 1))
michael@0 496 {
michael@0 497 // Round up
michael@0 498 elementCount = (static_cast<unsigned int>(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor;
michael@0 499 }
michael@0 500 else
michael@0 501 {
michael@0 502 elementCount = static_cast<unsigned int>(instances) / attrib.mDivisor;
michael@0 503 }
michael@0 504 }
michael@0 505
michael@0 506 if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
michael@0 507 {
michael@0 508 if (outSpaceRequired)
michael@0 509 {
michael@0 510 *outSpaceRequired = elementSize * elementCount;
michael@0 511 }
michael@0 512 return true;
michael@0 513 }
michael@0 514 else
michael@0 515 {
michael@0 516 return false;
michael@0 517 }
michael@0 518 }
michael@0 519 else
michael@0 520 {
michael@0 521 const unsigned int elementSize = 4;
michael@0 522 if (outSpaceRequired)
michael@0 523 {
michael@0 524 *outSpaceRequired = elementSize * 4;
michael@0 525 }
michael@0 526 return true;
michael@0 527 }
michael@0 528 }
michael@0 529
michael@0 530 }

mercurial