Add FreeType, progress to title screen

This commit is contained in:
elasota
2019-12-21 18:40:17 -05:00
parent c9c6976344
commit 8354d13a84
901 changed files with 444265 additions and 440 deletions

View File

@@ -1,14 +1,40 @@
#include "GpDisplayDriverD3D11.h"
#include "GpDisplayDriverSurfaceD3D11.h"
#include "GpWindows.h"
#include "GpFiber_Win32.h"
#include <d3d11.h>
#include <dxgi1_2.h>
#include <float.h>
#include <emmintrin.h>
#include <stdio.h>
#pragma comment (lib, "d3d11.lib")
namespace GpBinarizedShaders
{
extern const unsigned char *g_drawQuadV_D3D11[2];
extern const unsigned char *g_drawQuadPaletteP_D3D11[2];
extern const unsigned char *g_drawQuadRGBP_D3D11[2];
extern const unsigned char *g_drawQuad15BitP_D3D11[2];
}
struct GpShaderCodeBlob
{
const void *m_data;
size_t m_size;
};
static GpShaderCodeBlob GetBinarizedShader(const unsigned char **shaderPointers)
{
GpShaderCodeBlob blob;
blob.m_data = shaderPointers[0];
blob.m_size = shaderPointers[1] - shaderPointers[0];
return blob;
}
void DebugPrintf(const char *fmt, ...)
{
char buf[256];
@@ -34,7 +60,7 @@ LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
return DefWindowProc(hWnd, message, wParam, lParam);
}
void StartD3DForWindow(HWND hWnd, IDXGISwapChain1*& swapChain)
void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpComPtr<ID3D11Device>& outDevice, GpComPtr<ID3D11DeviceContext>& outContext)
{
DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
@@ -57,7 +83,7 @@ void StartD3DForWindow(HWND hWnd, IDXGISwapChain1*& swapChain)
UINT flags = 0;
const D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_9_1
D3D_FEATURE_LEVEL_10_0
};
flags |= D3D11_CREATE_DEVICE_DEBUG;
@@ -79,11 +105,230 @@ void StartD3DForWindow(HWND hWnd, IDXGISwapChain1*& swapChain)
IDXGIFactory2 *dxgiFactory = nullptr;
result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory));
IDXGISwapChain1 *swapChain = nullptr;
result = dxgiFactory->CreateSwapChainForHwnd(device, hWnd, &swapChainDesc, nullptr, nullptr, &swapChain);
// GP TODO: Fix the error handling here, it's bad...
outSwapChain = swapChain;
outDevice = device;
outContext = context;
}
bool GpDisplayDriverD3D11::InitResources()
{
// Fetch back buffer
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<LPVOID*>(m_backBufferTexture.GetMutablePtr()));
{
D3D11_TEXTURE2D_DESC bbTextureDesc;
m_backBufferTexture->GetDesc(&bbTextureDesc);
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtvDesc.Texture2D.MipSlice = 0;
if (m_device->CreateRenderTargetView(m_backBufferTexture, &rtvDesc, m_backBufferRTV.GetMutablePtr()) != S_OK)
return false;
}
// Quad vertex constant buffer
{
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.ByteWidth = sizeof(DrawQuadVertexConstants);
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
if (m_device->CreateBuffer(&bufferDesc, nullptr, m_drawQuadVertexConstantBuffer.GetMutablePtr()) != S_OK)
return false;
}
// Quad index buffer
{
const uint16_t indexBufferData[] = { 0, 1, 2, 1, 3, 2 };
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.ByteWidth = sizeof(indexBufferData);
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA initialData;
initialData.pSysMem = indexBufferData;
initialData.SysMemPitch = 0;
initialData.SysMemSlicePitch = 0;
if (m_device->CreateBuffer(&bufferDesc, &initialData, m_quadIndexBuffer.GetMutablePtr()) != S_OK)
return false;
}
// Quad vertex buffer
{
const float vertexBufferData[] =
{
0.f, 0.0f,
1.f, 0.f,
0.f, 1.f,
1.f, 1.f,
};
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.ByteWidth = sizeof(vertexBufferData);
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA initialData;
initialData.pSysMem = vertexBufferData;
initialData.SysMemPitch = 0;
initialData.SysMemSlicePitch = 0;
if (m_device->CreateBuffer(&bufferDesc, &initialData, m_quadVertexBuffer.GetMutablePtr()) != S_OK)
return false;
}
const GpShaderCodeBlob drawQuadVBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuadV_D3D11);
const GpShaderCodeBlob drawQuadPalettePBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuadPaletteP_D3D11);
const GpShaderCodeBlob drawQuadRGBPBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuadRGBP_D3D11);
const GpShaderCodeBlob drawQuad15BitPBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuad15BitP_D3D11);
m_device->CreateVertexShader(drawQuadVBlob.m_data, drawQuadVBlob.m_size, nullptr, m_drawQuadVertexShader.GetMutablePtr());
m_device->CreatePixelShader(drawQuadPalettePBlob.m_data, drawQuadPalettePBlob.m_size, nullptr, m_drawQuadPalettePixelShader.GetMutablePtr());
m_device->CreatePixelShader(drawQuadRGBPBlob.m_data, drawQuadRGBPBlob.m_size, nullptr, m_drawQuadRGBPixelShader.GetMutablePtr());
m_device->CreatePixelShader(drawQuad15BitPBlob.m_data, drawQuad15BitPBlob.m_size, nullptr, m_drawQuad15BitPixelShader.GetMutablePtr());
// Quad input layout
{
D3D11_INPUT_ELEMENT_DESC descs[] =
{
"POSITION", // Semantic name
0, // Semantic index
DXGI_FORMAT_R32G32_FLOAT, // Format
0, // Input slot
0, // Aligned byte offset
D3D11_INPUT_PER_VERTEX_DATA, // Input slot class
0 // Instance data step rate
};
m_device->CreateInputLayout(descs, sizeof(descs) / sizeof(descs[0]), drawQuadVBlob.m_data, drawQuadVBlob.m_size, m_drawQuadInputLayout.GetMutablePtr());
}
// Quad depth stencil state
{
D3D11_DEPTH_STENCIL_DESC desc;
desc.DepthEnable = FALSE;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
desc.StencilEnable = FALSE;
desc.StencilReadMask = 0;
desc.StencilWriteMask = 0;
desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
if (m_device->CreateDepthStencilState(&desc, m_drawQuadDepthStencilState.GetMutablePtr()) != S_OK)
return false;
}
// Nearest neighbor sampler desc
{
D3D11_SAMPLER_DESC samplerDesc;
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.f;
samplerDesc.MaxAnisotropy = 1;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
samplerDesc.BorderColor[0] = samplerDesc.BorderColor[1] = samplerDesc.BorderColor[2] = samplerDesc.BorderColor[3] = 1.0f;
samplerDesc.MinLOD = -FLT_MAX;
samplerDesc.MaxLOD = FLT_MAX;
if (m_device->CreateSamplerState(&samplerDesc, m_nearestNeighborSamplerState.GetMutablePtr()) != S_OK)
return false;
}
DXGI_FORMAT paletteTextureFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
// Palette texture
{
D3D11_TEXTURE1D_DESC desc;
desc.Width = 256;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = paletteTextureFormat;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
uint8_t initialDataBytes[256][4];
for (int i = 0; i < 256; i++)
{
for (int ch = 0; ch < 4; ch++)
initialDataBytes[i][ch] = 255;
}
D3D11_SUBRESOURCE_DATA initialData;
initialData.pSysMem = initialDataBytes[0];
initialData.SysMemPitch = 256 * 4;
initialData.SysMemSlicePitch = 256 * 4;
if (m_device->CreateTexture1D(&desc, &initialData, m_paletteTexture.GetMutablePtr()) != S_OK)
return false;
}
// Palette texture SRV
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
desc.Format = paletteTextureFormat;
desc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1D;
desc.Texture1D.MostDetailedMip = 0;
desc.Texture1D.MipLevels = 1;
if (m_device->CreateShaderResourceView(m_paletteTexture, &desc, m_paletteTextureSRV.GetMutablePtr()) != S_OK)
return false;
}
return true;
}
bool GpDisplayDriverD3D11::PresentFrameAndSync()
{
float clearColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
m_deviceContext->ClearRenderTargetView(m_backBufferRTV, clearColor);
ID3D11RenderTargetView *const rtv = m_backBufferRTV;
m_deviceContext->OMSetRenderTargets(1, &rtv, nullptr);
{
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = static_cast<FLOAT>(m_windowWidth);
viewport.Height = static_cast<FLOAT>(m_windowHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
m_deviceContext->RSSetViewports(1, &viewport);
}
m_properties.m_renderFunc(m_properties.m_renderFuncContext);
DXGI_PRESENT_PARAMETERS presentParams;
ZeroMemory(&presentParams, sizeof(presentParams));
@@ -228,11 +473,13 @@ void GpDisplayDriverD3D11::Run()
RECT wr = { 0, 0, m_windowWidth, m_windowHeight };
AdjustWindowRect(&wr, windowStyle, menus != NULL);
hWnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL);
hWnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL);
ShowWindow(hWnd, g_gpWindowsGlobals.m_nCmdShow);
StartD3DForWindow(hWnd, m_swapChain);
StartD3DForWindow(hWnd, m_swapChain, m_device, m_deviceContext);
InitResources();
LARGE_INTEGER lastTimestamp;
memset(&lastTimestamp, 0, sizeof(lastTimestamp));
@@ -274,6 +521,117 @@ void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned in
*pixelFormat = PortabilityLayer::PixelFormat_8BitStandard;
}
IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat)
{
return GpDisplayDriverSurfaceD3D11::Create(m_device, m_deviceContext, width, height, pixelFormat);
}
void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height)
{
ID3D11Buffer *vbPtr = m_quadVertexBuffer;
UINT vbStride = sizeof(float) * 2;
UINT zero = 0;
GpDisplayDriverSurfaceD3D11 *d3d11Surface = static_cast<GpDisplayDriverSurfaceD3D11*>(surface);
//m_deviceContext->OMSetDepthStencilState(m_drawQuadDepthStencilState, 0);
{
const float twoDivWidth = 2.0f / static_cast<float>(m_windowWidth);
const float negativeTwoDivHeight = -2.0f / static_cast<float>(m_windowHeight);
DrawQuadVertexConstants constantsData;
constantsData.m_ndcOriginX = static_cast<float>(x) * twoDivWidth - 1.0f;
constantsData.m_ndcOriginY = static_cast<float>(y) * negativeTwoDivHeight + 1.0f;
constantsData.m_ndcWidth = static_cast<float>(width) * twoDivWidth;
constantsData.m_ndcHeight = static_cast<float>(height) * negativeTwoDivHeight;
constantsData.m_surfaceDimensionX = static_cast<float>(d3d11Surface->GetWidth());
constantsData.m_surfaceDimensionY = static_cast<float>(d3d11Surface->GetHeight());
D3D11_MAPPED_SUBRESOURCE mappedConstants;
if (m_deviceContext->Map(m_drawQuadVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedConstants) == S_OK)
{
memcpy(mappedConstants.pData, &constantsData, sizeof(constantsData));
m_deviceContext->Unmap(m_drawQuadVertexConstantBuffer, 0);
}
}
m_deviceContext->IASetVertexBuffers(0, 1, &vbPtr, &vbStride, &zero);
m_deviceContext->IASetIndexBuffer(m_quadIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_deviceContext->IASetInputLayout(m_drawQuadInputLayout);
ID3D11Buffer *vsConstants = m_drawQuadVertexConstantBuffer;
m_deviceContext->VSSetShader(m_drawQuadVertexShader, nullptr, 0);
m_deviceContext->VSSetConstantBuffers(0, 1, &vsConstants);
ID3D11SamplerState *samplerStates[] =
{
m_nearestNeighborSamplerState,
};
m_deviceContext->PSSetSamplers(0, sizeof(samplerStates) / sizeof(samplerStates[0]), samplerStates);
PortabilityLayer::PixelFormat pixelFormat = d3d11Surface->GetPixelFormat();
if (pixelFormat == PortabilityLayer::PixelFormat_8BitStandard || pixelFormat == PortabilityLayer::PixelFormat_8BitCustom)
{
ID3D11ShaderResourceView *psResourceViews[] =
{
d3d11Surface->GetSRV(),
m_paletteTextureSRV
};
m_deviceContext->PSSetShader(m_drawQuadPalettePixelShader, nullptr, 0);
m_deviceContext->PSSetShaderResources(0, sizeof(psResourceViews) / sizeof(psResourceViews[0]), psResourceViews);
}
else if (pixelFormat == PortabilityLayer::PixelFormat_RGB555)
{
ID3D11ShaderResourceView *psResourceViews[] =
{
d3d11Surface->GetSRV(),
};
m_deviceContext->PSSetShader(m_drawQuad15BitPixelShader, nullptr, 0);
m_deviceContext->PSSetShaderResources(0, sizeof(psResourceViews) / sizeof(psResourceViews[0]), psResourceViews);
}
else if (pixelFormat == PortabilityLayer::PixelFormat_RGB32)
{
ID3D11ShaderResourceView *psResourceViews[] =
{
d3d11Surface->GetSRV(),
};
m_deviceContext->PSSetShader(m_drawQuadRGBPixelShader, nullptr, 0);
m_deviceContext->PSSetShaderResources(0, sizeof(psResourceViews) / sizeof(psResourceViews[0]), psResourceViews);
}
else
{
return;
}
m_deviceContext->DrawIndexed(6, 0, 0);
}
void GpDisplayDriverD3D11::UpdatePalette(const void *paletteData)
{
const size_t dataSize = 256 * 4;
const uint8_t *paletteDataBytes = static_cast<const uint8_t *>(paletteData);
D3D11_MAPPED_SUBRESOURCE mappedResource;
if (m_deviceContext->Map(m_paletteTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) == S_OK)
{
uint8_t *textureDataBytes = static_cast<uint8_t *>(mappedResource.pData);
for (size_t chunkOffset = 0; chunkOffset < dataSize; chunkOffset += sizeof(__m128i))
{
__m128i chunkData = _mm_loadu_si128(reinterpret_cast<const __m128i*>(paletteDataBytes + chunkOffset));
_mm_stream_si128(reinterpret_cast<__m128i*>(textureDataBytes + chunkOffset), chunkData);
}
m_deviceContext->Unmap(m_paletteTexture, 0);
}
}
GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties)
{
return new GpDisplayDriverD3D11(properties);
@@ -292,3 +650,7 @@ GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &prop
m_frameTimeSliceSize = m_QPFrequency.QuadPart * static_cast<LONGLONG>(properties.m_frameTimeLockNumerator) / static_cast<LONGLONG>(properties.m_frameTimeLockDenominator);
}
GpDisplayDriverD3D11::~GpDisplayDriverD3D11()
{
}