michael@0: #include "precompiled.h" michael@0: // michael@0: // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: // IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation. michael@0: michael@0: #include "libGLESv2/renderer/IndexBuffer11.h" michael@0: #include "libGLESv2/renderer/Renderer11.h" michael@0: michael@0: namespace rx michael@0: { michael@0: michael@0: IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) michael@0: { michael@0: mBuffer = NULL; michael@0: mBufferSize = 0; michael@0: mDynamicUsage = false; michael@0: } michael@0: michael@0: IndexBuffer11::~IndexBuffer11() michael@0: { michael@0: if (mBuffer) michael@0: { michael@0: mBuffer->Release(); michael@0: mBuffer = NULL; michael@0: } michael@0: } michael@0: michael@0: bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) michael@0: { michael@0: if (mBuffer) michael@0: { michael@0: mBuffer->Release(); michael@0: mBuffer = NULL; michael@0: } michael@0: michael@0: updateSerial(); michael@0: michael@0: if (bufferSize > 0) michael@0: { michael@0: ID3D11Device* dxDevice = mRenderer->getDevice(); michael@0: michael@0: D3D11_BUFFER_DESC bufferDesc; michael@0: bufferDesc.ByteWidth = bufferSize; michael@0: bufferDesc.Usage = D3D11_USAGE_DYNAMIC; michael@0: bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; michael@0: bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; michael@0: bufferDesc.MiscFlags = 0; michael@0: bufferDesc.StructureByteStride = 0; michael@0: michael@0: HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); michael@0: if (FAILED(result)) michael@0: { michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: mBufferSize = bufferSize; michael@0: mIndexType = indexType; michael@0: mDynamicUsage = dynamic; michael@0: michael@0: return true; michael@0: } michael@0: michael@0: IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer) michael@0: { michael@0: ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer)); michael@0: return static_cast(indexBuffer); michael@0: } michael@0: michael@0: bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) michael@0: { michael@0: if (mBuffer) michael@0: { michael@0: // Check for integer overflows and out-out-bounds map requests michael@0: if (offset + size < offset || offset + size > mBufferSize) michael@0: { michael@0: ERR("Index buffer map range is not inside the buffer."); michael@0: return false; michael@0: } michael@0: michael@0: ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); michael@0: michael@0: D3D11_MAPPED_SUBRESOURCE mappedResource; michael@0: HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); michael@0: if (FAILED(result)) michael@0: { michael@0: ERR("Index buffer map failed with error 0x%08x", result); michael@0: return false; michael@0: } michael@0: michael@0: *outMappedMemory = reinterpret_cast(mappedResource.pData) + offset; michael@0: return true; michael@0: } michael@0: else michael@0: { michael@0: ERR("Index buffer not initialized."); michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: bool IndexBuffer11::unmapBuffer() michael@0: { michael@0: if (mBuffer) michael@0: { michael@0: ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); michael@0: dxContext->Unmap(mBuffer, 0); michael@0: return true; michael@0: } michael@0: else michael@0: { michael@0: ERR("Index buffer not initialized."); michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: GLenum IndexBuffer11::getIndexType() const michael@0: { michael@0: return mIndexType; michael@0: } michael@0: michael@0: unsigned int IndexBuffer11::getBufferSize() const michael@0: { michael@0: return mBufferSize; michael@0: } michael@0: michael@0: bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) michael@0: { michael@0: if (bufferSize > mBufferSize || indexType != mIndexType) michael@0: { michael@0: return initialize(bufferSize, indexType, mDynamicUsage); michael@0: } michael@0: else michael@0: { michael@0: return true; michael@0: } michael@0: } michael@0: michael@0: bool IndexBuffer11::discard() michael@0: { michael@0: if (mBuffer) michael@0: { michael@0: ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); michael@0: michael@0: D3D11_MAPPED_SUBRESOURCE mappedResource; michael@0: HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); michael@0: if (FAILED(result)) michael@0: { michael@0: ERR("Index buffer map failed with error 0x%08x", result); michael@0: return false; michael@0: } michael@0: michael@0: dxContext->Unmap(mBuffer, 0); michael@0: michael@0: return true; michael@0: } michael@0: else michael@0: { michael@0: ERR("Index buffer not initialized."); michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: DXGI_FORMAT IndexBuffer11::getIndexFormat() const michael@0: { michael@0: switch (mIndexType) michael@0: { michael@0: case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT; michael@0: case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT; michael@0: case GL_UNSIGNED_INT: return DXGI_FORMAT_R32_UINT; michael@0: default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; michael@0: } michael@0: } michael@0: michael@0: ID3D11Buffer *IndexBuffer11::getBuffer() const michael@0: { michael@0: return mBuffer; michael@0: } michael@0: michael@0: }