blob: 83e8dfacecd5fb1e56c2baacde088577e04fb1f6 [file] [log] [blame]
// Copyright (c) 2015 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.
// StateManager11.h: Defines a class for caching D3D11 state
#include <array>
#include "libANGLE/angletypes.h"
#include "libANGLE/ContextState.h"
#include "libANGLE/State.h"
#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/Query11.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace rx
struct RenderTargetDesc;
struct Renderer11DeviceCaps;
struct dx_VertexConstants11
float depthRange[4];
float viewAdjust[4];
float viewCoords[4];
float viewScale[4];
struct dx_PixelConstants11
float depthRange[4];
float viewCoords[4];
float depthFront[4];
float viewScale[4];
struct dx_ComputeConstants11
unsigned int numWorkGroups[3];
unsigned int padding; // This just pads the struct to 16 bytes
class StateManager11 final : angle::NonCopyable
StateManager11(Renderer11 *renderer);
void initialize(const gl::Caps &caps);
void deinitialize();
void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
gl::Error setBlendState(const gl::Framebuffer *framebuffer,
const gl::BlendState &blendState,
const gl::ColorF &blendColor,
unsigned int sampleMask);
gl::Error setDepthStencilState(const gl::State &glState);
gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
void setViewport(const gl::Caps *caps, const gl::Rectangle &viewport, float zNear, float zFar);
void updatePresentPath(bool presentPathFastActive,
const gl::FramebufferAttachment *framebufferAttachment);
const dx_VertexConstants11 &getVertexConstants() const { return mVertexConstants; }
const dx_PixelConstants11 &getPixelConstants() const { return mPixelConstants; }
const dx_ComputeConstants11 &getComputeConstants() const { return mComputeConstants; }
void setComputeConstants(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
void setShaderResource(gl::SamplerType shaderType,
UINT resourceSlot,
ID3D11ShaderResourceView *srv);
gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd);
gl::Error syncFramebuffer(ContextImpl *contextImpl, gl::Framebuffer *framebuffer);
void invalidateRenderTarget();
void invalidateBoundViews();
void invalidateEverything();
void setOneTimeRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
void setOneTimeRenderTargets(ID3D11RenderTargetView **rtvs,
UINT numRtvs,
ID3D11DepthStencilView *dsv);
void onBeginQuery(Query11 *query);
void onDeleteQueryObject(Query11 *query);
gl::Error onMakeCurrent(const gl::ContextState &data);
gl::Error updateCurrentValueAttribs(const gl::State &state,
VertexDataManager *vertexDataManager);
const std::vector<TranslatedAttribute> &getCurrentValueAttribs() const;
void setViewportBounds(const int width, const int height);
void unsetConflictingSRVs(gl::SamplerType shaderType,
uintptr_t resource,
const gl::ImageIndex &index);
void unsetConflictingAttachmentResources(const gl::FramebufferAttachment *attachment,
ID3D11Resource *resource);
Renderer11 *mRenderer;
// Blend State
bool mBlendStateIsDirty;
// TODO(dianx) temporary representation of a dirty bit. once we move enough states in,
// try experimenting with dirty bit instead of a bool
gl::BlendState mCurBlendState;
gl::ColorF mCurBlendColor;
unsigned int mCurSampleMask;
// Currently applied depth stencil state
bool mDepthStencilStateIsDirty;
gl::DepthStencilState mCurDepthStencilState;
int mCurStencilRef;
int mCurStencilBackRef;
unsigned int mCurStencilSize;
Optional<bool> mCurDisableDepth;
Optional<bool> mCurDisableStencil;
// Currently applied rasterizer state
bool mRasterizerStateIsDirty;
gl::RasterizerState mCurRasterState;
// Currently applied scissor rectangle state
bool mScissorStateIsDirty;
bool mCurScissorEnabled;
gl::Rectangle mCurScissorRect;
// Currently applied viewport state
bool mViewportStateIsDirty;
gl::Rectangle mCurViewport;
float mCurNear;
float mCurFar;
// Things needed in viewport state
dx_VertexConstants11 mVertexConstants;
dx_PixelConstants11 mPixelConstants;
dx_ComputeConstants11 mComputeConstants;
// Render target variables
gl::Extents mViewportBounds;
// EGL_ANGLE_experimental_present_path variables
bool mCurPresentPathFastEnabled;
int mCurPresentPathFastColorBufferHeight;
// Current RenderTarget state
bool mRenderTargetIsDirty;
// Queries that are currently active in this state
std::set<Query11 *> mCurrentQueries;
// Currently applied textures
struct SRVRecord
uintptr_t srv;
uintptr_t resource;
// A cache of current SRVs that also tracks the highest 'used' (non-NULL) SRV
// We might want to investigate a more robust approach that is also fast when there's
// a large gap between used SRVs (e.g. if SRV 0 and 7 are non-NULL, this approach will
// waste time on SRVs 1-6.)
class SRVCache : angle::NonCopyable
SRVCache() : mHighestUsedSRV(0) {}
void initialize(size_t size) { mCurrentSRVs.resize(size); }
size_t size() const { return mCurrentSRVs.size(); }
size_t highestUsed() const { return mHighestUsedSRV; }
const SRVRecord &operator[](size_t index) const { return mCurrentSRVs[index]; }
void clear();
void update(size_t resourceIndex, ID3D11ShaderResourceView *srv);
std::vector<SRVRecord> mCurrentSRVs;
size_t mHighestUsedSRV;
SRVCache mCurVertexSRVs;
SRVCache mCurPixelSRVs;
// A block of NULL pointers, cached so we don't re-allocate every draw call
std::vector<ID3D11ShaderResourceView *> mNullSRVs;
// Current translations of "Current-Value" data - owned by Context, not VertexArray.
gl::AttributesMask mDirtyCurrentValueAttribs;
std::vector<TranslatedAttribute> mCurrentValueAttribs;
} // namespace rx