You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/RenderDll/XRenderD3D9/DeviceManager/TempDynBuffer.h

378 lines
11 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_DEVICEMANAGER_TEMPDYNBUFFER_H
#define CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_DEVICEMANAGER_TEMPDYNBUFFER_H
#pragma once
#include <RenderDll/Common/DevBuffer.h>
namespace TempDynBuffer
{
enum State
{
Default,
Allocated,
Locked,
Filled
};
struct ValidatorNull
{
void Check(State) {}
void Check2(State, State) {}
void Set(State) {}
};
struct ValidatorDbgBreak
{
ValidatorDbgBreak()
: m_state(Default) {}
void Check(State expectedState)
{
if (m_state != expectedState)
{
__debugbreak();
}
}
void Check2(State expectedState0, State expectedState1)
{
if (m_state != expectedState0 && m_state != expectedState1)
{
__debugbreak();
}
}
void Set(State newState)
{
m_state = newState;
}
State m_state;
};
#if !defined(_RELEASE)
typedef ValidatorDbgBreak ValidatorDefault;
#else
typedef ValidatorNull ValidatorDefault;
#endif
//////////////////////////////////////////////////////////////////////////
template<typename T, BUFFER_BIND_TYPE bindType, class Validator>
class TempDynBufferBase
{
public:
static const buffer_handle_t invalidHandle = ~0u;
protected:
TempDynBufferBase(IRenderer* renderer)
: m_handle(invalidHandle)
, m_renderer(renderer)
, m_numElements(0)
, m_DevBufMan(renderer->GetDeviceBufferManager())
, m_validator() {}
~TempDynBufferBase() { m_validator.Check(Default); }
void Allocate(size_t numElements) { AllocateInternal(numElements, sizeof(T)); }
bool IsAllocated() const { return m_handle != invalidHandle; }
void Release();
void Update(const T* pData) { UpdateInternal(pData, sizeof(T)); }
T* Lock();
void Unlock();
protected:
void AllocateInternal(size_t numElements, size_t elementSize);
void UpdateInternal(const void* pData, size_t elementSize);
protected:
IRenderer* m_renderer;
size_t m_handle;
size_t m_numElements;
CGuardedDeviceBufferManager m_DevBufMan;
Validator m_validator;
};
template<typename T, BUFFER_BIND_TYPE bindType, class Validator>
void TempDynBufferBase<T, bindType, Validator>::AllocateInternal(size_t numElements, size_t elementSize)
{
m_validator.Check(Default);
BUFFER_USAGE usageType = m_renderer->IsVideoThreadModeEnabled()
? BU_WHEN_LOADINGTHREAD_ACTIVE // use a separate pool for everything in video rendering mode
: BU_TRANSIENT_RT; // default to transient_RT
m_handle = m_DevBufMan.Create(bindType, usageType, numElements * elementSize);
IF (m_handle != invalidHandle, 1)
{
m_numElements = numElements;
m_validator.Set(Allocated);
}
}
template<typename T, BUFFER_BIND_TYPE bindType, class Validator>
void TempDynBufferBase<T, bindType, Validator>::Release()
{
IF (m_handle != invalidHandle, 1)
{
m_validator.Check2(Allocated, Filled);
m_DevBufMan.Destroy(m_handle);
m_handle = invalidHandle;
m_numElements = 0;
}
m_validator.Set(Default);
}
template<typename T, BUFFER_BIND_TYPE bindType, class Validator>
void TempDynBufferBase<T, bindType, Validator>::UpdateInternal(const void* pData, size_t elementSize)
{
m_validator.Check(Allocated);
m_DevBufMan.UpdateBuffer(m_handle, pData, m_numElements * elementSize);
m_validator.Set(Filled);
}
template<typename T, BUFFER_BIND_TYPE bindType, class Validator>
T* TempDynBufferBase<T, bindType, Validator>::Lock()
{
m_validator.Check(Allocated);
T* p = (T*) m_DevBufMan.BeginWrite(m_handle);
m_validator.Set(Locked);
return p;
}
template<typename T, BUFFER_BIND_TYPE bindType, class Validator>
void TempDynBufferBase<T, bindType, Validator>::Unlock()
{
m_validator.Check(Locked);
m_DevBufMan.EndReadWrite(m_handle);
m_validator.Set(Filled);
}
//////////////////////////////////////////////////////////////////////////
template<typename T, class Validator = ValidatorDefault>
class TempDynVBBase
: public TempDynBufferBase<T, BBT_VERTEX_BUFFER, Validator>
{
public:
typedef TempDynBufferBase<T, BBT_VERTEX_BUFFER, Validator> Base;
public:
using Base::IsAllocated;
using Base::Release;
using Base::Update;
using Base::Lock;
using Base::Unlock;
protected:
TempDynVBBase(IRenderer* renderer)
: TempDynBufferBase<T, BBT_VERTEX_BUFFER, Validator>(renderer),
m_renderer(renderer){}
~TempDynVBBase() {}
void BindInternal(uint32 streamID, size_t stride);
protected:
IRenderer* m_renderer = nullptr;
using Base::m_handle;
using Base::m_validator;
};
template<typename T, class Validator>
void TempDynVBBase<T, Validator>::BindInternal(uint32 streamID, size_t stride)
{
m_validator.Check(Filled);
size_t bufferOffset = ~0;
D3DBuffer* pVB = this->m_DevBufMan.GetD3D(m_handle, &bufferOffset);
m_renderer->FX_SetVStream(streamID, pVB, bufferOffset, stride);
}
//////////////////////////////////////////////////////////////////////////
template<typename T, class Validator = ValidatorDefault>
class TempDynVB
: public TempDynVBBase<T, Validator>
{
friend class TempDynVBAny;
public:
typedef TempDynVBBase<T, Validator> Base;
public:
static void CreateFillAndBind(const T* pData, size_t numElements, uint32 streamID) { CreateFillAndBindInternal(pData, numElements, streamID, sizeof(T)); }
public:
TempDynVB(IRenderer* renderer)
: TempDynVBBase<T, Validator>(renderer)
, m_renderer(renderer){}
using Base::Allocate;
void Bind(uint32 streamID) { BindInternal(streamID, sizeof(T)); }
protected:
static void CreateFillAndBindInternal(const void* pData, size_t numElements, uint32 streamID, size_t stride);
protected:
IRenderer* m_renderer = nullptr;
using Base::BindInternal;
protected:
TempDynVB(const TempDynVB&);
TempDynVB& operator=(const TempDynVB&);
};
template<typename T, class Validator>
void TempDynVB<T, Validator>::CreateFillAndBindInternal(const void* pData, size_t numElements, uint32 streamID, size_t stride)
{
TempDynVB<T, Validator> vb(gRenDev);
vb.AllocateInternal(numElements, stride);
vb.UpdateInternal(pData, stride);
vb.BindInternal(streamID, stride);
vb.Release();
}
//////////////////////////////////////////////////////////////////////////
template<class Validator = ValidatorDefault>
class TempDynInstVB
: public TempDynVBBase<void, Validator>
{
public:
typedef TempDynVBBase<void, Validator> Base;
public:
TempDynInstVB(IRenderer* renderer)
: TempDynVBBase<void, Validator>(renderer),
m_renderer(renderer)
{}
void Allocate(size_t numElements, size_t elementSize) { AllocateInternal(numElements, elementSize); }
void Bind(uint32 streamID, uint32 stride) { BindInternal(streamID, stride); }
protected:
using Base::AllocateInternal;
using Base::BindInternal;
protected:
IRenderer* m_renderer = nullptr;
TempDynInstVB(const TempDynInstVB&);
TempDynInstVB& operator=(const TempDynInstVB&);
};
//////////////////////////////////////////////////////////////////////////
class TempDynVBAny
{
public:
static void CreateFillAndBind(const void* pData, size_t numElements, uint32 streamID, size_t stride) { TempDynVB<void>::CreateFillAndBindInternal(pData, numElements, streamID, stride); }
private:
IRenderer* m_renderer = nullptr;
TempDynVBAny(IRenderer* renderer);
};
//////////////////////////////////////////////////////////////////////////
template <RenderIndexType idxType>
struct MapIndexType {};
template <>
struct MapIndexType<Index16>
{
typedef uint16 Type;
enum
{
Size = sizeof(Type)
};
};
template <>
struct MapIndexType<Index32>
{
typedef uint32 Type;
enum
{
Size = sizeof(Type)
};
};
template<RenderIndexType idxType, class Validator = ValidatorDefault>
class TempDynIB
: public TempDynBufferBase<typename MapIndexType<idxType>::Type, BBT_INDEX_BUFFER, Validator>
{
public:
typedef typename MapIndexType<idxType>::Type IndexDataType;
typedef TempDynBufferBase<IndexDataType, BBT_INDEX_BUFFER, Validator> Base;
public:
static void CreateFillAndBind(const IndexDataType* pData, size_t numElements);
public:
TempDynIB(IRenderer* renderer)
: TempDynBufferBase<IndexDataType, BBT_INDEX_BUFFER, Validator>(renderer),
m_renderer(renderer)
{}
void Allocate(size_t numElements);
using Base::IsAllocated;
using Base::Release;
using Base::Update;
using Base::Lock;
using Base::Unlock;
void Bind();
protected:
IRenderer* m_renderer = nullptr;
TempDynIB(const TempDynIB&);
TempDynIB& operator=(const TempDynIB&);
protected:
using Base::m_handle;
using Base::m_validator;
};
template<RenderIndexType idxType, class Validator>
void TempDynIB<idxType, Validator>::Allocate(size_t numElements)
{
Base::Allocate(numElements);
}
template<RenderIndexType idxType, class Validator>
void TempDynIB<idxType, Validator>::Bind()
{
m_validator.Check(Filled);
size_t bufferOffset = ~0;
D3DBuffer* pIB = this->m_DevBufMan.GetD3D(m_handle, &bufferOffset);
m_renderer->FX_SetIStream(pIB, bufferOffset, idxType);
}
template<RenderIndexType idxType, class Validator>
void TempDynIB<idxType, Validator>::CreateFillAndBind(const IndexDataType* pData, size_t numElements)
{
TempDynIB<idxType, Validator> ib(gcpRendD3D);
ib.Allocate(numElements);
ib.Update(pData);
ib.Bind();
ib.Release();
}
} // namespace TempDynBuffer
using TempDynBuffer::TempDynVB;
using TempDynBuffer::TempDynVBAny;
typedef TempDynBuffer::TempDynInstVB<> TempDynInstVB;
typedef TempDynBuffer::TempDynIB<Index16> TempDynIB16;
typedef TempDynBuffer::TempDynIB<Index32> TempDynIB32;
#endif // CRYINCLUDE_CRYENGINE_RENDERDLL_XRENDERD3D9_DEVICEMANAGER_TEMPDYNBUFFER_H