#pragma once // CPU-memory vertex/index buffers behind the D3D8 buffer handles. 40250 fills its buffers through // Lock/Unlock (CGrannyModel::__LoadVertices, CGrannyModelInstance deform) and the renderer later reads // them back, so the platform keeps the bytes in memory instead of creating device objects. #include "EterLib/StdAfx.h" #include #include #include inline std::atomic mt_next_cpu_buffer_id{1}; struct MtCpuVertexBuffer : IDirect3DVertexBuffer8 { const std::uint64_t id = mt_next_cpu_buffer_id.fetch_add(1, std::memory_order_relaxed); std::uint64_t revision = 0; std::vector bytes; DWORD fvf = 0; HRESULT Lock(UINT offset, UINT size, BYTE** data, DWORD) override { if (size_t(offset) + size > bytes.size()) return E_FAIL; *data = bytes.data() + offset; return S_OK; } HRESULT Unlock() override { ++revision; return S_OK; } }; struct MtCpuIndexBuffer : IDirect3DIndexBuffer8 { const std::uint64_t id = mt_next_cpu_buffer_id.fetch_add(1, std::memory_order_relaxed); std::uint64_t revision = 0; std::vector bytes; D3DFORMAT format = D3DFMT_INDEX16; HRESULT Lock(UINT offset, UINT size, BYTE** data, DWORD) override { if (size_t(offset) + size > bytes.size()) return E_FAIL; *data = bytes.data() + offset; return S_OK; } HRESULT Unlock() override { ++revision; return S_OK; } }; // D3DXGetFVFVertexSize. inline unsigned mt_fvf_vertex_size(DWORD fvf) { unsigned size = 0; switch (fvf & D3DFVF_POSITION_MASK) { case D3DFVF_XYZ: size += 12; break; case D3DFVF_XYZRHW: size += 16; break; case D3DFVF_XYZB1: size += 16; break; case D3DFVF_XYZB2: size += 20; break; case D3DFVF_XYZB3: size += 24; break; case D3DFVF_XYZB4: size += 28; break; case D3DFVF_XYZB5: size += 32; break; } if (fvf & D3DFVF_NORMAL) size += 12; if (fvf & D3DFVF_PSIZE) size += 4; if (fvf & D3DFVF_DIFFUSE) size += 4; if (fvf & D3DFVF_SPECULAR) size += 4; const unsigned texCount = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; for (unsigned i = 0; i < texCount; ++i) { static const unsigned coordSize[4] = { 8, 12, 16, 4 }; size += coordSize[(fvf >> (16 + i * 2)) & 3]; } return size; }