Commit 26143fdd by Xinghua Cao Committed by Commit Bot

ES31: Support bindImageTexture on Texture2D for compute shaders on D3D

BUG=angleproject:1987 TEST=angle_end2end_tests Change-Id: I3b0afb441a41dbd7f204b1d1bba7884c8d203ce1 Reviewed-on: https://chromium-review.googlesource.com/749004 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 10d41397
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 193 #define ANGLE_SH_VERSION 194
enum ShShaderSpec enum ShShaderSpec
{ {
......
...@@ -170,6 +170,8 @@ struct Uniform : public VariableWithLocation ...@@ -170,6 +170,8 @@ struct Uniform : public VariableWithLocation
int binding; int binding;
int offset; int offset;
bool readonly;
bool writeonly;
// Decide whether two uniforms are the same at shader link time, // Decide whether two uniforms are the same at shader link time,
// assuming one from vertex shader and the other from fragment shader. // assuming one from vertex shader and the other from fragment shader.
......
...@@ -93,7 +93,7 @@ struct UniformTypeInfo final : angle::NonCopyable ...@@ -93,7 +93,7 @@ struct UniformTypeInfo final : angle::NonCopyable
{ {
constexpr UniformTypeInfo(GLenum type, constexpr UniformTypeInfo(GLenum type,
GLenum componentType, GLenum componentType,
GLenum samplerTextureType, GLenum textureType,
GLenum transposedMatrixType, GLenum transposedMatrixType,
GLenum boolVectorType, GLenum boolVectorType,
int rowCount, int rowCount,
...@@ -107,7 +107,7 @@ struct UniformTypeInfo final : angle::NonCopyable ...@@ -107,7 +107,7 @@ struct UniformTypeInfo final : angle::NonCopyable
bool isImageType) bool isImageType)
: type(type), : type(type),
componentType(componentType), componentType(componentType),
samplerTextureType(samplerTextureType), textureType(textureType),
transposedMatrixType(transposedMatrixType), transposedMatrixType(transposedMatrixType),
boolVectorType(boolVectorType), boolVectorType(boolVectorType),
rowCount(rowCount), rowCount(rowCount),
...@@ -124,7 +124,7 @@ struct UniformTypeInfo final : angle::NonCopyable ...@@ -124,7 +124,7 @@ struct UniformTypeInfo final : angle::NonCopyable
GLenum type; GLenum type;
GLenum componentType; GLenum componentType;
GLenum samplerTextureType; GLenum textureType;
GLenum transposedMatrixType; GLenum transposedMatrixType;
GLenum boolVectorType; GLenum boolVectorType;
int rowCount; int rowCount;
......
...@@ -697,6 +697,8 @@ Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) ...@@ -697,6 +697,8 @@ Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable)
uniform.binding = variable.getType().getLayoutQualifier().binding; uniform.binding = variable.getType().getLayoutQualifier().binding;
uniform.location = variable.getType().getLayoutQualifier().location; uniform.location = variable.getType().getLayoutQualifier().location;
uniform.offset = variable.getType().getLayoutQualifier().offset; uniform.offset = variable.getType().getLayoutQualifier().offset;
uniform.readonly = variable.getType().getMemoryQualifier().readonly;
uniform.writeonly = variable.getType().getMemoryQualifier().writeonly;
return uniform; return uniform;
} }
......
...@@ -245,7 +245,8 @@ bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other, ...@@ -245,7 +245,8 @@ bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
return true; return true;
} }
Uniform::Uniform() : binding(-1), offset(-1) Uniform::Uniform() : binding(-1), offset(-1), readonly(false), writeonly(false)
{ {
} }
...@@ -254,7 +255,11 @@ Uniform::~Uniform() ...@@ -254,7 +255,11 @@ Uniform::~Uniform()
} }
Uniform::Uniform(const Uniform &other) Uniform::Uniform(const Uniform &other)
: VariableWithLocation(other), binding(other.binding), offset(other.offset) : VariableWithLocation(other),
binding(other.binding),
offset(other.offset),
readonly(other.readonly),
writeonly(other.writeonly)
{ {
} }
...@@ -263,13 +268,15 @@ Uniform &Uniform::operator=(const Uniform &other) ...@@ -263,13 +268,15 @@ Uniform &Uniform::operator=(const Uniform &other)
VariableWithLocation::operator=(other); VariableWithLocation::operator=(other);
binding = other.binding; binding = other.binding;
offset = other.offset; offset = other.offset;
readonly = other.readonly;
writeonly = other.writeonly;
return *this; return *this;
} }
bool Uniform::operator==(const Uniform &other) const bool Uniform::operator==(const Uniform &other) const
{ {
return VariableWithLocation::operator==(other) && binding == other.binding && return VariableWithLocation::operator==(other) && binding == other.binding &&
offset == other.offset; offset == other.offset && readonly == other.readonly && writeonly == other.writeonly;
} }
bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
...@@ -288,6 +295,10 @@ bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const ...@@ -288,6 +295,10 @@ bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
{ {
return false; return false;
} }
if (readonly != other.readonly || writeonly != other.writeonly)
{
return false;
}
return VariableWithLocation::isSameVariableAtLinkTime(other, true, true); return VariableWithLocation::isSameVariableAtLinkTime(other, true, true);
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/ProgramImpl.h" #include "libANGLE/renderer/ProgramImpl.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "platform/WorkaroundsD3D.h" #include "platform/WorkaroundsD3D.h"
namespace rx namespace rx
...@@ -31,22 +32,29 @@ class ShaderExecutableD3D; ...@@ -31,22 +32,29 @@ class ShaderExecutableD3D;
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1 #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
#endif #endif
enum class HLSLRegisterType : uint8_t
{
None = 0,
Texture = 1,
UnorderedAccessView = 2
};
// Helper struct representing a single shader uniform // Helper struct representing a single shader uniform
// TODO(jmadill): Make uniform blocks shared between all programs, so we don't need separate // TODO(jmadill): Make uniform blocks shared between all programs, so we don't need separate
// register indices. // register indices.
struct D3DUniform : private angle::NonCopyable struct D3DUniform : private angle::NonCopyable
{ {
D3DUniform(GLenum type, D3DUniform(GLenum type,
HLSLRegisterType reg,
const std::string &nameIn, const std::string &nameIn,
const std::vector<unsigned int> &arraySizesIn, const std::vector<unsigned int> &arraySizesIn,
bool defaultBlock); bool defaultBlock);
~D3DUniform(); ~D3DUniform();
bool isSampler() const; bool isSampler() const;
bool isImage() const;
bool isArray() const { return !arraySizes.empty(); } bool isArray() const { return !arraySizes.empty(); }
unsigned int getArraySizeProduct() const; unsigned int getArraySizeProduct() const;
bool isReferencedByVertexShader() const; bool isReferencedByVertexShader() const;
bool isReferencedByFragmentShader() const; bool isReferencedByFragmentShader() const;
bool isReferencedByComputeShader() const; bool isReferencedByComputeShader() const;
...@@ -65,6 +73,7 @@ struct D3DUniform : private angle::NonCopyable ...@@ -65,6 +73,7 @@ struct D3DUniform : private angle::NonCopyable
uint8_t *csData; uint8_t *csData;
// Register information. // Register information.
HLSLRegisterType regType;
unsigned int vsRegisterIndex; unsigned int vsRegisterIndex;
unsigned int psRegisterIndex; unsigned int psRegisterIndex;
unsigned int csRegisterIndex; unsigned int csRegisterIndex;
...@@ -175,6 +184,13 @@ class ProgramD3D : public ProgramImpl ...@@ -175,6 +184,13 @@ class ProgramD3D : public ProgramImpl
SamplerMapping updateSamplerMapping(); SamplerMapping updateSamplerMapping();
GLint getImageMapping(gl::ShaderType type,
unsigned int imageIndex,
bool readonly,
const gl::Caps &caps) const;
GLuint getUsedImageRange(gl::ShaderType type, bool readonly) const;
GLenum getImageTextureType(gl::ShaderType type, unsigned int imageIndex, bool readonly) const;
bool usesPointSize() const { return mUsesPointSize; } bool usesPointSize() const { return mUsesPointSize; }
bool usesPointSpriteEmulation() const; bool usesPointSpriteEmulation() const;
bool usesGeometryShader(GLenum drawMode) const; bool usesGeometryShader(GLenum drawMode) const;
...@@ -368,6 +384,13 @@ class ProgramD3D : public ProgramImpl ...@@ -368,6 +384,13 @@ class ProgramD3D : public ProgramImpl
GLenum textureType; GLenum textureType;
}; };
struct Image
{
Image();
bool active;
GLint logicalImageUnit;
};
typedef std::map<std::string, D3DUniform *> D3DUniformMap; typedef std::map<std::string, D3DUniform *> D3DUniformMap;
void defineUniformsAndAssignRegisters(const gl::Context *context); void defineUniformsAndAssignRegisters(const gl::Context *context);
...@@ -377,22 +400,26 @@ class ProgramD3D : public ProgramImpl ...@@ -377,22 +400,26 @@ class ProgramD3D : public ProgramImpl
void defineStructUniformFields(GLenum shaderType, void defineStructUniformFields(GLenum shaderType,
const std::vector<sh::ShaderVariable> &fields, const std::vector<sh::ShaderVariable> &fields,
const std::string &namePrefix, const std::string &namePrefix,
const HLSLRegisterType regType,
sh::HLSLBlockEncoder *encoder, sh::HLSLBlockEncoder *encoder,
D3DUniformMap *uniformMap); D3DUniformMap *uniformMap);
void defineArrayOfStructsUniformFields(GLenum shaderType, void defineArrayOfStructsUniformFields(GLenum shaderType,
const sh::ShaderVariable &uniform, const sh::ShaderVariable &uniform,
unsigned int arrayNestingIndex, unsigned int arrayNestingIndex,
const std::string &prefix, const std::string &prefix,
const HLSLRegisterType regType,
sh::HLSLBlockEncoder *encoder, sh::HLSLBlockEncoder *encoder,
D3DUniformMap *uniformMap); D3DUniformMap *uniformMap);
void defineArrayUniformElements(GLenum shaderType, void defineArrayUniformElements(GLenum shaderType,
const sh::ShaderVariable &uniform, const sh::ShaderVariable &uniform,
const std::string &fullName, const std::string &fullName,
const HLSLRegisterType regType,
sh::HLSLBlockEncoder *encoder, sh::HLSLBlockEncoder *encoder,
D3DUniformMap *uniformMap); D3DUniformMap *uniformMap);
void defineUniform(GLenum shaderType, void defineUniform(GLenum shaderType,
const sh::ShaderVariable &uniform, const sh::ShaderVariable &uniform,
const std::string &fullName, const std::string &fullName,
const HLSLRegisterType regType,
sh::HLSLBlockEncoder *encoder, sh::HLSLBlockEncoder *encoder,
D3DUniformMap *uniformMap); D3DUniformMap *uniformMap);
void assignAllSamplerRegisters(); void assignAllSamplerRegisters();
...@@ -404,6 +431,14 @@ class ProgramD3D : public ProgramImpl ...@@ -404,6 +431,14 @@ class ProgramD3D : public ProgramImpl
std::vector<Sampler> &outSamplers, std::vector<Sampler> &outSamplers,
GLuint *outUsedRange); GLuint *outUsedRange);
void assignAllImageRegisters();
void assignImageRegisters(size_t uniformIndex);
static void AssignImages(unsigned int startImageIndex,
int startLogicalImageUnit,
unsigned int imageCount,
std::vector<Image> &outImages,
GLuint *outUsedRange);
template <typename DestT> template <typename DestT>
void getUniformInternal(GLint location, DestT *dataOut) const; void getUniformInternal(GLint location, DestT *dataOut) const;
...@@ -491,6 +526,11 @@ class ProgramD3D : public ProgramImpl ...@@ -491,6 +526,11 @@ class ProgramD3D : public ProgramImpl
GLuint mUsedComputeSamplerRange; GLuint mUsedComputeSamplerRange;
bool mDirtySamplerMapping; bool mDirtySamplerMapping;
std::vector<Image> mImagesCS;
std::vector<Image> mReadonlyImagesCS;
GLuint mUsedComputeImageRange;
GLuint mUsedComputeReadonlyImageRange;
// Cache for pixel shader output layout to save reallocations. // Cache for pixel shader output layout to save reallocations.
std::vector<GLenum> mPixelShaderOutputLayoutCache; std::vector<GLenum> mPixelShaderOutputLayoutCache;
Optional<size_t> mCachedPixelExecutableIndex; Optional<size_t> mCachedPixelExecutableIndex;
...@@ -507,6 +547,7 @@ class ProgramD3D : public ProgramImpl ...@@ -507,6 +547,7 @@ class ProgramD3D : public ProgramImpl
std::vector<D3DVarying> mStreamOutVaryings; std::vector<D3DVarying> mStreamOutVaryings;
std::vector<D3DUniform *> mD3DUniforms; std::vector<D3DUniform *> mD3DUniforms;
std::map<std::string, int> mImageBindingMap;
std::vector<D3DUniformBlock> mD3DUniformBlocks; std::vector<D3DUniformBlock> mD3DUniformBlocks;
bool mVertexUniformsDirty; bool mVertexUniformsDirty;
......
...@@ -211,6 +211,14 @@ HRESULT CreateResource(ID3D11Device *device, ...@@ -211,6 +211,14 @@ HRESULT CreateResource(ID3D11Device *device,
} }
HRESULT CreateResource(ID3D11Device *device, HRESULT CreateResource(ID3D11Device *device,
const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc,
ID3D11Resource *resource,
ID3D11UnorderedAccessView **resourceOut)
{
return device->CreateUnorderedAccessView(resource, desc, resourceOut);
}
HRESULT CreateResource(ID3D11Device *device,
const D3D11_TEXTURE2D_DESC *desc, const D3D11_TEXTURE2D_DESC *desc,
const D3D11_SUBRESOURCE_DATA *initData, const D3D11_SUBRESOURCE_DATA *initData,
ID3D11Texture2D **texture) ID3D11Texture2D **texture)
......
...@@ -42,26 +42,28 @@ using InputElementArray = WrappedArray<D3D11_INPUT_ELEMENT_DESC>; ...@@ -42,26 +42,28 @@ using InputElementArray = WrappedArray<D3D11_INPUT_ELEMENT_DESC>;
using ShaderData = WrappedArray<uint8_t>; using ShaderData = WrappedArray<uint8_t>;
// Format: ResourceType, D3D11 type, DESC type, init data type. // Format: ResourceType, D3D11 type, DESC type, init data type.
#define ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ #define ANGLE_RESOURCE_TYPE_OP(NAME, OP) \
OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void) \ OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void) \
OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA) \ OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA) \
OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void) \ OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void) \
OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void) \ OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void) \
OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, \ OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, \
ID3D11Resource) \ ID3D11Resource) \
OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData, \ OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData, \
const std::vector<D3D11_SO_DECLARATION_ENTRY>) \ const std::vector<D3D11_SO_DECLARATION_ENTRY>) \
OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData) \ OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData) \
OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void) \ OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void) \
OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void) \ OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void) \
OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void) \ OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void) \
OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, \ OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, \
ID3D11Resource) \ ID3D11Resource) \
OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void) \ OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void) \
OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, \ OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, \
ID3D11Resource) \ ID3D11Resource) \
OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA) \ OP(NAME, UnorderedAccessView, ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC, \
OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA) \ ID3D11Resource) \
OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA) \
OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA) \
OP(NAME, VertexShader, ID3D11VertexShader, ShaderData, void) OP(NAME, VertexShader, ID3D11VertexShader, ShaderData, void)
#define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE, #define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE,
...@@ -357,6 +359,7 @@ namespace d3d11 ...@@ -357,6 +359,7 @@ namespace d3d11
ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS) ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS)
using SharedSRV = SharedResource11<ID3D11ShaderResourceView>; using SharedSRV = SharedResource11<ID3D11ShaderResourceView>;
using SharedUAV = SharedResource11<ID3D11UnorderedAccessView>;
} // namespace d3d11 } // namespace d3d11
#undef ANGLE_RESOURCE_TYPE_CLASS #undef ANGLE_RESOURCE_TYPE_CLASS
......
...@@ -295,6 +295,10 @@ class StateManager11 final : angle::NonCopyable ...@@ -295,6 +295,10 @@ class StateManager11 final : angle::NonCopyable
void setShaderResourceInternal(gl::ShaderType shaderType, void setShaderResourceInternal(gl::ShaderType shaderType,
UINT resourceSlot, UINT resourceSlot,
const SRVType *srv); const SRVType *srv);
template <typename UAVType>
void setUnorderedAccessViewInternal(gl::ShaderType shaderType,
UINT resourceSlot,
const UAVType *uav);
bool unsetConflictingView(ID3D11View *view); bool unsetConflictingView(ID3D11View *view);
bool unsetConflictingSRVs(gl::ShaderType shaderType, bool unsetConflictingSRVs(gl::ShaderType shaderType,
...@@ -324,6 +328,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -324,6 +328,7 @@ class StateManager11 final : angle::NonCopyable
gl::Error syncTextures(const gl::Context *context); gl::Error syncTextures(const gl::Context *context);
gl::Error applyTextures(const gl::Context *context, gl::ShaderType shaderType); gl::Error applyTextures(const gl::Context *context, gl::ShaderType shaderType);
gl::Error syncTexturesForCompute(const gl::Context *context);
gl::Error setSamplerState(const gl::Context *context, gl::Error setSamplerState(const gl::Context *context,
gl::ShaderType type, gl::ShaderType type,
...@@ -334,9 +339,15 @@ class StateManager11 final : angle::NonCopyable ...@@ -334,9 +339,15 @@ class StateManager11 final : angle::NonCopyable
gl::ShaderType type, gl::ShaderType type,
int index, int index,
gl::Texture *texture); gl::Texture *texture);
gl::Error setTextureForImage(const gl::Context *context,
gl::ShaderType type,
int index,
bool readonly,
const gl::ImageUnit &imageUnit);
// Faster than calling setTexture a jillion times // Faster than calling setTexture a jillion times
gl::Error clearTextures(gl::ShaderType shaderType, size_t rangeStart, size_t rangeEnd); gl::Error clearSRVs(gl::ShaderType shaderType, size_t rangeStart, size_t rangeEnd);
gl::Error clearUAVs(gl::ShaderType shaderType, size_t rangeStart, size_t rangeEnd);
void handleMultiviewDrawFramebufferChange(const gl::Context *context); void handleMultiviewDrawFramebufferChange(const gl::Context *context);
gl::Error syncCurrentValueAttribs(const gl::State &glState); gl::Error syncCurrentValueAttribs(const gl::State &glState);
...@@ -432,42 +443,50 @@ class StateManager11 final : angle::NonCopyable ...@@ -432,42 +443,50 @@ class StateManager11 final : angle::NonCopyable
std::set<Query11 *> mCurrentQueries; std::set<Query11 *> mCurrentQueries;
// Currently applied textures // Currently applied textures
struct SRVRecord template <typename DescType>
struct ViewRecord
{ {
uintptr_t srv; uintptr_t view;
uintptr_t resource; uintptr_t resource;
D3D11_SHADER_RESOURCE_VIEW_DESC desc; DescType desc;
}; };
// A cache of current SRVs that also tracks the highest 'used' (non-NULL) SRV // A cache of current Views that also tracks the highest 'used' (non-NULL) View.
// We might want to investigate a more robust approach that is also fast when there's // 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 // a large gap between used Views (e.g. if View 0 and 7 are non-NULL, this approach will
// waste time on SRVs 1-6.) // waste time on Views 1-6.)
class SRVCache : angle::NonCopyable template <typename ViewType, typename DescType>
class ViewCache : angle::NonCopyable
{ {
public: public:
SRVCache(); ViewCache();
~SRVCache(); ~ViewCache();
void initialize(size_t size) { mCurrentSRVs.resize(size); } void initialize(size_t size) { mCurrentViews.resize(size); }
size_t size() const { return mCurrentSRVs.size(); } size_t size() const { return mCurrentViews.size(); }
size_t highestUsed() const { return mHighestUsedSRV; } size_t highestUsed() const { return mHighestUsedView; }
const SRVRecord &operator[](size_t index) const { return mCurrentSRVs[index]; } const ViewRecord<DescType> &operator[](size_t index) const { return mCurrentViews[index]; }
void clear(); void clear();
void update(size_t resourceIndex, ID3D11ShaderResourceView *srv); void update(size_t resourceIndex, ViewType *view);
private: private:
std::vector<SRVRecord> mCurrentSRVs; std::vector<ViewRecord<DescType>> mCurrentViews;
size_t mHighestUsedSRV; size_t mHighestUsedView;
}; };
using SRVCache = ViewCache<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC>;
using UAVCache = ViewCache<ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC>;
SRVCache mCurVertexSRVs; SRVCache mCurVertexSRVs;
SRVCache mCurPixelSRVs; SRVCache mCurPixelSRVs;
SRVCache mCurComputeSRVs;
UAVCache mCurComputeUAVs;
SRVCache *getSRVCache(gl::ShaderType shaderType);
// A block of NULL pointers, cached so we don't re-allocate every draw call // A block of NULL pointers, cached so we don't re-allocate every draw call
std::vector<ID3D11ShaderResourceView *> mNullSRVs; std::vector<ID3D11ShaderResourceView *> mNullSRVs;
std::vector<ID3D11UnorderedAccessView *> mNullUAVs;
// Current translations of "Current-Value" data - owned by Context, not VertexArray. // Current translations of "Current-Value" data - owned by Context, not VertexArray.
gl::AttributesMask mDirtyCurrentValueAttribs; gl::AttributesMask mDirtyCurrentValueAttribs;
......
...@@ -87,7 +87,7 @@ def get_swizzle_format_id(internal_format, angle_format): ...@@ -87,7 +87,7 @@ def get_swizzle_format_id(internal_format, angle_format):
# The format itself can be used for swizzles if it can be accessed as a render target and # The format itself can be used for swizzles if it can be accessed as a render target and
# sampled and the bit count for all 4 channels is the same. # sampled and the bit count for all 4 channels is the same.
if "rtvFormat" in angle_format and "srvFormat" in angle_format and not channels_different and len(angle_format['channels']) == 4: if "rtvFormat" in angle_format and "srvFormat" in angle_format and "uavFormat" in angle_format and not channels_different and len(angle_format['channels']) == 4:
return angle_format["glInternalFormat"] if "glInternalFormat" in angle_format else internal_format return angle_format["glInternalFormat"] if "glInternalFormat" in angle_format else internal_format
b = int(math.ceil(float(max_component_bits) / 8) * 8) b = int(math.ceil(float(max_component_bits) / 8) * 8)
...@@ -144,6 +144,7 @@ format_entry_template = """{space}{{ ...@@ -144,6 +144,7 @@ format_entry_template = """{space}{{
{space} angle::Format::ID::{formatName}, {space} angle::Format::ID::{formatName},
{space} {texFormat}, {space} {texFormat},
{space} {srvFormat}, {space} {srvFormat},
{space} {uavFormat},
{space} {rtvFormat}, {space} {rtvFormat},
{space} {dsvFormat}, {space} {dsvFormat},
{space} {blitSRVFormat}, {space} {blitSRVFormat},
...@@ -159,6 +160,7 @@ split_format_entry_template = """{space} {condition} ...@@ -159,6 +160,7 @@ split_format_entry_template = """{space} {condition}
{space} angle::Format::ID::{formatName}, {space} angle::Format::ID::{formatName},
{space} {texFormat}, {space} {texFormat},
{space} {srvFormat}, {space} {srvFormat},
{space} {uavFormat},
{space} {rtvFormat}, {space} {rtvFormat},
{space} {dsvFormat}, {space} {dsvFormat},
{space} {blitSRVFormat}, {space} {blitSRVFormat},
...@@ -178,6 +180,7 @@ def json_to_table_data(internal_format, format_name, prefix, json): ...@@ -178,6 +180,7 @@ def json_to_table_data(internal_format, format_name, prefix, json):
"formatName": format_name, "formatName": format_name,
"texFormat": "DXGI_FORMAT_UNKNOWN", "texFormat": "DXGI_FORMAT_UNKNOWN",
"srvFormat": "DXGI_FORMAT_UNKNOWN", "srvFormat": "DXGI_FORMAT_UNKNOWN",
"uavFormat": "DXGI_FORMAT_UNKNOWN",
"rtvFormat": "DXGI_FORMAT_UNKNOWN", "rtvFormat": "DXGI_FORMAT_UNKNOWN",
"dsvFormat": "DXGI_FORMAT_UNKNOWN", "dsvFormat": "DXGI_FORMAT_UNKNOWN",
"condition": prefix, "condition": prefix,
......
...@@ -52,6 +52,9 @@ static constexpr std::array<SamplePositionsArray, 5> kSamplePositions = { ...@@ -52,6 +52,9 @@ static constexpr std::array<SamplePositionsArray, 5> kSamplePositions = {
0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f, 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f,
0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}}; 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}};
// TODO(xinghua.cao@intel.com): Get a more accurate limit.
static D3D_FEATURE_LEVEL kMinimumFeatureLevelForES31 = D3D_FEATURE_LEVEL_11_0;
// Helper functor for querying DXGI support. Saves passing the parameters repeatedly. // Helper functor for querying DXGI support. Saves passing the parameters repeatedly.
class DXGISupportHelper : angle::NonCopyable class DXGISupportHelper : angle::NonCopyable
{ {
...@@ -1208,6 +1211,11 @@ gl::Version GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel) ...@@ -1208,6 +1211,11 @@ gl::Version GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel)
} }
} }
D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31()
{
return kMinimumFeatureLevelForES31;
}
unsigned int GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel) unsigned int GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel)
{ {
switch (featureLevel) switch (featureLevel)
......
...@@ -73,6 +73,8 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons ...@@ -73,6 +73,8 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons
void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy); void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31();
} // namespace d3d11_gl } // namespace d3d11_gl
namespace d3d11 namespace d3d11
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
"R8G8B8A8_UNORM": { "R8G8B8A8_UNORM": {
"texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
"srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
"uavFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
"rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM",
"channels": "rgba", "channels": "rgba",
"componentType": "unorm", "componentType": "unorm",
...@@ -32,6 +33,7 @@ ...@@ -32,6 +33,7 @@
"R16G16B16A16_FLOAT": { "R16G16B16A16_FLOAT": {
"texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
"srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
"uavFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
"rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT",
"channels": "rgba", "channels": "rgba",
"componentType": "float", "componentType": "float",
...@@ -41,6 +43,7 @@ ...@@ -41,6 +43,7 @@
"R32G32B32A32_FLOAT": { "R32G32B32A32_FLOAT": {
"texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
"srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
"uavFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
"rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT",
"channels": "rgba", "channels": "rgba",
"componentType": "float", "componentType": "float",
...@@ -204,6 +207,7 @@ ...@@ -204,6 +207,7 @@
"R32_FLOAT": { "R32_FLOAT": {
"texFormat": "DXGI_FORMAT_R32_FLOAT", "texFormat": "DXGI_FORMAT_R32_FLOAT",
"srvFormat": "DXGI_FORMAT_R32_FLOAT", "srvFormat": "DXGI_FORMAT_R32_FLOAT",
"uavFormat": "DXGI_FORMAT_R32_FLOAT",
"rtvFormat": "DXGI_FORMAT_R32_FLOAT", "rtvFormat": "DXGI_FORMAT_R32_FLOAT",
"channels": "r", "channels": "r",
"componentType": "float", "componentType": "float",
...@@ -213,6 +217,7 @@ ...@@ -213,6 +217,7 @@
"R32_SINT": { "R32_SINT": {
"texFormat": "DXGI_FORMAT_R32_SINT", "texFormat": "DXGI_FORMAT_R32_SINT",
"srvFormat": "DXGI_FORMAT_R32_SINT", "srvFormat": "DXGI_FORMAT_R32_SINT",
"uavFormat": "DXGI_FORMAT_R32_SINT",
"rtvFormat": "DXGI_FORMAT_R32_SINT", "rtvFormat": "DXGI_FORMAT_R32_SINT",
"channels": "r", "channels": "r",
"componentType": "int", "componentType": "int",
...@@ -222,6 +227,7 @@ ...@@ -222,6 +227,7 @@
"R32_UINT": { "R32_UINT": {
"texFormat": "DXGI_FORMAT_R32_UINT", "texFormat": "DXGI_FORMAT_R32_UINT",
"srvFormat": "DXGI_FORMAT_R32_UINT", "srvFormat": "DXGI_FORMAT_R32_UINT",
"uavFormat": "DXGI_FORMAT_R32_UINT",
"rtvFormat": "DXGI_FORMAT_R32_UINT", "rtvFormat": "DXGI_FORMAT_R32_UINT",
"channels": "r", "channels": "r",
"componentType": "uint", "componentType": "uint",
...@@ -373,6 +379,7 @@ ...@@ -373,6 +379,7 @@
"R16G16B16A16_SINT": { "R16G16B16A16_SINT": {
"texFormat": "DXGI_FORMAT_R16G16B16A16_SINT", "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
"srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
"uavFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
"rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT",
"channels": "rgba", "channels": "rgba",
"componentType": "int", "componentType": "int",
...@@ -382,6 +389,7 @@ ...@@ -382,6 +389,7 @@
"R16G16B16A16_UINT": { "R16G16B16A16_UINT": {
"texFormat": "DXGI_FORMAT_R16G16B16A16_UINT", "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
"srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
"uavFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
"rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT",
"channels": "rgba", "channels": "rgba",
"componentType": "uint", "componentType": "uint",
...@@ -391,6 +399,7 @@ ...@@ -391,6 +399,7 @@
"R32G32B32A32_SINT": { "R32G32B32A32_SINT": {
"texFormat": "DXGI_FORMAT_R32G32B32A32_SINT", "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
"srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
"uavFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
"rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT",
"channels": "rgba", "channels": "rgba",
"componentType": "int", "componentType": "int",
...@@ -400,6 +409,7 @@ ...@@ -400,6 +409,7 @@
"R32G32B32A32_UINT": { "R32G32B32A32_UINT": {
"texFormat": "DXGI_FORMAT_R32G32B32A32_UINT", "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
"srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
"uavFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
"rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT",
"channels": "rgba", "channels": "rgba",
"componentType": "uint", "componentType": "uint",
...@@ -438,6 +448,7 @@ ...@@ -438,6 +448,7 @@
"R8G8B8A8_UINT": { "R8G8B8A8_UINT": {
"texFormat": "DXGI_FORMAT_R8G8B8A8_UINT", "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
"srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
"uavFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
"rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT",
"channels": "rgba", "channels": "rgba",
"componentType": "uint", "componentType": "uint",
...@@ -447,6 +458,7 @@ ...@@ -447,6 +458,7 @@
"R8G8B8A8_SNORM": { "R8G8B8A8_SNORM": {
"texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
"srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
"uavFormat": "DXGI_FORMAT_R8G8B8A8_SNORM",
"channels": "rgba", "channels": "rgba",
"componentType": "snorm", "componentType": "snorm",
"bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 },
......
...@@ -37,6 +37,7 @@ struct Format final : private angle::NonCopyable ...@@ -37,6 +37,7 @@ struct Format final : private angle::NonCopyable
angle::Format::ID formatID, angle::Format::ID formatID,
DXGI_FORMAT texFormat, DXGI_FORMAT texFormat,
DXGI_FORMAT srvFormat, DXGI_FORMAT srvFormat,
DXGI_FORMAT uavFormat,
DXGI_FORMAT rtvFormat, DXGI_FORMAT rtvFormat,
DXGI_FORMAT dsvFormat, DXGI_FORMAT dsvFormat,
DXGI_FORMAT blitSRVFormat, DXGI_FORMAT blitSRVFormat,
...@@ -54,6 +55,7 @@ struct Format final : private angle::NonCopyable ...@@ -54,6 +55,7 @@ struct Format final : private angle::NonCopyable
DXGI_FORMAT texFormat; DXGI_FORMAT texFormat;
DXGI_FORMAT srvFormat; DXGI_FORMAT srvFormat;
DXGI_FORMAT uavFormat;
DXGI_FORMAT rtvFormat; DXGI_FORMAT rtvFormat;
DXGI_FORMAT dsvFormat; DXGI_FORMAT dsvFormat;
...@@ -69,6 +71,7 @@ constexpr Format::Format() ...@@ -69,6 +71,7 @@ constexpr Format::Format()
formatID(angle::Format::ID::NONE), formatID(angle::Format::ID::NONE),
texFormat(DXGI_FORMAT_UNKNOWN), texFormat(DXGI_FORMAT_UNKNOWN),
srvFormat(DXGI_FORMAT_UNKNOWN), srvFormat(DXGI_FORMAT_UNKNOWN),
uavFormat(DXGI_FORMAT_UNKNOWN),
rtvFormat(DXGI_FORMAT_UNKNOWN), rtvFormat(DXGI_FORMAT_UNKNOWN),
dsvFormat(DXGI_FORMAT_UNKNOWN), dsvFormat(DXGI_FORMAT_UNKNOWN),
blitSRVFormat(DXGI_FORMAT_UNKNOWN), blitSRVFormat(DXGI_FORMAT_UNKNOWN),
...@@ -81,6 +84,7 @@ constexpr Format::Format(GLenum internalFormat, ...@@ -81,6 +84,7 @@ constexpr Format::Format(GLenum internalFormat,
angle::Format::ID formatID, angle::Format::ID formatID,
DXGI_FORMAT texFormat, DXGI_FORMAT texFormat,
DXGI_FORMAT srvFormat, DXGI_FORMAT srvFormat,
DXGI_FORMAT uavFormat,
DXGI_FORMAT rtvFormat, DXGI_FORMAT rtvFormat,
DXGI_FORMAT dsvFormat, DXGI_FORMAT dsvFormat,
DXGI_FORMAT blitSRVFormat, DXGI_FORMAT blitSRVFormat,
...@@ -90,6 +94,7 @@ constexpr Format::Format(GLenum internalFormat, ...@@ -90,6 +94,7 @@ constexpr Format::Format(GLenum internalFormat,
formatID(formatID), formatID(formatID),
texFormat(texFormat), texFormat(texFormat),
srvFormat(srvFormat), srvFormat(srvFormat),
uavFormat(uavFormat),
rtvFormat(rtvFormat), rtvFormat(rtvFormat),
dsvFormat(dsvFormat), dsvFormat(dsvFormat),
blitSRVFormat(blitSRVFormat), blitSRVFormat(blitSRVFormat),
......
...@@ -346,8 +346,6 @@ TEST_P(ComputeShaderTest, DispatchCompute) ...@@ -346,8 +346,6 @@ TEST_P(ComputeShaderTest, DispatchCompute)
// Use image uniform to write texture in compute shader, and verify the content is expected. // Use image uniform to write texture in compute shader, and verify the content is expected.
TEST_P(ComputeShaderTest, BindImageTexture) TEST_P(ComputeShaderTest, BindImageTexture)
{ {
ANGLE_SKIP_TEST_IF(IsD3D11());
GLTexture mTexture[2]; GLTexture mTexture[2];
GLFramebuffer mFramebuffer; GLFramebuffer mFramebuffer;
const std::string csSource = const std::string csSource =
...@@ -528,6 +526,88 @@ TEST_P(ComputeShaderTest, ImageSize) ...@@ -528,6 +526,88 @@ TEST_P(ComputeShaderTest, ImageSize)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Use image uniform to read and write textures in compute shader, and verify the contents.
TEST_P(ComputeShaderTest, BindImageTextureWithTexture2D)
{
GLTexture texture[2];
GLFramebuffer framebuffer;
const std::string csSource =
R"(#version 310 es
layout(local_size_x=4, local_size_y=2, local_size_z=1) in;
layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
void main()
{
uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
})";
constexpr int kWidth = 4, kHeight = 2;
constexpr GLuint kInputValues[2][8] = {{200, 200, 200, 200, 200, 200, 200, 200},
{100, 100, 100, 100, 100, 100, 100, 100}};
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
kInputValues[0]);
EXPECT_GL_NO_ERROR();
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
kInputValues[1]);
EXPECT_GL_NO_ERROR();
glUseProgram(0);
GLuint outputValues[8];
constexpr GLuint expectedValue_1 = 200;
constexpr GLuint expectedValue_2 = 100;
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[0], 0);
EXPECT_GL_NO_ERROR();
glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
for (int i = 0; i < kWidth * kHeight; i++)
{
EXPECT_EQ(expectedValue_1, outputValues[i]);
}
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
EXPECT_GL_NO_ERROR();
glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
for (int i = 0; i < kWidth * kHeight; i++)
{
EXPECT_EQ(expectedValue_2, outputValues[i]);
}
ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
glUseProgram(program.get());
glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
EXPECT_GL_NO_ERROR();
glBindImageTexture(1, texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
EXPECT_GL_NO_ERROR();
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
glUseProgram(0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
EXPECT_GL_NO_ERROR();
glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
EXPECT_GL_NO_ERROR();
for (int i = 0; i < kWidth * kHeight; i++)
{
EXPECT_EQ(expectedValue_1, outputValues[i]);
}
}
// Check that it is not possible to create a compute shader when the context does not support ES // Check that it is not possible to create a compute shader when the context does not support ES
// 3.10 // 3.10
TEST_P(ComputeShaderTestES3, NotSupported) TEST_P(ComputeShaderTestES3, NotSupported)
......
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