From c6d35f9894ac91048b7152c328510a4a9dc24da2 Mon Sep 17 00:00:00 2001 From: rogerman Date: Thu, 16 Sep 2021 15:16:37 -0700 Subject: [PATCH] Cocoa Port: Metal display views can now handle the possibility where the fetched main and touch display framebuffers are in different colorspaces. --- .../cocoa/MetalRendererCommonShaders.h | 3 +- .../cocoa/MetalRendererCommonShaders.metal | 7 +- .../cocoa/userinterface/MacMetalDisplayView.h | 3 +- .../userinterface/MacMetalDisplayView.mm | 170 ++++++++++-------- .../MacMetalDisplayViewShaders.metal | 10 +- 5 files changed, 118 insertions(+), 75 deletions(-) diff --git a/desmume/src/frontend/cocoa/MetalRendererCommonShaders.h b/desmume/src/frontend/cocoa/MetalRendererCommonShaders.h index bc50b81a9..6fc525e70 100644 --- a/desmume/src/frontend/cocoa/MetalRendererCommonShaders.h +++ b/desmume/src/frontend/cocoa/MetalRendererCommonShaders.h @@ -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 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); float4 convert_unorm666X_to_unorm8888(const float4 inColor); +float4 convert_unorm888X_to_unorm8888(const float4 inColor); #endif // _METAL_RENDERER_COMMON_H_ diff --git a/desmume/src/frontend/cocoa/MetalRendererCommonShaders.metal b/desmume/src/frontend/cocoa/MetalRendererCommonShaders.metal index c6f8f83be..200bdcbff 100644 --- a/desmume/src/frontend/cocoa/MetalRendererCommonShaders.metal +++ b/desmume/src/frontend/cocoa/MetalRendererCommonShaders.metal @@ -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 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 ); } + +float4 convert_unorm888X_to_unorm8888(const float4 inColor) +{ + return float4(inColor.rgb, 1.0f); +} diff --git a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.h b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.h index 69de5ff8d..6a02af5e7 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.h +++ b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.h @@ -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 it under the terms of the GNU General Public License as published by @@ -95,6 +95,7 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties; id _fetch888Pipeline; id _fetch555ConvertOnlyPipeline; id _fetch666ConvertOnlyPipeline; + id _fetch888ConvertOnlyPipeline; id deposterizePipeline; id hudPipeline; id hudRGBAPipeline; diff --git a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm index 95f23e681..279aa2b5b 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm +++ b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm @@ -81,6 +81,9 @@ [computePipelineDesc setComputeFunction:[defaultLibrary newFunctionWithName:@"convert_texture_unorm666X_to_unorm8888"]]; _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"]]; deposterizePipeline = [[device newComputePipelineStateWithDescriptor:computePipelineDesc options:MTLPipelineOptionNone reflection:nil error:nil] retain]; @@ -280,6 +283,7 @@ [_fetch888Pipeline release]; [_fetch555ConvertOnlyPipeline release]; [_fetch666ConvertOnlyPipeline release]; + [_fetch888ConvertOnlyPipeline release]; [deposterizePipeline release]; [hudPipeline release]; [hudRGBAPipeline release]; @@ -458,6 +462,8 @@ const NDSDisplayInfo ¤tDisplayInfo = GPUFetchObject->GetFetchDisplayInfoForBufferIndex(index); const bool isMainEnabled = currentDisplayInfo.isDisplayEnabled[NDSDisplayID_Main]; 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}; @@ -465,7 +471,7 @@ { if (isMainEnabled) { - if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Main]) + if (isMainNative) { targetTexPair.main = _texDisplayFetchNative[NDSDisplayID_Main][index]; } @@ -477,7 +483,7 @@ if (isTouchEnabled) { - if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch]) + if (isTouchNative) { targetTexPair.touch = _texDisplayFetchNative[NDSDisplayID_Touch][index]; } @@ -491,22 +497,21 @@ { id 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 (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([_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)]; @@ -515,7 +520,7 @@ [cce setBuffer:_bufMasterBrightMode[NDSDisplayID_Main][index] offset:0 atIndex:0]; [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:_texDisplayPostprocessNative[NDSDisplayID_Main][index] atIndex:1]; @@ -537,6 +542,19 @@ 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([_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)]; @@ -545,7 +563,7 @@ [cce setBuffer:_bufMasterBrightMode[NDSDisplayID_Touch][index] offset:0 atIndex:0]; [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:_texDisplayPostprocessNative[NDSDisplayID_Touch][index] atIndex:1]; @@ -570,65 +588,75 @@ else if (currentDisplayInfo.colorFormat != NDSColorFormat_BGR888_Rev) { id 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. - [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.colorFormat == NDSColorFormat_BGR555_Rev) { - if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Main]) - { - [cce setTexture:_texDisplayFetchNative[NDSDisplayID_Main][index] atIndex:0]; - [cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Main][index] atIndex:1]; - [cce dispatchThreadgroups:_fetchThreadGroupsPerGridNative - threadsPerThreadgroup:_fetchThreadsPerGroupNative]; - - targetTexPair.main = _texDisplayPostprocessNative[NDSDisplayID_Main][index]; - } - else - { - [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]; - } + // 16-bit textures aren't handled natively in Metal for macOS, so we need to explicitly convert to 32-bit here. + [cce setComputePipelineState:_fetch555ConvertOnlyPipeline]; + } + else if ( (currentDisplayInfo.colorFormat == NDSColorFormat_BGR666_Rev) && currentDisplayInfo.needConvertColorFormat[NDSDisplayID_Main] ) + { + [cce setComputePipelineState:_fetch666ConvertOnlyPipeline]; + } + else + { + [cce setComputePipelineState:_fetch888ConvertOnlyPipeline]; } - if (isTouchEnabled) + if (isMainNative) { - if (!currentDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch]) - { - [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]; - } + [cce setTexture:_texDisplayFetchNative[NDSDisplayID_Main][index] atIndex:0]; + [cce setTexture:_texDisplayPostprocessNative[NDSDisplayID_Main][index] atIndex:1]; + [cce dispatchThreadgroups:_fetchThreadGroupsPerGridNative + threadsPerThreadgroup:_fetchThreadsPerGroupNative]; + + targetTexPair.main = _texDisplayPostprocessNative[NDSDisplayID_Main][index]; + } + else + { + [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 (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]; } } diff --git a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayViewShaders.metal b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayViewShaders.metal index 5cf9fda06..96c5b37a5 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayViewShaders.metal +++ b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayViewShaders.metal @@ -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 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); } +kernel void convert_texture_unorm888X_to_unorm8888(const uint2 position [[thread_position_in_grid]], + const texture2d inTexture [[texture(0)]], + texture2d 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) { switch (mode)