diff options
Diffstat (limited to 'lib/win32/Effects11/d3dxGlobal.cpp')
-rw-r--r-- | lib/win32/Effects11/d3dxGlobal.cpp | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/lib/win32/Effects11/d3dxGlobal.cpp b/lib/win32/Effects11/d3dxGlobal.cpp new file mode 100644 index 0000000000..06cdcf92ed --- /dev/null +++ b/lib/win32/Effects11/d3dxGlobal.cpp @@ -0,0 +1,396 @@ +//-------------------------------------------------------------------------------------- +// File: d3dxGlobal.cpp +// +// Direct3D 11 Effects implementation for helper data structures +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// http://go.microsoft.com/fwlink/p/?LinkId=271568 +//-------------------------------------------------------------------------------------- + +#include "pchfx.h" + +// VS 2010's stdint.h conflicts with intsafe.h +#pragma warning(push) +#pragma warning(disable : 4005) +#include <intsafe.h> +#pragma warning(pop) + +#include <stdio.h> +#include <stdarg.h> + +namespace D3DX11Core +{ + +////////////////////////////////////////////////////////////////////////// +// CMemoryStream - A class to simplify reading binary data +////////////////////////////////////////////////////////////////////////// + +CMemoryStream::CMemoryStream() : m_pData(nullptr), m_cbData(0), m_readPtr(0) +{ +} + +CMemoryStream::~CMemoryStream() +{ +} + +_Use_decl_annotations_ +HRESULT CMemoryStream::SetData(const void *pData, size_t size) +{ + m_pData = (uint8_t*) pData; + m_cbData = size; + m_readPtr = 0; + + return S_OK; +} + +_Use_decl_annotations_ +HRESULT CMemoryStream::ReadAtOffset(size_t offset, size_t size, void **ppData) +{ + if (offset >= m_cbData) + return E_FAIL; + + m_readPtr = offset; + return Read(ppData, size); +} + +_Use_decl_annotations_ +HRESULT CMemoryStream::ReadAtOffset(size_t offset, LPCSTR *ppString) +{ + if (offset >= m_cbData) + return E_FAIL; + + m_readPtr = offset; + return Read(ppString); +} + +_Use_decl_annotations_ +HRESULT CMemoryStream::Read(void **ppData, size_t size) +{ + size_t temp = m_readPtr + size; + + if (temp < m_readPtr || temp > m_cbData) + return E_FAIL; + + *ppData = m_pData + m_readPtr; + m_readPtr = temp; + return S_OK; +} + +_Use_decl_annotations_ +HRESULT CMemoryStream::Read(uint32_t *pDword) +{ + uint32_t *pTempDword; + HRESULT hr; + + hr = Read((void**) &pTempDword, sizeof(uint32_t)); + if (FAILED(hr)) + return E_FAIL; + + *pDword = *pTempDword; + return S_OK; +} + +_Use_decl_annotations_ +HRESULT CMemoryStream::Read(LPCSTR *ppString) +{ + size_t iChar=m_readPtr; + for(; m_pData[iChar]; iChar++) + { + if (iChar > m_cbData) + return E_FAIL; + } + + *ppString = (LPCSTR) (m_pData + m_readPtr); + m_readPtr = iChar; + + return S_OK; +} + +size_t CMemoryStream::GetPosition() +{ + return m_readPtr; +} + +HRESULT CMemoryStream::Seek(_In_ size_t offset) +{ + if (offset > m_cbData) + return E_FAIL; + + m_readPtr = offset; + return S_OK; +} + +} + +////////////////////////////////////////////////////////////////////////// +// CDataBlock - used to dynamically build up the effect file in memory +////////////////////////////////////////////////////////////////////////// + +CDataBlock::CDataBlock() : + m_size(0), + m_maxSize(0), + m_pData(nullptr), + m_pNext(nullptr), + m_IsAligned(false) +{ +} + +CDataBlock::~CDataBlock() +{ + SAFE_DELETE_ARRAY(m_pData); + SAFE_DELETE(m_pNext); +} + +void CDataBlock::EnableAlignment() +{ + m_IsAligned = true; +} + +_Use_decl_annotations_ +HRESULT CDataBlock::AddData(const void *pvNewData, uint32_t bufferSize, CDataBlock **ppBlock) +{ + HRESULT hr = S_OK; + uint32_t bytesToCopy; + const uint8_t *pNewData = (const uint8_t*) pvNewData; + + if (m_maxSize == 0) + { + // This is a brand new DataBlock, fill it up + m_maxSize = std::max<uint32_t>(8192, bufferSize); + + VN( m_pData = new uint8_t[m_maxSize] ); + } + + assert(m_pData == AlignToPowerOf2(m_pData, c_DataAlignment)); + + bytesToCopy = std::min(m_maxSize - m_size, bufferSize); + memcpy(m_pData + m_size, pNewData, bytesToCopy); + pNewData += bytesToCopy; + + if (m_IsAligned) + { + assert(m_size == AlignToPowerOf2(m_size, c_DataAlignment)); + m_size += AlignToPowerOf2(bytesToCopy, c_DataAlignment); + } + else + { + m_size += bytesToCopy; + } + + bufferSize -= bytesToCopy; + *ppBlock = this; + + if (bufferSize != 0) + { + assert(nullptr == m_pNext); // make sure we're not overwriting anything + + // Couldn't fit all data into this block, spill over into next + VN( m_pNext = new CDataBlock() ); + if (m_IsAligned) + { + m_pNext->EnableAlignment(); + } + VH( m_pNext->AddData(pNewData, bufferSize, ppBlock) ); + } + +lExit: + return hr; +} + +_Use_decl_annotations_ +void* CDataBlock::Allocate(uint32_t bufferSize, CDataBlock **ppBlock) +{ + void *pRetValue; + uint32_t temp = m_size + bufferSize; + + if (temp < m_size) + return nullptr; + + *ppBlock = this; + + if (m_maxSize == 0) + { + // This is a brand new DataBlock, fill it up + m_maxSize = std::max<uint32_t>(8192, bufferSize); + + m_pData = new uint8_t[m_maxSize]; + if (!m_pData) + return nullptr; + memset(m_pData, 0xDD, m_maxSize); + } + else if (temp > m_maxSize) + { + assert(nullptr == m_pNext); // make sure we're not overwriting anything + + // Couldn't fit data into this block, spill over into next + m_pNext = new CDataBlock(); + if (!m_pNext) + return nullptr; + if (m_IsAligned) + { + m_pNext->EnableAlignment(); + } + + return m_pNext->Allocate(bufferSize, ppBlock); + } + + assert(m_pData == AlignToPowerOf2(m_pData, c_DataAlignment)); + + pRetValue = m_pData + m_size; + if (m_IsAligned) + { + assert(m_size == AlignToPowerOf2(m_size, c_DataAlignment)); + m_size = AlignToPowerOf2(temp, c_DataAlignment); + } + else + { + m_size = temp; + } + + return pRetValue; +} + + +////////////////////////////////////////////////////////////////////////// + +CDataBlockStore::CDataBlockStore() : + m_pFirst(nullptr), + m_pLast(nullptr), + m_Size(0), + m_Offset(0), + m_IsAligned(false) +{ +#if _DEBUG + m_cAllocations = 0; +#endif +} + +CDataBlockStore::~CDataBlockStore() +{ + // Can't just do SAFE_DELETE(m_pFirst) since it blows the stack when deleting long chains of data + CDataBlock* pData = m_pFirst; + while(pData) + { + CDataBlock* pCurrent = pData; + pData = pData->m_pNext; + pCurrent->m_pNext = nullptr; + delete pCurrent; + } + + // m_pLast will be deleted automatically +} + +void CDataBlockStore::EnableAlignment() +{ + m_IsAligned = true; +} + +_Use_decl_annotations_ +HRESULT CDataBlockStore::AddString(LPCSTR pString, uint32_t *pOffset) +{ + size_t strSize = strlen(pString) + 1; + assert( strSize <= 0xffffffff ); + return AddData(pString, (uint32_t)strSize, pOffset); +} + +_Use_decl_annotations_ +HRESULT CDataBlockStore::AddData(const void *pNewData, uint32_t bufferSize, uint32_t *pCurOffset) +{ + HRESULT hr = S_OK; + + if (bufferSize == 0) + { + if (pCurOffset) + { + *pCurOffset = 0; + } + goto lExit; + } + + if (!m_pFirst) + { + VN( m_pFirst = new CDataBlock() ); + if (m_IsAligned) + { + m_pFirst->EnableAlignment(); + } + m_pLast = m_pFirst; + } + + if (pCurOffset) + *pCurOffset = m_Size + m_Offset; + + VH( m_pLast->AddData(pNewData, bufferSize, &m_pLast) ); + m_Size += bufferSize; + +lExit: + return hr; +} + +void* CDataBlockStore::Allocate(_In_ uint32_t bufferSize) +{ + void *pRetValue = nullptr; + +#if _DEBUG + m_cAllocations++; +#endif + + if (!m_pFirst) + { + m_pFirst = new CDataBlock(); + if (!m_pFirst) + return nullptr; + + if (m_IsAligned) + { + m_pFirst->EnableAlignment(); + } + m_pLast = m_pFirst; + } + + if (FAILED(UIntAdd(m_Size, bufferSize, &m_Size))) + return nullptr; + + pRetValue = m_pLast->Allocate(bufferSize, &m_pLast); + if (!pRetValue) + return nullptr; + + return pRetValue; +} + +uint32_t CDataBlockStore::GetSize() +{ + return m_Size; +} + + +////////////////////////////////////////////////////////////////////////// + +#ifdef _DEBUG +_Use_decl_annotations_ +void __cdecl D3DXDebugPrintf(UINT lvl, LPCSTR szFormat, ...) +{ + UNREFERENCED_PARAMETER(lvl); + + char strA[4096]; + char strB[4096]; + + va_list ap; + va_start(ap, szFormat); + vsprintf_s(strA, sizeof(strA), szFormat, ap); + strA[4095] = '\0'; + va_end(ap); + + sprintf_s(strB, sizeof(strB), "Effects11: %s\r\n", strA); + + strB[4095] = '\0'; + + OutputDebugStringA(strB); +} +#endif // _DEBUG |