blob: a198f45729335135c1483a13290290f63677edff [file] [log] [blame]
// Copyright 2014 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.
// Buffer11.h: Defines the rx::Buffer11 class which implements rx::BufferImpl via rx::BufferD3D.
#include <array>
#include <map>
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/d3d/BufferD3D.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
namespace gl
class FramebufferAttachment;
namespace rx
struct PackPixelsParams;
class Renderer11;
struct SourceIndexData;
struct TranslatedAttribute;
// The order of this enum governs priority of 'getLatestBufferStorage'.
enum BufferUsage
// TODO: possibly share this buffer type with shader storage buffers.
typedef size_t DataRevision;
class Buffer11 : public BufferD3D
Buffer11(const gl::BufferState &state, Renderer11 *renderer);
virtual ~Buffer11();
gl::ErrorOrResult<ID3D11Buffer *> getBuffer(BufferUsage usage);
gl::ErrorOrResult<ID3D11Buffer *> getEmulatedIndexedBuffer(SourceIndexData *indexInfo,
const TranslatedAttribute &attribute,
GLint startVertex);
gl::Error getConstantBufferRange(GLintptr offset,
GLsizeiptr size,
ID3D11Buffer **bufferOut,
UINT *firstConstantOut,
UINT *numConstantsOut);
gl::ErrorOrResult<ID3D11ShaderResourceView *> getSRV(DXGI_FORMAT srvFormat);
bool isMapped() const { return mMappedStorage != nullptr; }
gl::Error packPixels(const gl::FramebufferAttachment &readAttachment,
const PackPixelsParams &params);
size_t getTotalCPUBufferMemoryBytes() const;
// BufferD3D implementation
size_t getSize() const override { return mSize; }
bool supportsDirectBinding() const override;
gl::Error getData(const uint8_t **outData) override;
void initializeStaticData() override;
void invalidateStaticData() override;
// BufferImpl implementation
gl::Error setData(ContextImpl *context,
GLenum target,
const void *data,
size_t size,
GLenum usage) override;
gl::Error setSubData(ContextImpl *context,
GLenum target,
const void *data,
size_t size,
size_t offset) override;
gl::Error copySubData(ContextImpl *contextImpl,
BufferImpl *source,
GLintptr sourceOffset,
GLintptr destOffset,
GLsizeiptr size) override;
gl::Error map(ContextImpl *contextImpl, GLenum access, void **mapPtr) override;
gl::Error mapRange(ContextImpl *contextImpl,
size_t offset,
size_t length,
GLbitfield access,
void **mapPtr) override;
gl::Error unmap(ContextImpl *contextImpl, GLboolean *result) override;
gl::Error markTransformFeedbackUsage() override;
// We use two set of dirty events. Static buffers are marked dirty whenever
// data changes, because they must be re-translated. Direct buffers only need to be
// updated when the underlying ID3D11Buffer pointer changes - hopefully far less often.
OnBufferDataDirtyChannel *getStaticBroadcastChannel();
OnBufferDataDirtyChannel *getDirectBroadcastChannel();
class BufferStorage;
class EmulatedIndexedStorage;
class NativeStorage;
class PackStorage;
class SystemMemoryStorage;
struct ConstantBufferCacheEntry
ConstantBufferCacheEntry() : storage(nullptr), lruCount(0) {}
BufferStorage *storage;
unsigned int lruCount;
void markBufferUsage(BufferUsage usage);
gl::Error garbageCollection(BufferUsage currentUsage);
gl::ErrorOrResult<NativeStorage *> getStagingStorage();
gl::ErrorOrResult<PackStorage *> getPackStorage();
gl::ErrorOrResult<SystemMemoryStorage *> getSystemMemoryStorage();
gl::Error updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize);
gl::ErrorOrResult<BufferStorage *> getBufferStorage(BufferUsage usage);
gl::ErrorOrResult<BufferStorage *> getLatestBufferStorage() const;
gl::ErrorOrResult<BufferStorage *> getConstantBufferRangeStorage(GLintptr offset,
GLsizeiptr size);
BufferStorage *allocateStorage(BufferUsage usage);
void updateDeallocThreshold(BufferUsage usage);
// Free the storage if we decide it isn't being used very often.
gl::Error checkForDeallocation(BufferUsage usage);
// For some cases of uniform buffer storage, we can't deallocate system memory storage.
bool canDeallocateSystemMemory() const;
Renderer11 *mRenderer;
size_t mSize;
BufferStorage *mMappedStorage;
std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages;
// These two arrays are used to track when to free unused storage.
std::array<unsigned int, BUFFER_USAGE_COUNT> mDeallocThresholds;
std::array<unsigned int, BUFFER_USAGE_COUNT> mIdleness;
// Cache of D3D11 constant buffer for specific ranges of buffer data.
// This is used to emulate UBO ranges on 11.0 devices.
// Constant buffers are indexed by there start offset.
typedef std::map<GLintptr /*offset*/, ConstantBufferCacheEntry> ConstantBufferCache;
ConstantBufferCache mConstantBufferRangeStoragesCache;
size_t mConstantBufferStorageAdditionalSize;
unsigned int mMaxConstantBufferLruCount;
OnBufferDataDirtyChannel mStaticBroadcastChannel;
OnBufferDataDirtyChannel mDirectBroadcastChannel;
} // namespace rx