Commit 86a07aec by Jamie Madill

Add LazyInputLayout to defer loading input layouts.

Lazily loading input layouts can also save memory and startup time. There are several cases where we don't need these resources until later, or sometimes, at all. BUG=angleproject:1014 Change-Id: I4e0d45353b5d3969bd1ed86ad26f47d34e542ed5 Reviewed-on: https://chromium-review.googlesource.com/282551Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org>
parent 531d5f45
...@@ -83,8 +83,6 @@ class Blit11 : angle::NonCopyable ...@@ -83,8 +83,6 @@ class Blit11 : angle::NonCopyable
BLITSHADER_3D_LUMAALPHA, BLITSHADER_3D_LUMAALPHA,
}; };
static BlitShaderType GetBlitShaderType(GLenum destinationFormat, bool isSigned, bool is3D);
enum SwizzleShaderType enum SwizzleShaderType
{ {
SWIZZLESHADER_INVALID, SWIZZLESHADER_INVALID,
...@@ -102,47 +100,48 @@ class Blit11 : angle::NonCopyable ...@@ -102,47 +100,48 @@ class Blit11 : angle::NonCopyable
SWIZZLESHADER_ARRAY_INT, SWIZZLESHADER_ARRAY_INT,
}; };
static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality);
gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor, bool stencilOnly);
typedef void (*WriteVertexFunction)(const gl::Box &sourceArea, const gl::Extents &sourceSize, typedef void (*WriteVertexFunction)(const gl::Box &sourceArea, const gl::Extents &sourceSize,
const gl::Box &destArea, const gl::Extents &destSize, const gl::Box &destArea, const gl::Extents &destSize,
void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, void *outVertices, unsigned int *outStride, unsigned int *outVertexCount,
D3D11_PRIMITIVE_TOPOLOGY *outTopology); D3D11_PRIMITIVE_TOPOLOGY *outTopology);
enum ShaderDimension
{
SHADER_2D,
SHADER_3D,
};
struct Shader struct Shader
{ {
WriteVertexFunction mVertexWriteFunction; ShaderDimension dimension;
ID3D11InputLayout *mInputLayout; ID3D11PixelShader *pixelShader;
ID3D11VertexShader *mVertexShader;
ID3D11GeometryShader *mGeometryShader;
ID3D11PixelShader *mPixelShader;
}; };
struct CommonShaders struct ShaderSupport
{ {
ID3D11VertexShader *vertexShader2D; ID3D11InputLayout *inputLayout;
ID3D11VertexShader *vertexShader3D; ID3D11VertexShader *vertexShader;
ID3D11GeometryShader *geometryShader3D; ID3D11GeometryShader *geometryShader;
WriteVertexFunction vertexWriteFunction;
}; };
void add2DBlitShaderToMap(BlitShaderType blitShaderType, const CommonShaders &commonShaders, ID3D11PixelShader *ps); ShaderSupport getShaderSupport(const Shader &shader);
void add3DBlitShaderToMap(BlitShaderType blitShaderType, const CommonShaders &commonShaders, ID3D11PixelShader *ps);
gl::Error getBlitShader(GLenum destFormat, bool isSigned, bool is3D, const Shader **shaderOut); static BlitShaderType GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension);
gl::Error getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shaderOut); static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality);
void addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, bool is2D, const CommonShaders &commonShaders, ID3D11PixelShader *ps); gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor, bool stencilOnly);
void clearShaderMap(); void addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps);
gl::Error getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shaderOut);
gl::Error getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shaderOut);
gl::Error getCommonShaders(CommonShaders *commonShadersOut, bool get3D); void addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps);
ID3D11InputLayout *getQuad2DIL(); void clearShaderMap();
ID3D11InputLayout *getQuad3DIL();
Renderer11 *mRenderer; Renderer11 *mRenderer;
...@@ -156,11 +155,11 @@ class Blit11 : angle::NonCopyable ...@@ -156,11 +155,11 @@ class Blit11 : angle::NonCopyable
ID3D11RasterizerState *mScissorDisabledRasterizerState; ID3D11RasterizerState *mScissorDisabledRasterizerState;
ID3D11DepthStencilState *mDepthStencilState; ID3D11DepthStencilState *mDepthStencilState;
ID3D11InputLayout *mQuad2DIL; d3d11::LazyInputLayout mQuad2DIL;
d3d11::LazyShader<ID3D11VertexShader> mQuad2DVS; d3d11::LazyShader<ID3D11VertexShader> mQuad2DVS;
d3d11::LazyShader<ID3D11PixelShader> mDepthPS; d3d11::LazyShader<ID3D11PixelShader> mDepthPS;
ID3D11InputLayout *mQuad3DIL; d3d11::LazyInputLayout mQuad3DIL;
d3d11::LazyShader<ID3D11VertexShader> mQuad3DVS; d3d11::LazyShader<ID3D11VertexShader> mQuad3DVS;
d3d11::LazyShader<ID3D11GeometryShader> mQuad3DGS; d3d11::LazyShader<ID3D11GeometryShader> mQuad3DGS;
......
...@@ -192,8 +192,32 @@ ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], co ...@@ -192,8 +192,32 @@ ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], co
return CompilePS(device, byteCode, N, name); return CompilePS(device, byteCode, N, name);
} }
template <typename ResourceType>
class LazyResource : public angle::NonCopyable
{
public:
LazyResource() : mResource(nullptr), mAssociatedDevice(nullptr) {}
virtual ~LazyResource() { release(); }
virtual ResourceType *resolve(ID3D11Device *device) = 0;
void release() { SafeRelease(mResource); }
protected:
void checkAssociatedDevice(ID3D11Device *device);
ResourceType *mResource;
ID3D11Device *mAssociatedDevice;
};
template <typename ResourceType>
void LazyResource<ResourceType>::checkAssociatedDevice(ID3D11Device *device)
{
ASSERT(mAssociatedDevice == nullptr || device == mAssociatedDevice);
mAssociatedDevice = device;
}
template <typename D3D11ShaderType> template <typename D3D11ShaderType>
class LazyShader final : public angle::NonCopyable class LazyShader final : public LazyResource<D3D11ShaderType>
{ {
public: public:
// All parameters must be constexpr. Not supported in VS2013. // All parameters must be constexpr. Not supported in VS2013.
...@@ -202,65 +226,97 @@ class LazyShader final : public angle::NonCopyable ...@@ -202,65 +226,97 @@ class LazyShader final : public angle::NonCopyable
const char *name) const char *name)
: mByteCode(byteCode), : mByteCode(byteCode),
mByteCodeSize(byteCodeSize), mByteCodeSize(byteCodeSize),
mName(name), mName(name)
mShader(nullptr),
mAssociatedDevice(nullptr)
{ {
} }
~LazyShader() { release(); } D3D11ShaderType *resolve(ID3D11Device *device) override;
D3D11ShaderType *resolve(ID3D11Device *device);
void release() { SafeRelease(mShader); }
private: private:
void checkAssociatedDevice(ID3D11Device *device);
const BYTE *mByteCode; const BYTE *mByteCode;
size_t mByteCodeSize; size_t mByteCodeSize;
const char *mName; const char *mName;
D3D11ShaderType *mShader;
ID3D11Device *mAssociatedDevice;
}; };
template <typename D3D11ShaderType>
void LazyShader<D3D11ShaderType>::checkAssociatedDevice(ID3D11Device *device)
{
ASSERT(mAssociatedDevice == nullptr || device == mAssociatedDevice);
mAssociatedDevice = device;
}
template <> template <>
inline ID3D11VertexShader *LazyShader<ID3D11VertexShader>::resolve(ID3D11Device *device) inline ID3D11VertexShader *LazyShader<ID3D11VertexShader>::resolve(ID3D11Device *device)
{ {
checkAssociatedDevice(device); checkAssociatedDevice(device);
if (mShader == nullptr) if (mResource == nullptr)
{ {
mShader = CompileVS(device, mByteCode, mByteCodeSize, mName); mResource = CompileVS(device, mByteCode, mByteCodeSize, mName);
} }
return mShader; return mResource;
} }
template <> template <>
inline ID3D11GeometryShader *LazyShader<ID3D11GeometryShader>::resolve(ID3D11Device *device) inline ID3D11GeometryShader *LazyShader<ID3D11GeometryShader>::resolve(ID3D11Device *device)
{ {
checkAssociatedDevice(device); checkAssociatedDevice(device);
if (mShader == nullptr) if (mResource == nullptr)
{ {
mShader = CompileGS(device, mByteCode, mByteCodeSize, mName); mResource = CompileGS(device, mByteCode, mByteCodeSize, mName);
} }
return mShader; return mResource;
} }
template <> template <>
inline ID3D11PixelShader *LazyShader<ID3D11PixelShader>::resolve(ID3D11Device *device) inline ID3D11PixelShader *LazyShader<ID3D11PixelShader>::resolve(ID3D11Device *device)
{ {
checkAssociatedDevice(device); checkAssociatedDevice(device);
if (mShader == nullptr) if (mResource == nullptr)
{ {
mShader = CompilePS(device, mByteCode, mByteCodeSize, mName); mResource = CompilePS(device, mByteCode, mByteCodeSize, mName);
} }
return mShader; return mResource;
}
class LazyInputLayout final : public LazyResource<ID3D11InputLayout>
{
public:
LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
size_t inputDescLen,
const BYTE *byteCode,
size_t byteCodeLen,
const char *debugName);
ID3D11InputLayout *resolve(ID3D11Device *device) override;
private:
std::vector<D3D11_INPUT_ELEMENT_DESC> mInputDesc;
size_t mByteCodeLen;
const BYTE *mByteCode;
const char *mDebugName;
};
inline LazyInputLayout::LazyInputLayout(
const D3D11_INPUT_ELEMENT_DESC *inputDesc,
size_t inputDescLen,
const BYTE *byteCode,
size_t byteCodeLen,
const char *debugName)
: mInputDesc(inputDescLen),
mByteCodeLen(byteCodeLen),
mByteCode(byteCode),
mDebugName(debugName)
{
memcpy(&mInputDesc[0], inputDesc, sizeof(D3D11_INPUT_ELEMENT_DESC) * inputDescLen);
}
inline ID3D11InputLayout *LazyInputLayout::resolve(ID3D11Device *device)
{
checkAssociatedDevice(device);
if (mResource == nullptr)
{
HRESULT result = device->CreateInputLayout(
&mInputDesc[0], static_cast<UINT>(mInputDesc.size()), mByteCode, mByteCodeLen, &mResource);
ASSERT(SUCCEEDED(result));
UNUSED_ASSERTION_VARIABLE(result);
d3d11::SetDebugName(mResource, mDebugName);
}
return mResource;
} }
// Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to // Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment