Hash :
d1860ea1
Author :
Date :
2019-11-19T23:04:00
Metal: support OES_depth_texture Also added Depth32 & Depth16 texture data upload tests. Bug: angleproject:2634 Change-Id: I103f1cda1dc915f0dc8b04f7aaa2d8c0f9220cda Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1919281 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-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
//
// Copyright 2019 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.
//
// mtl_resources.h:
// Declares wrapper classes for Metal's MTLTexture and MTLBuffer.
//
#ifndef LIBANGLE_RENDERER_METAL_MTL_RESOURCES_H_
#define LIBANGLE_RENDERER_METAL_MTL_RESOURCES_H_
#import <Metal/Metal.h>
#include <atomic>
#include <memory>
#include "common/FastVector.h"
#include "common/MemoryBuffer.h"
#include "common/angleutils.h"
#include "libANGLE/Error.h"
#include "libANGLE/ImageIndex.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/metal/mtl_common.h"
#include "libANGLE/renderer/metal/mtl_format_utils.h"
namespace rx
{
class ContextMtl;
namespace mtl
{
class CommandQueue;
class BlitCommandEncoder;
class Resource;
class Texture;
class Buffer;
using ResourceRef = std::shared_ptr<Resource>;
using TextureRef = std::shared_ptr<Texture>;
using TextureWeakRef = std::weak_ptr<Texture>;
using BufferRef = std::shared_ptr<Buffer>;
using BufferWeakRef = std::weak_ptr<Buffer>;
class Resource : angle::NonCopyable
{
public:
virtual ~Resource() {}
bool isBeingUsedByGPU(Context *context) const;
void setUsedByCommandBufferWithQueueSerial(uint64_t serial, bool writing);
const std::atomic<uint64_t> &getCommandBufferQueueSerial() const
{
return mUsageRef->cmdBufferQueueSerial;
}
// Flag indicate whether we should synchornize the content to CPU after GPU changed this
// resource's content.
bool isCPUReadMemDirty() const { return mUsageRef->cpuReadMemDirty; }
void resetCPUReadMemDirty() { mUsageRef->cpuReadMemDirty = false; }
protected:
Resource();
// Share the GPU usage ref with other resource
Resource(Resource *other);
private:
struct UsageRef
{
// The id of the last command buffer that is using this resource.
std::atomic<uint64_t> cmdBufferQueueSerial{0};
// NOTE(hqle): resource dirty handle is not threadsafe.
// This flag means the resource was issued to be modified by GPU, if CPU wants to read
// its content, explicit synchornization call must be invoked.
bool cpuReadMemDirty = false;
};
// One resource object might just be a view of another resource. For example, a texture 2d
// object might be a view of one face of a cube texture object. Another example is one texture
// object of size 2x2 might be a mipmap view of a texture object size 4x4. Thus, if one object
// is being used by a command buffer, it means the other object is being used also. In this
// case, the two objects must share the same UsageRef property.
std::shared_ptr<UsageRef> mUsageRef;
};
class Texture final : public Resource,
public WrappedObject<id<MTLTexture>>,
public std::enable_shared_from_this<Texture>
{
public:
static angle::Result Make2DTexture(ContextMtl *context,
const Format &format,
uint32_t width,
uint32_t height,
uint32_t mips /** use zero to create full mipmaps chain */,
bool renderTargetOnly,
bool allowTextureView,
TextureRef *refOut);
static angle::Result MakeCubeTexture(ContextMtl *context,
const Format &format,
uint32_t size,
uint32_t mips /** use zero to create full mipmaps chain */,
bool renderTargetOnly,
bool allowTextureView,
TextureRef *refOut);
static TextureRef MakeFromMetal(id<MTLTexture> metalTexture);
// Allow CPU to read & write data directly to this texture?
bool isCPUAccessible() const;
void replaceRegion(ContextMtl *context,
MTLRegion region,
uint32_t mipmapLevel,
uint32_t slice,
const uint8_t *data,
size_t bytesPerRow);
// read pixel data from slice 0
void getBytes(ContextMtl *context,
size_t bytesPerRow,
MTLRegion region,
uint32_t mipmapLevel,
uint8_t *dataOut);
// Create 2d view of a cube face which full range of mip levels.
TextureRef createCubeFaceView(uint32_t face);
// Create a view of one slice at a level.
TextureRef createSliceMipView(uint32_t slice, uint32_t level);
// Create a view with different format
TextureRef createViewWithDifferentFormat(MTLPixelFormat format);
MTLTextureType textureType() const;
MTLPixelFormat pixelFormat() const;
uint32_t mipmapLevels() const;
uint32_t width(uint32_t level = 0) const;
uint32_t height(uint32_t level = 0) const;
gl::Extents size(uint32_t level = 0) const;
gl::Extents size(const gl::ImageIndex &index) const;
// For render target
MTLColorWriteMask getColorWritableMask() const { return *mColorWritableMask; }
void setColorWritableMask(MTLColorWriteMask mask) { *mColorWritableMask = mask; }
// Change the wrapped metal object. Special case for swapchain image
void set(id<MTLTexture> metalTexture);
// sync content between CPU and GPU
void syncContent(ContextMtl *context, mtl::BlitCommandEncoder *encoder);
private:
using ParentClass = WrappedObject<id<MTLTexture>>;
Texture(id<MTLTexture> metalTexture);
Texture(ContextMtl *context,
MTLTextureDescriptor *desc,
uint32_t mips,
bool renderTargetOnly,
bool supportTextureView);
// Create a texture view
Texture(Texture *original, MTLPixelFormat format);
Texture(Texture *original, MTLTextureType type, NSRange mipmapLevelRange, uint32_t slice);
void syncContent(ContextMtl *context);
// This property is shared between this object and its views:
std::shared_ptr<MTLColorWriteMask> mColorWritableMask;
};
class Buffer final : public Resource, public WrappedObject<id<MTLBuffer>>
{
public:
static angle::Result MakeBuffer(ContextMtl *context,
size_t size,
const uint8_t *data,
BufferRef *bufferOut);
angle::Result reset(ContextMtl *context, size_t size, const uint8_t *data);
uint8_t *map(ContextMtl *context);
void unmap(ContextMtl *context);
size_t size() const;
private:
Buffer(ContextMtl *context, size_t size, const uint8_t *data);
};
} // namespace mtl
} // namespace rx
#endif /* LIBANGLE_RENDERER_METAL_MTL_RESOURCES_H_ */