1 // 2 // Copyright 2016 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // TextureVk.h: 7 // Defines the class interface for TextureVk, implementing TextureImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_ 12 13 #include "libANGLE/renderer/TextureImpl.h" 14 #include "libANGLE/renderer/vulkan/CommandGraph.h" 15 #include "libANGLE/renderer/vulkan/RenderTargetVk.h" 16 #include "libANGLE/renderer/vulkan/SamplerVk.h" 17 #include "libANGLE/renderer/vulkan/vk_helpers.h" 18 19 namespace rx 20 { 21 22 class TextureVk : public TextureImpl 23 { 24 public: 25 TextureVk(const gl::TextureState &state, RendererVk *renderer); 26 ~TextureVk() override; 27 void onDestroy(const gl::Context *context) override; 28 29 angle::Result setImage(const gl::Context *context, 30 const gl::ImageIndex &index, 31 GLenum internalFormat, 32 const gl::Extents &size, 33 GLenum format, 34 GLenum type, 35 const gl::PixelUnpackState &unpack, 36 const uint8_t *pixels) override; 37 angle::Result setSubImage(const gl::Context *context, 38 const gl::ImageIndex &index, 39 const gl::Box &area, 40 GLenum format, 41 GLenum type, 42 const gl::PixelUnpackState &unpack, 43 gl::Buffer *unpackBuffer, 44 const uint8_t *pixels) override; 45 46 angle::Result setCompressedImage(const gl::Context *context, 47 const gl::ImageIndex &index, 48 GLenum internalFormat, 49 const gl::Extents &size, 50 const gl::PixelUnpackState &unpack, 51 size_t imageSize, 52 const uint8_t *pixels) override; 53 angle::Result setCompressedSubImage(const gl::Context *context, 54 const gl::ImageIndex &index, 55 const gl::Box &area, 56 GLenum format, 57 const gl::PixelUnpackState &unpack, 58 size_t imageSize, 59 const uint8_t *pixels) override; 60 61 angle::Result copyImage(const gl::Context *context, 62 const gl::ImageIndex &index, 63 const gl::Rectangle &sourceArea, 64 GLenum internalFormat, 65 gl::Framebuffer *source) override; 66 angle::Result copySubImage(const gl::Context *context, 67 const gl::ImageIndex &index, 68 const gl::Offset &destOffset, 69 const gl::Rectangle &sourceArea, 70 gl::Framebuffer *source) override; 71 72 angle::Result copyTexture(const gl::Context *context, 73 const gl::ImageIndex &index, 74 GLenum internalFormat, 75 GLenum type, 76 size_t sourceLevel, 77 bool unpackFlipY, 78 bool unpackPremultiplyAlpha, 79 bool unpackUnmultiplyAlpha, 80 const gl::Texture *source) override; 81 angle::Result copySubTexture(const gl::Context *context, 82 const gl::ImageIndex &index, 83 const gl::Offset &destOffset, 84 size_t sourceLevel, 85 const gl::Box &sourceBox, 86 bool unpackFlipY, 87 bool unpackPremultiplyAlpha, 88 bool unpackUnmultiplyAlpha, 89 const gl::Texture *source) override; 90 91 angle::Result copyCompressedTexture(const gl::Context *context, 92 const gl::Texture *source) override; 93 94 angle::Result setStorage(const gl::Context *context, 95 gl::TextureType type, 96 size_t levels, 97 GLenum internalFormat, 98 const gl::Extents &size) override; 99 100 angle::Result setStorageExternalMemory(const gl::Context *context, 101 gl::TextureType type, 102 size_t levels, 103 GLenum internalFormat, 104 const gl::Extents &size, 105 gl::MemoryObject *memoryObject, 106 GLuint64 offset) override; 107 108 angle::Result setEGLImageTarget(const gl::Context *context, 109 gl::TextureType type, 110 egl::Image *image) override; 111 112 angle::Result setImageExternal(const gl::Context *context, 113 gl::TextureType type, 114 egl::Stream *stream, 115 const egl::Stream::GLTextureDescription &desc) override; 116 117 angle::Result generateMipmap(const gl::Context *context) override; 118 119 angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) override; 120 121 angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override; 122 angle::Result releaseTexImage(const gl::Context *context) override; 123 124 angle::Result getAttachmentRenderTarget(const gl::Context *context, 125 GLenum binding, 126 const gl::ImageIndex &imageIndex, 127 FramebufferAttachmentRenderTarget **rtOut) override; 128 129 angle::Result syncState(const gl::Context *context, 130 const gl::Texture::DirtyBits &dirtyBits) override; 131 132 angle::Result setStorageMultisample(const gl::Context *context, 133 gl::TextureType type, 134 GLsizei samples, 135 GLint internalformat, 136 const gl::Extents &size, 137 bool fixedSampleLocations) override; 138 139 angle::Result initializeContents(const gl::Context *context, 140 const gl::ImageIndex &imageIndex) override; 141 getImage()142 const vk::ImageHelper &getImage() const 143 { 144 ASSERT(mImage && mImage->valid()); 145 return *mImage; 146 } 147 getImage()148 vk::ImageHelper &getImage() 149 { 150 ASSERT(mImage && mImage->valid()); 151 return *mImage; 152 } 153 154 void releaseOwnershipOfImage(const gl::Context *context); 155 156 const vk::ImageView &getReadImageView() const; 157 // A special view for cube maps as a 2D array, used with shaders that do texelFetch() and for 158 // seamful cube map emulation. 159 const vk::ImageView &getFetchImageView() const; 160 angle::Result getLayerLevelDrawImageView(vk::Context *context, 161 size_t layer, 162 size_t level, 163 vk::ImageView **imageViewOut); 164 const vk::Sampler &getSampler() const; 165 166 angle::Result ensureImageInitialized(ContextVk *contextVk); 167 getSerial()168 Serial getSerial() const { return mSerial; } 169 overrideStagingBufferSizeForTesting(size_t initialSizeForTesting)170 void overrideStagingBufferSizeForTesting(size_t initialSizeForTesting) 171 { 172 mStagingBufferInitialSize = initialSizeForTesting; 173 } 174 175 private: 176 struct TextureVkViews final : angle::NonCopyable 177 { 178 TextureVkViews(); 179 ~TextureVkViews(); 180 181 void release(ContextVk *contextVk, Serial currentSerial); 182 vk::ImageView mDrawBaseLevelImageView; 183 vk::ImageView mReadBaseLevelImageView; 184 vk::ImageView mReadMipmapImageView; 185 vk::ImageView mFetchBaseLevelImageView; 186 vk::ImageView mFetchMipmapImageView; 187 }; 188 189 // Transform an image index from the frontend into one that can be used on the backing 190 // ImageHelper, taking into account mipmap or cube face offsets 191 gl::ImageIndex getNativeImageIndex(const gl::ImageIndex &inputImageIndex) const; 192 uint32_t getNativeImageLevel(uint32_t frontendLevel) const; 193 uint32_t getNativeImageLayer(uint32_t frontendLayer) const; 194 195 void releaseAndDeleteImage(ContextVk *contextVk); 196 angle::Result ensureImageAllocated(ContextVk *contextVk, const vk::Format &format); 197 void setImageHelper(ContextVk *contextVk, 198 vk::ImageHelper *imageHelper, 199 gl::TextureType imageType, 200 const vk::Format &format, 201 uint32_t imageLevelOffset, 202 uint32_t imageLayerOffset, 203 bool selfOwned); 204 void updateImageHelper(ContextVk *context, const vk::Format &internalFormat); 205 206 angle::Result redefineImage(const gl::Context *context, 207 const gl::ImageIndex &index, 208 const vk::Format &format, 209 const gl::Extents &size); 210 211 angle::Result setImageImpl(const gl::Context *context, 212 const gl::ImageIndex &index, 213 const gl::InternalFormat &formatInfo, 214 const gl::Extents &size, 215 GLenum type, 216 const gl::PixelUnpackState &unpack, 217 const uint8_t *pixels); 218 angle::Result setSubImageImpl(const gl::Context *context, 219 const gl::ImageIndex &index, 220 const gl::Box &area, 221 const gl::InternalFormat &formatInfo, 222 GLenum type, 223 const gl::PixelUnpackState &unpack, 224 const uint8_t *pixels, 225 const vk::Format &vkFormat); 226 227 angle::Result copyImageDataToBuffer(ContextVk *contextVk, 228 size_t sourceLevel, 229 uint32_t layerCount, 230 const gl::Rectangle &sourceArea, 231 uint8_t **outDataPtr); 232 233 angle::Result generateMipmapsWithCPU(const gl::Context *context); 234 235 angle::Result generateMipmapLevelsWithCPU(ContextVk *contextVk, 236 const angle::Format &sourceFormat, 237 GLuint layer, 238 GLuint firstMipLevel, 239 GLuint maxMipLevel, 240 size_t sourceWidth, 241 size_t sourceHeight, 242 size_t sourceRowPitch, 243 uint8_t *sourceData); 244 245 angle::Result copySubImageImpl(const gl::Context *context, 246 const gl::ImageIndex &index, 247 const gl::Offset &destOffset, 248 const gl::Rectangle &sourceArea, 249 const gl::InternalFormat &internalFormat, 250 gl::Framebuffer *source); 251 252 angle::Result copySubTextureImpl(ContextVk *contextVk, 253 const gl::ImageIndex &index, 254 const gl::Offset &destOffset, 255 const gl::InternalFormat &destFormat, 256 size_t sourceLevel, 257 const gl::Rectangle &sourceArea, 258 bool unpackFlipY, 259 bool unpackPremultiplyAlpha, 260 bool unpackUnmultiplyAlpha, 261 TextureVk *source); 262 263 angle::Result copySubImageImplWithTransfer(ContextVk *contextVk, 264 const gl::ImageIndex &index, 265 const gl::Offset &destOffset, 266 const vk::Format &destFormat, 267 size_t sourceLevel, 268 size_t sourceLayer, 269 const gl::Rectangle &sourceArea, 270 vk::ImageHelper *srcImage); 271 272 angle::Result copySubImageImplWithDraw(ContextVk *contextVk, 273 const gl::ImageIndex &index, 274 const gl::Offset &destOffset, 275 const vk::Format &destFormat, 276 size_t sourceLevel, 277 const gl::Rectangle &sourceArea, 278 bool isSrcFlipY, 279 bool unpackFlipY, 280 bool unpackPremultiplyAlpha, 281 bool unpackUnmultiplyAlpha, 282 vk::ImageHelper *srcImage, 283 const vk::ImageView *srcView); 284 285 angle::Result initImage(ContextVk *contextVk, 286 const vk::Format &format, 287 const gl::Extents &extents, 288 const uint32_t levelCount, 289 vk::CommandBuffer *commandBuffer); 290 void releaseImage(ContextVk *context); 291 void releaseImageViews(ContextVk *contextVk); 292 void releaseStagingBuffer(ContextVk *context); 293 uint32_t getLevelCount() const; 294 angle::Result initImageViews(ContextVk *contextVk, 295 const vk::Format &format, 296 uint32_t levelCount, 297 uint32_t layerCount); 298 angle::Result init3DRenderTargets(ContextVk *contextVk); 299 angle::Result initImageViewImpl(ContextVk *contextVk, 300 const vk::Format &format, 301 uint32_t levelCount, 302 uint32_t layerCount, 303 TextureVkViews *views, 304 VkImageAspectFlags aspectFlags, 305 gl::SwizzleState mappedSwizzle); 306 angle::Result initCubeMapRenderTargets(ContextVk *contextVk); 307 308 angle::Result ensureImageInitializedImpl(ContextVk *contextVk, 309 const gl::Extents &baseLevelExtents, 310 uint32_t levelCount, 311 const vk::Format &format); 312 onStagingBufferChange()313 void onStagingBufferChange() { onStateChange(angle::SubjectMessage::SubjectChanged); } 314 315 const TextureVkViews *getTextureViews() const; 316 317 bool mOwnsImage; 318 319 gl::TextureType mImageNativeType; 320 321 // The layer offset to apply when converting from a frontend texture layer to a texture layer in 322 // mImage. Used when this texture sources a cube map face or 3D texture layer from an EGL image. 323 uint32_t mImageLayerOffset; 324 325 // The level offset to apply when converting from a frontend texture level to texture level in 326 // mImage. 327 uint32_t mImageLevelOffset; 328 329 vk::ImageHelper *mImage; 330 331 TextureVkViews mDefaultViews; 332 TextureVkViews mStencilViews; 333 std::vector<std::vector<vk::ImageView>> mLayerLevelDrawImageViews; 334 vk::Sampler mSampler; 335 336 RenderTargetVk mRenderTarget; 337 std::vector<vk::ImageView> mLayerFetchImageView; 338 std::vector<RenderTargetVk> m3DRenderTargets; 339 std::vector<RenderTargetVk> mCubeMapRenderTargets; 340 341 // The serial is used for cache indexing. 342 Serial mSerial; 343 344 // Overridden in some tests. 345 size_t mStagingBufferInitialSize; 346 }; 347 348 } // namespace rx 349 350 #endif // LIBANGLE_RENDERER_VULKAN_TEXTUREVK_H_ 351