Edit

kc3-lang/angle/src/libGLESv2/geometry/dx9.cpp

Branch :

  • Show log

    Commit

  • Author : alokp@chromium.org
    Date : 2010-03-22 19:33:14
    Hash : ea0e1af4
    Message : Minor reshuffling of directory structure in preparation of ESSL to GLSL compiler work. 1. Added include/GLSLANG which includes compiler API 2. Deleted src/include and moved the header files to the same directory as the corresponding source files 3. Modied include path to be relative to src/. I have only fixed paths for files I moved. We should fix it for all new files at least. It is much easier to see where an included file is coming from. I noticed that a few libGLESv2 source files include headers from libEGL project, which seems wrong. I think we should address this issue. Next step: move compiler source files to compiler/frontend and create two new projects compiler/glsl_backend and compiler/hlsl_backend. Review URL: http://codereview.appspot.com/662042 git-svn-id: https://angleproject.googlecode.com/svn/trunk@62 736b8ea6-26fd-11df-bfd4-992fa37f6226

  • src/libGLESv2/geometry/dx9.cpp
  • //
    // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // geometry/dx9.h: Direct3D 9-based implementation of BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer.
    
    #include "dx9.h"
    
    #include <cstddef>
    
    #define GL_APICALL
    #include <GLES2/gl2.h>
    
    #include "Context.h"
    #include "common/debug.h"
    
    #include "geometry/vertexconversion.h"
    
    namespace
    {
    template <class InputType, template <std::size_t IncomingWidth> class WidenRule, class ElementConverter, class DefaultValueRule = gl::SimpleDefaultValues<InputType> >
    class FormatConverterFactory
    {
      private:
        template <std::size_t IncomingWidth>
        static gl::FormatConverter getFormatConverterForSize()
        {
            gl::FormatConverter formatConverter;
    
            formatConverter.identity = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::identity;
            formatConverter.outputVertexSize = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::finalSize;
            formatConverter.convertIndexed = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::convertIndexed;
            formatConverter.convertArray = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::convertArray;
    
            return formatConverter;
        }
    
      public:
        static gl::FormatConverter getFormatConverter(std::size_t size)
        {
            switch (size)
            {
              case 1: return getFormatConverterForSize<1>();
              case 2: return getFormatConverterForSize<2>();
              case 3: return getFormatConverterForSize<3>();
              case 4: return getFormatConverterForSize<4>();
              default: UNREACHABLE(); return getFormatConverterForSize<1>();
            }
        }
    };
    }
    
    namespace gl
    {
    
    Dx9BackEnd::Dx9BackEnd(IDirect3DDevice9 *d3ddevice)
        : mDevice(d3ddevice)
    {
        mDevice->AddRef();
    }
    
    Dx9BackEnd::~Dx9BackEnd()
    {
        mDevice->Release();
    }
    
    TranslatedVertexBuffer *Dx9BackEnd::createVertexBuffer(std::size_t size)
    {
        return new Dx9VertexBuffer(mDevice, size);
    }
    
    TranslatedIndexBuffer *Dx9BackEnd::createIndexBuffer(std::size_t size)
    {
        return new Dx9IndexBuffer(mDevice, size);
    }
    
    // Mapping from OpenGL-ES vertex attrib type to D3D decl type:
    //
    // BYTE                 Translate to SHORT, expand to x2,x4 as needed.
    // BYTE-norm            Translate to FLOAT since it can't be exactly represented as SHORT-norm.
    // UNSIGNED_BYTE        x4 only. x1,x2,x3=>x4
    // UNSIGNED_BYTE-norm   x4 only, x1,x2,x3=>x4
    // SHORT                x2,x4 supported. x1=>x2, x3=>x4
    // SHORT-norm           x2,x4 supported. x1=>x2, x3=>x4
    // UNSIGNED_SHORT       unsupported, translate to float
    // UNSIGNED_SHORT-norm  x2,x4 supported. x1=>x2, x3=>x4
    // FIXED (not in WebGL) Translate to float.
    // FLOAT                Fully supported.
    
    FormatConverter Dx9BackEnd::getFormatConverter(GLenum type, std::size_t size, bool normalize)
    {
        // FIXME: This should be rewritten to use C99 exact-sized types.
        switch (type)
        {
          case GL_BYTE:
            if (normalize)
            {
                return FormatConverterFactory<char, NoWiden, Normalize<char> >::getFormatConverter(size);
            }
            else
            {
                return FormatConverterFactory<char, WidenToEven, Cast<char, short> >::getFormatConverter(size);
            }
    
          case GL_UNSIGNED_BYTE:
            if (normalize)
            {
                return FormatConverterFactory<unsigned char, WidenToFour, Identity<unsigned char>, NormalizedDefaultValues<unsigned char> >::getFormatConverter(size);
            }
            else
            {
                return FormatConverterFactory<unsigned char, WidenToFour, Identity<unsigned char> >::getFormatConverter(size);
            }
    
          case GL_SHORT:
            if (normalize)
            {
                return FormatConverterFactory<short, WidenToEven, Identity<short>, NormalizedDefaultValues<short> >::getFormatConverter(size);
            }
            else
            {
                return FormatConverterFactory<short, WidenToEven, Identity<short> >::getFormatConverter(size);
            }
    
          case GL_UNSIGNED_SHORT:
            if (normalize)
            {
                return FormatConverterFactory<unsigned short, WidenToEven, Identity<unsigned short>, NormalizedDefaultValues<unsigned short> >::getFormatConverter(size);
            }
            else
            {
                return FormatConverterFactory<unsigned short, NoWiden, Cast<unsigned short, float> >::getFormatConverter(size);
            }
    
          case GL_FIXED:
            return FormatConverterFactory<int, NoWiden, FixedToFloat<int, 16> >::getFormatConverter(size);
    
          case GL_FLOAT:
            return FormatConverterFactory<float, NoWiden, Identity<float> >::getFormatConverter(size);
    
          default: UNREACHABLE(); return FormatConverterFactory<float, NoWiden, Identity<float> >::getFormatConverter(1);
        }
    }
    
    D3DDECLTYPE Dx9BackEnd::mapAttributeType(GLenum type, std::size_t size, bool normalized) const
    {
        static const D3DDECLTYPE byteTypes[2][4] = { { D3DDECLTYPE_SHORT2, D3DDECLTYPE_SHORT2, D3DDECLTYPE_SHORT4, D3DDECLTYPE_SHORT4 }, { D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2, D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT4 } };
        static const D3DDECLTYPE shortTypes[2][4] = { { D3DDECLTYPE_SHORT2, D3DDECLTYPE_SHORT2, D3DDECLTYPE_SHORT4, D3DDECLTYPE_SHORT4 }, { D3DDECLTYPE_SHORT2N, D3DDECLTYPE_SHORT2N, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_SHORT4N } };
        static const D3DDECLTYPE ushortTypes[2][4] = { { D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2, D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT4 }, { D3DDECLTYPE_USHORT2N, D3DDECLTYPE_USHORT2N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_USHORT4N } };
    
        static const D3DDECLTYPE floatTypes[4] =  { D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2, D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT4 };
    
        switch (type)
        {
          case GL_BYTE: return byteTypes[normalized][size-1];
          case GL_UNSIGNED_BYTE: return normalized ? D3DDECLTYPE_UBYTE4N : D3DDECLTYPE_UBYTE4;
          case GL_SHORT: return shortTypes[normalized][size-1];
          case GL_UNSIGNED_SHORT: return ushortTypes[normalized][size-1];
    
          case GL_FIXED:
          case GL_FLOAT:
            return floatTypes[size-1];
    
          default:
            UNREACHABLE();
            return D3DDECLTYPE_FLOAT1;
        }
    }
    
    IDirect3DVertexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedVertexBuffer *vb) const
    {
        return vb ? static_cast<Dx9VertexBuffer*>(vb)->getBuffer() : NULL;
    }
    
    IDirect3DIndexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedIndexBuffer *ib) const
    {
        return ib ? static_cast<Dx9IndexBuffer*>(ib)->getBuffer() : NULL;
    }
    
    GLenum Dx9BackEnd::preDraw(const TranslatedAttribute *attributes)
    {
        HRESULT hr;
    
        D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS+1];
    
        D3DVERTEXELEMENT9 *nextElement = &elements[0];
    
        for (BYTE i = 0; i < MAX_VERTEX_ATTRIBS; i++)
        {
            if (attributes[i].enabled)
            {
                nextElement->Stream = i;
                nextElement->Offset = 0;
                nextElement->Type = static_cast<BYTE>(mapAttributeType(attributes[i].type, attributes[i].size, attributes[i].normalized));
                nextElement->Method = D3DDECLMETHOD_DEFAULT;
                nextElement->Usage = D3DDECLUSAGE_TEXCOORD;
                nextElement->UsageIndex = attributes[i].programAttribute;
                nextElement++;
            }
        }
    
        static const D3DVERTEXELEMENT9 end = D3DDECL_END();
        *nextElement = end;
    
        IDirect3DVertexDeclaration9* vertexDeclaration;
        hr = mDevice->CreateVertexDeclaration(elements, &vertexDeclaration);
        mDevice->SetVertexDeclaration(vertexDeclaration);
        vertexDeclaration->Release();
    
        for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
        {
            if (attributes[i].enabled)
            {
                mDevice->SetStreamSource(i, getDxBuffer(attributes[i].buffer), attributes[i].offset, attributes[i].stride);
            }
            else
            {
                mDevice->SetStreamSource(i, 0, 0, 0);
            }
        }
    
        return GL_NO_ERROR;
    }
    
    Dx9BackEnd::Dx9VertexBuffer::Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size)
        : TranslatedVertexBuffer(size)
    {
        HRESULT hr = device->CreateVertexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
        if (hr != S_OK)
        {
            ERR("Out of memory allocating a vertex buffer of size %lu.", size);
            throw std::bad_alloc();
        }
    }
    
    Dx9BackEnd::Dx9VertexBuffer::~Dx9VertexBuffer()
    {
        mVertexBuffer->Release();
    }
    
    IDirect3DVertexBuffer9 *Dx9BackEnd::Dx9VertexBuffer::getBuffer() const
    {
        return mVertexBuffer;
    }
    
    void *Dx9BackEnd::Dx9VertexBuffer::map()
    {
        void *mapPtr;
    
        mVertexBuffer->Lock(0, 0, &mapPtr, 0);
    
        return mapPtr;
    }
    
    void Dx9BackEnd::Dx9VertexBuffer::unmap()
    {
        mVertexBuffer->Unlock();
    }
    
    void Dx9BackEnd::Dx9VertexBuffer::recycle()
    {
        void *dummy;
        mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
        mVertexBuffer->Unlock();
    }
    
    void *Dx9BackEnd::Dx9VertexBuffer::streamingMap(std::size_t offset, std::size_t size)
    {
        void *mapPtr;
    
        mVertexBuffer->Lock(offset, size, &mapPtr, D3DLOCK_NOOVERWRITE);
    
        return mapPtr;
    }
    
    Dx9BackEnd::Dx9IndexBuffer::Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size)
        : TranslatedIndexBuffer(size)
    {
        HRESULT hr = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &mIndexBuffer, NULL);
        if (hr != S_OK)
        {
            ERR("Out of memory allocating an index buffer of size %lu.", size);
            throw std::bad_alloc();
        }
    }
    
    Dx9BackEnd::Dx9IndexBuffer::~Dx9IndexBuffer()
    {
        mIndexBuffer->Release();
    }
    
    IDirect3DIndexBuffer9*Dx9BackEnd::Dx9IndexBuffer::getBuffer() const
    {
        return mIndexBuffer;
    }
    
    void *Dx9BackEnd::Dx9IndexBuffer::map()
    {
        void *mapPtr;
    
        mIndexBuffer->Lock(0, 0, &mapPtr, 0);
    
        return mapPtr;
    }
    
    void Dx9BackEnd::Dx9IndexBuffer::unmap()
    {
        mIndexBuffer->Unlock();
    }
    
    void Dx9BackEnd::Dx9IndexBuffer::recycle()
    {
        void *dummy;
        mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
        mIndexBuffer->Unlock();
    }
    
    void *Dx9BackEnd::Dx9IndexBuffer::streamingMap(std::size_t offset, std::size_t size)
    {
        void *mapPtr;
    
        mIndexBuffer->Lock(offset, size, &mapPtr, D3DLOCK_NOOVERWRITE);
    
        return mapPtr;
    }
    
    }