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.
#if defined(GL_ETC1_RGB8_OES) || defined(CC_USE_METAL)
_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;
_offset = ETC_PKM_HEADER_SIZE;
return true;

View File

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

View File

@ -27,6 +27,7 @@
#include "../Texture.h"
#include "DeviceMTL.h"
#import <Metal/Metal.h>
#include <array>
CC_BACKEND_BEGIN
/**
@ -54,7 +55,7 @@ public:
* @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.
*/
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
@ -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 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
@ -93,7 +94,7 @@ public:
* Update sampler
* @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
@ -113,13 +114,17 @@ public:
* Update texture description.
* @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.
* @return A MTLTexture object.
*/
inline id<MTLTexture> getMTLTexture() const { return _mtlTexture; }
inline id<MTLTexture> getMTLTexture() const { return _mtlTextures[0]; }
/**
* Get MTLSamplerState object
@ -128,7 +133,7 @@ public:
inline id<MTLSamplerState> getMTLSamplerState() const { return _mtlSamplerState; }
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);
MTLSamplerAddressMode _sAddressMode;
@ -137,8 +142,11 @@ private:
MTLSamplerMinMagFilter _magFilter;
MTLSamplerMipFilter _mipFilter;
TextureDescriptor _textureDescriptor;
id<MTLDevice> _mtlDevice = nil;
id<MTLTexture> _mtlTexture = nil;
std::array<id<MTLTexture>, CC_META_TEXTURES + 1> _mtlTextures;
int _mtlMaxTexIdx = 0;
id<MTLSamplerState> _mtlSamplerState = nil;
unsigned int _bytesPerRow = 0;
};
@ -160,7 +168,7 @@ public:
* Update sampler
* @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.
@ -187,7 +195,7 @@ public:
* Update texture description.
* @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.

View File

@ -193,25 +193,31 @@ TextureMTL::TextureMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descrip
: backend::Texture2DBackend(descriptor)
{
_mtlDevice = mtlDevice;
_mtlTextures.fill(nil);
updateTextureDescriptor(descriptor);
}
TextureMTL::~TextureMTL()
{
[_mtlTexture release];
id<MTLTexture> texture;
int i = 0;
while((texture = _mtlTextures[i++]))
[texture release];
[_mtlSamplerState release];
}
void TextureMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler)
void TextureMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int index)
{
createSampler(_mtlDevice, sampler);
}
void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor)
void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
{
TextureBackend::updateTextureDescriptor(descriptor);
createTexture(_mtlDevice, descriptor);
updateSamplerDescriptor(descriptor.samplerDescriptor);
_textureDescriptor = descriptor;
TextureBackend::updateTextureDescriptor(descriptor, index);
createTexture(_mtlDevice, descriptor, index);
updateSamplerDescriptor(descriptor.samplerDescriptor, index);
if (PixelFormat::RGB888 == _textureFormat)
{
_bitsPerElement = 4 * 8;
@ -220,13 +226,16 @@ void TextureMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescript
_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 =
{
{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);
[_mtlTexture replaceRegion:region
[mtlTexture replaceRegion:region
mipmapLevel:level
withBytes:convertedData
bytesPerRow:bytesPerRow];
@ -262,7 +271,7 @@ void TextureMTL::updateCompressedSubData(std::size_t xoffset, std::size_t yoffse
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);
if(pixelFormat == MTLPixelFormatInvalid)
@ -282,9 +291,10 @@ void TextureMTL::createTexture(id<MTLDevice> mtlDevice, const TextureDescriptor&
textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
}
if(_mtlTexture)
[_mtlTexture release];
_mtlTexture = [mtlDevice newTextureWithDescriptor:textureDescriptor];
id<MTLTexture>& mtlTexture = _mtlTextures[index];
if(mtlTexture)
[mtlTexture release];
mtlTexture = [mtlDevice newTextureWithDescriptor:textureDescriptor];
}
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);
Utils::getTextureBytes(x, y, width, height, _mtlTexture, flipImageCallback);
Utils::getTextureBytes(x, y, width, height, _mtlTextures[0], flipImageCallback);
}
void TextureMTL::generateMipmaps()
@ -350,11 +360,22 @@ void TextureMTL::generateMipmaps()
if(!_hasMipmaps)
{
_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)
: backend::TextureCubemapBackend(descriptor)
{
@ -368,7 +389,7 @@ TextureCubeMTL::~TextureCubeMTL()
[_mtlSamplerState release];
}
void TextureCubeMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor)
void TextureCubeMTL::updateTextureDescriptor(const cocos2d::backend::TextureDescriptor &descriptor, int index)
{
TextureBackend::updateTextureDescriptor(descriptor);
createTexture(_mtlDevice, descriptor);
@ -431,7 +452,7 @@ void TextureCubeMTL::createSampler(id<MTLDevice> mtlDevice, const SamplerDescrip
[mtlDescriptor release];
}
void TextureCubeMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler)
void TextureCubeMTL::updateSamplerDescriptor(const SamplerDescriptor &sampler, int /*index*/)
{
createSampler(_mtlDevice, sampler);
}