blob: 14cdacced6e76fc61f9f84f6804dbe5740b62ee4 [file] [log] [blame]
//
// Copyright 2002 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.
//
// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
namespace rx
{
IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
{
mIndexBuffer = nullptr;
mBufferSize = 0;
mIndexType = gl::DrawElementsType::InvalidEnum;
mDynamic = false;
}
IndexBuffer9::~IndexBuffer9()
{
SafeRelease(mIndexBuffer);
}
angle::Result IndexBuffer9::initialize(const gl::Context *context,
unsigned int bufferSize,
gl::DrawElementsType indexType,
bool dynamic)
{
SafeRelease(mIndexBuffer);
updateSerial();
if (bufferSize > 0)
{
D3DFORMAT format = D3DFMT_UNKNOWN;
if (indexType == gl::DrawElementsType::UnsignedShort ||
indexType == gl::DrawElementsType::UnsignedByte)
{
format = D3DFMT_INDEX16;
}
else if (indexType == gl::DrawElementsType::UnsignedInt)
{
ASSERT(mRenderer->getNativeExtensions().elementIndexUint);
format = D3DFMT_INDEX32;
}
else
UNREACHABLE();
DWORD usageFlags = D3DUSAGE_WRITEONLY;
if (dynamic)
{
usageFlags |= D3DUSAGE_DYNAMIC;
}
HRESULT result =
mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
ANGLE_TRY_HR(GetImplAs<Context9>(context), result,
"Failed to allocate internal index buffer");
}
mBufferSize = bufferSize;
mIndexType = indexType;
mDynamic = dynamic;
return angle::Result::Continue;
}
angle::Result IndexBuffer9::mapBuffer(const gl::Context *context,
unsigned int offset,
unsigned int size,
void **outMappedMemory)
{
ASSERT(mIndexBuffer);
DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
void *mapPtr = nullptr;
HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to lock internal index buffer");
*outMappedMemory = mapPtr;
return angle::Result::Continue;
}
angle::Result IndexBuffer9::unmapBuffer(const gl::Context *context)
{
ASSERT(mIndexBuffer);
HRESULT result = mIndexBuffer->Unlock();
ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to unlock internal index buffer");
return angle::Result::Continue;
}
gl::DrawElementsType IndexBuffer9::getIndexType() const
{
return mIndexType;
}
unsigned int IndexBuffer9::getBufferSize() const
{
return mBufferSize;
}
angle::Result IndexBuffer9::setSize(const gl::Context *context,
unsigned int bufferSize,
gl::DrawElementsType indexType)
{
if (bufferSize > mBufferSize || indexType != mIndexType)
{
return initialize(context, bufferSize, indexType, mDynamic);
}
return angle::Result::Continue;
}
angle::Result IndexBuffer9::discard(const gl::Context *context)
{
ASSERT(mIndexBuffer);
void *dummy;
HRESULT result;
Context9 *context9 = GetImplAs<Context9>(context);
result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
ANGLE_TRY_HR(context9, result, "Failed to lock internal index buffer");
result = mIndexBuffer->Unlock();
ANGLE_TRY_HR(context9, result, "Failed to unlock internal index buffer");
return angle::Result::Continue;
}
D3DFORMAT IndexBuffer9::getIndexFormat() const
{
switch (mIndexType)
{
case gl::DrawElementsType::UnsignedByte:
return D3DFMT_INDEX16;
case gl::DrawElementsType::UnsignedShort:
return D3DFMT_INDEX16;
case gl::DrawElementsType::UnsignedInt:
return D3DFMT_INDEX32;
default:
UNREACHABLE();
return D3DFMT_UNKNOWN;
}
}
IDirect3DIndexBuffer9 *IndexBuffer9::getBuffer() const
{
return mIndexBuffer;
}
} // namespace rx