Metal support RC0 released

Hi. I’m testing cocos v4 on macOS and iOS, and it looks like shaders are not working when they are applied to SpriteBatchNodes. They only work on Sprites that are not part of a batchNode.
Is there anything else I should do apart from assigning the shader (backend::ProgramState) to the SpriteBatchNode with setProgramState?

@kmaker it is better that you provide a demo to describe it.

@zhangxm please take a look to the code below. Shader is not being applied when set on the batch node:

std::string fileImage = "sample.png";
SpriteBatchNode* batch = SpriteBatchNode::create(fileImage);
batch->setProgramState(new (std::nothrow) backend::ProgramState(program));
addChild(batch);

Rect rect;
rect.size = batch->getTexture()->getContentSize();
Sprite* bg = Sprite::createWithTexture(batch->getTexture(), rect);
bg->setBatchNode(batch);
bg->setAnchorPoint(Vec2(0,0));
batch->addChild(bg);

but if it is applied directly to the Sprite, it works:

Sprite* bg1 = Sprite::create(fileImage);
bg1->setAnchorPoint(Vec2(0,0));
bg1->setProgramState(new (std::nothrow) backend::ProgramState(program));
addChild(bg1);

Am I missing something?

@kmaker What’s your program type?

I tried a few. Here’s one:

auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::GRAY_SCALE);

@kmaker fixed in PR 20344.

Perfect! It’s working now. Thanks

Hi. Why is instance variable backend::ProgramState* _programState duplicated on so many classes? It is already defined on superclass Node.
This leads to unwanted behaviour. For example, if you set a ProgramState on a Label and then retrieve it using getProgramState, you will get a different one! That’s because getProgramState is defined by Node, and so the the ivar returned is the one from Node rather than Label.

@kmaker yep, it’s duplicated. We forgot to remove the _programState in derived classes. Fixed in PR 20350

Great! Thanks for fixing it so quickly.

I’m having a Metal related error when a ClippingRectangleNode has a negative Y pos. I see a message on console:

-[MTLDebugRenderCommandEncoder setScissorRect:]:2703: failed assertion `(rect.y(1556) + rect.height(0))(1556) must be <= render pass height(1536)'

I guess CommandBufferMTL::setScissorRect needs to clamp values before they go to Metal.

This code should reproduce the error:

auto n = ClippingRectangleNode::create();
n->setPosition(Vec2(0, -10));
addChild(n);

auto s = Sprite::create("sample.png");
n->addChild(s);

@kmaker It has already fixed in PR 20348, you can update to the latest.

Thanks @coulsonwang

Another question: is v4 dropping support for tvOS?
I’ve made a quick test adding a tvOS target to cocos to generate the lib and was able to launch an app on tvOS simulator (using prebuilt libs from iOS), but it crashed because DeviceInfoMTL does not recognise the FeatureSet and textures cannot be created.
If I manually set the _featureSet on DeviceInfoMTL instance, the app runs without problems.

It would be great if you can keep tvOS support from v3 to v4, specially being so close of getting it right.

@kmaker we have not resource to support tvOS, we can not make sure if it works or not. But if somebody found a bug and send a PR, then we will consider to merge it if it doesn’t break iOS.

1 Like

Ok @zhangxm, I’ll try to help with that as much as I can.

2 Likes