for MTL layer

This commit is contained in:
halx99 2019-11-22 22:10:55 -08:00
parent c08e2cda4d
commit c180c29d32
4 changed files with 63 additions and 30 deletions

View File

@ -1448,7 +1448,11 @@ bool Image::initWithETCData(const unsigned char* data, ssize_t dataLen, bool own
//old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy. //old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy.
#if defined(GL_ETC1_RGB8_OES) || defined(CC_USE_METAL) #if defined(GL_ETC1_RGB8_OES) || defined(CC_USE_METAL)
_pixelFormat = backend::PixelFormat::ETC; _pixelFormat = backend::PixelFormat::ETC;
_data = data; if(ownData) _data = (unsigned char*)data;
else {
_data = (unsigned char*)malloc(dataLen);
if(_data) memcpy(_data, data, dataLen);
}
_dataLen = dataLen; _dataLen = dataLen;
_offset = ETC_PKM_HEADER_SIZE; _offset = ETC_PKM_HEADER_SIZE;
return true; return true;

View File

@ -104,7 +104,7 @@ public:
*/ */
inline bool hasMipmaps() const { return _hasMipmaps; } inline bool hasMipmaps() const { return _hasMipmaps; }
virtual int getCount() const = 0; virtual int getCount() const { return 1; };
protected: protected:
/** /**

View File

@ -27,6 +27,7 @@
#include "../Texture.h" #include "../Texture.h"
#include "DeviceMTL.h" #include "DeviceMTL.h"
#import <Metal/Metal.h> #import <Metal/Metal.h>
#include <array>
CC_BACKEND_BEGIN CC_BACKEND_BEGIN
/** /**
@ -54,7 +55,7 @@ public:
* @param height Specifies the height of the texture image. * @param height Specifies the height of the texture image.
* @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image. * @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
*/ */
virtual void updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level) override; virtual void updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level, int index = 0) override;
/** /**
* Update a two-dimensional texture image in a compressed format * Update a two-dimensional texture image in a compressed format
@ -75,7 +76,7 @@ public:
* @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image. * @param level Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
* @param data Specifies a pointer to the image data in memory. * @param data Specifies a pointer to the image data in memory.
*/ */
virtual void updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data) override; virtual void updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data, int index = 0) override;
/** /**
* Update a two-dimensional texture subimage in a compressed format * Update a two-dimensional texture subimage in a compressed format
@ -93,7 +94,7 @@ public:
* Update sampler * Update sampler
* @param sampler Specifies the sampler descriptor. * @param sampler Specifies the sampler descriptor.
*/ */
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler) override; virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler, int index = 0) override;
/** /**
* Read a block of pixels from the drawable texture * Read a block of pixels from the drawable texture
@ -113,13 +114,17 @@ public:
* Update texture description. * Update texture description.
* @param descriptor Specifies texture and sampler descriptor. * @param descriptor Specifies texture and sampler descriptor.
*/ */
virtual void updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor) override; virtual void updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index = 0) override;
int getCount() const override { return _mtlMaxTexIdx + 1; };
id<MTLTexture> ensure(int index);
/** /**
* Get MTLTexture object. * Get MTLTexture object.
* @return A MTLTexture object. * @return A MTLTexture object.
*/ */
inline id<MTLTexture> getMTLTexture() const { return _mtlTexture; } inline id<MTLTexture> getMTLTexture() const { return _mtlTextures[0]; }
/** /**
* Get MTLSamplerState object * Get MTLSamplerState object
@ -128,7 +133,7 @@ public:
inline id<MTLSamplerState> getMTLSamplerState() const { return _mtlSamplerState; } inline id<MTLSamplerState> getMTLSamplerState() const { return _mtlSamplerState; }
private: private:
void createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor); void createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor, int index);
void createSampler(id<MTLDevice> mtlDevice, const SamplerDescriptor& descriptor); void createSampler(id<MTLDevice> mtlDevice, const SamplerDescriptor& descriptor);
MTLSamplerAddressMode _sAddressMode; MTLSamplerAddressMode _sAddressMode;
@ -137,8 +142,11 @@ private:
MTLSamplerMinMagFilter _magFilter; MTLSamplerMinMagFilter _magFilter;
MTLSamplerMipFilter _mipFilter; MTLSamplerMipFilter _mipFilter;
TextureDescriptor _textureDescriptor;
id<MTLDevice> _mtlDevice = nil; id<MTLDevice> _mtlDevice = nil;
id<MTLTexture> _mtlTexture = nil; std::array<id<MTLTexture>, CC_META_TEXTURES + 1> _mtlTextures;
int _mtlMaxTexIdx = 0;
id<MTLSamplerState> _mtlSamplerState = nil; id<MTLSamplerState> _mtlSamplerState = nil;
unsigned int _bytesPerRow = 0; unsigned int _bytesPerRow = 0;
}; };
@ -160,7 +168,7 @@ public:
* Update sampler * Update sampler
* @param sampler Specifies the sampler descriptor. * @param sampler Specifies the sampler descriptor.
*/ */
virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler) override; virtual void updateSamplerDescriptor(const SamplerDescriptor &sampler, int index = 0) override;
/** /**
* Update texutre cube data in give slice side. * Update texutre cube data in give slice side.
@ -187,7 +195,7 @@ public:
* Update texture description. * Update texture description.
* @param descriptor Specifies texture and sampler descriptor. * @param descriptor Specifies texture and sampler descriptor.
*/ */
virtual void updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor) override; virtual void updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index = 0) override;
/** /**
* Get MTLTexture object. * Get MTLTexture object.

View File

@ -193,25 +193,31 @@ TextureMTL::TextureMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descrip
: backend::Texture2DBackend(descriptor) : backend::Texture2DBackend(descriptor)
{ {
_mtlDevice = mtlDevice; _mtlDevice = mtlDevice;
_mtlTextures.fill(nil);
updateTextureDescriptor(descriptor); updateTextureDescriptor(descriptor);
} }
TextureMTL::~TextureMTL() TextureMTL::~TextureMTL()
{ {
[_mtlTexture release]; id<MTLTexture> texture;
int i = 0;
while((texture = _mtlTextures[i++]))
[texture release];
[_mtlSamplerState release]; [_mtlSamplerState release];
} }
void TextureMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler) void TextureMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int index)
{ {
createSampler(_mtlDevice, sampler); createSampler(_mtlDevice, sampler);
} }
void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor) void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
{ {
TextureBackend::updateTextureDescriptor(descriptor); _textureDescriptor = descriptor;
createTexture(_mtlDevice, descriptor); TextureBackend::updateTextureDescriptor(descriptor, index);
updateSamplerDescriptor(descriptor.samplerDescriptor); createTexture(_mtlDevice, descriptor, index);
updateSamplerDescriptor(descriptor.samplerDescriptor, index);
if (PixelFormat::RGB888 == _textureFormat) if (PixelFormat::RGB888 == _textureFormat)
{ {
_bitsPerElement = 4 * 8; _bitsPerElement = 4 * 8;
@ -220,13 +226,16 @@ void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescript
_bytesPerRow = descriptor.width * _bitsPerElement / 8 ; _bytesPerRow = descriptor.width * _bitsPerElement / 8 ;
} }
void TextureMTL::updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level) void TextureMTL::updateData(uint8_t* data, std::size_t width , std::size_t height, std::size_t level, int index)
{ {
updateSubData(0, 0, width, height, level, data); updateSubData(0, 0, width, height, level, data, index);
} }
void TextureMTL::updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data) void TextureMTL::updateSubData(std::size_t xoffset, std::size_t yoffset, std::size_t width, std::size_t height, std::size_t level, uint8_t* data, int index)
{ {
auto mtlTexture = ensure(index);
if(!mtlTexture) return;
MTLRegion region = MTLRegion region =
{ {
{xoffset, yoffset, 0}, // MTLOrigin {xoffset, yoffset, 0}, // MTLOrigin
@ -240,7 +249,7 @@ void TextureMTL::updateSubData(std::size_t xoffset, std::size_t yoffset, std::si
std::size_t bytesPerRow = getBytesPerRow(_textureFormat, width, _bitsPerElement); std::size_t bytesPerRow = getBytesPerRow(_textureFormat, width, _bitsPerElement);
[_mtlTexture replaceRegion:region [mtlTexture replaceRegion:region
mipmapLevel:level mipmapLevel:level
withBytes:convertedData withBytes:convertedData
bytesPerRow:bytesPerRow]; bytesPerRow:bytesPerRow];
@ -262,7 +271,7 @@ void TextureMTL::updateCompressedSubData(std::size_t xoffset, std::size_t yoffse
updateSubData(xoffset, yoffset, width, height, level, data); updateSubData(xoffset, yoffset, width, height, level, data);
} }
void TextureMTL::createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor) void TextureMTL::createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor, int index)
{ {
MTLPixelFormat pixelFormat = Utils::toMTLPixelFormat(descriptor.textureFormat); MTLPixelFormat pixelFormat = Utils::toMTLPixelFormat(descriptor.textureFormat);
if(pixelFormat == MTLPixelFormatInvalid) if(pixelFormat == MTLPixelFormatInvalid)
@ -282,9 +291,10 @@ void TextureMTL::createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor&
textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
} }
if(_mtlTexture) id<MTLTexture>& mtlTexture = _mtlTextures[index];
[_mtlTexture release]; if(mtlTexture)
_mtlTexture = [mtlDevice newTextureWithDescriptor:textureDescriptor]; [mtlTexture release];
mtlTexture = [mtlDevice newTextureWithDescriptor:textureDescriptor];
} }
void TextureMTL::createSampler(id<MTLDevice> mtlDevice, const SamplerDescriptor &descriptor) void TextureMTL::createSampler(id<MTLDevice> mtlDevice, const SamplerDescriptor &descriptor)
@ -339,7 +349,7 @@ void TextureMTL::getBytes(std::size_t x, std::size_t y, std::size_t width, std::
} }
}; };
auto flipImageCallback = std::bind(flipImageFunc, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto flipImageCallback = std::bind(flipImageFunc, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
Utils::getTextureBytes(x, y, width, height, _mtlTexture, flipImageCallback); Utils::getTextureBytes(x, y, width, height, _mtlTextures[0], flipImageCallback);
} }
void TextureMTL::generateMipmaps() void TextureMTL::generateMipmaps()
@ -350,11 +360,22 @@ void TextureMTL::generateMipmaps()
if(!_hasMipmaps) if(!_hasMipmaps)
{ {
_hasMipmaps = true; _hasMipmaps = true;
Utils::generateMipmaps(_mtlTexture); Utils::generateMipmaps(_mtlTextures[0]);
} }
} }
id<MTLTexture> TextureMTL::ensure(int index)
{
if(index < CC_META_TEXTURES) {
id<MTLTexture>& mtlTexture = _mtlTextures[index];
if(mtlTexture) return mtlTexture;
createTexture(_mtlDevice, _textureDescriptor, index);
if(_mtlMaxTexIdx < index) _mtlMaxTexIdx = index;
return mtlTexture;
}
return nil;
}
TextureCubeMTL::TextureCubeMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor) TextureCubeMTL::TextureCubeMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descriptor)
: backend::TextureCubemapBackend(descriptor) : backend::TextureCubemapBackend(descriptor)
{ {
@ -368,7 +389,7 @@ TextureCubeMTL::~TextureCubeMTL()
[_mtlSamplerState release]; [_mtlSamplerState release];
} }
void TextureCubeMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor) void TextureCubeMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
{ {
TextureBackend::updateTextureDescriptor(descriptor); TextureBackend::updateTextureDescriptor(descriptor);
createTexture(_mtlDevice, descriptor); createTexture(_mtlDevice, descriptor);
@ -431,7 +452,7 @@ void TextureCubeMTL::createSampler(id<MTLDevice> mtlDevice, const SamplerDescrip
[mtlDescriptor release]; [mtlDescriptor release];
} }
void TextureCubeMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler) void TextureCubeMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int /*index*/)
{ {
createSampler(_mtlDevice, sampler); createSampler(_mtlDevice, sampler);
} }