Cocoa Port: Metal display views can now handle the possibility where the fetched main and touch display framebuffers are in different colorspaces.

This commit is contained in:
rogerman 2021-09-16 15:16:37 -07:00
parent ff28ca6df5
commit c6d35f9894
5 changed files with 118 additions and 75 deletions

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2018 DeSmuME team Copyright (C) 2018-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -25,5 +25,6 @@ uchar4 pack_unorm8888_to_rgba6665(const float4 inColor);
uchar4 pack_unorm8888_to_rgba8888(const float4 inColor); uchar4 pack_unorm8888_to_rgba8888(const float4 inColor);
float4 convert_unorm666X_to_unorm8888(const float4 inColor); float4 convert_unorm666X_to_unorm8888(const float4 inColor);
float4 convert_unorm888X_to_unorm8888(const float4 inColor);
#endif // _METAL_RENDERER_COMMON_H_ #endif // _METAL_RENDERER_COMMON_H_

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2018 DeSmuME team Copyright (C) 2018-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -54,3 +54,8 @@ float4 convert_unorm666X_to_unorm8888(const float4 inColor)
{ {
return float4( inColor.rgb * (255.0f/63.0f), 1.0f ); return float4( inColor.rgb * (255.0f/63.0f), 1.0f );
} }
float4 convert_unorm888X_to_unorm8888(const float4 inColor)
{
return float4(inColor.rgb, 1.0f);
}

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2017-2018 DeSmuME team Copyright (C) 2017-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -95,6 +95,7 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties;
id<MTLComputePipelineState> _fetch888Pipeline; id<MTLComputePipelineState> _fetch888Pipeline;
id<MTLComputePipelineState> _fetch555ConvertOnlyPipeline; id<MTLComputePipelineState> _fetch555ConvertOnlyPipeline;
id<MTLComputePipelineState> _fetch666ConvertOnlyPipeline; id<MTLComputePipelineState> _fetch666ConvertOnlyPipeline;
id<MTLComputePipelineState> _fetch888ConvertOnlyPipeline;
id<MTLComputePipelineState> deposterizePipeline; id<MTLComputePipelineState> deposterizePipeline;
id<MTLRenderPipelineState> hudPipeline; id<MTLRenderPipelineState> hudPipeline;
id<MTLRenderPipelineState> hudRGBAPipeline; id<MTLRenderPipelineState> hudRGBAPipeline;

View File

@ -81,6 +81,9 @@
[computePipelineDesc setComputeFunction:[defaultLibrary newFunctionWithName:@"convert_texture_unorm666X_to_unorm8888"]]; [computePipelineDesc setComputeFunction:[defaultLibrary newFunctionWithName:@"convert_texture_unorm666X_to_unorm8888"]];
_fetch666ConvertOnlyPipeline = [[device newComputePipelineStateWithDescriptor:computePipelineDesc options:MTLPipelineOptionNone reflection:nil error:nil] retain]; _fetch666ConvertOnlyPipeline = [[device newComputePipelineStateWithDescriptor:computePipelineDesc options:MTLPipelineOptionNone reflection:nil error:nil] retain];
[computePipelineDesc setComputeFunction:[defaultLibrary newFunctionWithName:@"convert_texture_unorm888X_to_unorm8888"]];
_fetch888ConvertOnlyPipeline = [[device newComputePipelineStateWithDescriptor:computePipelineDesc options:MTLPipelineOptionNone reflection:nil error:nil] retain];
[computePipelineDesc setComputeFunction:[defaultLibrary newFunctionWithName:@"src_filter_deposterize"]]; [computePipelineDesc setComputeFunction:[defaultLibrary newFunctionWithName:@"src_filter_deposterize"]];
deposterizePipeline = [[device newComputePipelineStateWithDescriptor:computePipelineDesc options:MTLPipelineOptionNone reflection:nil error:nil] retain]; deposterizePipeline = [[device newComputePipelineStateWithDescriptor:computePipelineDesc options:MTLPipelineOptionNone reflection:nil error:nil] retain];
@ -280,6 +283,7 @@
[_fetch888Pipeline release]; [_fetch888Pipeline release];
[_fetch555ConvertOnlyPipeline release]; [_fetch555ConvertOnlyPipeline release];
[_fetch666ConvertOnlyPipeline release]; [_fetch666ConvertOnlyPipeline release];
[_fetch888ConvertOnlyPipeline release];
[deposterizePipeline release]; [deposterizePipeline release];
[hudPipeline release]; [hudPipeline release];
[hudRGBAPipeline release]; [hudRGBAPipeline release];
@ -458,6 +462,8 @@
const NDSDisplayInfo &currentDisplayInfo = GPUFetchObject->GetFetchDisplayInfoForBufferIndex(index); const NDSDisplayInfo &currentDisplayInfo = GPUFetchObject->GetFetchDisplayInfoForBufferIndex(index);
const bool isMainEnabled = currentDisplayInfo.isDisplayEnabled[NDSDisplayID_Main]; const bool isMainEnabled = currentDisplayInfo.isDisplayEnabled[NDSDisplayID_Main];
const bool isTouchEnabled = currentDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch]; const bool isTouchEnabled = currentDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch];
const bool isMainNative = !currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Main];
const bool isTouchNative = !currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch];
MetalTexturePair targetTexPair = {index, currentDisplayInfo.sequenceNumber, nil, nil}; MetalTexturePair targetTexPair = {index, currentDisplayInfo.sequenceNumber, nil, nil};
@ -465,7 +471,7 @@
{ {
if (isMainEnabled) if (isMainEnabled)
{ {
if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Main]) if (isMainNative)
{ {
targetTexPair.main = _texDisplayFetchNative[NDSDisplayID_Main][index]; targetTexPair.main = _texDisplayFetchNative[NDSDisplayID_Main][index];
} }
@ -477,7 +483,7 @@
if (isTouchEnabled) if (isTouchEnabled)
{ {
if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch]) if (isTouchNative)
{ {
targetTexPair.touch = _texDisplayFetchNative[NDSDisplayID_Touch][index]; targetTexPair.touch = _texDisplayFetchNative[NDSDisplayID_Touch][index];
} }
@ -491,22 +497,21 @@
{ {
id<MTLComputeCommandEncoder> cce = [cb computeCommandEncoder]; id<MTLComputeCommandEncoder> cce = [cb computeCommandEncoder];
if (currentDisplayInfo.colorFormat == NDSColorFormat_BGR555_Rev)
{
[cce setComputePipelineState:_fetch555Pipeline];
}
else if ( (currentDisplayInfo.colorFormat == NDSColorFormat_BGR666_Rev) &&
(currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Main] || currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Touch]) )
{
[cce setComputePipelineState:_fetch666Pipeline];
}
else
{
[cce setComputePipelineState:_fetch888Pipeline];
}
if (isMainEnabled) if (isMainEnabled)
{ {
if (currentDisplayInfo.colorFormat == NDSColorFormat_BGR555_Rev)
{
[cce setComputePipelineState:_fetch555Pipeline];
}
else if ( (currentDisplayInfo.colorFormat == NDSColorFormat_BGR666_Rev) && currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Main] )
{
[cce setComputePipelineState:_fetch666Pipeline];
}
else
{
[cce setComputePipelineState:_fetch888Pipeline];
}
memcpy([_bufMasterBrightMode[NDSDisplayID_Main][index] contents], currentDisplayInfo.masterBrightnessMode[NDSDisplayID_Main], sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT); memcpy([_bufMasterBrightMode[NDSDisplayID_Main][index] contents], currentDisplayInfo.masterBrightnessMode[NDSDisplayID_Main], sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
memcpy([_bufMasterBrightIntensity[NDSDisplayID_Main][index] contents], currentDisplayInfo.masterBrightnessIntensity[NDSDisplayID_Main], sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT); memcpy([_bufMasterBrightIntensity[NDSDisplayID_Main][index] contents], currentDisplayInfo.masterBrightnessIntensity[NDSDisplayID_Main], sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
[_bufMasterBrightMode[NDSDisplayID_Main][index] didModifyRange:NSMakeRange(0, sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT)]; [_bufMasterBrightMode[NDSDisplayID_Main][index] didModifyRange:NSMakeRange(0, sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT)];
@ -515,7 +520,7 @@
[cce setBuffer:_bufMasterBrightMode[NDSDisplayID_Main][index] offset:0 atIndex:0]; [cce setBuffer:_bufMasterBrightMode[NDSDisplayID_Main][index] offset:0 atIndex:0];
[cce setBuffer:_bufMasterBrightIntensity[NDSDisplayID_Main][index] offset:0 atIndex:1]; [cce setBuffer:_bufMasterBrightIntensity[NDSDisplayID_Main][index] offset:0 atIndex:1];
if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Main]) if (isMainNative)
{ {
[cce setTexture:_texDisplayFetchNative[NDSDisplayID_Main][index] atIndex:0]; [cce setTexture:_texDisplayFetchNative[NDSDisplayID_Main][index] atIndex:0];
[cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Main][index] atIndex:1]; [cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Main][index] atIndex:1];
@ -537,6 +542,19 @@
if (isTouchEnabled) if (isTouchEnabled)
{ {
if (currentDisplayInfo.colorFormat == NDSColorFormat_BGR555_Rev)
{
[cce setComputePipelineState:_fetch555Pipeline];
}
else if ( (currentDisplayInfo.colorFormat == NDSColorFormat_BGR666_Rev) && currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Touch] )
{
[cce setComputePipelineState:_fetch666Pipeline];
}
else
{
[cce setComputePipelineState:_fetch888Pipeline];
}
memcpy([_bufMasterBrightMode[NDSDisplayID_Touch][index] contents], currentDisplayInfo.masterBrightnessMode[NDSDisplayID_Touch], sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT); memcpy([_bufMasterBrightMode[NDSDisplayID_Touch][index] contents], currentDisplayInfo.masterBrightnessMode[NDSDisplayID_Touch], sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
memcpy([_bufMasterBrightIntensity[NDSDisplayID_Touch][index] contents], currentDisplayInfo.masterBrightnessIntensity[NDSDisplayID_Touch], sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT); memcpy([_bufMasterBrightIntensity[NDSDisplayID_Touch][index] contents], currentDisplayInfo.masterBrightnessIntensity[NDSDisplayID_Touch], sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT);
[_bufMasterBrightMode[NDSDisplayID_Touch][index] didModifyRange:NSMakeRange(0, sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT)]; [_bufMasterBrightMode[NDSDisplayID_Touch][index] didModifyRange:NSMakeRange(0, sizeof(uint8_t) * GPU_FRAMEBUFFER_NATIVE_HEIGHT)];
@ -545,7 +563,7 @@
[cce setBuffer:_bufMasterBrightMode[NDSDisplayID_Touch][index] offset:0 atIndex:0]; [cce setBuffer:_bufMasterBrightMode[NDSDisplayID_Touch][index] offset:0 atIndex:0];
[cce setBuffer:_bufMasterBrightIntensity[NDSDisplayID_Touch][index] offset:0 atIndex:1]; [cce setBuffer:_bufMasterBrightIntensity[NDSDisplayID_Touch][index] offset:0 atIndex:1];
if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch]) if (isTouchNative)
{ {
[cce setTexture:_texDisplayFetchNative[NDSDisplayID_Touch][index] atIndex:0]; [cce setTexture:_texDisplayFetchNative[NDSDisplayID_Touch][index] atIndex:0];
[cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Touch][index] atIndex:1]; [cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Touch][index] atIndex:1];
@ -570,65 +588,75 @@
else if (currentDisplayInfo.colorFormat != NDSColorFormat_BGR888_Rev) else if (currentDisplayInfo.colorFormat != NDSColorFormat_BGR888_Rev)
{ {
id<MTLComputeCommandEncoder> cce = [cb computeCommandEncoder]; id<MTLComputeCommandEncoder> cce = [cb computeCommandEncoder];
bool isPipelineStateSet = false;
if (currentDisplayInfo.colorFormat == NDSColorFormat_BGR555_Rev) if (isMainEnabled)
{ {
// 16-bit textures aren't handled natively in Metal for macOS, so we need to explicitly convert to 32-bit here. if (currentDisplayInfo.colorFormat == NDSColorFormat_BGR555_Rev)
[cce setComputePipelineState:_fetch555ConvertOnlyPipeline];
isPipelineStateSet = true;
}
else if ( (currentDisplayInfo.colorFormat == NDSColorFormat_BGR666_Rev) &&
(currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Main] || currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Touch]) )
{
[cce setComputePipelineState:_fetch666ConvertOnlyPipeline];
isPipelineStateSet = true;
}
if (isPipelineStateSet)
{
if (isMainEnabled)
{ {
if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Main]) // 16-bit textures aren't handled natively in Metal for macOS, so we need to explicitly convert to 32-bit here.
{ [cce setComputePipelineState:_fetch555ConvertOnlyPipeline];
[cce setTexture:_texDisplayFetchNative[NDSDisplayID_Main][index] atIndex:0]; }
[cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Main][index] atIndex:1]; else if ( (currentDisplayInfo.colorFormat == NDSColorFormat_BGR666_Rev) && currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Main] )
[cce dispatchThreadgroups:_fetchThreadGroupsPerGridNative {
threadsPerThreadgroup:_fetchThreadsPerGroupNative]; [cce setComputePipelineState:_fetch666ConvertOnlyPipeline];
}
targetTexPair.main = _texDisplayPostprocessNative[NDSDisplayID_Main][index]; else
} {
else [cce setComputePipelineState:_fetch888ConvertOnlyPipeline];
{
[cce setTexture:_texDisplayFetchCustom[NDSDisplayID_Main][index] atIndex:0];
[cce setTexture:_texDisplayPostprocessCustom[NDSDisplayID_Main][index] atIndex:1];
[cce dispatchThreadgroups:_fetchThreadGroupsPerGridCustom
threadsPerThreadgroup:_fetchThreadsPerGroupCustom];
targetTexPair.main = _texDisplayPostprocessCustom[NDSDisplayID_Main][index];
}
} }
if (isTouchEnabled) if (isMainNative)
{ {
if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch]) [cce setTexture:_texDisplayFetchNative[NDSDisplayID_Main][index] atIndex:0];
{ [cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Main][index] atIndex:1];
[cce setTexture:_texDisplayFetchNative[NDSDisplayID_Touch][index] atIndex:0]; [cce dispatchThreadgroups:_fetchThreadGroupsPerGridNative
[cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Touch][index] atIndex:1]; threadsPerThreadgroup:_fetchThreadsPerGroupNative];
[cce dispatchThreadgroups:_fetchThreadGroupsPerGridNative
threadsPerThreadgroup:_fetchThreadsPerGroupNative];
targetTexPair.touch = _texDisplayPostprocessNative[NDSDisplayID_Touch][index]; targetTexPair.main = _texDisplayPostprocessNative[NDSDisplayID_Main][index];
} }
else else
{ {
[cce setTexture:_texDisplayFetchCustom[NDSDisplayID_Touch][index] atIndex:0]; [cce setTexture:_texDisplayFetchCustom[NDSDisplayID_Main][index] atIndex:0];
[cce setTexture:_texDisplayPostprocessCustom[NDSDisplayID_Touch][index] atIndex:1]; [cce setTexture:_texDisplayPostprocessCustom[NDSDisplayID_Main][index] atIndex:1];
[cce dispatchThreadgroups:_fetchThreadGroupsPerGridCustom [cce dispatchThreadgroups:_fetchThreadGroupsPerGridCustom
threadsPerThreadgroup:_fetchThreadsPerGroupCustom]; threadsPerThreadgroup:_fetchThreadsPerGroupCustom];
targetTexPair.touch = _texDisplayPostprocessCustom[NDSDisplayID_Touch][index]; targetTexPair.main = _texDisplayPostprocessCustom[NDSDisplayID_Main][index];
} }
}
if (isTouchEnabled)
{
if (currentDisplayInfo.colorFormat == NDSColorFormat_BGR555_Rev)
{
[cce setComputePipelineState:_fetch555ConvertOnlyPipeline];
}
else if ( (currentDisplayInfo.colorFormat == NDSColorFormat_BGR666_Rev) && currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Touch] )
{
[cce setComputePipelineState:_fetch666ConvertOnlyPipeline];
}
else
{
[cce setComputePipelineState:_fetch888ConvertOnlyPipeline];
}
if (isTouchNative)
{
[cce setTexture:_texDisplayFetchNative[NDSDisplayID_Touch][index] atIndex:0];
[cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Touch][index] atIndex:1];
[cce dispatchThreadgroups:_fetchThreadGroupsPerGridNative
threadsPerThreadgroup:_fetchThreadsPerGroupNative];
targetTexPair.touch = _texDisplayPostprocessNative[NDSDisplayID_Touch][index];
}
else
{
[cce setTexture:_texDisplayFetchCustom[NDSDisplayID_Touch][index] atIndex:0];
[cce setTexture:_texDisplayPostprocessCustom[NDSDisplayID_Touch][index] atIndex:1];
[cce dispatchThreadgroups:_fetchThreadGroupsPerGridCustom
threadsPerThreadgroup:_fetchThreadsPerGroupCustom];
targetTexPair.touch = _texDisplayPostprocessCustom[NDSDisplayID_Touch][index];
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2017-2018 DeSmuME team Copyright (C) 2017-2021 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -491,6 +491,14 @@ kernel void convert_texture_unorm666X_to_unorm8888(const uint2 position [[thread
outTexture.write(outColor, position); outTexture.write(outColor, position);
} }
kernel void convert_texture_unorm888X_to_unorm8888(const uint2 position [[thread_position_in_grid]],
const texture2d<float, access::read> inTexture [[texture(0)]],
texture2d<float, access::write> outTexture [[texture(1)]])
{
const float4 outColor = convert_unorm888X_to_unorm8888( inTexture.read(position) );
outTexture.write(outColor, position);
}
float3 nds_apply_master_brightness(const float3 inColor, const uchar mode, const float intensity) float3 nds_apply_master_brightness(const float3 inColor, const uchar mode, const float intensity)
{ {
switch (mode) switch (mode)