Cocoa Port: Update the Metal blitter to support Y-flipping of the rendered video frame, matching the same feature that already exists in the OpenGL blitter.

This commit is contained in:
rogerman 2018-07-27 02:10:28 -07:00
parent 4913c0e7ae
commit bee3fd30ce
3 changed files with 26 additions and 10 deletions

View File

@ -246,7 +246,8 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties;
outputPipelineState:(id<MTLRenderPipelineState>)outputPipelineState
hudPipelineState:(id<MTLRenderPipelineState>)hudPipelineState
texDisplays:(MetalTexturePair)texDisplay
mrfi:(MetalRenderFrameInfo)mrfi;
mrfi:(MetalRenderFrameInfo)mrfi
doYFlip:(BOOL)willFlip;
- (void) renderStartAtIndex:(uint8_t)index;
- (void) renderFinishAtIndex:(uint8_t)index;
- (ClientDisplayBufferState) renderBufferStateAtIndex:(uint8_t)index;

View File

@ -1885,6 +1885,7 @@
hudPipelineState:(id<MTLRenderPipelineState>)hudPipelineState
texDisplays:(MetalTexturePair)texDisplay
mrfi:(MetalRenderFrameInfo)mrfi
doYFlip:(BOOL)willFlip
{
// Generate the command encoder.
id<MTLRenderCommandEncoder> rce = [cb renderCommandEncoderWithDescriptor:_outputRenderPassDesc];
@ -1899,6 +1900,7 @@
}
// Draw the NDS displays.
const uint8_t doYFlip = (willFlip) ? 1 : 0;
const NDSDisplayInfo &displayInfo = cdp->GetEmuDisplayInfo();
const float backlightIntensity[2] = { displayInfo.backlightIntensity[NDSDisplayID_Main], displayInfo.backlightIntensity[NDSDisplayID_Touch] };
@ -1906,6 +1908,7 @@
[rce setVertexBytes:_vtxPositionBuffer length:sizeof(_vtxPositionBuffer) atIndex:0];
[rce setVertexBytes:_texCoordBuffer length:sizeof(_texCoordBuffer) atIndex:1];
[rce setVertexBytes:&_cdvPropertiesBuffer length:sizeof(_cdvPropertiesBuffer) atIndex:2];
[rce setVertexBytes:&doYFlip length:sizeof(uint8_t) atIndex:3];
switch (cdp->GetPresenterProperties().mode)
{
@ -1986,13 +1989,14 @@
[rce setVertexBuffer:_hudVtxColorBuffer[mrfi.renderIndex] offset:0 atIndex:1];
[rce setVertexBuffer:_hudTexCoordBuffer[mrfi.renderIndex] offset:0 atIndex:2];
[rce setVertexBytes:&_cdvPropertiesBuffer length:sizeof(_cdvPropertiesBuffer) atIndex:3];
[rce setVertexBytes:&doYFlip length:sizeof(uint8_t) atIndex:4];
[rce setFragmentTexture:[self texHUDCharMap] atIndex:0];
// First, draw the inputs.
if (mrfi.willDrawHUDInput)
{
isScreenOverlay = 1;
[rce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:4];
[rce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:5];
[rce setFragmentSamplerState:[sharedData samplerHUDBox] atIndex:0];
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:mrfi.hudTouchLineLength * 6
@ -2001,7 +2005,7 @@
indexBufferOffset:(mrfi.hudStringLength + HUD_INPUT_ELEMENT_LENGTH) * 6 * sizeof(uint16_t)];
isScreenOverlay = 0;
[rce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:4];
[rce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:5];
[rce setFragmentSamplerState:[sharedData samplerHUDText] atIndex:0];
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:HUD_INPUT_ELEMENT_LENGTH * 6
@ -2011,7 +2015,7 @@
}
// Next, draw the backing text box.
[rce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:4];
[rce setVertexBytes:&isScreenOverlay length:sizeof(uint8_t) atIndex:5];
[rce setFragmentSamplerState:[sharedData samplerHUDBox] atIndex:0];
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:6
@ -2092,7 +2096,8 @@
outputPipelineState:[self outputRGBAPipeline]
hudPipelineState:[sharedData hudRGBAPipeline]
texDisplays:texProcess
mrfi:mrfi];
mrfi:mrfi
doYFlip:YES];
id<MTLBlitCommandEncoder> bce = [cb blitCommandEncoder];
@ -2198,7 +2203,8 @@
outputPipelineState:[presenterObject outputDrawablePipeline]
hudPipelineState:[[presenterObject sharedData] hudPipeline]
texDisplays:texProcess
mrfi:mrfi];
mrfi:mrfi
doYFlip:NO];
[cbRender addScheduledHandler:^(id<MTLCommandBuffer> block) {
[presenterObject setRenderBufferState:ClientDisplayBufferState_Reading index:mrfi.renderIndex];

View File

@ -146,7 +146,8 @@ vertex HUDVtx hud_vertex(const device float2 *inPosition [[buffer(0)]],
const device uint32_t *inColor [[buffer(1)]],
const device float2 *inTexCoord [[buffer(2)]],
const constant DisplayViewShaderProperties &viewProps [[buffer(3)]],
const constant uint8_t &isScreenOverlay [[buffer(4)]],
const constant uint8_t &doYFlip [[buffer(4)]],
const constant uint8_t &isScreenOverlay [[buffer(5)]],
const uint vid [[vertex_id]])
{
const float angleRadians = viewProps.rotation * (M_PI_F/180.0f);
@ -160,8 +161,10 @@ vertex HUDVtx hud_vertex(const device float2 *inPosition [[buffer(0)]],
const float2x2 scale = float2x2( float2(viewProps.viewScale, 0.0f),
float2( 0.0f, viewProps.viewScale));
const float2 yFlip = (doYFlip != 0) ? float2(1.0f, -1.0f) : float2(1.0f, 1.0f);
HUDVtx outVtx;
outVtx.position = (isScreenOverlay != 0) ? float4(projection * rotation * scale * inPosition[vid], 0.0f, 1.0f) : float4(projection * inPosition[vid], 0.0f, 1.0f);
outVtx.position = (isScreenOverlay != 0) ? float4(projection * rotation * scale * inPosition[vid] * yFlip, 0.0f, 1.0f) : float4(projection * inPosition[vid] * yFlip, 0.0f, 1.0f);
outVtx.color = float4( (float)((inColor[vid] >> 0) & 0xFF) / 255.0f, (float)((inColor[vid] >> 8) & 0xFF) / 255.0f, (float)((inColor[vid] >> 16) & 0xFF) / 255.0f, (float)((inColor[vid] >> 24) & 0xFF) / 255.0f );
outVtx.texCoord = inTexCoord[vid];
outVtx.lowerHUDMipMapLevel = (viewProps.lowerHUDMipMapLevel == 1);
@ -181,6 +184,7 @@ fragment float4 hud_fragment(const HUDVtx vtx [[stage_in]],
vertex DisplayVtx display_output_vertex(const device float2 *inPosition [[buffer(0)]],
const device float2 *inTexCoord [[buffer(1)]],
const constant DisplayViewShaderProperties &viewProps [[buffer(2)]],
const constant uint8_t &doYFlip [[buffer(3)]],
const uint vid [[vertex_id]])
{
const float angleRadians = viewProps.rotation * (M_PI_F/180.0f);
@ -194,8 +198,10 @@ vertex DisplayVtx display_output_vertex(const device float2 *inPosition [[buffer
const float2x2 scale = float2x2( float2(viewProps.viewScale, 0.0f),
float2( 0.0f, viewProps.viewScale));
const float2 yFlip = (doYFlip != 0) ? float2(1.0f, -1.0f) : float2(1.0f, 1.0f);
DisplayVtx outVtx;
outVtx.position = float4(projection * rotation * scale * inPosition[vid], 0.0f, 1.0f);
outVtx.position = float4(projection * rotation * scale * inPosition[vid] * yFlip, 0.0f, 1.0f);
outVtx.texCoord = inTexCoord[vid];
return outVtx;
@ -204,6 +210,7 @@ vertex DisplayVtx display_output_vertex(const device float2 *inPosition [[buffer
vertex DisplayVtx display_output_bicubic_vertex(const device float2 *inPosition [[buffer(0)]],
const device float2 *inTexCoord [[buffer(1)]],
const constant DisplayViewShaderProperties &viewProps [[buffer(2)]],
const constant uint8_t &doYFlip [[buffer(3)]],
const uint vid [[vertex_id]])
{
const float angleRadians = viewProps.rotation * (M_PI_F/180.0f);
@ -217,8 +224,10 @@ vertex DisplayVtx display_output_bicubic_vertex(const device float2 *inPosition
const float2x2 scale = float2x2( float2(viewProps.viewScale, 0.0f),
float2( 0.0f, viewProps.viewScale));
const float2 yFlip = (doYFlip != 0) ? float2(1.0f, -1.0f) : float2(1.0f, 1.0f);
DisplayVtx outVtx;
outVtx.position = float4(projection * rotation * scale * inPosition[vid], 0.0f, 1.0f);
outVtx.position = float4(projection * rotation * scale * inPosition[vid] * yFlip, 0.0f, 1.0f);
outVtx.texCoord = floor(inTexCoord[vid] - 0.5f) + 0.5f;
return outVtx;