mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Add a DX11 video plugin.
Might or might not work for you, yet. Anyway, read the soon to be created forum thread on this plugin before asking any questions. Huge thanks to rodolfoosvaldobogado for helping me out in various areas. Also, thanks to everyone on IRC who supported me during development ;) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5680 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@@ -511,6 +511,7 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, u32 H
|
||||
// alpha test will always fail, so restart the shader and just make it an empty function
|
||||
p = pmainstart;
|
||||
WRITE(p, "ocol0 = 0;\n");
|
||||
WRITE(p, "depth = 1.f;\n");
|
||||
WRITE(p, "discard;return;\n");
|
||||
}
|
||||
else
|
||||
@@ -952,7 +953,7 @@ static bool WriteAlphaTest(char *&p, u32 HLSL)
|
||||
compindex = bpmem.alphaFunc.comp1 % 8;
|
||||
WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table
|
||||
|
||||
WRITE(p, ")){ocol0 = 0;discard;return;}\n");
|
||||
WRITE(p, ")){ocol0 = 0;depth = 1.f;discard;return;}\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -198,6 +198,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_WiimoteNew", "Plugin
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputUICommon", "Core\InputUICommon\InputUICommon.vcproj", "{374E2DB7-42DF-4E59-8474-62B6687F4978}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_VideoDX11", "Plugins\Plugin_VideoDX11\Plugin_VideoDX11.vcproj", "{21DBE606-2958-43AC-A14E-B6B798D56554}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED}
|
||||
{E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} = {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA}
|
||||
{1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE} = {1C8436C9-DBAF-42BE-83BC-CF3EC9175ABE}
|
||||
{C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
@@ -570,6 +578,18 @@ Global
|
||||
{374E2DB7-42DF-4E59-8474-62B6687F4978}.Release|Win32.Build.0 = Release|Win32
|
||||
{374E2DB7-42DF-4E59-8474-62B6687F4978}.Release|x64.ActiveCfg = Release|x64
|
||||
{374E2DB7-42DF-4E59-8474-62B6687F4978}.Release|x64.Build.0 = Release|x64
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.Debug|x64.Build.0 = Debug|x64
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.DebugFast|Win32.ActiveCfg = DebugFast|Win32
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.DebugFast|Win32.Build.0 = DebugFast|Win32
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.DebugFast|x64.ActiveCfg = DebugFast|x64
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.DebugFast|x64.Build.0 = DebugFast|x64
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.Release|Win32.Build.0 = Release|Win32
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.Release|x64.ActiveCfg = Release|x64
|
||||
{21DBE606-2958-43AC-A14E-B6B798D56554}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,139 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "BPFunctions.h"
|
||||
#include "D3DBase.h"
|
||||
#include "VideoConfig.h"
|
||||
#include "Common.h"
|
||||
#include "TextureCache.h"
|
||||
#include "VertexManager.h"
|
||||
#include "VertexShaderManager.h"
|
||||
#include "Render.h"
|
||||
|
||||
namespace BPFunctions
|
||||
{
|
||||
|
||||
void FlushPipeline()
|
||||
{
|
||||
VertexManager::Flush();
|
||||
}
|
||||
|
||||
void SetGenerationMode(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetGenerationMode();
|
||||
}
|
||||
|
||||
void SetScissor(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetScissorRect();
|
||||
}
|
||||
|
||||
void SetLineWidth(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetLineWidth();
|
||||
}
|
||||
|
||||
void SetDepthMode(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetDepthMode();
|
||||
}
|
||||
|
||||
void SetBlendMode(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetBlendMode(false);
|
||||
}
|
||||
void SetDitherMode(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetDitherMode();
|
||||
}
|
||||
void SetLogicOpMode(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetLogicOpMode();
|
||||
}
|
||||
|
||||
void SetColorMask(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetColorMask();
|
||||
}
|
||||
|
||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
||||
{
|
||||
if (!g_ActiveConfig.bEFBCopyDisable)
|
||||
{
|
||||
if (g_ActiveConfig.bCopyEFBToTexture)
|
||||
{
|
||||
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("TODO: Implement EFB copying to RAM %s %d\n", __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||
{
|
||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
||||
bool zEnable = bpmem.zmode.updateenable;
|
||||
|
||||
if (colorEnable || alphaEnable || zEnable)
|
||||
{
|
||||
u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
u32 z = bpmem.clearZValue;
|
||||
|
||||
Renderer::ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z);
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreRenderState(const BPCmd &bp)
|
||||
{
|
||||
Renderer::RestoreAPIState();
|
||||
}
|
||||
|
||||
bool GetConfig(const int &type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CONFIG_ISWII:
|
||||
return g_VideoInitialize.bWii;
|
||||
case CONFIG_DISABLEFOG:
|
||||
return g_ActiveConfig.bDisableFog;
|
||||
case CONFIG_SHOWEFBREGIONS:
|
||||
return false;
|
||||
default:
|
||||
PanicAlert("GetConfig Error: Unknown Config Type!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
u8 *GetPointer(const u32 &address)
|
||||
{
|
||||
return g_VideoInitialize.pGetMemoryPointer(address);
|
||||
}
|
||||
|
||||
void SetTextureMode(const BPCmd &bp)
|
||||
{
|
||||
Renderer::SetSamplerState(bp.address & 3, (bp.address & 0xE0) == 0xA0);
|
||||
}
|
||||
|
||||
void SetInterlacingMode(const BPCmd &bp)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,391 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "D3DBase.h"
|
||||
#include "D3DTexture.h"
|
||||
#include "D3DShader.h"
|
||||
#include "D3Dcompiler.h"
|
||||
#include "VideoConfig.h"
|
||||
#include "Render.h"
|
||||
#include "XFStructs.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
namespace D3D
|
||||
{
|
||||
|
||||
ID3D11Device* device = NULL;
|
||||
ID3D11DeviceContext* context = NULL;
|
||||
IDXGISwapChain* swapchain = NULL;
|
||||
D3D_FEATURE_LEVEL featlevel;
|
||||
D3DTexture2D* backbuf = NULL;
|
||||
HWND hWnd;
|
||||
|
||||
unsigned int xres, yres;
|
||||
|
||||
bool bFrameInProgress = false;
|
||||
|
||||
EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL)
|
||||
{
|
||||
for (unsigned int k = 0;k < 8;k++)
|
||||
{
|
||||
float border[4] = {0.f, 0.f, 0.f, 0.f};
|
||||
shader_resources[k] = NULL;
|
||||
samplerdesc[k] = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, 0.f, 16, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX);
|
||||
}
|
||||
|
||||
blenddesc.AlphaToCoverageEnable = FALSE;
|
||||
blenddesc.IndependentBlendEnable = FALSE;
|
||||
blenddesc.RenderTarget[0].BlendEnable = FALSE;
|
||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
||||
blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
|
||||
blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
|
||||
depthdesc.DepthEnable = TRUE;
|
||||
depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||
depthdesc.DepthFunc = D3D11_COMPARISON_LESS;
|
||||
depthdesc.StencilEnable = FALSE;
|
||||
depthdesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||
depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||
|
||||
// this probably must be changed once multisampling support gets added
|
||||
rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0, false, false, false, false);
|
||||
|
||||
pscbuf = NULL;
|
||||
vscbuf = NULL;
|
||||
vshaderchanged = false;
|
||||
inp_layout = NULL;
|
||||
num_inp_elems = 0;
|
||||
|
||||
pscbufchanged = false;
|
||||
vscbufchanged = false;
|
||||
}
|
||||
|
||||
EmuGfxState::~EmuGfxState()
|
||||
{
|
||||
for (unsigned int k = 0;k < 8;k++)
|
||||
SAFE_RELEASE(shader_resources[k])
|
||||
|
||||
SAFE_RELEASE(vsbytecode);
|
||||
SAFE_RELEASE(psbytecode);
|
||||
SAFE_RELEASE(vertexshader);
|
||||
SAFE_RELEASE(pixelshader);
|
||||
|
||||
SAFE_RELEASE(pscbuf);
|
||||
SAFE_RELEASE(vscbuf);
|
||||
|
||||
SAFE_RELEASE(inp_layout);
|
||||
}
|
||||
|
||||
// TODO: No need to store the whole bytecode, signature might be enough (?)
|
||||
void EmuGfxState::SetVShader(ID3D11VertexShader* shader, ID3D10Blob* bcode)
|
||||
{
|
||||
// TODO: vshaderchanged actually just needs to be true if the signature changed
|
||||
if (bcode && vsbytecode != bcode->GetBufferPointer()) vshaderchanged = true;
|
||||
SAFE_RELEASE(vsbytecode);
|
||||
SAFE_RELEASE(vertexshader);
|
||||
|
||||
if (shader && bcode)
|
||||
{
|
||||
vertexshader = shader;
|
||||
shader->AddRef();
|
||||
vsbytecode = bcode;
|
||||
bcode->AddRef();
|
||||
}
|
||||
else if (shader || bcode)
|
||||
{
|
||||
PanicAlert("Invalid parameters!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void EmuGfxState::SetPShader(ID3D11PixelShader* shader)
|
||||
{
|
||||
if (pixelshader) pixelshader->Release();
|
||||
pixelshader = shader;
|
||||
if (shader) shader->AddRef();
|
||||
}
|
||||
|
||||
void EmuGfxState::SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num)
|
||||
{
|
||||
num_inp_elems = num;
|
||||
memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC));
|
||||
}
|
||||
|
||||
void EmuGfxState::SetShaderResource(int stage, ID3D11ShaderResourceView* srv)
|
||||
{
|
||||
if (shader_resources[stage]) shader_resources[stage]->Release();
|
||||
shader_resources[stage] = srv;
|
||||
if (srv) srv->AddRef();
|
||||
}
|
||||
|
||||
void EmuGfxState::SetAlphaBlendEnable(bool enable)
|
||||
{
|
||||
blenddesc.RenderTarget[0].BlendEnable = enable;
|
||||
}
|
||||
|
||||
void EmuGfxState::SetRenderTargetWriteMask(UINT8 mask)
|
||||
{
|
||||
blenddesc.RenderTarget[0].RenderTargetWriteMask = mask;
|
||||
}
|
||||
|
||||
void EmuGfxState::ApplyState()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
// input layout (only needs to be updated if the vertex shader signature changed)
|
||||
if (vshaderchanged)
|
||||
{
|
||||
if (inp_layout) inp_layout->Release();
|
||||
hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->GetBufferPointer(), vsbytecode->GetBufferSize(), &inp_layout);
|
||||
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
|
||||
SetDebugObjectName((ID3D11DeviceChild*)inp_layout, "an input layout of EmuGfxState");
|
||||
vshaderchanged = false;
|
||||
}
|
||||
D3D::context->IASetInputLayout(inp_layout);
|
||||
|
||||
// vertex shader
|
||||
// TODO: divide the global variables of the generated shaders into about 5 constant buffers
|
||||
// TODO: improve interaction between EmuGfxState and global state management, so that we don't need to set the constant buffers every time
|
||||
if (!vscbuf)
|
||||
{
|
||||
unsigned int size = ((sizeof(float)*952)&(~0xffff))+0x10000; // must be a multiple of 16
|
||||
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
device->CreateBuffer(&cbdesc, NULL, &vscbuf);
|
||||
SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "a vertex shader constant buffer of EmuGfxState");
|
||||
}
|
||||
if (vscbufchanged)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
memcpy(map.pData, vsconstants, sizeof(vsconstants));
|
||||
context->Unmap(vscbuf, 0);
|
||||
}
|
||||
D3D::context->VSSetConstantBuffers(0, 1, &vscbuf);
|
||||
|
||||
// pixel shader
|
||||
if (!pscbuf)
|
||||
{
|
||||
unsigned int size = ((sizeof(float)*116)&(~0xffff))+0x10000; // must be a multiple of 16
|
||||
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
device->CreateBuffer(&cbdesc, NULL, &pscbuf);
|
||||
SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "a pixel shader constant buffer of EmuGfxState");
|
||||
}
|
||||
if (pscbufchanged)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
memcpy(map.pData, psconstants, sizeof(psconstants));
|
||||
context->Unmap(pscbuf, 0);
|
||||
pscbufchanged = false;
|
||||
}
|
||||
D3D::context->PSSetConstantBuffers(0, 1, &pscbuf);
|
||||
|
||||
ID3D11SamplerState* samplerstate[8];
|
||||
for (unsigned int stage = 0; stage < 8; stage++)
|
||||
{
|
||||
if (shader_resources[stage])
|
||||
{
|
||||
hr = D3D::device->CreateSamplerState(&samplerdesc[stage], &samplerstate[stage]);
|
||||
if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage);
|
||||
else SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "a sampler state of EmuGfxState");
|
||||
}
|
||||
else samplerstate[stage] = NULL;
|
||||
}
|
||||
D3D::context->PSSetSamplers(0, 8, samplerstate);
|
||||
for (unsigned int stage = 0; stage < 8; stage++)
|
||||
SAFE_RELEASE(samplerstate[stage]);
|
||||
|
||||
ID3D11BlendState* blstate;
|
||||
hr = device->CreateBlendState(&blenddesc, &blstate);
|
||||
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
|
||||
context->OMSetBlendState(blstate, NULL, 0xFFFFFFFF);
|
||||
SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState");
|
||||
blstate->Release();
|
||||
|
||||
rastdesc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;
|
||||
ID3D11RasterizerState* raststate;
|
||||
hr = device->CreateRasterizerState(&rastdesc, &raststate);
|
||||
if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__);
|
||||
SetDebugObjectName((ID3D11DeviceChild*)raststate, "a rasterizer state of EmuGfxState");
|
||||
context->RSSetState(raststate);
|
||||
raststate->Release();
|
||||
|
||||
ID3D11DepthStencilState* depth_state;
|
||||
hr = device->CreateDepthStencilState(&depthdesc, &depth_state);
|
||||
if (SUCCEEDED(hr)) SetDebugObjectName((ID3D11DeviceChild*)depth_state, "a depth-stencil state of EmuGfxState");
|
||||
else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__);
|
||||
context->OMSetDepthStencilState(depth_state, 0);
|
||||
depth_state->Release();
|
||||
|
||||
context->PSSetShader(pixelshader, NULL, 0);
|
||||
context->VSSetShader(vertexshader, NULL, 0);
|
||||
context->PSSetShaderResources(0, 8, shader_resources);
|
||||
}
|
||||
|
||||
void EmuGfxState::AlphaPass()
|
||||
{
|
||||
context->PSSetShader(pixelshader, NULL, 0);
|
||||
|
||||
ID3D11BlendState* blstate;
|
||||
D3D11_BLEND_DESC desc = blenddesc;
|
||||
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
|
||||
desc.RenderTarget[0].BlendEnable = FALSE;
|
||||
HRESULT hr = device->CreateBlendState(&desc, &blstate);
|
||||
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
|
||||
SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState (created during alpha pass)");
|
||||
context->OMSetBlendState(blstate, NULL, 0xFFFFFFFF);
|
||||
blstate->Release();
|
||||
}
|
||||
|
||||
void EmuGfxState::ResetShaderResources()
|
||||
{
|
||||
for (unsigned int k = 0;k < 8;k++)
|
||||
SAFE_RELEASE(shader_resources[k]);
|
||||
}
|
||||
|
||||
EmuGfxState* gfxstate = NULL;
|
||||
|
||||
HRESULT Create(HWND wnd)
|
||||
{
|
||||
hWnd = wnd;
|
||||
HRESULT hr;
|
||||
|
||||
RECT client;
|
||||
GetClientRect(hWnd, &client);
|
||||
xres = client.right - client.left;
|
||||
yres = client.bottom - client.top;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferCount = 1;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
sd.BufferDesc.Width = xres;
|
||||
sd.BufferDesc.Height = yres;
|
||||
sd.BufferDesc.RefreshRate.Numerator = 60;
|
||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.OutputWindow = wnd;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = TRUE;
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
D3D11_CREATE_DEVICE_FLAG device_flags = (D3D11_CREATE_DEVICE_FLAG)(D3D11_CREATE_DEVICE_DEBUG|D3D11_CREATE_DEVICE_SINGLETHREADED);
|
||||
#else
|
||||
D3D11_CREATE_DEVICE_FLAG device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||
#endif
|
||||
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, device_flags, NULL, 0, D3D11_SDK_VERSION, &sd, &swapchain, &device, &featlevel, &context);
|
||||
if (FAILED(hr) || !device || !context || !swapchain)
|
||||
{
|
||||
MessageBox(wnd, _T("Failed to initialize Direct3D."), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||
SAFE_RELEASE(device);
|
||||
SAFE_RELEASE(context);
|
||||
SAFE_RELEASE(swapchain);
|
||||
return E_FAIL;
|
||||
}
|
||||
SetDebugObjectName((ID3D11DeviceChild*)context, "device context");
|
||||
|
||||
ID3D11Texture2D* buf;
|
||||
hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 plugin"), MB_OK | MB_ICONERROR);
|
||||
device->Release();
|
||||
context->Release();
|
||||
swapchain->Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||
buf->Release();
|
||||
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
|
||||
SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");
|
||||
|
||||
context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL);
|
||||
|
||||
gfxstate = new EmuGfxState;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Close()
|
||||
{
|
||||
// release all bound resources
|
||||
context->ClearState();
|
||||
|
||||
if (gfxstate) delete gfxstate;
|
||||
SAFE_RELEASE(backbuf);
|
||||
SAFE_RELEASE(context);
|
||||
SAFE_RELEASE(swapchain);
|
||||
ULONG references = device->Release();
|
||||
if (references)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Unreleased references: %i.", references);
|
||||
}
|
||||
else
|
||||
{
|
||||
NOTICE_LOG(VIDEO, "Successfully released all device references!");
|
||||
}
|
||||
device = NULL;
|
||||
}
|
||||
|
||||
/* just returning the 4_0 ones here */
|
||||
const char* VertexShaderVersionString() { return "vs_4_0"; }
|
||||
const char* PixelShaderVersionString() { return "ps_4_0"; }
|
||||
|
||||
D3DTexture2D* &GetBackBuffer() { return backbuf; }
|
||||
unsigned int GetBackBufferWidth() { return xres; }
|
||||
unsigned int GetBackBufferHeight() { return yres; }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
// TODO: Check whether we need to do anything here
|
||||
}
|
||||
|
||||
bool BeginFrame()
|
||||
{
|
||||
if (bFrameInProgress)
|
||||
{
|
||||
PanicAlert("BeginFrame called although a frame is already in progress");
|
||||
return false;
|
||||
}
|
||||
bFrameInProgress = true;
|
||||
return (device != NULL);
|
||||
}
|
||||
|
||||
void EndFrame()
|
||||
{
|
||||
if (!bFrameInProgress)
|
||||
{
|
||||
PanicAlert("EndFrame called although no frame is in progress");
|
||||
return;
|
||||
}
|
||||
bFrameInProgress = false;
|
||||
}
|
||||
|
||||
void Present()
|
||||
{
|
||||
// TODO: Is 1 the correct value for vsyncing?
|
||||
swapchain->Present((UINT)g_ActiveConfig.bVSync, 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,147 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
using std::vector;
|
||||
using std::list;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
|
||||
#define SAFE_RELEASE(x) { if (x) (x)->Release(); (x) = NULL; }
|
||||
|
||||
class D3DTexture2D;
|
||||
namespace D3D
|
||||
{
|
||||
|
||||
HRESULT Create(HWND wnd);
|
||||
void Close();
|
||||
|
||||
extern ID3D11Device *device;
|
||||
extern ID3D11DeviceContext *context;
|
||||
extern IDXGISwapChain *swapchain;
|
||||
extern bool bFrameInProgress;
|
||||
|
||||
void Reset();
|
||||
bool BeginFrame();
|
||||
void EndFrame();
|
||||
void Present();
|
||||
|
||||
unsigned int GetBackBufferWidth();
|
||||
unsigned int GetBackBufferHeight();
|
||||
D3DTexture2D* &GetBackBuffer();
|
||||
const char *PixelShaderVersionString();
|
||||
const char *VertexShaderVersionString();
|
||||
|
||||
// Ihis function will assign a name to the given resource.
|
||||
// The DirectX debug layer will make it easier to identify resources that way,
|
||||
// e.g. when listing up all resources who have unreleased references.
|
||||
inline void SetDebugObjectName(ID3D11DeviceChild* resource, const char *name)
|
||||
{
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
resource->SetPrivateData( WKPDID_D3DDebugObjectName, strlen(name), name);
|
||||
#endif
|
||||
}
|
||||
|
||||
// stores the pipeline state to use when calling VertexManager::Flush()
|
||||
class EmuGfxState
|
||||
{
|
||||
public:
|
||||
EmuGfxState();
|
||||
~EmuGfxState();
|
||||
|
||||
void SetVShader(ID3D11VertexShader *shader, ID3D10Blob *bcode);
|
||||
void SetPShader(ID3D11PixelShader *shader);
|
||||
void SetInputElements(const D3D11_INPUT_ELEMENT_DESC *elems, UINT num);
|
||||
void SetShaderResource(int stage, ID3D11ShaderResourceView *srv);
|
||||
|
||||
void ApplyState(); // apply current state
|
||||
void AlphaPass(); // only modify the current state to enable the alpha pass
|
||||
void ResetShaderResources(); // disable all shader resources
|
||||
|
||||
// blend state
|
||||
void SetAlphaBlendEnable(bool enable);
|
||||
void SetRenderTargetWriteMask(UINT8 mask);
|
||||
void SetSrcBlend(D3D11_BLEND val) // TODO: Check whether e.g. the dest color check is needed here
|
||||
{
|
||||
blenddesc.RenderTarget[0].SrcBlend = val;
|
||||
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
else blenddesc.RenderTarget[0].SrcBlendAlpha = val;
|
||||
}
|
||||
void SetDestBlend(D3D11_BLEND val)
|
||||
{
|
||||
blenddesc.RenderTarget[0].DestBlend = val;
|
||||
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
|
||||
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
|
||||
else blenddesc.RenderTarget[0].DestBlendAlpha = val;
|
||||
}
|
||||
void SetBlendOp(D3D11_BLEND_OP val)
|
||||
{
|
||||
blenddesc.RenderTarget[0].BlendOp = val;
|
||||
blenddesc.RenderTarget[0].BlendOpAlpha = val;
|
||||
}
|
||||
|
||||
// sampler states
|
||||
void SetSamplerFilter(DWORD stage, D3D11_FILTER filter) { samplerdesc[stage].Filter = filter; }
|
||||
|
||||
// TODO: add methods for changing the other states instead of modifying them directly
|
||||
|
||||
D3D11_SAMPLER_DESC samplerdesc[8];
|
||||
D3D11_RASTERIZER_DESC rastdesc;
|
||||
D3D11_DEPTH_STENCIL_DESC depthdesc;
|
||||
|
||||
float psconstants[116];
|
||||
float vsconstants[952];
|
||||
bool vscbufchanged;
|
||||
bool pscbufchanged;
|
||||
|
||||
private:
|
||||
ID3D11VertexShader* vertexshader;
|
||||
ID3D10Blob* vsbytecode;
|
||||
ID3D11PixelShader* pixelshader;
|
||||
ID3D10Blob* psbytecode;
|
||||
bool vshaderchanged;
|
||||
|
||||
ID3D11Buffer* vscbuf;
|
||||
ID3D11Buffer* pscbuf;
|
||||
|
||||
ID3D11InputLayout* inp_layout;
|
||||
D3D11_INPUT_ELEMENT_DESC inp_elems[32];
|
||||
int num_inp_elems;
|
||||
|
||||
ID3D11ShaderResourceView* shader_resources[8];
|
||||
D3D11_BLEND_DESC blenddesc;
|
||||
};
|
||||
|
||||
extern EmuGfxState *gfxstate;
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,141 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <d3dx11.h>
|
||||
#include <d3dcompiler.h>
|
||||
#include <string>
|
||||
|
||||
#include "VideoConfig.h"
|
||||
#include "D3DShader.h"
|
||||
|
||||
namespace D3D
|
||||
{
|
||||
|
||||
// bytecode->shader
|
||||
ID3D11VertexShader* CreateVertexShaderFromByteCode(void* bytecode, unsigned int len)
|
||||
{
|
||||
ID3D11VertexShader* v_shader;
|
||||
HRESULT hr = D3D::device->CreateVertexShader(bytecode, len, NULL, &v_shader);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__);
|
||||
v_shader = NULL;
|
||||
}
|
||||
return v_shader;
|
||||
}
|
||||
|
||||
// code->bytecode
|
||||
bool CompileVertexShader(const char* code, unsigned int len, ID3D10Blob** blob)
|
||||
{
|
||||
ID3D10Blob* shaderBuffer = NULL;
|
||||
ID3D10Blob* errorBuffer = NULL;
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
||||
#else
|
||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_SKIP_VALIDATION;
|
||||
#endif
|
||||
HRESULT hr = D3DCompile(code, len, NULL, NULL, NULL, "main", D3D::VertexShaderVersionString(),
|
||||
flags, 0, &shaderBuffer, &errorBuffer);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
||||
msg += "\n\n";
|
||||
msg += code;
|
||||
MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
||||
|
||||
*blob = NULL;
|
||||
}
|
||||
else *blob = shaderBuffer;
|
||||
|
||||
//cleanup
|
||||
if (errorBuffer) errorBuffer->Release();
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
// bytecode->shader
|
||||
ID3D11PixelShader* CreatePixelShaderFromByteCode(void* bytecode, unsigned int len)
|
||||
{
|
||||
ID3D11PixelShader* p_shader;
|
||||
HRESULT hr = D3D::device->CreatePixelShader(bytecode, len, NULL, &p_shader);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
|
||||
p_shader = NULL;
|
||||
}
|
||||
return p_shader;
|
||||
}
|
||||
|
||||
// code->bytecode
|
||||
bool CompilePixelShader(const char* code, unsigned int len, ID3D10Blob** blob)
|
||||
{
|
||||
ID3D10Blob* shaderBuffer = NULL;
|
||||
ID3D10Blob* errorBuffer = NULL;
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_DEBUG|D3D10_SHADER_WARNINGS_ARE_ERRORS;
|
||||
#else
|
||||
UINT flags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY|D3D10_SHADER_OPTIMIZATION_LEVEL3|D3D10_SHADER_SKIP_VALIDATION;
|
||||
#endif
|
||||
HRESULT hr = D3DCompile(code, len, NULL, NULL, NULL, "main", D3D::PixelShaderVersionString(),
|
||||
flags, 0, &shaderBuffer, &errorBuffer);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
std::string msg = (char*)errorBuffer->GetBufferPointer();
|
||||
msg += "\n\n";
|
||||
msg += code;
|
||||
MessageBoxA(0, msg.c_str(), "Error compiling pixel shader", MB_ICONERROR);
|
||||
|
||||
*blob = NULL;
|
||||
}
|
||||
else *blob = shaderBuffer;
|
||||
|
||||
// cleanup
|
||||
if (errorBuffer) errorBuffer->Release();
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len)
|
||||
{
|
||||
ID3D10Blob* blob = NULL;
|
||||
if (CompileVertexShader(code, len, &blob))
|
||||
{
|
||||
ID3D11VertexShader* v_shader = CreateVertexShaderFromByteCode(blob);
|
||||
blob->Release();
|
||||
return v_shader;
|
||||
}
|
||||
PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, unsigned int len)
|
||||
{
|
||||
ID3D10Blob* blob = NULL;
|
||||
CompilePixelShader(code, len, &blob);
|
||||
if (blob)
|
||||
{
|
||||
ID3D11PixelShader* p_shader = CreatePixelShaderFromByteCode(blob);
|
||||
blob->Release();
|
||||
return p_shader;
|
||||
}
|
||||
PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "D3DBase.h"
|
||||
|
||||
namespace D3D
|
||||
{
|
||||
ID3D11VertexShader* CreateVertexShaderFromByteCode(void* bytecode, unsigned int len);
|
||||
ID3D11PixelShader* CreatePixelShaderFromByteCode(void* bytecode, unsigned int len);
|
||||
|
||||
// The returned bytecode buffers should be Release()d.
|
||||
bool CompileVertexShader(const char* code, unsigned int len, ID3D10Blob** blob);
|
||||
bool CompilePixelShader(const char* code, unsigned int len, ID3D10Blob** blob);
|
||||
|
||||
// Utility functions
|
||||
ID3D11VertexShader* CompileAndCreateVertexShader(const char* code, unsigned int len);
|
||||
ID3D11PixelShader* CompileAndCreatePixelShader(const char* code, unsigned int len);
|
||||
|
||||
inline ID3D11VertexShader* CreateVertexShaderFromByteCode(ID3D10Blob* bytecode) { return CreateVertexShaderFromByteCode(bytecode->GetBufferPointer(), bytecode->GetBufferSize()); }
|
||||
inline ID3D11PixelShader* CreatePixelShaderFromByteCode(ID3D10Blob* bytecode) { return CreatePixelShaderFromByteCode(bytecode->GetBufferPointer(), bytecode->GetBufferSize()); }
|
||||
inline ID3D11VertexShader* CompileAndCreateVertexShader(ID3D10Blob* code) { return CompileAndCreateVertexShader((const char*)code->GetBufferPointer(), code->GetBufferSize()); }
|
||||
inline ID3D11PixelShader* CompileAndCreatePixelShader(ID3D10Blob* code) { return CompileAndCreatePixelShader((const char*)code->GetBufferPointer(), code->GetBufferSize()); }
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "d3dx11.h"
|
||||
#include "D3DBase.h"
|
||||
#include "D3DTexture.h"
|
||||
|
||||
namespace D3D
|
||||
{
|
||||
|
||||
// buffers for storing the data for DEFAULT textures
|
||||
const char* texbuf = NULL;
|
||||
unsigned int texbufsize = 0;
|
||||
|
||||
void ReplaceTexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int width, unsigned int height, unsigned int pitch, DXGI_FORMAT fmt, PC_TexFormat pcfmt, unsigned int level, D3D11_USAGE usage)
|
||||
{
|
||||
void* outptr;
|
||||
unsigned int destPitch;
|
||||
bool bExpand = false;
|
||||
|
||||
if (usage == D3D11_USAGE_DYNAMIC || usage == D3D11_USAGE_STAGING)
|
||||
{
|
||||
if (level != 0) PanicAlert("Dynamic textures don't support mipmaps, but given level is not 0 at %s %d\n", __FILE__, __LINE__);
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
D3D::context->Map(pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
outptr = map.pData;
|
||||
destPitch = map.RowPitch;
|
||||
}
|
||||
else if (usage == D3D11_USAGE_DEFAULT)
|
||||
{
|
||||
if (texbufsize < 4*width*height)
|
||||
{
|
||||
if (texbuf) delete[] texbuf;
|
||||
texbuf = new char[4*width*height];
|
||||
texbufsize = 4*width*height;
|
||||
}
|
||||
outptr = (void*)texbuf;
|
||||
destPitch = width * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("ReplaceTexture2D called on an immutable texture!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Merge the conversions done here to VideoDecoder
|
||||
switch (pcfmt)
|
||||
{
|
||||
case PC_TEX_FMT_IA4_AS_IA8:
|
||||
case PC_TEX_FMT_IA8:
|
||||
for (unsigned int y = 0; y < height; y++)
|
||||
{
|
||||
u16* in = (u16*)buffer + y * pitch;
|
||||
u32* pBits = (u32*)((u8*)outptr + y * destPitch);
|
||||
for (unsigned int x = 0; x < width; x++)
|
||||
{
|
||||
const u8 I = (*in & 0xFF);
|
||||
const u8 A = (*in & 0xFF00) >> 8;
|
||||
*pBits = (A << 24) | (I << 16) | (I << 8) | I;
|
||||
in++;
|
||||
pBits++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PC_TEX_FMT_I8:
|
||||
case PC_TEX_FMT_I4_AS_I8:
|
||||
for (unsigned int y = 0; y < height; y++)
|
||||
{
|
||||
u8* in = (u8*)buffer + y * pitch;
|
||||
u32* pBits = (u32*)((u8*)outptr + y * destPitch);
|
||||
for (unsigned int x = 0; x < width; x++)
|
||||
{
|
||||
const u8 col = *in;
|
||||
*pBits = 0xFF000000 | (col << 16) | (col << 8) | col;
|
||||
in++;
|
||||
pBits++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PC_TEX_FMT_BGRA32:
|
||||
// BGRA32 textures can be uploaded directly to VRAM when using DEFAULT textures
|
||||
if (usage == D3D11_USAGE_DEFAULT) break;
|
||||
for (unsigned int y = 0; y < height; y++)
|
||||
{
|
||||
u32* in = (u32*)buffer + y * pitch;
|
||||
u32* pBits = (u32*)((u8*)outptr + y * destPitch);
|
||||
for (unsigned int x = 0; x < width; x++)
|
||||
{
|
||||
const u32 col = *in;
|
||||
*pBits = col;
|
||||
in++;
|
||||
pBits++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PC_TEX_FMT_RGB565:
|
||||
for (unsigned int y = 0; y < height; y++)
|
||||
{
|
||||
u16* in = (u16*)buffer + y * pitch;
|
||||
u32* pBits = (u32*)((u8*)outptr + y * destPitch);
|
||||
for (unsigned int x = 0; x < width; x++)
|
||||
{
|
||||
const u16 col = *in;
|
||||
*pBits = 0xFF000000 | (((col&0x1f)<<3)) | ((col&0x7e0)<<5) | ((col&0xF800)<<8);
|
||||
pBits++;
|
||||
in++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PanicAlert("Unknown tex fmt %d\n", pcfmt);
|
||||
break;
|
||||
}
|
||||
if (usage == D3D11_USAGE_DYNAMIC)
|
||||
{
|
||||
// TODO: UpdateSubresource might be faster than mapping
|
||||
D3D::context->Unmap(pTexture, 0);
|
||||
}
|
||||
else if (usage == D3D11_USAGE_DEFAULT)
|
||||
{
|
||||
D3D11_BOX dest_region = CD3D11_BOX(0, 0, 0, width, height, 1);
|
||||
if (pcfmt == PC_TEX_FMT_BGRA32)
|
||||
D3D::context->UpdateSubresource(pTexture, level, &dest_region, buffer, 4*pitch, 4*(4*pitch)*height);
|
||||
else
|
||||
D3D::context->UpdateSubresource(pTexture, level, &dest_region, outptr, destPitch, 4*width*height);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
D3DTexture2D* D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels)
|
||||
{
|
||||
ID3D11Texture2D* pTexture = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
D3D11_CPU_ACCESS_FLAG cpuflags;
|
||||
if (usage == D3D11_USAGE_STAGING) cpuflags = (D3D11_CPU_ACCESS_FLAG)((int)D3D11_CPU_ACCESS_WRITE|(int)D3D11_CPU_ACCESS_READ);
|
||||
else if (usage == D3D11_USAGE_DYNAMIC) cpuflags = D3D11_CPU_ACCESS_WRITE;
|
||||
else cpuflags = (D3D11_CPU_ACCESS_FLAG)0;
|
||||
D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(fmt, width, height, 1, levels, bind, usage, cpuflags);
|
||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &pTexture);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
PanicAlert("Failed to create texture at %s %d\n", __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
D3DTexture2D* ret = new D3DTexture2D(pTexture, bind);
|
||||
pTexture->Release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void D3DTexture2D::AddRef()
|
||||
{
|
||||
ref++;
|
||||
}
|
||||
|
||||
UINT D3DTexture2D::Release()
|
||||
{
|
||||
ref--;
|
||||
if (ref == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
ID3D11Texture2D* &D3DTexture2D::GetTex() { return tex; }
|
||||
ID3D11ShaderResourceView* &D3DTexture2D::GetSRV() { return srv; }
|
||||
ID3D11RenderTargetView* &D3DTexture2D::GetRTV() { return rtv; }
|
||||
ID3D11DepthStencilView* &D3DTexture2D::GetDSV() { return dsv; }
|
||||
|
||||
D3DTexture2D::D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind,
|
||||
DXGI_FORMAT srv_format, DXGI_FORMAT dsv_format, DXGI_FORMAT rtv_format)
|
||||
: ref(1), tex(texptr), srv(NULL), rtv(NULL), dsv(NULL)
|
||||
{
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = CD3D11_SHADER_RESOURCE_VIEW_DESC(D3D11_SRV_DIMENSION_TEXTURE2D, srv_format);
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc = CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D, dsv_format);
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = CD3D11_RENDER_TARGET_VIEW_DESC(D3D11_RTV_DIMENSION_TEXTURE2D, rtv_format);
|
||||
if (bind & D3D11_BIND_SHADER_RESOURCE) D3D::device->CreateShaderResourceView(tex, &srv_desc, &srv);
|
||||
if (bind & D3D11_BIND_RENDER_TARGET) D3D::device->CreateRenderTargetView(tex, &rtv_desc, &rtv);
|
||||
if (bind & D3D11_BIND_DEPTH_STENCIL) D3D::device->CreateDepthStencilView(tex, &dsv_desc, &dsv);
|
||||
tex->AddRef();
|
||||
}
|
||||
|
||||
D3DTexture2D::~D3DTexture2D()
|
||||
{
|
||||
if (srv) srv->Release();
|
||||
if (rtv) rtv->Release();
|
||||
if (dsv) dsv->Release();
|
||||
tex->Release();
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "D3DBase.h"
|
||||
#include "TextureDecoder.h"
|
||||
|
||||
namespace D3D
|
||||
{
|
||||
void ReplaceTexture2D(ID3D11Texture2D* pTexture, const u8* buffer, unsigned int width, unsigned int height, unsigned int pitch, DXGI_FORMAT fmt, PC_TexFormat pcfmt, unsigned int level, D3D11_USAGE usage);
|
||||
}
|
||||
|
||||
class D3DTexture2D
|
||||
{
|
||||
public:
|
||||
// there are two ways to create a D3DTexture2D object:
|
||||
// either create an ID3D11Texture2D object, pass it to the constructor and specify what views to create
|
||||
// or let the texture automatically be created by D3DTexture2D::Create
|
||||
|
||||
D3DTexture2D(ID3D11Texture2D* texptr, D3D11_BIND_FLAG bind, DXGI_FORMAT srv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN, DXGI_FORMAT rtv_format = DXGI_FORMAT_UNKNOWN);
|
||||
static D3DTexture2D* Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT fmt = DXGI_FORMAT_B8G8R8A8_UNORM, unsigned int levels = 1);
|
||||
|
||||
// reference counting, use AddRef() when creating a new reference and Release() it when you don't need it anymore
|
||||
void AddRef();
|
||||
UINT Release();
|
||||
|
||||
ID3D11Texture2D* &GetTex();
|
||||
ID3D11ShaderResourceView* &GetSRV();
|
||||
ID3D11RenderTargetView* &GetRTV();
|
||||
ID3D11DepthStencilView* &GetDSV();
|
||||
|
||||
private:
|
||||
~D3DTexture2D();
|
||||
|
||||
ID3D11Texture2D* tex;
|
||||
ID3D11ShaderResourceView* srv;
|
||||
ID3D11RenderTargetView* rtv;
|
||||
ID3D11DepthStencilView* dsv;
|
||||
D3D11_BIND_FLAG bindflags;
|
||||
UINT ref;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "D3DBase.h"
|
||||
#include <math.h>
|
||||
#include <MathUtil.h>
|
||||
|
||||
namespace D3D
|
||||
{
|
||||
// Font creation flags
|
||||
#define D3DFONT_BOLD 0x0001
|
||||
#define D3DFONT_ITALIC 0x0002
|
||||
|
||||
// Font rendering flags
|
||||
#define D3DFONT_CENTERED 0x0001
|
||||
|
||||
class CD3DFont
|
||||
{
|
||||
ID3D11ShaderResourceView* m_pTexture;
|
||||
ID3D11Buffer* m_pVB;
|
||||
ID3D11InputLayout* m_InputLayout;
|
||||
ID3D11PixelShader* m_pshader;
|
||||
ID3D11VertexShader* m_vshader;
|
||||
ID3D11BlendState* m_blendstate;
|
||||
ID3D11RasterizerState* m_raststate;
|
||||
const int m_dwTexWidth;
|
||||
const int m_dwTexHeight;
|
||||
float m_fTexCoords[128-32][4];
|
||||
|
||||
public:
|
||||
CD3DFont();
|
||||
// 2D text drawing function
|
||||
// Initializing and destroying device-dependent objects
|
||||
int Init();
|
||||
int Shutdown();
|
||||
int DrawTextScaled(float x, float y,
|
||||
float scale,
|
||||
float spacing, u32 dwColor,
|
||||
const char* strText, bool center=true);
|
||||
};
|
||||
|
||||
extern CD3DFont font;
|
||||
|
||||
void InitUtils();
|
||||
void ShutdownUtils();
|
||||
|
||||
void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
||||
const D3D11_RECT* rSource,
|
||||
int SourceWidth,
|
||||
int SourceHeight,
|
||||
ID3D11PixelShader* PShader,
|
||||
ID3D11VertexShader* VShader,
|
||||
ID3D11InputLayout* layout);
|
||||
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||
const MathUtil::Rectangle<float>* rSource,
|
||||
int SourceWidth,
|
||||
int SourceHeight,
|
||||
const MathUtil::Rectangle<float>* rDest,
|
||||
ID3D11PixelShader* PShader,
|
||||
ID3D11VertexShader* Vshader,
|
||||
ID3D11InputLayout* layout);
|
||||
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
|
||||
void SaveRenderStates();
|
||||
void RestoreRenderStates();
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "resource.h"
|
||||
#include "W32Util/PropertySheet.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
#include "D3DBase.h"
|
||||
|
||||
#include "VideoConfig.h"
|
||||
|
||||
#include "TextureCache.h"
|
||||
|
||||
const char* aspect_ratio_names[4] = {
|
||||
"Auto",
|
||||
"Force 16:9 Widescreen",
|
||||
"Force 4:3 Standard",
|
||||
"Stretch to Window",
|
||||
};
|
||||
|
||||
struct TabDirect3D : public W32Util::Tab
|
||||
{
|
||||
void Init(HWND hDlg)
|
||||
{
|
||||
WCHAR tempwstr[2000];
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, aspect_ratio_names[i], -1, tempwstr, 2000);
|
||||
ComboBox_AddString(GetDlgItem(hDlg, IDC_ASPECTRATIO), tempwstr);
|
||||
}
|
||||
ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_ASPECTRATIO), g_Config.iAspectRatio);
|
||||
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_WIDESCREEN_HACK), g_Config.bWidescreenHack);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_VSYNC), g_Config.bVSync);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE), g_Config.bSafeTextureCache);
|
||||
|
||||
if (g_Config.iSafeTextureCache_ColorSamples == 0)
|
||||
{
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_SAFE), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_Config.iSafeTextureCache_ColorSamples > 128)
|
||||
{
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_NORMAL), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_FAST), true);
|
||||
}
|
||||
}
|
||||
Button_Enable(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_SAFE), g_Config.bSafeTextureCache);
|
||||
Button_Enable(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_NORMAL), g_Config.bSafeTextureCache);
|
||||
Button_Enable(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_FAST), g_Config.bSafeTextureCache);
|
||||
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_EFB_ACCESS_ENABLE), g_Config.bEFBAccessEnable);
|
||||
}
|
||||
|
||||
void Command(HWND hDlg,WPARAM wParam)
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_ASPECTRATIO:
|
||||
g_Config.iAspectRatio = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_ASPECTRATIO));
|
||||
break;
|
||||
case IDC_VSYNC:
|
||||
g_Config.bVSync = Button_GetCheck(GetDlgItem(hDlg, IDC_VSYNC)) ? true : false;
|
||||
break;
|
||||
case IDC_WIDESCREEN_HACK:
|
||||
g_Config.bWidescreenHack = Button_GetCheck(GetDlgItem(hDlg, IDC_WIDESCREEN_HACK)) ? true : false;
|
||||
break;
|
||||
case IDC_SAFE_TEXTURE_CACHE:
|
||||
g_Config.bSafeTextureCache = Button_GetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE)) == 0 ? false : true;
|
||||
Button_Enable(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_SAFE), g_Config.bSafeTextureCache);
|
||||
Button_Enable(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_NORMAL), g_Config.bSafeTextureCache);
|
||||
Button_Enable(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_FAST), g_Config.bSafeTextureCache);
|
||||
break;
|
||||
case IDC_EFB_ACCESS_ENABLE:
|
||||
g_Config.bEFBAccessEnable = Button_GetCheck(GetDlgItem(hDlg, IDC_EFB_ACCESS_ENABLE)) == 0 ? false : true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Apply(HWND hDlg)
|
||||
{
|
||||
if (Button_GetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_SAFE)))
|
||||
{
|
||||
g_Config.iSafeTextureCache_ColorSamples = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Button_GetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_NORMAL)))
|
||||
{
|
||||
if (g_Config.iSafeTextureCache_ColorSamples < 512)
|
||||
{
|
||||
g_Config.iSafeTextureCache_ColorSamples = 512;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_Config.iSafeTextureCache_ColorSamples > 128 || g_Config.iSafeTextureCache_ColorSamples == 0)
|
||||
{
|
||||
g_Config.iSafeTextureCache_ColorSamples = 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_Config.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str());
|
||||
}
|
||||
};
|
||||
|
||||
struct TabAdvanced : public W32Util::Tab
|
||||
{
|
||||
void Init(HWND hDlg)
|
||||
{
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_OSDHOTKEY), g_Config.bOSDHotKey);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_OVERLAYFPS), g_Config.bShowFPS);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_OVERLAYSTATS), g_Config.bOverlayStats);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_OVERLAYPROJSTATS), g_Config.bOverlayProjStats);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_WIREFRAME), g_Config.bWireFrame);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_DISABLEFOG), g_Config.bDisableFog);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLEEFBCOPY), !g_Config.bEFBCopyDisable);
|
||||
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_TEXFMT_OVERLAY), g_Config.bTexFmtOverlayEnable);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_TEXFMT_CENTER), g_Config.bTexFmtOverlayCenter);
|
||||
Button_GetCheck(GetDlgItem(hDlg, IDC_TEXFMT_OVERLAY)) ? Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), true) : Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), false);
|
||||
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_FORCEANISOTROPY),g_Config.iMaxAnisotropy > 1);
|
||||
Button_SetCheck(GetDlgItem(hDlg, IDC_EFBSCALEDCOPY), g_Config.bCopyEFBScaled);
|
||||
|
||||
if (Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEEFBCOPY))) Button_Enable(GetDlgItem(hDlg,IDC_EFBSCALEDCOPY), true);
|
||||
else Button_Enable(GetDlgItem(hDlg, IDC_EFBSCALEDCOPY), false);
|
||||
}
|
||||
void Command(HWND hDlg,WPARAM wParam)
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_TEXFMT_OVERLAY:
|
||||
Button_GetCheck(GetDlgItem(hDlg, IDC_TEXFMT_OVERLAY)) ? Button_Enable(GetDlgItem(hDlg, IDC_TEXFMT_CENTER), true) : Button_Enable(GetDlgItem(hDlg, IDC_TEXFMT_CENTER), false);
|
||||
break;
|
||||
|
||||
case IDC_ENABLEEFBCOPY:
|
||||
if (Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEEFBCOPY))) Button_Enable(GetDlgItem(hDlg, IDC_EFBSCALEDCOPY), true);
|
||||
else Button_Enable(GetDlgItem(hDlg, IDC_EFBSCALEDCOPY), false);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
void Apply(HWND hDlg)
|
||||
{
|
||||
g_Config.bTexFmtOverlayEnable = Button_GetCheck(GetDlgItem(hDlg, IDC_TEXFMT_OVERLAY)) ? true : false;
|
||||
g_Config.bTexFmtOverlayCenter = Button_GetCheck(GetDlgItem(hDlg, IDC_TEXFMT_CENTER)) ? true : false;
|
||||
|
||||
g_Config.bOSDHotKey = Button_GetCheck(GetDlgItem(hDlg, IDC_OSDHOTKEY)) ? true : false;
|
||||
g_Config.bShowFPS = Button_GetCheck(GetDlgItem(hDlg, IDC_OVERLAYFPS)) ? true : false;
|
||||
g_Config.bOverlayStats = Button_GetCheck(GetDlgItem(hDlg, IDC_OVERLAYSTATS)) ? true : false;
|
||||
g_Config.bOverlayProjStats = Button_GetCheck(GetDlgItem(hDlg, IDC_OVERLAYPROJSTATS)) ? true : false;
|
||||
g_Config.bWireFrame = Button_GetCheck(GetDlgItem(hDlg, IDC_WIREFRAME)) ? true : false;
|
||||
g_Config.bDisableFog = Button_GetCheck(GetDlgItem(hDlg, IDC_DISABLEFOG)) ? true : false;
|
||||
g_Config.bEFBCopyDisable = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLEEFBCOPY)) ? false : true;
|
||||
g_Config.bCopyEFBToTexture = !g_Config.bEFBCopyDisable;
|
||||
g_Config.bDumpTextures = false;
|
||||
g_Config.bDumpFrames = false;
|
||||
g_Config.bShowShaderErrors = true;
|
||||
g_Config.bUseNativeMips = true;
|
||||
|
||||
g_Config.iMaxAnisotropy = Button_GetCheck(GetDlgItem(hDlg, IDC_FORCEANISOTROPY)) ? 8 : 1;
|
||||
g_Config.bForceFiltering = false;
|
||||
g_Config.bHiresTextures = false;
|
||||
g_Config.bCopyEFBScaled = Button_GetCheck(GetDlgItem(hDlg, IDC_EFBSCALEDCOPY)) ? true : false;
|
||||
g_Config.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str());
|
||||
}
|
||||
};
|
||||
|
||||
struct TabAbout : public W32Util::Tab
|
||||
{
|
||||
void Init(HWND hDlg) {}
|
||||
void Command(HWND hDlg,WPARAM wParam) {}
|
||||
void Apply(HWND hDlg) {}
|
||||
};
|
||||
|
||||
void DlgSettings_Show(HINSTANCE hInstance, HWND _hParent)
|
||||
{
|
||||
bool tfoe = g_Config.bTexFmtOverlayEnable;
|
||||
bool tfoc = g_Config.bTexFmtOverlayCenter;
|
||||
|
||||
g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str());
|
||||
W32Util::PropSheet sheet;
|
||||
sheet.Add(new TabDirect3D, (LPCTSTR)IDD_SETTINGS, _T("Direct3D"));
|
||||
sheet.Add(new TabAdvanced, (LPCTSTR)IDD_ADVANCED, _T("Advanced"));
|
||||
sheet.Add(new TabAbout, (LPCTSTR)IDD_ABOUT, _T("About"));
|
||||
|
||||
#ifdef DEBUGFAST
|
||||
sheet.Show(hInstance,_hParent,_T("DX11 Graphics Plugin (DEBUGFAST)"));
|
||||
#elif defined _DEBUG
|
||||
sheet.Show(hInstance,_hParent,_T("DX11 Graphics Plugin"));
|
||||
#else
|
||||
sheet.Show(hInstance,_hParent,_T("DX11 Graphics Plugin (DEBUG)"));
|
||||
#endif
|
||||
|
||||
if ((tfoe != g_Config.bTexFmtOverlayEnable) ||
|
||||
((g_Config.bTexFmtOverlayEnable) && ( tfoc != g_Config.bTexFmtOverlayCenter)))
|
||||
{
|
||||
TextureCache::Invalidate(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#pragma once
|
||||
|
||||
void DlgSettings_Show(HINSTANCE hInstance, HWND parent);
|
||||
@@ -0,0 +1,246 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "VideoConfig.h"
|
||||
#include "main.h"
|
||||
#include "EmuWindow.h"
|
||||
#include "D3DBase.h"
|
||||
#include "Fifo.h"
|
||||
|
||||
|
||||
int OSDChoice = 0 , OSDTime = 0, OSDInternalW = 0, OSDInternalH = 0;
|
||||
|
||||
namespace EmuWindow
|
||||
{
|
||||
HWND m_hWnd = NULL;
|
||||
HWND m_hParent = NULL;
|
||||
HINSTANCE m_hInstance = NULL;
|
||||
WNDCLASSEX wndClass;
|
||||
const TCHAR m_szClassName[] = _T("DolphinEmuWnd");
|
||||
int g_winstyle;
|
||||
static volatile bool s_sizing;
|
||||
|
||||
bool IsSizing()
|
||||
{
|
||||
return s_sizing;
|
||||
}
|
||||
|
||||
HWND GetWnd()
|
||||
{
|
||||
return m_hWnd;
|
||||
}
|
||||
|
||||
HWND GetParentWnd()
|
||||
{
|
||||
return m_hParent;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// KeyDown events
|
||||
// -------------
|
||||
void OnKeyDown(WPARAM wParam)
|
||||
{
|
||||
switch (LOWORD( wParam ))
|
||||
{
|
||||
case '3': // OSD keys
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
if (g_Config.bOSDHotKey)
|
||||
OSDMenu(wParam);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
switch( iMsg )
|
||||
{
|
||||
case WM_PAINT:
|
||||
{
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
hdc = BeginPaint(hWnd, &ps);
|
||||
EndPaint(hWnd, &ps);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_ENTERSIZEMOVE:
|
||||
s_sizing = true;
|
||||
break;
|
||||
|
||||
case WM_EXITSIZEMOVE:
|
||||
s_sizing = false;
|
||||
break;
|
||||
|
||||
/* Post thes mouse events to the main window, it's nessesary because in difference to the
|
||||
keyboard inputs these events only appear here, not in the parent window or any other WndProc()*/
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
PostMessage(GetParentWnd(), iMsg, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
// When the user closes the window, we post an event to the main window to call Stop()
|
||||
// Which then handles all the necessary steps to Shutdown the core + the plugins
|
||||
if (m_hParent == NULL)
|
||||
PostMessage(m_hParent, WM_USER, WM_USER_STOP, 0);
|
||||
break;
|
||||
|
||||
case WM_USER:
|
||||
if (wParam == WM_USER_KEYDOWN)
|
||||
OnKeyDown(lParam);
|
||||
else if (wParam == WIIMOTE_DISCONNECT)
|
||||
PostMessage(m_hParent, WM_USER, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
switch (wParam)
|
||||
{
|
||||
case SC_SCREENSAVE:
|
||||
case SC_MONITORPOWER:
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hWnd, iMsg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
case WM_SETCURSOR:
|
||||
PostMessage(m_hParent, WM_USER, WM_USER_SETCURSOR, 0);
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hWnd, iMsg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// OSD Menu
|
||||
// -------------
|
||||
// Let's begin with 3 since 1 and 2 are default Wii keys
|
||||
// -------------
|
||||
void OSDMenu(WPARAM wParam)
|
||||
{
|
||||
switch( LOWORD( wParam ))
|
||||
{
|
||||
case '3':
|
||||
OSDChoice = 1;
|
||||
// Toggle native resolution
|
||||
OSDInternalW = D3D::GetBackBufferWidth();
|
||||
OSDInternalH = D3D::GetBackBufferHeight();
|
||||
break;
|
||||
case '4':
|
||||
OSDChoice = 2;
|
||||
// Toggle aspect ratio
|
||||
g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3;
|
||||
break;
|
||||
case '5':
|
||||
OSDChoice = 3;
|
||||
PanicAlert("Toggling EFB copy not implemented!\n");
|
||||
break;
|
||||
case '6':
|
||||
OSDChoice = 4;
|
||||
g_Config.bDisableFog = !g_Config.bDisableFog;
|
||||
break;
|
||||
case '7':
|
||||
OSDChoice = 5;
|
||||
g_Config.bDisableLighting = !g_Config.bDisableLighting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title)
|
||||
{
|
||||
wndClass.cbSize = sizeof( wndClass );
|
||||
wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
||||
wndClass.lpfnWndProc = WndProc;
|
||||
wndClass.cbClsExtra = 0;
|
||||
wndClass.cbWndExtra = 0;
|
||||
wndClass.hInstance = hInstance;
|
||||
wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
|
||||
wndClass.hCursor = NULL;
|
||||
wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
|
||||
wndClass.lpszMenuName = NULL;
|
||||
wndClass.lpszClassName = m_szClassName;
|
||||
wndClass.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
|
||||
|
||||
m_hInstance = hInstance;
|
||||
RegisterClassEx( &wndClass );
|
||||
|
||||
m_hParent = parent;
|
||||
|
||||
m_hWnd = CreateWindow(m_szClassName, title, WS_CHILD,
|
||||
0, 0, width, height, m_hParent, NULL, hInstance, NULL);
|
||||
|
||||
return m_hWnd;
|
||||
}
|
||||
|
||||
void Show()
|
||||
{
|
||||
ShowWindow(m_hWnd, SW_SHOW);
|
||||
BringWindowToTop(m_hWnd);
|
||||
UpdateWindow(m_hWnd);
|
||||
SetFocus(m_hParent);
|
||||
}
|
||||
|
||||
HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title)
|
||||
{
|
||||
// TODO:
|
||||
// 1. Remove redundant window manipulation,
|
||||
// 2. Make DX11 in fullscreen can be overlapped by other dialogs
|
||||
HWND Ret;
|
||||
int x=0, y=0, width=640, height=480;
|
||||
g_VideoInitialize.pRequestWindowSize(x, y, width, height);
|
||||
|
||||
Ret = OpenWindow(hParent, hInstance, width, height, title);
|
||||
|
||||
if (Ret)
|
||||
{
|
||||
Show();
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
void Close()
|
||||
{
|
||||
if (m_hParent == NULL)
|
||||
DestroyWindow(m_hWnd);
|
||||
UnregisterClass(m_szClassName, m_hInstance);
|
||||
}
|
||||
|
||||
void SetSize(int width, int height)
|
||||
{
|
||||
RECT rc = {0, 0, width, height};
|
||||
DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
|
||||
AdjustWindowRect(&rc, style, false);
|
||||
|
||||
int w = rc.right - rc.left;
|
||||
int h = rc.bottom - rc.top;
|
||||
|
||||
rc.left = (1280 - w)/2;
|
||||
rc.right = rc.left + w;
|
||||
rc.top = (1024 - h)/2;
|
||||
rc.bottom = rc.top + h;
|
||||
MoveWindow(m_hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef _EMUWINDOW_H
|
||||
#define _EMUWINDOW_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace EmuWindow
|
||||
{
|
||||
|
||||
HWND GetWnd();
|
||||
HWND GetParentWnd();
|
||||
HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR* title);
|
||||
void Show();
|
||||
void Close();
|
||||
void SetSize(int displayWidth, int displayHeight);
|
||||
bool IsSizing();
|
||||
void OSDMenu(WPARAM wParam);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,314 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "D3DBase.h"
|
||||
#include "D3DTexture.h"
|
||||
#include "D3DUtil.h"
|
||||
#include "Render.h"
|
||||
#include "FBManager.h"
|
||||
#include "VideoConfig.h"
|
||||
#include "PixelShaderCache.h"
|
||||
#include "VertexShaderCache.h"
|
||||
|
||||
#undef CHECK
|
||||
#define CHECK(cond, Message) if (!(cond)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: %s" , __FILE__, __LINE__, Message); }
|
||||
|
||||
FramebufferManager FBManager;
|
||||
ID3D11SamplerState* copytoVirtualXFBsampler = NULL;
|
||||
|
||||
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
|
||||
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
|
||||
|
||||
D3DTexture2D* &FramebufferManager::GetEFBDepthTexture() { return m_efb.depth_tex; }
|
||||
D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; }
|
||||
ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; }
|
||||
|
||||
void FramebufferManager::Create()
|
||||
{
|
||||
unsigned int target_width = Renderer::GetFullTargetWidth();
|
||||
unsigned int target_height = Renderer::GetFullTargetHeight();
|
||||
ID3D11Texture2D* buf;
|
||||
D3D11_TEXTURE2D_DESC texdesc;
|
||||
HRESULT hr;
|
||||
|
||||
// create framebuffer color texture
|
||||
m_efb.color_tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_B8G8R8A8_UNORM);
|
||||
CHECK(m_efb.color_tex != NULL, "create EFB color texture");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetTex(), "EFB color texture");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetRTV(), "EFB color texture render target view");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_tex->GetSRV(), "EFB color texture shader resource view");
|
||||
|
||||
// create a staging texture for Renderer::AccessEFB
|
||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_B8G8R8A8_UNORM, 1, 1, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_WRITE|D3D11_CPU_ACCESS_READ);
|
||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.color_staging_buf);
|
||||
CHECK(hr==S_OK, "create EFB color staging buffer");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.color_staging_buf, "EFB color staging texture (used for Renderer::AccessEFB)");
|
||||
|
||||
// EFB depth buffer
|
||||
// TODO: Only bind as shader resource if EFB access enabled
|
||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R24G8_TYPELESS, target_width, target_height, 1, 1, D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE);
|
||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||
CHECK(hr==S_OK, "create EFB depth texture");
|
||||
m_efb.depth_tex = new D3DTexture2D(buf, (D3D11_BIND_FLAG)(D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE), DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT);
|
||||
buf->Release();
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetTex(), "EFB depth texture");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetDSV(), "EFB depth texture depth stencil view");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_tex->GetSRV(), "EFB depth texture shader resource view");
|
||||
|
||||
// render target for depth buffer access in Renderer::AccessEFB
|
||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 4, 4, 1, 1, D3D11_BIND_RENDER_TARGET);
|
||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &buf);
|
||||
CHECK(hr==S_OK, "create EFB depth read texture");
|
||||
m_efb.depth_read_texture = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
|
||||
buf->Release();
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetTex(), "EFB depth read texture (used in Renderer::AccessEFB)");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_read_texture->GetRTV(), "EFB depth read texture render target view (used in Renderer::AccessEFB)");
|
||||
|
||||
// staging texture to which we copy the data from m_efb.depth_read_texture
|
||||
texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R32_FLOAT, 4, 4, 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE);
|
||||
hr = D3D::device->CreateTexture2D(&texdesc, NULL, &m_efb.depth_staging_buf);
|
||||
CHECK(hr==S_OK, "create EFB depth staging buffer");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)");
|
||||
|
||||
// sampler state for FramebufferManager::copyToVirtualXFB
|
||||
float border[4] = {0.f, 0.f, 0.f, 0.f};
|
||||
D3D11_SAMPLER_DESC samplerdesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX);
|
||||
D3D::device->CreateSamplerState(&samplerdesc, ©toVirtualXFBsampler);
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)copytoVirtualXFBsampler, "sampler state used for FramebufferManager::copyToVirtualXFB");
|
||||
}
|
||||
|
||||
void FramebufferManager::Destroy()
|
||||
{
|
||||
SAFE_RELEASE(m_efb.color_tex);
|
||||
SAFE_RELEASE(m_efb.color_staging_buf);
|
||||
SAFE_RELEASE(m_efb.depth_tex);
|
||||
SAFE_RELEASE(m_efb.depth_staging_buf);
|
||||
SAFE_RELEASE(m_efb.depth_read_texture);
|
||||
|
||||
SAFE_RELEASE(copytoVirtualXFBsampler);
|
||||
|
||||
for (VirtualXFBListType::iterator it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it)
|
||||
SAFE_RELEASE(it->xfbSource.tex);
|
||||
|
||||
m_virtualXFBList.clear();
|
||||
SAFE_RELEASE(m_realXFBSource.tex);
|
||||
}
|
||||
|
||||
void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||
{
|
||||
copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||
}
|
||||
|
||||
const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||
{
|
||||
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||
}
|
||||
|
||||
FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
||||
{
|
||||
u32 srcLower = xfbAddr;
|
||||
u32 srcUpper = xfbAddr + 2 * width * height;
|
||||
|
||||
VirtualXFBListType::iterator it;
|
||||
for (it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it)
|
||||
{
|
||||
u32 dstLower = it->xfbAddr;
|
||||
u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
|
||||
|
||||
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
||||
return it;
|
||||
}
|
||||
|
||||
// that address is not in the Virtual XFB list.
|
||||
return m_virtualXFBList.end();
|
||||
}
|
||||
|
||||
void FramebufferManager::replaceVirtualXFB()
|
||||
{
|
||||
VirtualXFBListType::iterator it = m_virtualXFBList.begin();
|
||||
|
||||
s32 srcLower = it->xfbAddr;
|
||||
s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
|
||||
s32 lineSize = 2 * it->xfbWidth;
|
||||
|
||||
it++;
|
||||
|
||||
while (it != m_virtualXFBList.end())
|
||||
{
|
||||
s32 dstLower = it->xfbAddr;
|
||||
s32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
|
||||
|
||||
if (dstLower >= srcLower && dstUpper <= srcUpper)
|
||||
{
|
||||
// invalidate the data
|
||||
it->xfbAddr = 0;
|
||||
it->xfbHeight = 0;
|
||||
it->xfbWidth = 0;
|
||||
}
|
||||
else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
||||
{
|
||||
s32 upperOverlap = (srcUpper - dstLower) / lineSize;
|
||||
s32 lowerOverlap = (dstUpper - srcLower) / lineSize;
|
||||
|
||||
if (upperOverlap > 0 && lowerOverlap < 0)
|
||||
{
|
||||
it->xfbAddr += lineSize * upperOverlap;
|
||||
it->xfbHeight -= upperOverlap;
|
||||
}
|
||||
else if (lowerOverlap > 0)
|
||||
{
|
||||
it->xfbHeight -= lowerOverlap;
|
||||
}
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||
{
|
||||
// TODO
|
||||
PanicAlert("copyToRealXFB not implemented, yet\n");
|
||||
}
|
||||
|
||||
void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||
{
|
||||
D3DTexture2D* xfbTex;
|
||||
HRESULT hr = 0;
|
||||
|
||||
VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight);
|
||||
|
||||
if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
|
||||
{
|
||||
PanicAlert("Requested creating a new virtual XFB although the maximum number has already been reached! Report this to the devs");
|
||||
return;
|
||||
}
|
||||
|
||||
float scaleX = Renderer::GetTargetScaleX();
|
||||
float scaleY = Renderer::GetTargetScaleY();
|
||||
TargetRectangle targetSource,efbSource;
|
||||
efbSource = Renderer::ConvertEFBRectangle(sourceRc);
|
||||
targetSource.top = (int)(sourceRc.top * scaleY);
|
||||
targetSource.bottom = (int)(sourceRc.bottom * scaleY);
|
||||
targetSource.left = (int)(sourceRc.left * scaleX);
|
||||
targetSource.right = (int)(sourceRc.right * scaleX);
|
||||
unsigned int target_width = targetSource.right - targetSource.left;
|
||||
unsigned int target_height = targetSource.bottom - targetSource.top;
|
||||
if (it != m_virtualXFBList.end()) // overwrite an existing Virtual XFB
|
||||
{
|
||||
it->xfbAddr = xfbAddr;
|
||||
it->xfbWidth = fbWidth;
|
||||
it->xfbHeight = fbHeight;
|
||||
|
||||
it->xfbSource.srcAddr = xfbAddr;
|
||||
it->xfbSource.srcWidth = fbWidth;
|
||||
it->xfbSource.srcHeight = fbHeight;
|
||||
|
||||
if (it->xfbSource.texWidth != target_width || it->xfbSource.texHeight != target_height || !(it->xfbSource.tex))
|
||||
{
|
||||
SAFE_RELEASE(it->xfbSource.tex);
|
||||
it->xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_B8G8R8A8_UNORM);
|
||||
if (it->xfbSource.tex == NULL) PanicAlert("Failed to create XFB texture\n");
|
||||
}
|
||||
xfbTex = it->xfbSource.tex;
|
||||
|
||||
it->xfbSource.texWidth = target_width;
|
||||
it->xfbSource.texHeight = target_height;
|
||||
|
||||
// move this Virtual XFB to the front of the list.
|
||||
m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, it);
|
||||
|
||||
// keep stale XFB data from being used
|
||||
replaceVirtualXFB();
|
||||
}
|
||||
else // create a new Virtual XFB and place it at the front of the list
|
||||
{
|
||||
VirtualXFB newVirt;
|
||||
|
||||
newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_B8G8R8A8_UNORM);
|
||||
if (newVirt.xfbSource.tex == NULL) PanicAlert("Failed to create a new virtual XFB");
|
||||
|
||||
newVirt.xfbAddr = xfbAddr;
|
||||
newVirt.xfbWidth = fbWidth;
|
||||
newVirt.xfbHeight = fbHeight;
|
||||
|
||||
xfbTex = newVirt.xfbSource.tex;
|
||||
newVirt.xfbSource.texWidth = target_width;
|
||||
newVirt.xfbSource.texHeight = target_height;
|
||||
|
||||
// Add the new Virtual XFB to the list
|
||||
if (m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
|
||||
{
|
||||
PanicAlert("Requested creating a new virtual XFB although the maximum number has already been reached! Report this to the devs");
|
||||
newVirt.xfbSource.tex->Release();
|
||||
return;
|
||||
// TODO, possible alternative to failing: just delete the oldest virtual XFB:
|
||||
// m_virtualXFBList.back().xfbSource.tex->Release();
|
||||
// m_virtualXFBList.pop_back();
|
||||
}
|
||||
m_virtualXFBList.push_front(newVirt);
|
||||
}
|
||||
if (!xfbTex->GetRTV()) return;
|
||||
|
||||
Renderer::ResetAPIState(); // reset any game specific settings
|
||||
|
||||
// copy EFB data to XFB and restore render target again
|
||||
D3D11_RECT sourcerect = CD3D11_RECT(efbSource.left, efbSource.top, efbSource.right, efbSource.bottom);
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)target_width, (float)target_height);
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
D3D::context->PSSetSamplers(0, 1, ©toVirtualXFBsampler);
|
||||
D3D::context->OMSetRenderTargets(1, &xfbTex->GetRTV(), NULL);
|
||||
D3D::drawShadedTexQuad(GetEFBColorTexture()->GetSRV(), &sourcerect,
|
||||
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(), VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout());
|
||||
D3D::context->OMSetRenderTargets(1, &GetEFBColorTexture()->GetRTV(), GetEFBDepthTexture()->GetDSV());
|
||||
Renderer::RestoreAPIState();
|
||||
}
|
||||
|
||||
const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||
{
|
||||
PanicAlert("getRealXFBSource not implemented, yet\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const XFBSource** FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
|
||||
{
|
||||
xfbCount = 0;
|
||||
|
||||
if (m_virtualXFBList.size() == 0) // no Virtual XFBs available
|
||||
return NULL;
|
||||
|
||||
u32 srcLower = xfbAddr;
|
||||
u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
||||
|
||||
VirtualXFBListType::iterator it;
|
||||
for (it = m_virtualXFBList.end(); it != m_virtualXFBList.begin();)
|
||||
{
|
||||
--it;
|
||||
|
||||
u32 dstLower = it->xfbAddr;
|
||||
u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
|
||||
|
||||
if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
|
||||
{
|
||||
m_overlappingXFBArray[xfbCount] = &(it->xfbSource);
|
||||
xfbCount++;
|
||||
}
|
||||
}
|
||||
return &m_overlappingXFBArray[0];
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _FBMANAGER_D3D_H_
|
||||
#define _FBMANAGER_D3D_H_
|
||||
|
||||
#include <list>
|
||||
#include "D3DBase.h"
|
||||
|
||||
// On the GameCube, the game sends a request for the graphics processor to
|
||||
// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
|
||||
// called the XFB (External Framebuffer). The size and location of the XFB is
|
||||
// decided at the time of the copy, and the format is always YUYV. The video
|
||||
// interface is given a pointer to the XFB, which will be decoded and
|
||||
// displayed on the TV.
|
||||
//
|
||||
// There are two ways for Dolphin to emulate this:
|
||||
//
|
||||
// Real XFB mode:
|
||||
//
|
||||
// Dolphin will behave like the GameCube and encode the EFB to
|
||||
// a portion of GameCube RAM. The emulated video interface will decode the data
|
||||
// for output to the screen.
|
||||
//
|
||||
// Advantages: Behaves exactly like the GameCube.
|
||||
// Disadvantages: Resolution will be limited.
|
||||
//
|
||||
// Virtual XFB mode:
|
||||
//
|
||||
// When a request is made to copy the EFB to an XFB, Dolphin
|
||||
// will remember the RAM location and size of the XFB in a Virtual XFB list.
|
||||
// The video interface will look up the XFB in the list and use the enhanced
|
||||
// data stored there, if available.
|
||||
//
|
||||
// Advantages: Enables high resolution graphics, better than real hardware.
|
||||
// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
|
||||
// possible but uncommon), the Virtual XFB will not capture this information.
|
||||
|
||||
// There may be multiple XFBs in GameCube RAM. This is the maximum number to
|
||||
// virtualize.
|
||||
const int MAX_VIRTUAL_XFB = 8;
|
||||
|
||||
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||
{
|
||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||
}
|
||||
|
||||
struct XFBSource
|
||||
{
|
||||
XFBSource()
|
||||
{
|
||||
this->srcAddr = 0;
|
||||
this->srcWidth = 0;
|
||||
this->srcHeight = 0;
|
||||
this->tex = NULL;
|
||||
this->texWidth = 0;
|
||||
this->texHeight = 0;
|
||||
}
|
||||
|
||||
u32 srcAddr;
|
||||
u32 srcWidth;
|
||||
u32 srcHeight;
|
||||
|
||||
D3DTexture2D* tex;
|
||||
unsigned int texWidth;
|
||||
unsigned int texHeight;
|
||||
};
|
||||
|
||||
class FramebufferManager
|
||||
{
|
||||
public:
|
||||
FramebufferManager()
|
||||
{
|
||||
m_efb.color_tex = NULL;
|
||||
m_efb.color_staging_buf = NULL;
|
||||
m_efb.depth_tex = NULL;
|
||||
m_efb.depth_staging_buf = NULL;
|
||||
m_efb.depth_read_texture = NULL;
|
||||
|
||||
m_realXFBSource.tex = NULL;
|
||||
}
|
||||
|
||||
void Create();
|
||||
void Destroy();
|
||||
|
||||
void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||
const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||
|
||||
D3DTexture2D* &GetEFBColorTexture();
|
||||
ID3D11Texture2D* &GetEFBColorStagingBuffer();
|
||||
|
||||
D3DTexture2D* &GetEFBDepthTexture();
|
||||
D3DTexture2D* &GetEFBDepthReadTexture();
|
||||
ID3D11Texture2D* &GetEFBDepthStagingBuffer();
|
||||
|
||||
private:
|
||||
|
||||
struct VirtualXFB
|
||||
{
|
||||
// Address and size in GameCube RAM
|
||||
u32 xfbAddr;
|
||||
u32 xfbWidth;
|
||||
u32 xfbHeight;
|
||||
|
||||
XFBSource xfbSource;
|
||||
};
|
||||
|
||||
typedef std::list<VirtualXFB> VirtualXFBListType;
|
||||
|
||||
VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height);
|
||||
|
||||
void replaceVirtualXFB();
|
||||
|
||||
void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||
void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||
const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||
const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||
|
||||
XFBSource m_realXFBSource; // used in real XFB mode
|
||||
VirtualXFBListType m_virtualXFBList; // used in virtual XFB mode
|
||||
|
||||
const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
||||
|
||||
struct
|
||||
{
|
||||
D3DTexture2D* color_tex;
|
||||
ID3D11Texture2D* color_staging_buf;
|
||||
|
||||
D3DTexture2D* depth_tex;
|
||||
ID3D11Texture2D* depth_staging_buf;
|
||||
D3DTexture2D* depth_read_texture;
|
||||
} m_efb;
|
||||
};
|
||||
|
||||
extern FramebufferManager FBManager;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2003-2009 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _GLOBALS_H_
|
||||
#define _GLOBALS_H_
|
||||
|
||||
#include "Common.h"
|
||||
#include "VideoConfig.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "VideoCommon.h"
|
||||
#include "pluginspecs_video.h"
|
||||
|
||||
// A global plugin specification
|
||||
extern PLUGIN_GLOBALS* globals;
|
||||
|
||||
#endif // _GLOBALS_H_
|
||||
@@ -0,0 +1,148 @@
|
||||
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "D3DBase.h"
|
||||
|
||||
#include "Profiler.h"
|
||||
#include "x64Emitter.h"
|
||||
#include "ABI.h"
|
||||
#include "MemoryUtil.h"
|
||||
#include "VertexShaderGen.h"
|
||||
#include "VertexShaderCache.h"
|
||||
|
||||
#include "CPMemory.h"
|
||||
#include "NativeVertexFormat.h"
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
class D3DVertexFormat : public NativeVertexFormat
|
||||
{
|
||||
D3D11_INPUT_ELEMENT_DESC m_elems[32];
|
||||
UINT m_num_elems;
|
||||
|
||||
public:
|
||||
D3DVertexFormat();
|
||||
~D3DVertexFormat();
|
||||
void Initialize(const PortableVertexDeclaration &_vtx_decl);
|
||||
void SetupVertexPointers() const;
|
||||
};
|
||||
|
||||
NativeVertexFormat* NativeVertexFormat::Create()
|
||||
{
|
||||
return new D3DVertexFormat();
|
||||
}
|
||||
|
||||
D3DVertexFormat::D3DVertexFormat() : m_num_elems(0) { }
|
||||
D3DVertexFormat::~D3DVertexFormat() {}
|
||||
|
||||
DXGI_FORMAT VarToD3D(VarType t, int size)
|
||||
{
|
||||
DXGI_FORMAT retval = DXGI_FORMAT_UNKNOWN;
|
||||
static const DXGI_FORMAT lookup1[5] = {
|
||||
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32_FLOAT
|
||||
};
|
||||
static const DXGI_FORMAT lookup2[5] = {
|
||||
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R32G32_FLOAT
|
||||
};
|
||||
static const DXGI_FORMAT lookup3[5] = {
|
||||
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32G32B32_FLOAT
|
||||
};
|
||||
static const DXGI_FORMAT lookup4[5] = {
|
||||
DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R32G32B32A32_FLOAT
|
||||
};
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1: retval = lookup1[t]; break;
|
||||
case 2: retval = lookup2[t]; break;
|
||||
case 3: retval = lookup3[t]; break;
|
||||
case 4: retval = lookup4[t]; break;
|
||||
default: break;
|
||||
}
|
||||
if (retval == DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
|
||||
{
|
||||
vertex_stride = _vtx_decl.stride;
|
||||
memset(m_elems, 0, sizeof(m_elems));
|
||||
|
||||
m_elems[m_num_elems].SemanticName = "POSITION";
|
||||
m_elems[m_num_elems].AlignedByteOffset = 0;
|
||||
m_elems[m_num_elems].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
++m_num_elems;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (_vtx_decl.normal_offset[i] > 0)
|
||||
{
|
||||
m_elems[m_num_elems].SemanticName = "NORMAL";
|
||||
m_elems[m_num_elems].SemanticIndex = i;
|
||||
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.normal_offset[i];
|
||||
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.normal_gl_type, _vtx_decl.normal_gl_size);
|
||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
++m_num_elems;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (_vtx_decl.color_offset[i] > 0)
|
||||
{
|
||||
m_elems[m_num_elems].SemanticName = "COLOR";
|
||||
m_elems[m_num_elems].SemanticIndex = i;
|
||||
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.color_offset[i];
|
||||
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.color_gl_type, 4);
|
||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
++m_num_elems;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (_vtx_decl.texcoord_offset[i] > 0)
|
||||
{
|
||||
m_elems[m_num_elems].SemanticName = "TEXCOORD";
|
||||
m_elems[m_num_elems].SemanticIndex = i;
|
||||
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.texcoord_offset[i];
|
||||
m_elems[m_num_elems].Format = VarToD3D(_vtx_decl.texcoord_gl_type[i], _vtx_decl.texcoord_size[i]);
|
||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
++m_num_elems;
|
||||
}
|
||||
}
|
||||
|
||||
if (_vtx_decl.posmtx_offset != -1)
|
||||
{
|
||||
m_elems[m_num_elems].SemanticName = "BLENDINDICES";
|
||||
m_elems[m_num_elems].AlignedByteOffset = _vtx_decl.posmtx_offset;
|
||||
m_elems[m_num_elems].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
m_elems[m_num_elems].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
++m_num_elems;
|
||||
}
|
||||
}
|
||||
|
||||
void D3DVertexFormat::SetupVertexPointers() const
|
||||
{
|
||||
D3D::gfxstate->SetInputElements(m_elems, m_num_elems);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user