1bdf2d80f459d43f5a6df074431bacf41584f81b7shannon.woods@transgaming.com#include "precompiled.h"
270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com//
370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com// Use of this source code is governed by a BSD-style license that can be
570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com// found in the LICENSE file.
670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com//
770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com// BufferStorage11.cpp Defines the BufferStorage11 class.
970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
1070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com#include "libGLESv2/renderer/BufferStorage11.h"
1170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com#include "libGLESv2/main.h"
12486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/renderer/Renderer11.h"
1370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
1470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comnamespace rx
1570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
1670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
1770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comBufferStorage11::BufferStorage11(Renderer11 *renderer)
1870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
1970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mRenderer = renderer;
2070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
2170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mStagingBuffer = NULL;
2270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mStagingBufferSize = 0;
2370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
2470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mBuffer = NULL;
2570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mBufferSize = 0;
2670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
2770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mSize = 0;
2870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
2970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mResolvedData = NULL;
3070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mResolvedDataSize = 0;
3170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mResolvedDataValid = false;
3270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
3370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mReadUsageCount = 0;
3470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mWriteUsageCount = 0;
3570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
3670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
3770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comBufferStorage11::~BufferStorage11()
3870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
3970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (mStagingBuffer)
4070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
4170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mStagingBuffer->Release();
4270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mStagingBuffer = NULL;
4370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
4470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
4570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (mBuffer)
4670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
4770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mBuffer->Release();
4870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mBuffer = NULL;
4970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
5070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
5170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (mResolvedData)
5270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
5370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        free(mResolvedData);
5470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mResolvedData = NULL;
5570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
5670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
5770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
5870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comBufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage)
5970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
6070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage));
6170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    return static_cast<BufferStorage11*>(bufferStorage);
6270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
6370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
6470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comvoid *BufferStorage11::getData()
6570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
6670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (!mResolvedDataValid)
6770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
6870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        ID3D11Device *device = mRenderer->getDevice();
6970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        ID3D11DeviceContext *context = mRenderer->getDeviceContext();
7070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        HRESULT result;
7170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
7270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        if (!mStagingBuffer || mStagingBufferSize < mBufferSize)
7370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        {
7470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (mStagingBuffer)
7570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
7670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mStagingBuffer->Release();
7770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mStagingBuffer = NULL;
7870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mStagingBufferSize = 0;
7970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
8070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
8170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            D3D11_BUFFER_DESC bufferDesc;
8270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.ByteWidth = mSize;
8370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.Usage = D3D11_USAGE_STAGING;
8470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.BindFlags = 0;
8570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
8670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.MiscFlags = 0;
8770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.StructureByteStride = 0;
8870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
8970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer);
9070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (FAILED(result))
9170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
9270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
9370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
9470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
9570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            mStagingBufferSize = bufferDesc.ByteWidth;
9670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        }
9770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
9870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        if (!mResolvedData || mResolvedDataSize < mBufferSize)
9970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        {
10070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            free(mResolvedData);
10170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            mResolvedData = malloc(mSize);
10270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            mResolvedDataSize = mSize;
10370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        }
10470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
10570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        D3D11_BOX srcBox;
10670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.left = 0;
10770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.right = mSize;
10870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.top = 0;
10970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.bottom = 1;
11070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.front = 0;
11170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.back = 1;
11270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
11370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        context->CopySubresourceRegion(mStagingBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox);
11470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
11570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        D3D11_MAPPED_SUBRESOURCE mappedResource;
11670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        result = context->Map(mStagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource);
11770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        if (FAILED(result))
11870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        {
11970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
12070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        }
12170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
12270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        memcpy(mResolvedData, mappedResource.pData, mSize);
12370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
12470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        context->Unmap(mStagingBuffer, 0);
12570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
12670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mResolvedDataValid = true;
12770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
12870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
12970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mReadUsageCount = 0;
13070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
13170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    return mResolvedData;
13270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
13370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
13470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comvoid BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset)
13570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
13670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    ID3D11Device *device = mRenderer->getDevice();
13770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    ID3D11DeviceContext *context = mRenderer->getDeviceContext();
13870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    HRESULT result;
13970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
14070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    unsigned int requiredBufferSize = size + offset;
14170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    unsigned int requiredStagingSize = size;
14270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    bool directInitialization = offset == 0 && (!mBuffer || mBufferSize < size + offset);
14370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
14470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (!directInitialization)
14570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
14670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        if (!mStagingBuffer || mStagingBufferSize < requiredStagingSize)
14770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        {
14870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (mStagingBuffer)
14970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
15070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mStagingBuffer->Release();
15170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mStagingBuffer = NULL;
15270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mStagingBufferSize = 0;
15370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
15470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
15570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            D3D11_BUFFER_DESC bufferDesc;
15670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.ByteWidth = size;
15770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.Usage = D3D11_USAGE_STAGING;
15870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.BindFlags = 0;
15970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
16070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.MiscFlags = 0;
16170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            bufferDesc.StructureByteStride = 0;
16270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
16345494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            if (data)
16445494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            {
16545494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                D3D11_SUBRESOURCE_DATA initialData;
16645494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                initialData.pSysMem = data;
16745494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                initialData.SysMemPitch = size;
16845494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                initialData.SysMemSlicePitch = 0;
16945494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang
17045494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                result = device->CreateBuffer(&bufferDesc, &initialData, &mStagingBuffer);
17145494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            }
17245494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            else
17345494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            {
17445494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer);
17545494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            }
17670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
17770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (FAILED(result))
17870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
17970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                return gl::error(GL_OUT_OF_MEMORY);
18070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
18170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
18270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            mStagingBufferSize = size;
18370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        }
18445494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang        else if (data)
18570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        {
18670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            D3D11_MAPPED_SUBRESOURCE mappedResource;
18770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            result = context->Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
18870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (FAILED(result))
18970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
19070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                return gl::error(GL_OUT_OF_MEMORY);
19170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
19270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
19370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            memcpy(mappedResource.pData, data, size);
19470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
19570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            context->Unmap(mStagingBuffer, 0);
19670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        }
19770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
19870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
19970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (!mBuffer || mBufferSize < size + offset)
20070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
20170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        D3D11_BUFFER_DESC bufferDesc;
20270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        bufferDesc.ByteWidth = requiredBufferSize;
20370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        bufferDesc.Usage = D3D11_USAGE_DEFAULT;
20470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
20570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        bufferDesc.CPUAccessFlags = 0;
20670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        bufferDesc.MiscFlags = 0;
20770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        bufferDesc.StructureByteStride = 0;
20870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
20970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        if (directInitialization)
21070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        {
21170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // Since the data will fill the entire buffer (being larger than the initial size and having
21270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // no offset), the buffer can be initialized with the data so no staging buffer is required
21370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
21470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // No longer need the old buffer
21570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (mBuffer)
21670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
21770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mBuffer->Release();
21870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mBuffer = NULL;
21970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mBufferSize = 0;
22070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
22170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
22245494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            if (data)
22345494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            {
22445494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                D3D11_SUBRESOURCE_DATA initialData;
22545494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                initialData.pSysMem = data;
22645494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                initialData.SysMemPitch = size;
22745494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                initialData.SysMemSlicePitch = 0;
22845494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang
22945494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                result = device->CreateBuffer(&bufferDesc, &initialData, &mBuffer);
23045494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            }
23145494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            else
23245494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            {
23345494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang                result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
23445494d463d72c4b6c2b2071c5b361713d2ae0a25Geoff Lang            }
23570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
23670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (FAILED(result))
23770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
23870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                return gl::error(GL_OUT_OF_MEMORY);
23970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
24070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        }
24170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        else if (mBuffer && offset > 0)
24270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        {
24370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // If offset is greater than zero and the buffer is non-null, need to preserve the data from
24470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // the old buffer up to offset
24570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            ID3D11Buffer *newBuffer = NULL;
24670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
24770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
24870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (FAILED(result))
24970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
25070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                return gl::error(GL_OUT_OF_MEMORY);
25170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
25270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
25370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            D3D11_BOX srcBox;
25470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            srcBox.left = 0;
25570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            srcBox.right = std::min(offset, mBufferSize);
25670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            srcBox.top = 0;
25770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            srcBox.bottom = 1;
25870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            srcBox.front = 0;
25970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            srcBox.back = 1;
26070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
26170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox);
26270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
26370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            mBuffer->Release();
26470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            mBuffer = newBuffer;
26570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        }
26670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        else
26770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        {
26870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // Simple case, nothing needs to be copied from the old buffer to the new one, just create
26970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // a new buffer
27070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
27170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // No longer need the old buffer
27270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (mBuffer)
27370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
27470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mBuffer->Release();
27570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mBuffer = NULL;
27670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                mBufferSize = 0;
27770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
27870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
27970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            // Create a new buffer for data storage
28070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
28170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            if (FAILED(result))
28270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            {
28370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com                return gl::error(GL_OUT_OF_MEMORY);
28470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com            }
28570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        }
28670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
28770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        updateSerial();
28870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mBufferSize = bufferDesc.ByteWidth;
28970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
29070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
29170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (!directInitialization)
29270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
29370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        ASSERT(mStagingBuffer && mStagingBufferSize >= requiredStagingSize);
29470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
29570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        // Data is already put into the staging buffer, copy it over to the data buffer
29670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        D3D11_BOX srcBox;
29770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.left = 0;
29870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.right = size;
29970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.top = 0;
30070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.bottom = 1;
30170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.front = 0;
30270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        srcBox.back = 1;
30370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
30470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        context->CopySubresourceRegion(mBuffer, 0, offset, 0, 0, mStagingBuffer, 0, &srcBox);
30570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
30670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
30770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mSize = std::max(mSize, offset + size);
30870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
30970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mWriteUsageCount = 0;
31070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
31170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mResolvedDataValid = false;
31270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
31370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
31470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comvoid BufferStorage11::clear()
31570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
31670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mResolvedDataValid = false;
31770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mSize = 0;
31870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
31970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
32070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comunsigned int BufferStorage11::getSize() const
32170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
32270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    return mSize;
32370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
32470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
32570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.combool BufferStorage11::supportsDirectBinding() const
32670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
32770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    return true;
32870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
32970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
33070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comvoid BufferStorage11::markBufferUsage()
33170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
33270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mReadUsageCount++;
33370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    mWriteUsageCount++;
33470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
33570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    static const unsigned int usageLimit = 5;
33670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
33770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (mReadUsageCount > usageLimit && mResolvedData)
33870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
33970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        free(mResolvedData);
34070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mResolvedData = NULL;
34170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mResolvedDataSize = 0;
34270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mResolvedDataValid = false;
34370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
34470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
34570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    if (mReadUsageCount > usageLimit && mWriteUsageCount > usageLimit && mStagingBuffer)
34670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    {
34770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mStagingBuffer->Release();
34870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mStagingBuffer = NULL;
34970c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com        mStagingBufferSize = 0;
35070c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    }
35170c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
35270c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
35370c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.comID3D11Buffer *BufferStorage11::getBuffer() const
35470c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com{
35570c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com    return mBuffer;
35670c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
35770c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com
35870c856f60cd3a6fc750ab4f1aea406895a6ce175shannon.woods@transgaming.com}
359