Hash :
d3dfda2b
Author :
Date :
2015-07-06T08:28:49
Refactor how we store vertex formats. Instead of storing a vertex format as a struct with the full info, instead use an enum, and look up the info when we need it. This saves a lot of constructor initialization time, operator comparison time, and storage. It also will allow us to look up D3D format info more quickly. BUG=angleproject:959 Change-Id: I202fd1ea96981073bc1b5b232b1ec3efa91485cb Reviewed-on: https://chromium-review.googlesource.com/277289 Reviewed-by: Geoff Lang <geofflang@chromium.org> Tested-by: Jamie Madill <jmadill@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
//
// Copyright (c) 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.
//
// ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
#ifndef LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
#define LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
#include <string>
#include <vector>
#include "common/Optional.h"
#include "compiler/translator/blocklayoutHLSL.h"
#include "libANGLE/Constants.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/ProgramImpl.h"
#include "libANGLE/renderer/Workarounds.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h"
namespace gl
{
struct LinkedUniform;
struct VariableLocation;
struct VertexFormat;
}
namespace rx
{
class RendererD3D;
class UniformStorageD3D;
class ShaderExecutableD3D;
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
// It should only be used selectively to work around specific bugs.
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
#endif
class ProgramD3D : public ProgramImpl
{
public:
ProgramD3D(RendererD3D *renderer);
virtual ~ProgramD3D();
const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
int getShaderVersion() const { return mShaderVersion; }
GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const;
GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
GLint getUsedSamplerRange(gl::SamplerType type) const;
void updateSamplerMapping();
bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps);
bool usesPointSize() const { return mUsesPointSize; }
bool usesPointSpriteEmulation() const;
bool usesGeometryShader() const;
bool usesInstancedPointSpriteEmulation() const;
GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
gl::Error save(gl::BinaryOutputStream *stream);
gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutableD3D **outExectuable);
gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
gl::Error getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
ShaderExecutableD3D *getGeometryExecutable() const { return mGeometryExecutable; }
LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
int registers);
LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
gl::Shader *fragmentShader, gl::Shader *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum transformFeedbackBufferMode,
int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
std::map<int, gl::VariableLocation> *outputVariables);
void bindAttributeLocation(GLuint index, const std::string &name) override;
void initializeUniformStorage();
gl::Error applyUniforms();
gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) override;
bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
unsigned int registerIndex, const gl::Caps &caps);
void dirtyAllUniforms();
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform1iv(GLint location, GLsizei count, const GLint *v);
void setUniform2iv(GLint location, GLsizei count, const GLint *v);
void setUniform3iv(GLint location, GLsizei count, const GLint *v);
void setUniform4iv(GLint location, GLsizei count, const GLint *v);
void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void getUniformfv(GLint location, GLfloat *params);
void getUniformiv(GLint location, GLint *params);
void getUniformuiv(GLint location, GLuint *params);
const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps);
bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps);
void reset();
unsigned int getSerial() const;
void initAttributesByLayout();
void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const;
void updateCachedInputLayout(const gl::Program *program, const gl::State &state);
const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; }
private:
class VertexExecutable
{
public:
typedef std::vector<GLenum> Signature;
VertexExecutable(const gl::InputLayout &inputLayout,
const Signature &signature,
ShaderExecutableD3D *shaderExecutable);
~VertexExecutable();
bool matchesSignature(const Signature &signature) const;
static void getSignature(RendererD3D *renderer,
const gl::InputLayout &inputLayout,
Signature *signatureOut);
const gl::InputLayout &inputs() const { return mInputs; }
const Signature &signature() const { return mSignature; }
ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
private:
gl::InputLayout mInputs;
Signature mSignature;
ShaderExecutableD3D *mShaderExecutable;
};
class PixelExecutable
{
public:
PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutableD3D *shaderExecutable);
~PixelExecutable();
bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
private:
std::vector<GLenum> mOutputSignature;
ShaderExecutableD3D *mShaderExecutable;
};
struct Sampler
{
Sampler();
bool active;
GLint logicalTextureUnit;
GLenum textureType;
};
void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister);
void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName,
sh::HLSLBlockEncoder *encoder);
bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
template <typename T>
void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
template <int cols, int rows>
void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
template <typename T>
void getUniformv(GLint location, T *params, GLenum uniformType);
template <typename VarT>
void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
bool inRowMajorLayout);
RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL;
std::vector<VertexExecutable *> mVertexExecutables;
std::vector<PixelExecutable *> mPixelExecutables;
ShaderExecutableD3D *mGeometryExecutable;
std::string mVertexHLSL;
D3DCompilerWorkarounds mVertexWorkarounds;
std::string mPixelHLSL;
D3DCompilerWorkarounds mPixelWorkarounds;
bool mUsesFragDepth;
std::vector<PixelShaderOutputVariable> mPixelShaderKey;
bool mUsesPointSize;
UniformStorageD3D *mVertexUniformStorage;
UniformStorageD3D *mFragmentUniformStorage;
GLenum mTransformFeedbackBufferMode;
std::vector<Sampler> mSamplersPS;
std::vector<Sampler> mSamplersVS;
GLuint mUsedVertexSamplerRange;
GLuint mUsedPixelSamplerRange;
bool mDirtySamplerMapping;
// Cache for validateSamplers
std::vector<GLenum> mTextureUnitTypesCache;
// Cache for getPixelExecutableForFramebuffer
std::vector<GLenum> mPixelShaderOutputFormatCache;
int mShaderVersion;
int mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS];
unsigned int mSerial;
Optional<bool> mCachedValidateSamplersResult;
std::vector<GLint> mVertexUBOCache;
std::vector<GLint> mFragmentUBOCache;
VertexExecutable::Signature mCachedVertexSignature;
gl::InputLayout mCachedInputLayout;
static unsigned int issueSerial();
static unsigned int mCurrentSerial;
};
}
#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_