1#include "precompiled.h"
2//
3// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
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// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
9
10#include "libGLESv2/renderer/d3d11/IndexBuffer11.h"
11#include "libGLESv2/renderer/d3d11/Renderer11.h"
12
13namespace rx
14{
15
16IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
17{
18    mBuffer = NULL;
19    mBufferSize = 0;
20    mDynamicUsage = false;
21}
22
23IndexBuffer11::~IndexBuffer11()
24{
25    SafeRelease(mBuffer);
26}
27
28bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
29{
30    SafeRelease(mBuffer);
31
32    updateSerial();
33
34    if (bufferSize > 0)
35    {
36        ID3D11Device* dxDevice = mRenderer->getDevice();
37
38        D3D11_BUFFER_DESC bufferDesc;
39        bufferDesc.ByteWidth = bufferSize;
40        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
41        bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
42        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
43        bufferDesc.MiscFlags = 0;
44        bufferDesc.StructureByteStride = 0;
45
46        HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
47        if (FAILED(result))
48        {
49            return false;
50        }
51    }
52
53    mBufferSize = bufferSize;
54    mIndexType = indexType;
55    mDynamicUsage = dynamic;
56
57    return true;
58}
59
60IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
61{
62    ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer));
63    return static_cast<IndexBuffer11*>(indexBuffer);
64}
65
66bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
67{
68    if (mBuffer)
69    {
70        // Check for integer overflows and out-out-bounds map requests
71        if (offset + size < offset || offset + size > mBufferSize)
72        {
73            ERR("Index buffer map range is not inside the buffer.");
74            return false;
75        }
76
77        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
78
79        D3D11_MAPPED_SUBRESOURCE mappedResource;
80        HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
81        if (FAILED(result))
82        {
83            ERR("Index buffer map failed with error 0x%08x", result);
84            return false;
85        }
86
87        *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
88        return true;
89    }
90    else
91    {
92        ERR("Index buffer not initialized.");
93        return false;
94    }
95}
96
97bool IndexBuffer11::unmapBuffer()
98{
99    if (mBuffer)
100    {
101        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
102        dxContext->Unmap(mBuffer, 0);
103        return true;
104    }
105    else
106    {
107        ERR("Index buffer not initialized.");
108        return false;
109    }
110}
111
112GLenum IndexBuffer11::getIndexType() const
113{
114    return mIndexType;
115}
116
117unsigned int IndexBuffer11::getBufferSize() const
118{
119    return mBufferSize;
120}
121
122bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
123{
124    if (bufferSize > mBufferSize || indexType != mIndexType)
125    {
126        return initialize(bufferSize, indexType, mDynamicUsage);
127    }
128    else
129    {
130        return true;
131    }
132}
133
134bool IndexBuffer11::discard()
135{
136    if (mBuffer)
137    {
138        ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
139
140        D3D11_MAPPED_SUBRESOURCE mappedResource;
141        HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
142        if (FAILED(result))
143        {
144            ERR("Index buffer map failed with error 0x%08x", result);
145            return false;
146        }
147
148        dxContext->Unmap(mBuffer, 0);
149
150        return true;
151    }
152    else
153    {
154        ERR("Index buffer not initialized.");
155        return false;
156    }
157}
158
159DXGI_FORMAT IndexBuffer11::getIndexFormat() const
160{
161    switch (mIndexType)
162    {
163      case GL_UNSIGNED_BYTE:    return DXGI_FORMAT_R16_UINT;
164      case GL_UNSIGNED_SHORT:   return DXGI_FORMAT_R16_UINT;
165      case GL_UNSIGNED_INT:     return DXGI_FORMAT_R32_UINT;
166      default: UNREACHABLE();   return DXGI_FORMAT_UNKNOWN;
167    }
168}
169
170ID3D11Buffer *IndexBuffer11::getBuffer() const
171{
172    return mBuffer;
173}
174
175}