mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
UpdateF, dx reinit
This commit is contained in:
parent
fa2cb7ba56
commit
e87bf5b029
24 changed files with 1029 additions and 415 deletions
|
@ -18,6 +18,7 @@ using namespace DirectX;
|
|||
//#include <D3DX11async.h>
|
||||
//#include <D3DX10math.h>
|
||||
//#include <DxErr.h>
|
||||
#include <dxgi1_3.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
#include "util/AllocDebug.h"
|
||||
|
@ -192,6 +193,7 @@ void DXShaderParam::SetFloat4(float x, float y, float z, float w)
|
|||
DXShader::DXShader()
|
||||
{
|
||||
//? mD3DEffect = NULL;
|
||||
mVertexDef = NULL;
|
||||
mD3DPixelShader = NULL;
|
||||
mD3DVertexShader = NULL;
|
||||
mD3DLayout = NULL;
|
||||
|
@ -201,25 +203,235 @@ DXShader::DXShader()
|
|||
|
||||
DXShader::~DXShader()
|
||||
{
|
||||
DXShaderParamMap::iterator itr = mParamsMap.begin();
|
||||
while (itr != mParamsMap.end())
|
||||
{
|
||||
delete itr->second;
|
||||
++itr;
|
||||
}
|
||||
if (mD3DLayout != NULL)
|
||||
mD3DLayout->Release();
|
||||
if (mD3DVertexShader != NULL)
|
||||
mD3DVertexShader->Release();
|
||||
if (mD3DPixelShader != NULL)
|
||||
mD3DPixelShader->Release();
|
||||
if (mConstBuffer != NULL)
|
||||
mConstBuffer->Release();
|
||||
|
||||
delete mVertexDef;
|
||||
ReleaseNative();
|
||||
|
||||
//? if (mD3DEffect != NULL)
|
||||
//? mD3DEffect->Release();
|
||||
}
|
||||
|
||||
void DXShader::ReleaseNative()
|
||||
{
|
||||
if (mD3DLayout != NULL)
|
||||
mD3DLayout->Release();
|
||||
mD3DLayout = NULL;
|
||||
if (mD3DVertexShader != NULL)
|
||||
mD3DVertexShader->Release();
|
||||
mD3DVertexShader = NULL;
|
||||
if (mD3DPixelShader != NULL)
|
||||
mD3DPixelShader->Release();
|
||||
mD3DPixelShader = NULL;
|
||||
if (mConstBuffer != NULL)
|
||||
mConstBuffer->Release();
|
||||
mConstBuffer = NULL;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
typedef HRESULT(WINAPI* Func_D3DX10CompileFromFileW)(LPCWSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude,
|
||||
LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs);
|
||||
|
||||
static Func_D3DX10CompileFromFileW gFunc_D3DX10CompileFromFileW;
|
||||
|
||||
static bool LoadDXShader(const StringImpl& filePath, const StringImpl& entry, const StringImpl& profile, ID3D10Blob** outBuffer)
|
||||
{
|
||||
HRESULT hr;
|
||||
String outObj = filePath + "_" + entry + "_" + profile;
|
||||
|
||||
bool useCache = false;
|
||||
auto srcDate = ::BfpFile_GetTime_LastWrite(filePath.c_str());
|
||||
auto cacheDate = ::BfpFile_GetTime_LastWrite(outObj.c_str());
|
||||
if (cacheDate >= srcDate)
|
||||
useCache = true;
|
||||
|
||||
if (!useCache)
|
||||
{
|
||||
if (gFunc_D3DX10CompileFromFileW == NULL)
|
||||
{
|
||||
auto lib = LoadLibraryA("D3DCompiler_47.dll");
|
||||
if (lib != NULL)
|
||||
gFunc_D3DX10CompileFromFileW = (Func_D3DX10CompileFromFileW)::GetProcAddress(lib, "D3DCompileFromFile");
|
||||
}
|
||||
|
||||
if (gFunc_D3DX10CompileFromFileW == NULL)
|
||||
useCache = true;
|
||||
}
|
||||
|
||||
if (!useCache)
|
||||
{
|
||||
if (gFunc_D3DX10CompileFromFileW == NULL)
|
||||
{
|
||||
auto lib = LoadLibraryA("D3DCompiler_47.dll");
|
||||
if (lib != NULL)
|
||||
gFunc_D3DX10CompileFromFileW = (Func_D3DX10CompileFromFileW)::GetProcAddress(lib, "D3DCompileFromFile");
|
||||
}
|
||||
|
||||
ID3D10Blob* errorMessage = NULL;
|
||||
auto dxResult = gFunc_D3DX10CompileFromFileW(UTF8Decode(filePath).c_str(), NULL, NULL, entry.c_str(), profile.c_str(),
|
||||
D3D10_SHADER_DEBUG | D3D10_SHADER_ENABLE_STRICTNESS, 0, outBuffer, &errorMessage);
|
||||
|
||||
if (DXFAILED(dxResult))
|
||||
{
|
||||
if (errorMessage != NULL)
|
||||
{
|
||||
BF_FATAL(StrFormat("Vertex shader load failed: %s", (char*)errorMessage->GetBufferPointer()).c_str());
|
||||
errorMessage->Release();
|
||||
}
|
||||
else
|
||||
BF_FATAL("Shader load failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ptr = (*outBuffer)->GetBufferPointer();
|
||||
int size = (int)(*outBuffer)->GetBufferSize();
|
||||
|
||||
FILE* fp = fopen(outObj.c_str(), "wb");
|
||||
if (fp != NULL)
|
||||
{
|
||||
fwrite(ptr, 1, size, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FILE* fp = fopen(outObj.c_str(), "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
BF_FATAL("Failed to load compiled shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
D3D10CreateBlob(size, outBuffer);
|
||||
auto ptr = (*outBuffer)->GetBufferPointer();
|
||||
fread(ptr, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DXShader::Load()
|
||||
{
|
||||
//HRESULT hr;
|
||||
|
||||
ID3D10Blob* errorMessage = NULL;
|
||||
ID3D10Blob* vertexShaderBuffer = NULL;
|
||||
ID3D10Blob* pixelShaderBuffer = NULL;
|
||||
|
||||
LoadDXShader(mSrcPath + ".fx", "VS", "vs_4_0", &vertexShaderBuffer);
|
||||
LoadDXShader(mSrcPath + ".fx", "PS", "ps_4_0", &pixelShaderBuffer);
|
||||
|
||||
defer(
|
||||
{
|
||||
vertexShaderBuffer->Release();
|
||||
pixelShaderBuffer->Release();
|
||||
});
|
||||
|
||||
mHas2DPosition = false;
|
||||
mVertexSize = 0;
|
||||
mD3DLayout = NULL;
|
||||
|
||||
static const char* semanticNames[] = {
|
||||
"POSITION",
|
||||
"POSITION",
|
||||
"COLOR",
|
||||
"TEXCOORD",
|
||||
"NORMAL",
|
||||
"BINORMAL",
|
||||
"TANGENT",
|
||||
"BLENDINDICES",
|
||||
"BLENDWEIGHT",
|
||||
"DEPTH",
|
||||
"FOG",
|
||||
"POINTSIZE",
|
||||
"SAMPLE",
|
||||
"TESSELLATEFACTOR" };
|
||||
|
||||
static const DXGI_FORMAT dxgiFormat[] = {
|
||||
DXGI_FORMAT_R32_FLOAT/*VertexElementFormat_Single*/,
|
||||
DXGI_FORMAT_R32G32_FLOAT/*VertexElementFormat_Vector2*/,
|
||||
DXGI_FORMAT_R32G32B32_FLOAT/*VertexElementFormat_Vector3*/,
|
||||
DXGI_FORMAT_R32G32B32A32_FLOAT/*VertexElementFormat_Vector4*/,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM/*VertexElementFormat_Color*/,
|
||||
DXGI_FORMAT_R8G8B8A8_UINT/*VertexElementFormat_Byte4*/,
|
||||
DXGI_FORMAT_R16G16_UINT/*VertexElementFormat_Short2*/,
|
||||
DXGI_FORMAT_R16G16B16A16_UINT/*VertexElementFormat_Short4*/,
|
||||
DXGI_FORMAT_R16G16_UNORM/*VertexElementFormat_NormalizedShort2*/,
|
||||
DXGI_FORMAT_R16G16B16A16_UNORM/*VertexElementFormat_NormalizedShort4*/,
|
||||
DXGI_FORMAT_R16G16_FLOAT/*VertexElementFormat_HalfVector2*/,
|
||||
DXGI_FORMAT_R16G16B16A16_FLOAT/*VertexElementFormat_HalfVector4*/
|
||||
};
|
||||
|
||||
static const int dxgiSize[] = {
|
||||
sizeof(float) * 1/*VertexElementFormat_Single*/,
|
||||
sizeof(float) * 2/*VertexElementFormat_Vector2*/,
|
||||
sizeof(float) * 3/*VertexElementFormat_Vector3*/,
|
||||
sizeof(float) * 4/*VertexElementFormat_Vector4*/,
|
||||
sizeof(uint32)/*VertexElementFormat_Color*/,
|
||||
sizeof(uint8) * 4/*VertexElementFormat_Byte4*/,
|
||||
sizeof(uint16) * 2/*VertexElementFormat_Short2*/,
|
||||
sizeof(uint16) * 4/*VertexElementFormat_Short4*/,
|
||||
sizeof(uint16) * 2/*VertexElementFormat_NormalizedShort2*/,
|
||||
sizeof(uint16) * 4/*VertexElementFormat_NormalizedShort4*/,
|
||||
sizeof(uint16) * 2/*VertexElementFormat_HalfVector2*/,
|
||||
sizeof(uint16) * 4/*VertexElementFormat_HalfVector4*/
|
||||
};
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC layout[64];
|
||||
for (int elementIdx = 0; elementIdx < mVertexDef->mNumElements; elementIdx++)
|
||||
{
|
||||
VertexDefData* vertexDefData = &mVertexDef->mElementData[elementIdx];
|
||||
|
||||
if (vertexDefData->mUsage == VertexElementUsage_Position2D)
|
||||
mHas2DPosition = true;
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC* elementDesc = &layout[elementIdx];
|
||||
elementDesc->SemanticName = semanticNames[vertexDefData->mUsage];
|
||||
elementDesc->SemanticIndex = vertexDefData->mUsageIndex;
|
||||
elementDesc->Format = dxgiFormat[vertexDefData->mFormat];
|
||||
elementDesc->InputSlot = 0;
|
||||
elementDesc->AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
|
||||
elementDesc->InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
elementDesc->InstanceDataStepRate = 0;
|
||||
mVertexSize += dxgiSize[vertexDefData->mFormat];
|
||||
}
|
||||
|
||||
/* =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
UINT numElements = sizeof(layout) / sizeof(layout[0]);*/
|
||||
HRESULT result = mRenderDevice->mD3DDevice->CreateInputLayout(layout, mVertexDef->mNumElements, vertexShaderBuffer->GetBufferPointer(),
|
||||
vertexShaderBuffer->GetBufferSize(), &mD3DLayout);
|
||||
DXCHECK(result);
|
||||
if (FAILED(result))
|
||||
return false;
|
||||
|
||||
// Create the vertex shader from the buffer.
|
||||
result = mRenderDevice->mD3DDevice->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &mD3DVertexShader);
|
||||
DXCHECK(result);
|
||||
if (FAILED(result))
|
||||
return false;
|
||||
|
||||
// Create the pixel shader from the buffer.
|
||||
result = mRenderDevice->mD3DDevice->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &mD3DPixelShader);
|
||||
DXCHECK(result);
|
||||
if (FAILED(result))
|
||||
return false;
|
||||
|
||||
Init();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DXShader::ReinitNative()
|
||||
{
|
||||
ReleaseNative();
|
||||
Load();
|
||||
}
|
||||
|
||||
ShaderParam* DXShader::GetShaderParam(const StringImpl& name)
|
||||
{
|
||||
DXShaderParamMap::iterator itr = mParamsMap.find(name);
|
||||
|
@ -248,8 +460,8 @@ DXTexture::DXTexture()
|
|||
mD3DRenderTargetView = NULL;
|
||||
mRenderDevice = NULL;
|
||||
mD3DDepthBuffer = NULL;
|
||||
mD3DDepthStencilView = NULL;
|
||||
mImageData = NULL;
|
||||
mD3DDepthStencilView = NULL;
|
||||
mContentBits = NULL;
|
||||
}
|
||||
|
||||
DXTexture::~DXTexture()
|
||||
|
@ -258,7 +470,7 @@ DXTexture::~DXTexture()
|
|||
((DXRenderDevice*)mRenderDevice)->mTextureMap.Remove(mPath);
|
||||
|
||||
//OutputDebugStrF("DXTexture::~DXTexture %@\n", this);
|
||||
delete mImageData;
|
||||
delete mContentBits;
|
||||
if (mD3DResourceView != NULL)
|
||||
mD3DResourceView->Release();
|
||||
if (mD3DDepthStencilView != NULL)
|
||||
|
@ -267,6 +479,8 @@ DXTexture::~DXTexture()
|
|||
mD3DDepthBuffer->Release();
|
||||
if (mD3DTexture != NULL)
|
||||
mD3DTexture->Release();
|
||||
if (mRenderDevice != NULL)
|
||||
mRenderDevice->mTextures.Remove(this);
|
||||
}
|
||||
|
||||
void DXTexture::ReleaseNative()
|
||||
|
@ -297,6 +511,44 @@ void DXTexture::ReleaseNative()
|
|||
|
||||
void DXTexture::ReinitNative()
|
||||
{
|
||||
ReleaseNative();
|
||||
|
||||
int aWidth = 0;
|
||||
int aHeight = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA resData;
|
||||
resData.pSysMem = mContentBits;
|
||||
resData.SysMemPitch = mWidth * 4;
|
||||
resData.SysMemSlicePitch = mWidth * mHeight * 4;
|
||||
|
||||
// Create the target texture
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Width = mWidth;
|
||||
desc.Height = mHeight;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
|
||||
//OutputDebugStrF("Creating texture\n");
|
||||
|
||||
auto dxRenderDevice = (DXRenderDevice*)mRenderDevice;
|
||||
|
||||
DXCHECK(dxRenderDevice->mD3DDevice->CreateTexture2D(&desc, (mContentBits != NULL) ? &resData : NULL, &mD3DTexture));
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srDesc;
|
||||
srDesc.Format = desc.Format;
|
||||
srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srDesc.Texture2D.MostDetailedMip = 0;
|
||||
srDesc.Texture2D.MipLevels = 1;
|
||||
|
||||
DXCHECK(dxRenderDevice->mD3DDevice->CreateShaderResourceView(mD3DTexture, &srDesc, &mD3DResourceView));
|
||||
|
||||
OutputDebugStrF("DXTexture::ReinitNative %p\n", this);
|
||||
}
|
||||
|
||||
void DXTexture::PhysSetAsTarget()
|
||||
|
@ -338,12 +590,24 @@ void DXTexture::Blt(ImageData* imageData, int x, int y)
|
|||
box.front = 0;
|
||||
box.back = 1;
|
||||
mRenderDevice->mD3DDeviceContext->UpdateSubresource(mD3DTexture, 0, &box, imageData->mBits, imageData->mWidth * sizeof(uint32), 0);
|
||||
|
||||
if (mContentBits != NULL)
|
||||
{
|
||||
for (int yOfs = 0; yOfs < imageData->mHeight; yOfs++)
|
||||
memcpy(mContentBits + x + (y + yOfs) * mWidth, imageData->mBits + yOfs * imageData->mWidth, imageData->mWidth * 4);
|
||||
}
|
||||
}
|
||||
|
||||
void DXTexture::SetBits(int destX, int destY, int destWidth, int destHeight, int srcPitch, uint32* bits)
|
||||
{
|
||||
D3D11_BOX box = { (UINT)destX, (UINT)destY, (UINT)0, (UINT)(destX + destWidth), (UINT)(destY + destHeight), 1 };
|
||||
mRenderDevice->mD3DDeviceContext->UpdateSubresource(mD3DTexture, 0, &box, bits, srcPitch * sizeof(uint32), 0);
|
||||
|
||||
if (mContentBits != NULL)
|
||||
{
|
||||
for (int y = 0; y < destHeight; y++)
|
||||
memcpy(mContentBits + destX + (destY + y) * mWidth, bits + (y * srcPitch), destWidth * 4);
|
||||
}
|
||||
}
|
||||
|
||||
void DXTexture::GetBits(int srcX, int srcY, int srcWidth, int srcHeight, int destPitch, uint32* bits)
|
||||
|
@ -367,7 +631,7 @@ void DXTexture::GetBits(int srcX, int srcY, int srcWidth, int srcHeight, int des
|
|||
srcBox.top = srcY;
|
||||
srcBox.right = srcX + srcWidth;
|
||||
srcBox.bottom = srcY + srcHeight;
|
||||
srcBox.back = 1;
|
||||
srcBox.back = 1;
|
||||
|
||||
ID3D11Texture2D *texture;
|
||||
DXCHECK(mRenderDevice->mD3DDevice->CreateTexture2D(&texDesc, 0, &texture));
|
||||
|
@ -532,20 +796,18 @@ void DXRenderDevice::PhysSetRenderState(RenderState* renderState)
|
|||
{
|
||||
HRESULT result = NULL;
|
||||
|
||||
D3D11_BUFFER_DESC matrixBufferDesc;
|
||||
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
matrixBufferDesc.ByteWidth = sizeof(float[4]);
|
||||
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
matrixBufferDesc.MiscFlags = 0;
|
||||
matrixBufferDesc.StructureByteStride = 0;
|
||||
|
||||
static ID3D11Buffer* matrixBuffer = NULL;
|
||||
|
||||
if (matrixBuffer == NULL)
|
||||
if (mMatrix2DBuffer == NULL)
|
||||
{
|
||||
D3D11_BUFFER_DESC matrixBufferDesc;
|
||||
matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
matrixBufferDesc.ByteWidth = sizeof(float[4]);
|
||||
matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
matrixBufferDesc.MiscFlags = 0;
|
||||
matrixBufferDesc.StructureByteStride = 0;
|
||||
|
||||
// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
|
||||
result = mD3DDevice->CreateBuffer(&matrixBufferDesc, NULL, &matrixBuffer);
|
||||
result = mD3DDevice->CreateBuffer(&matrixBufferDesc, NULL, &mMatrix2DBuffer);
|
||||
if (FAILED(result))
|
||||
{
|
||||
return;
|
||||
|
@ -554,7 +816,7 @@ void DXRenderDevice::PhysSetRenderState(RenderState* renderState)
|
|||
|
||||
// Lock the constant buffer so it can be written to.
|
||||
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||
result = mD3DDeviceContext->Map(matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||
result = mD3DDeviceContext->Map(mMatrix2DBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||
if (FAILED(result))
|
||||
{
|
||||
return;
|
||||
|
@ -568,10 +830,10 @@ void DXRenderDevice::PhysSetRenderState(RenderState* renderState)
|
|||
dataPtr[3] = 0;
|
||||
|
||||
// Unlock the constant buffer.
|
||||
mD3DDeviceContext->Unmap(matrixBuffer, 0);
|
||||
mD3DDeviceContext->Unmap(mMatrix2DBuffer, 0);
|
||||
|
||||
//float params[4] = {mCurRenderTarget->mWidth, mCurRenderTarget->mHeight, 0, 0};
|
||||
mD3DDeviceContext->VSSetConstantBuffers(0, 1, &matrixBuffer);
|
||||
mD3DDeviceContext->VSSetConstantBuffers(0, 1, &mMatrix2DBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1003,7 +1265,7 @@ void DXRenderState::ReleaseNative()
|
|||
|
||||
void DXRenderState::ReinitNative()
|
||||
{
|
||||
|
||||
ReleaseNative();
|
||||
}
|
||||
|
||||
void DXRenderState::InvalidateRasterizerState()
|
||||
|
@ -1264,6 +1526,8 @@ DXRenderWindow::DXRenderWindow(DXRenderDevice* renderDevice, WinBFWindow* window
|
|||
mD3DRenderTargetView = NULL;
|
||||
mD3DDepthBuffer = NULL;
|
||||
mD3DDepthStencilView = NULL;
|
||||
mRefreshRate = 0;
|
||||
mFrameWaitObject = NULL;
|
||||
|
||||
mRenderDevice = renderDevice;
|
||||
mDXRenderDevice = renderDevice;
|
||||
|
@ -1275,30 +1539,31 @@ DXRenderWindow::DXRenderWindow(DXRenderDevice* renderDevice, WinBFWindow* window
|
|||
ReinitNative();
|
||||
}
|
||||
|
||||
|
||||
DXRenderWindow::~DXRenderWindow()
|
||||
{
|
||||
ReleaseNative();
|
||||
}
|
||||
|
||||
|
||||
void DXRenderWindow::ReleaseNative()
|
||||
{
|
||||
if (mD3DRenderTargetView != NULL)
|
||||
{
|
||||
if (mFrameWaitObject != NULL)
|
||||
::CloseHandle(mFrameWaitObject);
|
||||
mFrameWaitObject = NULL;
|
||||
if (mD3DRenderTargetView != NULL)
|
||||
mD3DRenderTargetView->Release();
|
||||
mD3DRenderTargetView = NULL;
|
||||
}
|
||||
if (mD3DBackBuffer != NULL)
|
||||
{
|
||||
mD3DRenderTargetView = NULL;
|
||||
if (mD3DBackBuffer != NULL)
|
||||
mD3DBackBuffer->Release();
|
||||
mD3DBackBuffer = NULL;
|
||||
}
|
||||
if (mDXSwapChain != NULL)
|
||||
{
|
||||
mD3DBackBuffer = NULL;
|
||||
if (mDXSwapChain != NULL)
|
||||
mDXSwapChain->Release();
|
||||
mDXSwapChain = NULL;
|
||||
}
|
||||
mDXSwapChain = NULL;
|
||||
if (mD3DRenderTargetView != NULL)
|
||||
mD3DRenderTargetView->Release();
|
||||
mD3DRenderTargetView = NULL;
|
||||
if (mD3DDepthStencilView != NULL)
|
||||
mD3DDepthStencilView->Release();
|
||||
mD3DDepthStencilView = NULL;
|
||||
}
|
||||
|
||||
void DXRenderWindow::ReinitNative()
|
||||
|
@ -1314,8 +1579,8 @@ void DXRenderWindow::ReinitNative()
|
|||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.Windowed = mWindowed ? TRUE : FALSE;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;// DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH /*| DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT*/;
|
||||
|
||||
IDXGIDevice* pDXGIDevice = NULL;
|
||||
mDXRenderDevice->mD3DDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDXGIDevice);
|
||||
|
@ -1324,6 +1589,14 @@ void DXRenderWindow::ReinitNative()
|
|||
pDXGIDevice->Release();
|
||||
pDXGIDevice = NULL;
|
||||
|
||||
// IDXGISwapChain2* swapChain2 = NULL;
|
||||
// mDXSwapChain->QueryInterface(__uuidof(IDXGISwapChain2), (void**)&swapChain2);
|
||||
// if (swapChain2 != NULL)
|
||||
// {
|
||||
// mFrameWaitObject = swapChain2->GetFrameLatencyWaitableObject();
|
||||
// swapChain2->Release();
|
||||
// }
|
||||
|
||||
DXCHECK(mDXSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mD3DBackBuffer));
|
||||
DXCHECK(mDXRenderDevice->mD3DDevice->CreateRenderTargetView(mD3DBackBuffer, NULL, &mD3DRenderTargetView));
|
||||
|
||||
|
@ -1406,7 +1679,14 @@ void DXRenderWindow::Resized()
|
|||
mD3DDepthBuffer->Release();
|
||||
mD3DRenderTargetView->Release();
|
||||
mD3DDepthStencilView->Release();
|
||||
DXCHECK(mDXSwapChain->ResizeBuffers(0, mWidth, mHeight, DXGI_FORMAT_UNKNOWN, 0));
|
||||
|
||||
HRESULT hr = mDXSwapChain->ResizeBuffers(0, mWidth, mHeight, DXGI_FORMAT_UNKNOWN,
|
||||
DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH /*| DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT*/);
|
||||
|
||||
if ((hr == DXGI_ERROR_DEVICE_REMOVED) || (hr == DXGI_ERROR_DEVICE_RESET))
|
||||
((DXRenderDevice*)mRenderDevice)->mNeedsReinitNative = true;
|
||||
else
|
||||
DXCHECK(hr);
|
||||
|
||||
D3D11_TEXTURE2D_DESC descDepth;
|
||||
ZeroMemory(&descDepth, sizeof(descDepth));
|
||||
|
@ -1435,8 +1715,10 @@ void DXRenderWindow::Resized()
|
|||
|
||||
void DXRenderWindow::Present()
|
||||
{
|
||||
mDXSwapChain->Present((mWindow->mFlags & BFWINDOW_VSYNC) ? 1 : 0, 0);
|
||||
//DXCHECK();
|
||||
HRESULT hr = mDXSwapChain->Present((mWindow->mFlags & BFWINDOW_VSYNC) ? 1 : 0, 0);
|
||||
|
||||
if ((hr == DXGI_ERROR_DEVICE_REMOVED) || (hr == DXGI_ERROR_DEVICE_RESET))
|
||||
((DXRenderDevice*)mRenderDevice)->mNeedsReinitNative = true;
|
||||
}
|
||||
|
||||
void DXRenderWindow::CopyBitsTo(uint32* dest, int width, int height)
|
||||
|
@ -1476,28 +1758,110 @@ void DXRenderWindow::CopyBitsTo(uint32* dest, int width, int height)
|
|||
texture->Release();
|
||||
}
|
||||
|
||||
float DXRenderWindow::GetRefreshRate()
|
||||
{
|
||||
if (mRefreshRate == 0)
|
||||
{
|
||||
mRefreshRate = -1;
|
||||
|
||||
IDXGIOutput* output = NULL;
|
||||
mDXSwapChain->GetContainingOutput(&output);
|
||||
if (output != NULL)
|
||||
{
|
||||
DXGI_OUTPUT_DESC outputDesc;
|
||||
output->GetDesc(&outputDesc);
|
||||
|
||||
MONITORINFOEXW info;
|
||||
info.cbSize = sizeof(info);
|
||||
// get the associated monitor info
|
||||
if (GetMonitorInfoW(outputDesc.Monitor, &info) != 0)
|
||||
{
|
||||
// using the CCD get the associated path and display configuration
|
||||
UINT32 requiredPaths, requiredModes;
|
||||
if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &requiredPaths, &requiredModes) == ERROR_SUCCESS)
|
||||
{
|
||||
std::vector<DISPLAYCONFIG_PATH_INFO> paths(requiredPaths);
|
||||
std::vector<DISPLAYCONFIG_MODE_INFO> modes2(requiredModes);
|
||||
if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &requiredPaths, paths.data(), &requiredModes, modes2.data(), nullptr) == ERROR_SUCCESS)
|
||||
{
|
||||
// iterate through all the paths until find the exact source to match
|
||||
for (auto& p : paths)
|
||||
{
|
||||
DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName;
|
||||
sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
|
||||
sourceName.header.size = sizeof(sourceName);
|
||||
sourceName.header.adapterId = p.sourceInfo.adapterId;
|
||||
sourceName.header.id = p.sourceInfo.id;
|
||||
if (DisplayConfigGetDeviceInfo(&sourceName.header) == ERROR_SUCCESS)
|
||||
{
|
||||
// find the matched device which is associated with current device
|
||||
// there may be the possibility that display may be duplicated and windows may be one of them in such scenario
|
||||
// there may be two callback because source is same target will be different
|
||||
// as window is on both the display so either selecting either one is ok
|
||||
if (wcscmp(info.szDevice, sourceName.viewGdiDeviceName) == 0)
|
||||
{
|
||||
// get the refresh rate
|
||||
UINT numerator = p.targetInfo.refreshRate.Numerator;
|
||||
UINT denominator = p.targetInfo.refreshRate.Denominator;
|
||||
mRefreshRate = (float)numerator / (float)denominator;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return mRefreshRate;
|
||||
}
|
||||
|
||||
bool DXRenderWindow::WaitForVBlank()
|
||||
{
|
||||
IDXGIOutput* output = NULL;
|
||||
mDXSwapChain->GetContainingOutput(&output);
|
||||
if (output == NULL)
|
||||
return false;
|
||||
bool success = output->WaitForVBlank() == 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
DXRenderDevice::DXRenderDevice()
|
||||
{
|
||||
mD3DDevice = NULL;
|
||||
|
||||
mD3DDevice = NULL;
|
||||
mNeedsReinitNative = false;
|
||||
mMatrix2DBuffer = NULL;
|
||||
}
|
||||
|
||||
DXRenderDevice::~DXRenderDevice()
|
||||
{
|
||||
for (auto& kv : mTextureMap)
|
||||
kv.mValue->mRenderDevice = NULL;
|
||||
for (auto window : mRenderWindowList)
|
||||
((DXRenderWindow*)window)->ReleaseNative();
|
||||
for (auto shader : mShaders)
|
||||
shader->ReleaseNative();
|
||||
for (auto renderState : mRenderStates)
|
||||
renderState->ReleaseNative();
|
||||
for (auto texture : mTextures)
|
||||
{
|
||||
texture->ReleaseNative();
|
||||
texture->mRenderDevice = NULL;
|
||||
}
|
||||
|
||||
mD3DVertexBuffer->Release();
|
||||
mD3DIndexBuffer->Release();
|
||||
delete mDefaultRenderState;
|
||||
ReleaseNative();
|
||||
|
||||
delete mDefaultRenderState;
|
||||
}
|
||||
|
||||
bool DXRenderDevice::Init(BFApp* app)
|
||||
{
|
||||
BP_ZONE("DXRenderDevice::Init");
|
||||
|
||||
mApp = app;
|
||||
WinBFApp* winApp = (WinBFApp*) app;
|
||||
|
||||
D3D_FEATURE_LEVEL featureLevelArr[] =
|
||||
|
@ -1626,6 +1990,9 @@ void DXRenderDevice::ReleaseNative()
|
|||
{
|
||||
mD3DVertexBuffer->Release();
|
||||
mD3DVertexBuffer = NULL;
|
||||
if (mMatrix2DBuffer != NULL)
|
||||
mMatrix2DBuffer->Release();
|
||||
mMatrix2DBuffer = NULL;
|
||||
mD3DIndexBuffer->Release();
|
||||
mD3DIndexBuffer = NULL;
|
||||
mD3DNormalBlendState->Release();
|
||||
|
@ -1636,20 +2003,37 @@ void DXRenderDevice::ReleaseNative()
|
|||
mD3DWrapSamplerState = NULL;
|
||||
mD3DDeviceContext->Release();
|
||||
mD3DDeviceContext = NULL;
|
||||
|
||||
// ID3D11Debug* debug = NULL;
|
||||
// mD3DDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&debug);
|
||||
// if (debug != NULL)
|
||||
// {
|
||||
// debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
|
||||
// debug->Release();
|
||||
// }
|
||||
|
||||
mD3DDevice->Release();
|
||||
mD3DDevice = NULL;
|
||||
}
|
||||
|
||||
void DXRenderDevice::ReinitNative()
|
||||
{
|
||||
Init(NULL);
|
||||
AutoCrit autoCrit(mApp->mCritSect);
|
||||
|
||||
if (mMatrix2DBuffer != NULL)
|
||||
mMatrix2DBuffer->Release();
|
||||
mMatrix2DBuffer = NULL;
|
||||
|
||||
Init(mApp);
|
||||
|
||||
for (auto window : mRenderWindowList)
|
||||
((DXRenderWindow*)window)->ReinitNative();
|
||||
for (auto kv : mRenderStates)
|
||||
kv->ReinitNative();
|
||||
for (auto kv : mRenderStates)
|
||||
kv->ReinitNative();
|
||||
for (auto shader : mShaders)
|
||||
shader->ReinitNative();
|
||||
for (auto renderState : mRenderStates)
|
||||
renderState->ReinitNative();
|
||||
for (auto tex : mTextures)
|
||||
tex->ReinitNative();
|
||||
}
|
||||
|
||||
void DXRenderDevice::FrameStart()
|
||||
|
@ -1918,6 +2302,10 @@ Texture* DXRenderDevice::LoadTexture(ImageData* imageData, int flags)
|
|||
DXCHECK(mD3DDevice->CreateShaderResourceView(d3DTexture, &srDesc, &d3DShaderResourceView));
|
||||
|
||||
DXTexture* aTexture = new DXTexture();
|
||||
|
||||
aTexture->mContentBits = new uint32[aWidth * aHeight];
|
||||
memcpy(aTexture->mContentBits, imageData->mBits, aWidth * aHeight * 4);
|
||||
|
||||
aTexture->mRenderDevice = this;
|
||||
aTexture->mWidth = aWidth;
|
||||
aTexture->mHeight = aHeight;
|
||||
|
@ -1976,204 +2364,21 @@ Texture* DXRenderDevice::CreateDynTexture(int width, int height)
|
|||
return aTexture;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
typedef HRESULT (WINAPI* Func_D3DX10CompileFromFileW)(LPCWSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude,
|
||||
LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs);
|
||||
|
||||
static Func_D3DX10CompileFromFileW gFunc_D3DX10CompileFromFileW;
|
||||
|
||||
static bool LoadDXShader(const StringImpl& filePath, const StringImpl& entry, const StringImpl& profile, ID3D10Blob** outBuffer)
|
||||
{
|
||||
HRESULT hr;
|
||||
String outObj = filePath + "_" + entry + "_" + profile;
|
||||
|
||||
bool useCache = false;
|
||||
auto srcDate = ::BfpFile_GetTime_LastWrite(filePath.c_str());
|
||||
auto cacheDate = ::BfpFile_GetTime_LastWrite(outObj.c_str());
|
||||
if (cacheDate >= srcDate)
|
||||
useCache = true;
|
||||
|
||||
if (!useCache)
|
||||
{
|
||||
if (gFunc_D3DX10CompileFromFileW == NULL)
|
||||
{
|
||||
auto lib = LoadLibraryA("D3DCompiler_47.dll");
|
||||
if (lib != NULL)
|
||||
gFunc_D3DX10CompileFromFileW = (Func_D3DX10CompileFromFileW)::GetProcAddress(lib, "D3DCompileFromFile");
|
||||
}
|
||||
|
||||
if (gFunc_D3DX10CompileFromFileW == NULL)
|
||||
useCache = true;
|
||||
}
|
||||
|
||||
if (!useCache)
|
||||
{
|
||||
if (gFunc_D3DX10CompileFromFileW == NULL)
|
||||
{
|
||||
auto lib = LoadLibraryA("D3DCompiler_47.dll");
|
||||
if (lib != NULL)
|
||||
gFunc_D3DX10CompileFromFileW = (Func_D3DX10CompileFromFileW)::GetProcAddress(lib, "D3DCompileFromFile");
|
||||
}
|
||||
|
||||
ID3D10Blob* errorMessage = NULL;
|
||||
auto dxResult = gFunc_D3DX10CompileFromFileW(UTF8Decode(filePath).c_str(), NULL, NULL, entry.c_str(), profile.c_str(),
|
||||
D3D10_SHADER_DEBUG | D3D10_SHADER_ENABLE_STRICTNESS, 0, outBuffer, &errorMessage);
|
||||
|
||||
if (DXFAILED(dxResult))
|
||||
{
|
||||
if (errorMessage != NULL)
|
||||
{
|
||||
BF_FATAL(StrFormat("Vertex shader load failed: %s", (char*)errorMessage->GetBufferPointer()).c_str());
|
||||
errorMessage->Release();
|
||||
}
|
||||
else
|
||||
BF_FATAL("Shader load failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ptr = (*outBuffer)->GetBufferPointer();
|
||||
int size = (int)(*outBuffer)->GetBufferSize();
|
||||
|
||||
FILE* fp = fopen(outObj.c_str(), "wb");
|
||||
if (fp != NULL)
|
||||
{
|
||||
fwrite(ptr, 1, size, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FILE* fp = fopen(outObj.c_str(), "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
BF_FATAL("Failed to load compiled shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
D3D10CreateBlob(size, outBuffer);
|
||||
auto ptr = (*outBuffer)->GetBufferPointer();
|
||||
fread(ptr, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Shader* DXRenderDevice::LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition)
|
||||
{
|
||||
BP_ZONE("DXRenderDevice::LoadShader");
|
||||
|
||||
//HRESULT hr;
|
||||
|
||||
ID3D10Blob* errorMessage = NULL;
|
||||
ID3D10Blob* vertexShaderBuffer = NULL;
|
||||
ID3D10Blob* pixelShaderBuffer = NULL;
|
||||
|
||||
LoadDXShader(fileName + ".fx", "VS", "vs_4_0", &vertexShaderBuffer);
|
||||
LoadDXShader(fileName + ".fx", "PS", "ps_4_0", &pixelShaderBuffer);
|
||||
|
||||
DXShader* dxShader = new DXShader();
|
||||
|
||||
dxShader->mVertexSize = 0;
|
||||
dxShader->mD3DLayout = NULL;
|
||||
|
||||
static const char* semanticNames[] = {
|
||||
"POSITION",
|
||||
"POSITION",
|
||||
"COLOR",
|
||||
"TEXCOORD",
|
||||
"NORMAL",
|
||||
"BINORMAL",
|
||||
"TANGENT",
|
||||
"BLENDINDICES",
|
||||
"BLENDWEIGHT",
|
||||
"DEPTH",
|
||||
"FOG",
|
||||
"POINTSIZE",
|
||||
"SAMPLE",
|
||||
"TESSELLATEFACTOR"};
|
||||
|
||||
static const DXGI_FORMAT dxgiFormat[] = {
|
||||
DXGI_FORMAT_R32_FLOAT/*VertexElementFormat_Single*/,
|
||||
DXGI_FORMAT_R32G32_FLOAT/*VertexElementFormat_Vector2*/,
|
||||
DXGI_FORMAT_R32G32B32_FLOAT/*VertexElementFormat_Vector3*/,
|
||||
DXGI_FORMAT_R32G32B32A32_FLOAT/*VertexElementFormat_Vector4*/,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM/*VertexElementFormat_Color*/,
|
||||
DXGI_FORMAT_R8G8B8A8_UINT/*VertexElementFormat_Byte4*/,
|
||||
DXGI_FORMAT_R16G16_UINT/*VertexElementFormat_Short2*/,
|
||||
DXGI_FORMAT_R16G16B16A16_UINT/*VertexElementFormat_Short4*/,
|
||||
DXGI_FORMAT_R16G16_UNORM/*VertexElementFormat_NormalizedShort2*/,
|
||||
DXGI_FORMAT_R16G16B16A16_UNORM/*VertexElementFormat_NormalizedShort4*/,
|
||||
DXGI_FORMAT_R16G16_FLOAT/*VertexElementFormat_HalfVector2*/,
|
||||
DXGI_FORMAT_R16G16B16A16_FLOAT/*VertexElementFormat_HalfVector4*/
|
||||
};
|
||||
|
||||
static const int dxgiSize[] = {
|
||||
sizeof(float) * 1/*VertexElementFormat_Single*/,
|
||||
sizeof(float) * 2/*VertexElementFormat_Vector2*/,
|
||||
sizeof(float) * 3/*VertexElementFormat_Vector3*/,
|
||||
sizeof(float) * 4/*VertexElementFormat_Vector4*/,
|
||||
sizeof(uint32)/*VertexElementFormat_Color*/,
|
||||
sizeof(uint8) * 4/*VertexElementFormat_Byte4*/,
|
||||
sizeof(uint16) * 2/*VertexElementFormat_Short2*/,
|
||||
sizeof(uint16) * 4/*VertexElementFormat_Short4*/,
|
||||
sizeof(uint16) * 2/*VertexElementFormat_NormalizedShort2*/,
|
||||
sizeof(uint16) * 4/*VertexElementFormat_NormalizedShort4*/,
|
||||
sizeof(uint16) * 2/*VertexElementFormat_HalfVector2*/,
|
||||
sizeof(uint16) * 4/*VertexElementFormat_HalfVector4*/
|
||||
};
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC layout[64];
|
||||
for (int elementIdx = 0; elementIdx < vertexDefinition->mNumElements; elementIdx++)
|
||||
dxShader->mRenderDevice = this;
|
||||
dxShader->mSrcPath = fileName;
|
||||
dxShader->mVertexDef = new VertexDefinition(vertexDefinition);
|
||||
if (!dxShader->Load())
|
||||
{
|
||||
VertexDefData* vertexDefData = &vertexDefinition->mElementData[elementIdx];
|
||||
|
||||
if (vertexDefData->mUsage == VertexElementUsage_Position2D)
|
||||
dxShader->mHas2DPosition = true;
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC* elementDesc = &layout[elementIdx];
|
||||
elementDesc->SemanticName = semanticNames[vertexDefData->mUsage];
|
||||
elementDesc->SemanticIndex = vertexDefData->mUsageIndex;
|
||||
elementDesc->Format = dxgiFormat[vertexDefData->mFormat];
|
||||
elementDesc->InputSlot = 0;
|
||||
elementDesc->AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
|
||||
elementDesc->InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
elementDesc->InstanceDataStepRate = 0;
|
||||
dxShader->mVertexSize += dxgiSize[vertexDefData->mFormat];
|
||||
delete dxShader;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
UINT numElements = sizeof(layout) / sizeof(layout[0]);*/
|
||||
HRESULT result = mD3DDevice->CreateInputLayout(layout, vertexDefinition->mNumElements, vertexShaderBuffer->GetBufferPointer(),
|
||||
vertexShaderBuffer->GetBufferSize(), &dxShader->mD3DLayout);
|
||||
DXCHECK(result);
|
||||
if (FAILED(result))
|
||||
return NULL;
|
||||
|
||||
// Create the vertex shader from the buffer.
|
||||
result = mD3DDevice->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &dxShader->mD3DVertexShader);
|
||||
DXCHECK(result);
|
||||
if (FAILED(result))
|
||||
return NULL;
|
||||
|
||||
// Create the pixel shader from the buffer.
|
||||
result = mD3DDevice->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &dxShader->mD3DPixelShader);
|
||||
DXCHECK(result);
|
||||
if (FAILED(result))
|
||||
return NULL;
|
||||
|
||||
vertexShaderBuffer->Release();
|
||||
pixelShaderBuffer->Release();
|
||||
|
||||
dxShader->Init();
|
||||
return dxShader;
|
||||
mShaders.Add(dxShader);
|
||||
return dxShader;
|
||||
}
|
||||
|
||||
void DXRenderDevice::SetRenderState(RenderState* renderState)
|
||||
|
|
|
@ -60,22 +60,22 @@ public:
|
|||
DXRenderDevice* mRenderDevice;
|
||||
ID3D11Texture2D* mD3DTexture;
|
||||
ID3D11ShaderResourceView* mD3DResourceView;
|
||||
ID3D11RenderTargetView* mD3DRenderTargetView;
|
||||
ID3D11RenderTargetView* mD3DRenderTargetView;
|
||||
ID3D11Texture2D* mD3DDepthBuffer;
|
||||
ID3D11DepthStencilView* mD3DDepthStencilView;
|
||||
ImageData* mImageData;
|
||||
ID3D11DepthStencilView* mD3DDepthStencilView;
|
||||
uint32* mContentBits;
|
||||
|
||||
public:
|
||||
DXTexture();
|
||||
~DXTexture();
|
||||
|
||||
void ReleaseNative();
|
||||
void ReinitNative();
|
||||
|
||||
void ReleaseNative();
|
||||
void ReinitNative();
|
||||
|
||||
virtual void PhysSetAsTarget() override;
|
||||
virtual void Blt(ImageData* imageData, int x, int y) override;
|
||||
virtual void SetBits(int destX, int destY, int destWidth, int destHeight, int srcPitch, uint32* bits) override;
|
||||
virtual void GetBits(int srcX, int srcY, int srcWidth, int srcHeight, int destPitch, uint32* bits) override;
|
||||
virtual void GetBits(int srcX, int srcY, int srcWidth, int srcHeight, int destPitch, uint32* bits) override;
|
||||
};
|
||||
|
||||
class DXShaderParam : public ShaderParam
|
||||
|
@ -95,7 +95,11 @@ typedef std::map<String, DXShaderParam*> DXShaderParamMap;
|
|||
|
||||
class DXShader : public Shader
|
||||
{
|
||||
public:
|
||||
public:
|
||||
DXRenderDevice* mRenderDevice;
|
||||
String mSrcPath;
|
||||
VertexDefinition* mVertexDef;
|
||||
|
||||
ID3D11InputLayout* mD3DLayout;
|
||||
ID3D11VertexShader* mD3DVertexShader;
|
||||
ID3D11PixelShader* mD3DPixelShader;
|
||||
|
@ -107,7 +111,11 @@ public:
|
|||
DXShader();
|
||||
~DXShader();
|
||||
|
||||
virtual ShaderParam* GetShaderParam(const StringImpl& name) override;
|
||||
void ReleaseNative();
|
||||
void ReinitNative();
|
||||
|
||||
bool Load();
|
||||
virtual ShaderParam* GetShaderParam(const StringImpl& name) override;
|
||||
};
|
||||
|
||||
class DXDrawBatch : public DrawBatch
|
||||
|
@ -144,8 +152,10 @@ public:
|
|||
ID3D11RenderTargetView* mD3DRenderTargetView;
|
||||
ID3D11Texture2D* mD3DDepthBuffer;
|
||||
ID3D11DepthStencilView* mD3DDepthStencilView;
|
||||
HANDLE mFrameWaitObject;
|
||||
float mRefreshRate;
|
||||
bool mResizePending;
|
||||
bool mWindowed;
|
||||
bool mWindowed;
|
||||
int mPendingWidth;
|
||||
int mPendingHeight;
|
||||
|
||||
|
@ -164,6 +174,8 @@ public:
|
|||
virtual void Present() override;
|
||||
|
||||
void CopyBitsTo(uint32* dest, int width, int height);
|
||||
virtual float GetRefreshRate() override;
|
||||
virtual bool WaitForVBlank() override;
|
||||
};
|
||||
|
||||
typedef std::vector<DXDrawBatch*> DXDrawBatchVector;
|
||||
|
@ -174,7 +186,7 @@ typedef std::vector<DXDrawBatch*> DXDrawBatchVector;
|
|||
class DXDrawBufferPool
|
||||
{
|
||||
public:
|
||||
std::vector<void*> mPooledIndexBuffers;
|
||||
std::vector<void*> mPooledIndexBuffers;
|
||||
int mIdxPoolIdx;
|
||||
std::vector<void*> mPooledVertexBuffers;
|
||||
int mVtxPoolIdx;
|
||||
|
@ -237,8 +249,8 @@ public:
|
|||
class DXModelInstance : public ModelInstance
|
||||
{
|
||||
public:
|
||||
DXRenderDevice* mD3DRenderDevice;
|
||||
Array<DXModelMesh> mDXModelMeshs;
|
||||
DXRenderDevice* mD3DRenderDevice;
|
||||
Array<DXModelMesh> mDXModelMeshs;
|
||||
|
||||
public:
|
||||
DXModelInstance(ModelDef* modelDef);
|
||||
|
@ -282,11 +294,12 @@ public:
|
|||
IDXGIFactory* mDXGIFactory;
|
||||
ID3D11Device* mD3DDevice;
|
||||
ID3D11DeviceContext* mD3DDeviceContext;
|
||||
ID3D11BlendState* mD3DNormalBlendState;
|
||||
ID3D11BlendState* mD3DNormalBlendState;
|
||||
ID3D11SamplerState* mD3DDefaultSamplerState;
|
||||
ID3D11SamplerState* mD3DWrapSamplerState;
|
||||
bool mHasVSync;
|
||||
bool mNeedsReinitNative;
|
||||
|
||||
ID3D11Buffer* mMatrix2DBuffer;
|
||||
ID3D11Buffer* mD3DVertexBuffer;
|
||||
ID3D11Buffer* mD3DIndexBuffer;
|
||||
int mVtxByteIdx;
|
||||
|
@ -294,6 +307,7 @@ public:
|
|||
|
||||
HashSet<DXRenderState*> mRenderStates;
|
||||
HashSet<DXTexture*> mTextures;
|
||||
HashSet<DXShader*> mShaders;
|
||||
Dictionary<String, DXTexture*> mTextureMap;
|
||||
Dictionary<int, ID3D11Buffer*> mBufferMap;
|
||||
|
||||
|
|
|
@ -600,6 +600,9 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_DISPLAYCHANGE:
|
||||
((DXRenderWindow*)mRenderWindow)->mRefreshRate = 0;
|
||||
break;
|
||||
case WM_SIZE:
|
||||
mRenderWindow->Resized();
|
||||
if (mMovedFunc != NULL)
|
||||
|
@ -986,7 +989,6 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
|
||||
mIsMenuKeyHandled = false;
|
||||
int keyCode = (int) wParam;
|
||||
if (keyCode == VK_APPS)
|
||||
|
@ -995,8 +997,13 @@ LRESULT WinBFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||
if ((mKeyLayoutHasAltGr) && (keyCode == VK_MENU) && ((lParam & 0x01000000) != 0))
|
||||
keyCode = VK_RMENU;
|
||||
|
||||
mIsKeyDown[keyCode] = true;
|
||||
mIsKeyDown[keyCode] = true;
|
||||
|
||||
// if ((keyCode == 192) && (mIsKeyDown[VK_MENU]))
|
||||
// {
|
||||
// ((DXRenderDevice*)mRenderWindow->mRenderDevice)->mNeedsReinitNative = true;
|
||||
// }
|
||||
|
||||
for (auto kv : *menuIDMap)
|
||||
{
|
||||
WinBFMenu* aMenu = kv.mValue;
|
||||
|
@ -1275,10 +1282,71 @@ WinBFApp::WinBFApp()
|
|||
mInMsgProc = false;
|
||||
mDSoundManager = NULL;
|
||||
mDInputManager = NULL;
|
||||
|
||||
mVSyncThreadId = 0;
|
||||
mClosing = false;
|
||||
mVSyncActive = false;
|
||||
mVSyncThread = BfpThread_Create(VSyncThreadProcThunk, (void*)this, 128 * 1024, BfpThreadCreateFlag_StackSizeReserve, &mVSyncThreadId);
|
||||
BfpThread_SetPriority(mVSyncThread, BfpThreadPriority_High, NULL);
|
||||
}
|
||||
|
||||
void BFP_CALLTYPE WinBFApp::VSyncThreadProcThunk(void* ptr)
|
||||
{
|
||||
((WinBFApp*)ptr)->VSyncThreadProc();
|
||||
}
|
||||
|
||||
void WinBFApp::VSyncThreadProc()
|
||||
{
|
||||
while (!mClosing)
|
||||
{
|
||||
bool didWait = false;
|
||||
|
||||
IDXGIOutput* output = NULL;
|
||||
|
||||
//
|
||||
{
|
||||
AutoCrit autoCrit(mCritSect);
|
||||
if ((mRenderDevice != NULL) && (!mRenderDevice->mRenderWindowList.IsEmpty()))
|
||||
{
|
||||
auto renderWindow = (DXRenderWindow*)mRenderDevice->mRenderWindowList[0];
|
||||
renderWindow->mDXSwapChain->GetContainingOutput(&output);
|
||||
}
|
||||
}
|
||||
|
||||
if (output != NULL)
|
||||
{
|
||||
DWORD start = GetTickCount();
|
||||
bool success = output->WaitForVBlank() == 0;
|
||||
int elapsed = (int)(GetTickCount() - start);
|
||||
if (elapsed >= 20)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
didWait = true;
|
||||
mVSyncActive = true;
|
||||
mVSyncEvent.Set();
|
||||
}
|
||||
|
||||
output->Release();
|
||||
}
|
||||
|
||||
if (!didWait)
|
||||
{
|
||||
mVSyncActive = false;
|
||||
BfpThread_Sleep(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WinBFApp::~WinBFApp()
|
||||
{
|
||||
mClosing = true;
|
||||
BfpThread_WaitFor(mVSyncThread, -1);
|
||||
BfpThread_Release(mVSyncThread);
|
||||
|
||||
delete mRenderDevice;
|
||||
delete mDSoundManager;
|
||||
delete mDInputManager;
|
||||
|
@ -1288,6 +1356,8 @@ void WinBFApp::Init()
|
|||
{
|
||||
BP_ZONE("WinBFApp::Init");
|
||||
|
||||
AutoCrit autoCrit(mCritSect);
|
||||
|
||||
mRunning = true;
|
||||
mInMsgProc = false;
|
||||
|
||||
|
@ -1311,10 +1381,23 @@ void WinBFApp::Run()
|
|||
}
|
||||
}
|
||||
|
||||
void WinBFApp::Process()
|
||||
{
|
||||
BFApp::Process();
|
||||
|
||||
auto dxRenderDevice = (DXRenderDevice*)mRenderDevice;
|
||||
if (dxRenderDevice->mNeedsReinitNative)
|
||||
{
|
||||
dxRenderDevice->mNeedsReinitNative = false;
|
||||
dxRenderDevice->ReinitNative();
|
||||
mForceNextDraw = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WinBFApp::Draw()
|
||||
{
|
||||
mRenderDevice->FrameStart();
|
||||
BFApp::Draw();
|
||||
BFApp::Draw();
|
||||
mRenderDevice->FrameEnd();
|
||||
}
|
||||
|
||||
|
@ -1392,6 +1475,8 @@ void WinBFApp::GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fro
|
|||
|
||||
BFWindow* WinBFApp::CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
|
||||
{
|
||||
AutoCrit autoCrit(mCritSect);
|
||||
|
||||
BFWindow* aWindow = new WinBFWindow(parent, title, x, y, width, height, windowFlags);
|
||||
mWindowList.push_back(aWindow);
|
||||
|
||||
|
@ -2025,6 +2110,13 @@ BFSoundManager* WinBFApp::GetSoundManager()
|
|||
return mDSoundManager;
|
||||
}
|
||||
|
||||
intptr WinBFApp::GetCriticalThreadId(int idx)
|
||||
{
|
||||
if (idx == 0)
|
||||
return mVSyncThreadId;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WinBFWindow::ModalsRemoved()
|
||||
{
|
||||
::EnableWindow(mHWnd, TRUE);
|
||||
|
|
|
@ -32,7 +32,7 @@ typedef Dictionary<HMENU, WinBFMenu*> WinHMenuMap;
|
|||
|
||||
class WinBFWindow : public BFWindow
|
||||
{
|
||||
public:
|
||||
public:
|
||||
HWND mHWnd;
|
||||
bool mIsMouseInside;
|
||||
WinMenuIDMap mMenuIDMap;
|
||||
|
@ -93,13 +93,19 @@ public:
|
|||
|
||||
class WinBFApp : public BFApp
|
||||
{
|
||||
public:
|
||||
public:
|
||||
bool mInMsgProc;
|
||||
StringToUIntMap mClipboardFormatMap;
|
||||
DSoundManager* mDSoundManager;
|
||||
DInputManager* mDInputManager;
|
||||
|
||||
BfpThreadId mVSyncThreadId;
|
||||
BfpThread* mVSyncThread;
|
||||
volatile bool mClosing;
|
||||
|
||||
protected:
|
||||
void VSyncThreadProc();
|
||||
static void BFP_CALLTYPE VSyncThreadProcThunk(void* ptr);
|
||||
|
||||
virtual void Draw() override;
|
||||
virtual void PhysSetCursor() override;
|
||||
|
||||
|
@ -107,10 +113,11 @@ protected:
|
|||
|
||||
public:
|
||||
WinBFApp();
|
||||
virtual ~WinBFApp();
|
||||
virtual ~WinBFApp();
|
||||
|
||||
virtual void Init() override;
|
||||
virtual void Run() override;
|
||||
virtual void Run() override;
|
||||
virtual void Process() override;
|
||||
|
||||
virtual void GetDesktopResolution(int& width, int& height) override;
|
||||
virtual void GetWorkspaceRect(int& x, int& y, int& width, int& height) override;
|
||||
|
@ -129,6 +136,8 @@ public:
|
|||
virtual BFSysBitmap* LoadSysBitmap(const WCHAR* fileName) override;
|
||||
|
||||
virtual BFSoundManager* GetSoundManager() override;
|
||||
|
||||
virtual intptr GetCriticalThreadId(int idx) override;
|
||||
};
|
||||
|
||||
NS_BF_END;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue