Skip to content

Commit

Permalink
Renderer fix
Browse files Browse the repository at this point in the history
Fixed renderer on non desktop platforms
  • Loading branch information
albertofustinoni committed Jun 12, 2018
1 parent add5ddc commit cdd7de6
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 160 deletions.
66 changes: 31 additions & 35 deletions RetriX.UWP.Unsafe/Components/RenderTargetManager.cs
Expand Up @@ -14,44 +14,48 @@ internal class RenderTargetManager : IDisposable
{
private const uint RenderTargetMinSize = 1024;

private static readonly IReadOnlyDictionary<PixelFormats, int> PixelFormatsSizeMapping = new Dictionary<PixelFormats, int>
{
{ PixelFormats.XRGB8888, 4 },
{ PixelFormats.RGB565, 2 },
{ PixelFormats.RGB0555, 2 },
{ PixelFormats.Unknown, 0 },
};

private object RenderTargetLock { get; } = new object();
private CanvasBitmap RenderTarget { get; set; } = null;
public TextureFilterTypes RenderTargetFilterType { get; set; } = TextureFilterTypes.Bilinear;
private IDirect3DSurface RenderTargetSurface { get; set; } = null;

private Rect RenderTargetViewport = new Rect();
//This may be different from viewport's width/haight.
private float RenderTargetAspectRatio { get; set; } = 1.0f;

private PixelFormats currentCorePixelFormat = PixelFormats.Unknown;
public PixelFormats CurrentCorePixelFormat
private GameGeometry currentGeometry;
public GameGeometry CurrentGeometry
{
get { return currentCorePixelFormat; }
set { currentCorePixelFormat = value; CurrentCorePixelSize = PixelFormatsSizeMapping[currentCorePixelFormat]; }
get => currentGeometry;
set
{
currentGeometry = value;
RenderTargetAspectRatio = currentGeometry.AspectRatio;
if (RenderTargetAspectRatio < 0.1f)
{
RenderTargetAspectRatio = (float)(currentGeometry.BaseWidth) / currentGeometry.BaseHeight;
}
}
}

public PixelFormats CurrentPixelFormat { get; set; } = PixelFormats.Unknown;
public Rotations CurrentRotation { get; set; }

private int CurrentCorePixelSize = 0;

public void Dispose()
{
RenderTarget?.Dispose();
RenderTarget = null;
}

RenderTargetSurface?.Dispose();
RenderTargetSurface = null;
public void CreateResources(CanvasDrawingSession drawingSession)
{
Dispose();
UpdateRenderTargetSize(drawingSession);
}

public void Render(CanvasDrawingSession drawingSession, Size canvasSize)
{
UpdateRenderTargetSize(drawingSession);

var viewportWidth = RenderTargetViewport.Width;
var viewportHeight = RenderTargetViewport.Height;
var aspectRatio = RenderTargetAspectRatio;
Expand Down Expand Up @@ -91,15 +95,15 @@ public void Render(CanvasDrawingSession drawingSession, Size canvasSize)

public unsafe void UpdateFromCoreOutputRGB0555(CanvasDevice device, IReadOnlyList<ushort> data, uint width, uint height, ulong pitch)
{
if (data == null || RenderTarget == null || CurrentCorePixelSize == 0)
if (data == null || RenderTarget == null || CurrentPixelFormat == PixelFormats.Unknown)
return;

lock (RenderTargetLock)
{
RenderTargetViewport.Width = width;
RenderTargetViewport.Height = height;

using (var renderTargetMap = new D3DSurfaceMap(device, RenderTargetSurface))
using (var renderTargetMap = new BitmapMap(device, RenderTarget))
{
var dataPtr = (byte*)new IntPtr(renderTargetMap.Data).ToPointer();
FramebufferConverter.ConvertFrameBufferRGB0555ToXRGB8888(width, height, data, (int)pitch, dataPtr, (int)renderTargetMap.PitchBytes);
Expand All @@ -109,15 +113,15 @@ public unsafe void UpdateFromCoreOutputRGB0555(CanvasDevice device, IReadOnlyLis

public unsafe void UpdateFromCoreOutputRGB565(CanvasDevice device, IReadOnlyList<ushort> data, uint width, uint height, ulong pitch)
{
if (data == null || RenderTarget == null || CurrentCorePixelSize == 0)
if (data == null || RenderTarget == null || CurrentPixelFormat == PixelFormats.Unknown)
return;

lock (RenderTargetLock)
{
RenderTargetViewport.Width = width;
RenderTargetViewport.Height = height;

using (var renderTargetMap = new D3DSurfaceMap(device, RenderTargetSurface))
using (var renderTargetMap = new BitmapMap(device, RenderTarget))
{
var dataPtr = (byte*)new IntPtr(renderTargetMap.Data).ToPointer();
FramebufferConverter.ConvertFrameBufferRGB565ToXRGB8888(width, height, data, (int)pitch, dataPtr, (int)renderTargetMap.PitchBytes);
Expand All @@ -127,48 +131,40 @@ public unsafe void UpdateFromCoreOutputRGB565(CanvasDevice device, IReadOnlyList

public unsafe void UpdateFromCoreOutputXRGB8888(CanvasDevice device, IReadOnlyList<uint> data, uint width, uint height, ulong pitch)
{
if (data == null || RenderTarget == null || CurrentCorePixelSize == 0)
if (data == null || RenderTarget == null || CurrentPixelFormat == PixelFormats.Unknown)
return;

lock (RenderTargetLock)
{
RenderTargetViewport.Width = width;
RenderTargetViewport.Height = height;

using (var renderTargetMap = new D3DSurfaceMap(device, RenderTargetSurface))
using (var renderTargetMap = new BitmapMap(device, RenderTarget))
{
var dataPtr = (byte*)new IntPtr(renderTargetMap.Data).ToPointer();
FramebufferConverter.ConvertFrameBufferXRGB8888(width, height, data, (int)pitch, dataPtr, (int)renderTargetMap.PitchBytes);
}
}
}

public void UpdateRenderTargetSize(CanvasDevice device, GameGeometry geometry)
private void UpdateRenderTargetSize(CanvasDrawingSession drawingSession)
{
RenderTargetAspectRatio = geometry.AspectRatio;
if (RenderTargetAspectRatio < 0.1f)
{
RenderTargetAspectRatio = (float)(geometry.BaseWidth) / geometry.BaseHeight;
}

if (RenderTarget != null)
{
var currentSize = RenderTarget.Size;
if (currentSize.Width >= geometry.MaxWidth && currentSize.Height >= geometry.MaxHeight)
if (currentSize.Width >= CurrentGeometry.MaxWidth && currentSize.Height >= CurrentGeometry.MaxHeight)
{
return;
}
}

lock (RenderTargetLock)
{
var size = Math.Max(Math.Max(geometry.MaxWidth, geometry.MaxHeight), RenderTargetMinSize);
var size = Math.Max(Math.Max(CurrentGeometry.MaxWidth, CurrentGeometry.MaxHeight), RenderTargetMinSize);
size = ClosestGreaterPowerTwo(size);

RenderTarget?.Dispose();
RenderTargetSurface?.Dispose();
RenderTargetSurface = D3DSurfaceMap.CreateMappableD3DSurface(device, size, size);
RenderTarget = CanvasBitmap.CreateFromDirect3D11Surface(device, RenderTargetSurface);
RenderTarget = BitmapMap.CreateMappableBitmap(drawingSession, size, size);
}
}

Expand Down
6 changes: 3 additions & 3 deletions RetriX.UWP.Unsafe/RetriX.UWP.Unsafe.csproj
Expand Up @@ -136,9 +136,9 @@
<Project>{58B82D57-A956-4492-96FB-3E82FA82798A}</Project>
<Name>RetriX.Shared</Name>
</ProjectReference>
<ProjectReference Include="..\Retrix.UWP.Native\Retrix.UWP.Native.vcxproj">
<Project>{aa168014-f150-4a65-93f9-121da3eb0a01}</Project>
<Name>Retrix.UWP.Native</Name>
<ProjectReference Include="..\RetriX.UWP.Native\RetriX.UWP.Native.vcxproj">
<Project>{0e82ee5a-b44a-4b8b-928a-a981c2cf8917}</Project>
<Name>RetriX.UWP.Native</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
Expand Down
10 changes: 3 additions & 7 deletions RetriX.UWP.Unsafe/Services/VideoService.cs
@@ -1,4 +1,5 @@
using LibRetriX;
using Microsoft.Graphics.Canvas.UI;
using Microsoft.Graphics.Canvas.UI.Xaml;
using RetriX.Shared.Services;
using RetriX.UWP.Components;
Expand Down Expand Up @@ -96,17 +97,12 @@ public void RenderVideoFrameXRGB8888(IReadOnlyList<uint> data, uint width, uint

public void GeometryChanged(GameGeometry geometry)
{
if (RenderPanel == null)
{
return;
}

RenderTargetManager.UpdateRenderTargetSize(RenderPanel.Device, geometry);
RenderTargetManager.CurrentGeometry = geometry;
}

public void PixelFormatChanged(PixelFormats format)
{
RenderTargetManager.CurrentCorePixelFormat = format;
RenderTargetManager.CurrentPixelFormat = format;
}

public void TimingsChanged(SystemTimings timings)
Expand Down
32 changes: 16 additions & 16 deletions RetriX.sln
Expand Up @@ -7,12 +7,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RetriX.Shared", "RetriX.Sha
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RetriX.Shared.Test", "RetriX.Shared.Test\RetriX.Shared.Test.csproj", "{BD097630-DD91-4658-855A-A61246B5D2CA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Retrix.UWP.Native", "Retrix.UWP.Native\Retrix.UWP.Native.vcxproj", "{AA168014-F150-4A65-93F9-121DA3EB0A01}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RetriX.UWP.Unsafe", "RetriX.UWP.Unsafe\RetriX.UWP.Unsafe.csproj", "{0D8D76F1-1383-437C-9482-BBD3C9723768}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RetriX.UWP", "RetriX.UWP\RetriX.UWP.csproj", "{17975A5B-67F5-494F-937D-9132AC78BD35}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetriX.UWP.Native", "RetriX.UWP.Native\RetriX.UWP.Native.vcxproj", "{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -57,20 +57,6 @@ Global
{BD097630-DD91-4658-855A-A61246B5D2CA}.Release|x64.Build.0 = Release|Any CPU
{BD097630-DD91-4658-855A-A61246B5D2CA}.Release|x86.ActiveCfg = Release|Any CPU
{BD097630-DD91-4658-855A-A61246B5D2CA}.Release|x86.Build.0 = Release|Any CPU
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Debug|Any CPU.ActiveCfg = Debug|Win32
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Debug|ARM.ActiveCfg = Debug|ARM
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Debug|ARM.Build.0 = Debug|ARM
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Debug|x64.ActiveCfg = Debug|x64
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Debug|x64.Build.0 = Debug|x64
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Debug|x86.ActiveCfg = Debug|Win32
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Debug|x86.Build.0 = Debug|Win32
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Release|Any CPU.ActiveCfg = Release|Win32
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Release|ARM.ActiveCfg = Release|ARM
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Release|ARM.Build.0 = Release|ARM
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Release|x64.ActiveCfg = Release|x64
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Release|x64.Build.0 = Release|x64
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Release|x86.ActiveCfg = Release|Win32
{AA168014-F150-4A65-93F9-121DA3EB0A01}.Release|x86.Build.0 = Release|Win32
{0D8D76F1-1383-437C-9482-BBD3C9723768}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D8D76F1-1383-437C-9482-BBD3C9723768}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D8D76F1-1383-437C-9482-BBD3C9723768}.Debug|ARM.ActiveCfg = Debug|ARM
Expand Down Expand Up @@ -107,6 +93,20 @@ Global
{17975A5B-67F5-494F-937D-9132AC78BD35}.Release|x86.ActiveCfg = Release|x86
{17975A5B-67F5-494F-937D-9132AC78BD35}.Release|x86.Build.0 = Release|x86
{17975A5B-67F5-494F-937D-9132AC78BD35}.Release|x86.Deploy.0 = Release|x86
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Debug|Any CPU.ActiveCfg = Debug|Win32
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Debug|ARM.ActiveCfg = Debug|ARM
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Debug|ARM.Build.0 = Debug|ARM
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Debug|x64.ActiveCfg = Debug|x64
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Debug|x64.Build.0 = Debug|x64
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Debug|x86.ActiveCfg = Debug|Win32
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Debug|x86.Build.0 = Debug|Win32
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Release|Any CPU.ActiveCfg = Release|Win32
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Release|ARM.ActiveCfg = Release|ARM
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Release|ARM.Build.0 = Release|ARM
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Release|x64.ActiveCfg = Release|x64
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Release|x64.Build.0 = Release|x64
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Release|x86.ActiveCfg = Release|Win32
{0E82EE5A-B44A-4B8B-928A-A981C2CF8917}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
45 changes: 45 additions & 0 deletions Retrix.UWP.Native/BitmapMap.cpp
@@ -0,0 +1,45 @@
#include "pch.h"
#include "BitmapMap.h"

using namespace Retrix::UWP::Native;
using namespace Platform;

BitmapMap::BitmapMap(CanvasDevice^ device, CanvasBitmap^ bitmap)
{
d2dBitmap = GetWrappedResource<ID2D1Bitmap1, CanvasBitmap>(device, bitmap);
__abi_ThrowIfFailed(d2dBitmap->Map(D2D1_MAP_OPTIONS_WRITE | D2D1_MAP_OPTIONS_DISCARD, &map));
}

BitmapMap::~BitmapMap()
{
__abi_ThrowIfFailed(d2dBitmap->Unmap());
}

CanvasBitmap^ BitmapMap::CreateMappableBitmap(CanvasDrawingSession^ drawingSession, unsigned int width, unsigned int height)
{
ComPtr<ID3D11Device> d3dDevice;
__abi_ThrowIfFailed(GetDXGIInterface(drawingSession->Device, d3dDevice.GetAddressOf()));

D3D11_TEXTURE2D_DESC texDesc = { 0 };
texDesc.Width = width;
texDesc.Height = height;
texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DYNAMIC;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
texDesc.MiscFlags = 0;

ComPtr<ID3D11Texture2D> d3dTexture;
__abi_ThrowIfFailed(d3dDevice->CreateTexture2D(&texDesc, nullptr, d3dTexture.GetAddressOf()));

ComPtr<IDXGISurface> d3dSurface;
__abi_ThrowIfFailed(d3dTexture.As(&d3dSurface));

auto winRTSurface = CreateDirect3DSurface(d3dSurface.Get());
auto output = CanvasBitmap::CreateFromDirect3D11Surface(drawingSession, winRTSurface);
return output;
}
36 changes: 36 additions & 0 deletions Retrix.UWP.Native/BitmapMap.h
@@ -0,0 +1,36 @@
#pragma once

using namespace Microsoft::Graphics::Canvas;
using namespace Microsoft::WRL;
using namespace Platform;
using namespace Windows::Graphics::DirectX::Direct3D11;

namespace Retrix
{
namespace UWP
{
namespace Native
{
public ref class BitmapMap sealed
{
#ifdef _WIN64
typedef int64 UnsafeIntPtr;
#else
typedef int32 UnsafeIntPtr;
#endif
private:
ComPtr<ID2D1Bitmap1> d2dBitmap;
D2D1_MAPPED_RECT map;

public:
property uint32 PitchBytes { uint32 get() { return map.pitch; } }
property UnsafeIntPtr Data { UnsafeIntPtr get() { return (UnsafeIntPtr)map.bits; } }

BitmapMap(CanvasDevice^ device, CanvasBitmap^ bitmap);
virtual ~BitmapMap();

static CanvasBitmap^ CreateMappableBitmap(CanvasDrawingSession^ drawingSession, unsigned int width, unsigned int height);
};
}
}
}
53 changes: 0 additions & 53 deletions Retrix.UWP.Native/D3DSurfaceMap.cpp

This file was deleted.

0 comments on commit cdd7de6

Please sign in to comment.