Files
Xenia-Canary/src/xenia/gpu/d3d11/d3d11_window.cc

126 lines
3.5 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <xenia/gpu/d3d11/d3d11_window.h>
using namespace xe;
using namespace xe::gpu;
using namespace xe::gpu::d3d11;
using namespace xe::ui;
using namespace xe::ui::win32;
D3D11Window::D3D11Window(
xe_run_loop_ref run_loop,
IDXGIFactory1* dxgi_factory, ID3D11Device* device) :
Win32Window(run_loop) {
dxgi_factory_ = dxgi_factory;
dxgi_factory_->AddRef();
device_ = device;
device_->AddRef();
device_->GetImmediateContext(&context_);
swap_chain_ = 0;
render_target_view_ = 0;
closing.AddListener([](UIEvent& e) {
xe_run_loop_quit(e.window()->run_loop());
});
}
D3D11Window::~D3D11Window() {
if (context_) {
context_->ClearState();
}
XESAFERELEASE(render_target_view_);
XESAFERELEASE(context_);
XESAFERELEASE(swap_chain_);
XESAFERELEASE(device_);
XESAFERELEASE(dxgi_factory_);
}
int D3D11Window::Initialize(const char* title, uint32_t width, uint32_t height) {
int result = Win32Window::Initialize(title, width, height);
if (result) {
return result;
}
// Setup swap chain.
DXGI_SWAP_CHAIN_DESC desc;
xe_zero_struct(&desc, sizeof(desc));
desc.OutputWindow = handle();
desc.Windowed = TRUE;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
// Setup buffers.
desc.BufferCount = 2;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferDesc.Width = width;
desc.BufferDesc.Height = height;
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.BufferDesc.RefreshRate.Numerator = 60;
desc.BufferDesc.RefreshRate.Denominator = 1;
// Disable multisampling.
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
// Create!
HRESULT hr = dxgi_factory_->CreateSwapChain(
device_,
&desc,
&swap_chain_);
if (FAILED(hr)) {
XELOGE("CreateSwapChain failed with %.8X", hr);
return 1;
}
// Create a render target view to draw into.
ID3D11Texture2D* back_buffer = 0;
hr = swap_chain_->GetBuffer(
0, __uuidof(ID3D11Texture2D), (void**)&back_buffer);
if (FAILED(hr)) {
XELOGE("GetBuffer (back_buffer) failed with %.8X", hr);
return 1;
}
hr = device_->CreateRenderTargetView(
back_buffer, NULL, &render_target_view_);
back_buffer->Release();
if (FAILED(hr)) {
XELOGE("CreateRenderTargetView (back_buffer) failed with %.8X", hr);
return 1;
}
context_->OMSetRenderTargets(1, &render_target_view_, NULL);
return 0;
}
void D3D11Window::Swap() {
// Swap buffers.
// TODO(benvanik): control vsync with flag.
bool vsync = true;
HRESULT hr = swap_chain_->Present(vsync ? 1 : 0, 0);
if (FAILED(hr)) {
XELOGE("Present failed with %.8X", hr);
}
}
bool D3D11Window::OnResize(uint32_t width, uint32_t height) {
if (!Win32Window::OnResize(width, height)) {
return false;
}
// TODO(benvanik): resize swap buffers?
return true;
}