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:
parent
4913c0e7ae
commit
bee3fd30ce
|
@ -246,7 +246,8 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties;
|
||||||
outputPipelineState:(id<MTLRenderPipelineState>)outputPipelineState
|
outputPipelineState:(id<MTLRenderPipelineState>)outputPipelineState
|
||||||
hudPipelineState:(id<MTLRenderPipelineState>)hudPipelineState
|
hudPipelineState:(id<MTLRenderPipelineState>)hudPipelineState
|
||||||
texDisplays:(MetalTexturePair)texDisplay
|
texDisplays:(MetalTexturePair)texDisplay
|
||||||
mrfi:(MetalRenderFrameInfo)mrfi;
|
mrfi:(MetalRenderFrameInfo)mrfi
|
||||||
|
doYFlip:(BOOL)willFlip;
|
||||||
- (void) renderStartAtIndex:(uint8_t)index;
|
- (void) renderStartAtIndex:(uint8_t)index;
|
||||||
- (void) renderFinishAtIndex:(uint8_t)index;
|
- (void) renderFinishAtIndex:(uint8_t)index;
|
||||||
- (ClientDisplayBufferState) renderBufferStateAtIndex:(uint8_t)index;
|
- (ClientDisplayBufferState) renderBufferStateAtIndex:(uint8_t)index;
|
||||||
|
|
|
@ -1885,6 +1885,7 @@
|
||||||
hudPipelineState:(id<MTLRenderPipelineState>)hudPipelineState
|
hudPipelineState:(id<MTLRenderPipelineState>)hudPipelineState
|
||||||
texDisplays:(MetalTexturePair)texDisplay
|
texDisplays:(MetalTexturePair)texDisplay
|
||||||
mrfi:(MetalRenderFrameInfo)mrfi
|
mrfi:(MetalRenderFrameInfo)mrfi
|
||||||
|
doYFlip:(BOOL)willFlip
|
||||||
{
|
{
|
||||||
// Generate the command encoder.
|
// Generate the command encoder.
|
||||||
id<MTLRenderCommandEncoder> rce = [cb renderCommandEncoderWithDescriptor:_outputRenderPassDesc];
|
id<MTLRenderCommandEncoder> rce = [cb renderCommandEncoderWithDescriptor:_outputRenderPassDesc];
|
||||||
|
@ -1899,6 +1900,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the NDS displays.
|
// Draw the NDS displays.
|
||||||
|
const uint8_t doYFlip = (willFlip) ? 1 : 0;
|
||||||
const NDSDisplayInfo &displayInfo = cdp->GetEmuDisplayInfo();
|
const NDSDisplayInfo &displayInfo = cdp->GetEmuDisplayInfo();
|
||||||
const float backlightIntensity[2] = { displayInfo.backlightIntensity[NDSDisplayID_Main], displayInfo.backlightIntensity[NDSDisplayID_Touch] };
|
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:_vtxPositionBuffer length:sizeof(_vtxPositionBuffer) atIndex:0];
|
||||||
[rce setVertexBytes:_texCoordBuffer length:sizeof(_texCoordBuffer) atIndex:1];
|
[rce setVertexBytes:_texCoordBuffer length:sizeof(_texCoordBuffer) atIndex:1];
|
||||||
[rce setVertexBytes:&_cdvPropertiesBuffer length:sizeof(_cdvPropertiesBuffer) atIndex:2];
|
[rce setVertexBytes:&_cdvPropertiesBuffer length:sizeof(_cdvPropertiesBuffer) atIndex:2];
|
||||||
|
[rce setVertexBytes:&doYFlip length:sizeof(uint8_t) atIndex:3];
|
||||||
|
|
||||||
switch (cdp->GetPresenterProperties().mode)
|
switch (cdp->GetPresenterProperties().mode)
|
||||||
{
|
{
|
||||||
|
@ -1986,13 +1989,14 @@
|
||||||
[rce setVertexBuffer:_hudVtxColorBuffer[mrfi.renderIndex] offset:0 atIndex:1];
|
[rce setVertexBuffer:_hudVtxColorBuffer[mrfi.renderIndex] offset:0 atIndex:1];
|
||||||
[rce setVertexBuffer:_hudTexCoordBuffer[mrfi.renderIndex] offset:0 atIndex:2];
|
[rce setVertexBuffer:_hudTexCoordBuffer[mrfi.renderIndex] offset:0 atIndex:2];
|
||||||
[rce setVertexBytes:&_cdvPropertiesBuffer length:sizeof(_cdvPropertiesBuffer) atIndex:3];
|
[rce setVertexBytes:&_cdvPropertiesBuffer length:sizeof(_cdvPropertiesBuffer) atIndex:3];
|
||||||
|
[rce setVertexBytes:&doYFlip length:sizeof(uint8_t) atIndex:4];
|
||||||
[rce setFragmentTexture:[self texHUDCharMap] atIndex:0];
|
[rce setFragmentTexture:[self texHUDCharMap] atIndex:0];
|
||||||
|
|
||||||
// First, draw the inputs.
|
// First, draw the inputs.
|
||||||
if (mrfi.willDrawHUDInput)
|
if (mrfi.willDrawHUDInput)
|
||||||
{
|
{
|
||||||
isScreenOverlay = 1;
|
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 setFragmentSamplerState:[sharedData samplerHUDBox] atIndex:0];
|
||||||
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
indexCount:mrfi.hudTouchLineLength * 6
|
indexCount:mrfi.hudTouchLineLength * 6
|
||||||
|
@ -2001,7 +2005,7 @@
|
||||||
indexBufferOffset:(mrfi.hudStringLength + HUD_INPUT_ELEMENT_LENGTH) * 6 * sizeof(uint16_t)];
|
indexBufferOffset:(mrfi.hudStringLength + HUD_INPUT_ELEMENT_LENGTH) * 6 * sizeof(uint16_t)];
|
||||||
|
|
||||||
isScreenOverlay = 0;
|
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 setFragmentSamplerState:[sharedData samplerHUDText] atIndex:0];
|
||||||
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
indexCount:HUD_INPUT_ELEMENT_LENGTH * 6
|
indexCount:HUD_INPUT_ELEMENT_LENGTH * 6
|
||||||
|
@ -2011,7 +2015,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, draw the backing text box.
|
// 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 setFragmentSamplerState:[sharedData samplerHUDBox] atIndex:0];
|
||||||
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
[rce drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
indexCount:6
|
indexCount:6
|
||||||
|
@ -2092,7 +2096,8 @@
|
||||||
outputPipelineState:[self outputRGBAPipeline]
|
outputPipelineState:[self outputRGBAPipeline]
|
||||||
hudPipelineState:[sharedData hudRGBAPipeline]
|
hudPipelineState:[sharedData hudRGBAPipeline]
|
||||||
texDisplays:texProcess
|
texDisplays:texProcess
|
||||||
mrfi:mrfi];
|
mrfi:mrfi
|
||||||
|
doYFlip:YES];
|
||||||
|
|
||||||
id<MTLBlitCommandEncoder> bce = [cb blitCommandEncoder];
|
id<MTLBlitCommandEncoder> bce = [cb blitCommandEncoder];
|
||||||
|
|
||||||
|
@ -2198,7 +2203,8 @@
|
||||||
outputPipelineState:[presenterObject outputDrawablePipeline]
|
outputPipelineState:[presenterObject outputDrawablePipeline]
|
||||||
hudPipelineState:[[presenterObject sharedData] hudPipeline]
|
hudPipelineState:[[presenterObject sharedData] hudPipeline]
|
||||||
texDisplays:texProcess
|
texDisplays:texProcess
|
||||||
mrfi:mrfi];
|
mrfi:mrfi
|
||||||
|
doYFlip:NO];
|
||||||
|
|
||||||
[cbRender addScheduledHandler:^(id<MTLCommandBuffer> block) {
|
[cbRender addScheduledHandler:^(id<MTLCommandBuffer> block) {
|
||||||
[presenterObject setRenderBufferState:ClientDisplayBufferState_Reading index:mrfi.renderIndex];
|
[presenterObject setRenderBufferState:ClientDisplayBufferState_Reading index:mrfi.renderIndex];
|
||||||
|
|
|
@ -146,7 +146,8 @@ vertex HUDVtx hud_vertex(const device float2 *inPosition [[buffer(0)]],
|
||||||
const device uint32_t *inColor [[buffer(1)]],
|
const device uint32_t *inColor [[buffer(1)]],
|
||||||
const device float2 *inTexCoord [[buffer(2)]],
|
const device float2 *inTexCoord [[buffer(2)]],
|
||||||
const constant DisplayViewShaderProperties &viewProps [[buffer(3)]],
|
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 uint vid [[vertex_id]])
|
||||||
{
|
{
|
||||||
const float angleRadians = viewProps.rotation * (M_PI_F/180.0f);
|
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),
|
const float2x2 scale = float2x2( float2(viewProps.viewScale, 0.0f),
|
||||||
float2( 0.0f, viewProps.viewScale));
|
float2( 0.0f, viewProps.viewScale));
|
||||||
|
|
||||||
|
const float2 yFlip = (doYFlip != 0) ? float2(1.0f, -1.0f) : float2(1.0f, 1.0f);
|
||||||
|
|
||||||
HUDVtx outVtx;
|
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.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.texCoord = inTexCoord[vid];
|
||||||
outVtx.lowerHUDMipMapLevel = (viewProps.lowerHUDMipMapLevel == 1);
|
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)]],
|
vertex DisplayVtx display_output_vertex(const device float2 *inPosition [[buffer(0)]],
|
||||||
const device float2 *inTexCoord [[buffer(1)]],
|
const device float2 *inTexCoord [[buffer(1)]],
|
||||||
const constant DisplayViewShaderProperties &viewProps [[buffer(2)]],
|
const constant DisplayViewShaderProperties &viewProps [[buffer(2)]],
|
||||||
|
const constant uint8_t &doYFlip [[buffer(3)]],
|
||||||
const uint vid [[vertex_id]])
|
const uint vid [[vertex_id]])
|
||||||
{
|
{
|
||||||
const float angleRadians = viewProps.rotation * (M_PI_F/180.0f);
|
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),
|
const float2x2 scale = float2x2( float2(viewProps.viewScale, 0.0f),
|
||||||
float2( 0.0f, viewProps.viewScale));
|
float2( 0.0f, viewProps.viewScale));
|
||||||
|
|
||||||
|
const float2 yFlip = (doYFlip != 0) ? float2(1.0f, -1.0f) : float2(1.0f, 1.0f);
|
||||||
|
|
||||||
DisplayVtx outVtx;
|
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];
|
outVtx.texCoord = inTexCoord[vid];
|
||||||
|
|
||||||
return outVtx;
|
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)]],
|
vertex DisplayVtx display_output_bicubic_vertex(const device float2 *inPosition [[buffer(0)]],
|
||||||
const device float2 *inTexCoord [[buffer(1)]],
|
const device float2 *inTexCoord [[buffer(1)]],
|
||||||
const constant DisplayViewShaderProperties &viewProps [[buffer(2)]],
|
const constant DisplayViewShaderProperties &viewProps [[buffer(2)]],
|
||||||
|
const constant uint8_t &doYFlip [[buffer(3)]],
|
||||||
const uint vid [[vertex_id]])
|
const uint vid [[vertex_id]])
|
||||||
{
|
{
|
||||||
const float angleRadians = viewProps.rotation * (M_PI_F/180.0f);
|
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),
|
const float2x2 scale = float2x2( float2(viewProps.viewScale, 0.0f),
|
||||||
float2( 0.0f, viewProps.viewScale));
|
float2( 0.0f, viewProps.viewScale));
|
||||||
|
|
||||||
|
const float2 yFlip = (doYFlip != 0) ? float2(1.0f, -1.0f) : float2(1.0f, 1.0f);
|
||||||
|
|
||||||
DisplayVtx outVtx;
|
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;
|
outVtx.texCoord = floor(inTexCoord[vid] - 0.5f) + 0.5f;
|
||||||
|
|
||||||
return outVtx;
|
return outVtx;
|
||||||
|
|
Loading…
Reference in New Issue