111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com// 211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. 311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be 411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com// found in the LICENSE file. 511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com// 611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation. 811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 9c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h" 10c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" 1111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 1211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.comnamespace rx 1311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 1411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 1511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.comIndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) 1611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 1711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com mBuffer = NULL; 1811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com mBufferSize = 0; 1911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com mDynamicUsage = false; 2011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 2111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 2211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.comIndexBuffer11::~IndexBuffer11() 2311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 24ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang SafeRelease(mBuffer); 2511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 2611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 27c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) 2811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 29ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang SafeRelease(mBuffer); 3011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 3111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com updateSerial(); 3211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 3311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com if (bufferSize > 0) 3411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 3511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com ID3D11Device* dxDevice = mRenderer->getDevice(); 3611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 3711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com D3D11_BUFFER_DESC bufferDesc; 3811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com bufferDesc.ByteWidth = bufferSize; 3911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com bufferDesc.Usage = D3D11_USAGE_DYNAMIC; 4011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; 4111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 4211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com bufferDesc.MiscFlags = 0; 4311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com bufferDesc.StructureByteStride = 0; 4411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 4511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); 4611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com if (FAILED(result)) 4711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 48c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); 4911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com } 5011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com } 5111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 5211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com mBufferSize = bufferSize; 5311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com mIndexType = indexType; 5411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com mDynamicUsage = dynamic; 5511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 56c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_NO_ERROR); 5711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 5811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 5911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.comIndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer) 6011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 618b400b1e8d84c5b93dd151807504a3e4b90d1b21apatrick@chromium.org ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer)); 6211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com return static_cast<IndexBuffer11*>(indexBuffer); 6311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 6411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 65c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) 6611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 67c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (!mBuffer) 6811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 69c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); 70c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang } 7111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 72c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang // Check for integer overflows and out-out-bounds map requests 73c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (offset + size < offset || offset + size > mBufferSize) 74c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang { 75c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_OUT_OF_MEMORY, "Index buffer map range is not inside the buffer."); 76c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang } 7711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 78c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 7911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 80c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang D3D11_MAPPED_SUBRESOURCE mappedResource; 81c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); 82c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (FAILED(result)) 8311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 84c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result); 8511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com } 86c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang 87c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset; 88c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_NO_ERROR); 8911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 9011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 91c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error IndexBuffer11::unmapBuffer() 9211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 93c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (!mBuffer) 9411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 95c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); 9611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com } 97c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang 98c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 99c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang dxContext->Unmap(mBuffer, 0); 100c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_NO_ERROR); 10111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 10211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 10311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.comGLenum IndexBuffer11::getIndexType() const 10411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 10511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com return mIndexType; 10611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 10711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 10811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.comunsigned int IndexBuffer11::getBufferSize() const 10911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 11011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com return mBufferSize; 11111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 11211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 113c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) 11411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 11511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com if (bufferSize > mBufferSize || indexType != mIndexType) 11611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 11711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com return initialize(bufferSize, indexType, mDynamicUsage); 11811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com } 11911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com else 12011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 121c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_NO_ERROR); 12211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com } 12311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 12411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 125c9e69b1941522095a3878d9e1501511ab4722139Geoff Langgl::Error IndexBuffer11::discard() 12611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 127c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (!mBuffer) 12811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 129c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); 130c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang } 13111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 132c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); 13311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 134c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang D3D11_MAPPED_SUBRESOURCE mappedResource; 135c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); 136c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang if (FAILED(result)) 13711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 138c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result); 13911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com } 140c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang 141c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang dxContext->Unmap(mBuffer, 0); 142c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang 143c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang return gl::Error(GL_NO_ERROR); 14411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 14511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 14611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.comDXGI_FORMAT IndexBuffer11::getIndexFormat() const 14711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 14811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com switch (mIndexType) 14911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com { 15011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT; 15111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT; 15211c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com case GL_UNSIGNED_INT: return DXGI_FORMAT_R32_UINT; 15311c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; 15411c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com } 15511c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 15611c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 15711c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.comID3D11Buffer *IndexBuffer11::getBuffer() const 15811c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com{ 15911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com return mBuffer; 16011c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com} 16111c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com 162c9e69b1941522095a3878d9e1501511ab4722139Geoff Lang} 163