mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Libretro: add experimental D3D11 support.
This commit is contained in:
parent
4d1503666a
commit
808bf8e681
@ -98,6 +98,8 @@ public:
|
||||
void DrawUP(const void *vdata, int vertexCount) override;
|
||||
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal);
|
||||
|
||||
void BeginFrame() override;
|
||||
|
||||
std::string GetInfoString(InfoField info) const override {
|
||||
switch (info) {
|
||||
case APIVERSION: return "Direct3D 11";
|
||||
@ -1274,6 +1276,34 @@ void D3D11DrawContext::Clear(int mask, uint32_t colorval, float depthVal, int st
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11DrawContext::BeginFrame() {
|
||||
context_->OMSetRenderTargets(1, &curRenderTargetView_, curDepthStencilView_);
|
||||
|
||||
if (curBlend_) {
|
||||
context_->OMSetBlendState(curBlend_->bs, blendFactor_, 0xFFFFFFFF);
|
||||
}
|
||||
if (curDepth_) {
|
||||
context_->OMSetDepthStencilState(curDepth_->dss, stencilRef_);
|
||||
}
|
||||
if (curRaster_) {
|
||||
context_->RSSetState(curRaster_->rs);
|
||||
}
|
||||
context_->IASetInputLayout(curInputLayout_);
|
||||
context_->VSSetShader(curVS_, nullptr, 0);
|
||||
context_->PSSetShader(curPS_, nullptr, 0);
|
||||
context_->GSSetShader(curGS_, nullptr, 0);
|
||||
if (curTopology_ != D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED) {
|
||||
context_->IASetPrimitiveTopology(curTopology_);
|
||||
}
|
||||
if (curPipeline_) {
|
||||
context_->IASetVertexBuffers(0, 1, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_);
|
||||
context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R32_UINT, nextIndexBufferOffset_);
|
||||
if (curPipeline_->dynamicUniforms) {
|
||||
context_->VSSetConstantBuffers(0, 1, &curPipeline_->dynamicUniforms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x, int y, int z, Framebuffer *dstfb, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBit) {
|
||||
D3D11Framebuffer *src = (D3D11Framebuffer *)srcfb;
|
||||
D3D11Framebuffer *dst = (D3D11Framebuffer *)dstfb;
|
||||
|
@ -1,10 +1,15 @@
|
||||
|
||||
set(LIBRETRO_SRCS
|
||||
libretro.cpp
|
||||
LibretroGraphicsContext.cpp
|
||||
LibretroGLContext.cpp
|
||||
LibretroVulkanContext.cpp
|
||||
libretro_vulkan.cpp
|
||||
)
|
||||
libretro_vulkan.cpp)
|
||||
|
||||
if(WIN32)
|
||||
set(LIBRETRO_SRCS ${LIBRETRO_SRCS}
|
||||
LibretroD3D11Context.cpp)
|
||||
endif()
|
||||
|
||||
include_directories(libretro)
|
||||
|
||||
|
104
libretro/LibretroD3D11Context.cpp
Normal file
104
libretro/LibretroD3D11Context.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
|
||||
#include "libretro/LibretroD3D11Context.h"
|
||||
#include "thin3d/d3d11_loader.h"
|
||||
#include <d3d11_1.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#undef __uuidof
|
||||
#define __uuidof(type) IID_##type
|
||||
#endif
|
||||
|
||||
bool LibretroD3D11Context::Init() {
|
||||
if (!LibretroHWRenderContext::Init())
|
||||
return false;
|
||||
|
||||
g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LibretroD3D11Context::CreateDrawContext() {
|
||||
if (!Libretro::environ_cb(RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE, (void **)&d3d11_) || !d3d11_) {
|
||||
ERROR_LOG(G3D, "Failed to get HW rendering interface!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (d3d11_->interface_version != RETRO_HW_RENDER_INTERFACE_D3D11_VERSION) {
|
||||
ERROR_LOG(G3D, "HW render interface mismatch, expected %u, got %u!\n", RETRO_HW_RENDER_INTERFACE_D3D11_VERSION, d3d11_->interface_version);
|
||||
return;
|
||||
}
|
||||
|
||||
ptr_D3DCompile = d3d11_->D3DCompile;
|
||||
|
||||
ID3D11Device1 *device1 = nullptr;
|
||||
d3d11_->device->QueryInterface(__uuidof(ID3D11Device1), (void **)&device1);
|
||||
|
||||
ID3D11DeviceContext1 *context1 = nullptr;
|
||||
d3d11_->context->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&context1);
|
||||
|
||||
draw_ = Draw::T3DCreateD3D11Context(d3d11_->device, d3d11_->context, device1, context1, d3d11_->featureLevel, NULL);
|
||||
}
|
||||
|
||||
void LibretroD3D11Context::DestroyDrawContext() {
|
||||
LibretroHWRenderContext::DestroyDrawContext();
|
||||
d3d11_ = nullptr;
|
||||
}
|
||||
|
||||
void LibretroD3D11Context::ContextDestroy()
|
||||
{
|
||||
LibretroHWRenderContext::ContextDestroy();
|
||||
#if 0
|
||||
// this should be enabled once DeviceLost/DeviceRestore can fully switch to a new draw context.
|
||||
DestroyDrawContext();
|
||||
#endif
|
||||
}
|
||||
|
||||
void LibretroD3D11Context::GotBackbuffer() {
|
||||
D3D11_TEXTURE2D_DESC desc{};
|
||||
desc.Width = PSP_CoreParameter().pixelWidth;
|
||||
desc.Height = PSP_CoreParameter().pixelHeight;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = format_;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
if (SUCCEEDED(d3d11_->device->CreateTexture2D(&desc, nullptr, &texture_))) {
|
||||
if (SUCCEEDED(d3d11_->device->CreateRenderTargetView(texture_, nullptr, &RTView_))) {
|
||||
if (SUCCEEDED(d3d11_->device->CreateShaderResourceView(texture_, nullptr, &SRView_))) {
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight, RTView_, texture_);
|
||||
return;
|
||||
}
|
||||
RTView_->Release();
|
||||
RTView_ = nullptr;
|
||||
}
|
||||
texture_->Release();
|
||||
texture_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void LibretroD3D11Context::LostBackbuffer() {
|
||||
LibretroGraphicsContext::LostBackbuffer();
|
||||
SRView_->Release();
|
||||
SRView_ = nullptr;
|
||||
RTView_->Release();
|
||||
RTView_ = nullptr;
|
||||
texture_->Release();
|
||||
texture_ = nullptr;
|
||||
}
|
||||
|
||||
void LibretroD3D11Context::SwapBuffers() {
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
d3d11_->context->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
|
||||
d3d11_->context->PSSetShaderResources(0, 1, &SRView_);
|
||||
LibretroHWRenderContext::SwapBuffers();
|
||||
|
||||
ID3D11ShaderResourceView * nullSRV = nullptr;
|
||||
d3d11_->context->PSSetShaderResources(0, 1, &nullSRV);
|
||||
|
||||
draw_->HandleEvent(Draw::Event::PRESENTED, 0, 0, nullptr, nullptr);
|
||||
}
|
28
libretro/LibretroD3D11Context.h
Normal file
28
libretro/LibretroD3D11Context.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#define HAVE_D3D11
|
||||
#include "libretro/libretro_d3d.h"
|
||||
#include "libretro/LibretroGraphicsContext.h"
|
||||
|
||||
class LibretroD3D11Context : public LibretroHWRenderContext {
|
||||
public:
|
||||
LibretroD3D11Context() : LibretroHWRenderContext(RETRO_HW_CONTEXT_DIRECT3D, 11) {}
|
||||
bool Init() override;
|
||||
|
||||
void SwapBuffers() override;
|
||||
void GotBackbuffer() override;
|
||||
void LostBackbuffer() override;
|
||||
void CreateDrawContext() override;
|
||||
void DestroyDrawContext() override;
|
||||
|
||||
void ContextDestroy() override;
|
||||
|
||||
GPUCore GetGPUCore() override { return GPUCORE_DIRECTX11; }
|
||||
const char *Ident() override { return "DirectX 11"; }
|
||||
private:
|
||||
retro_hw_render_interface_d3d11 *d3d11_ = nullptr;
|
||||
ID3D11Texture2D *texture_ = nullptr;
|
||||
ID3D11RenderTargetView *RTView_ = nullptr;
|
||||
ID3D11ShaderResourceView *SRView_ = nullptr;
|
||||
DXGI_FORMAT format_ = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
};
|
@ -5,6 +5,9 @@
|
||||
#ifndef NO_VULKAN
|
||||
#include "libretro/LibretroVulkanContext.h"
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include "libretro/LibretroD3D11Context.h"
|
||||
#endif
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Core/Config.h"
|
||||
@ -43,10 +46,12 @@ void LibretroHWRenderContext::ContextReset()
|
||||
{
|
||||
CreateDrawContext();
|
||||
PSP_CoreParameter().thin3d = draw_;
|
||||
draw_->CreatePresets();
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
|
||||
bool success = draw_->CreatePresets();
|
||||
assert(success);
|
||||
}
|
||||
|
||||
GotBackbuffer();
|
||||
|
||||
if (gpu)
|
||||
gpu->DeviceRestore();
|
||||
}
|
||||
@ -64,9 +69,20 @@ void LibretroHWRenderContext::ContextDestroy()
|
||||
#endif
|
||||
}
|
||||
|
||||
LostBackbuffer();
|
||||
gpu->DeviceLost();
|
||||
}
|
||||
|
||||
void LibretroGraphicsContext::GotBackbuffer()
|
||||
{
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
|
||||
}
|
||||
|
||||
void LibretroGraphicsContext::LostBackbuffer()
|
||||
{
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, -1, -1);
|
||||
}
|
||||
|
||||
LibretroGraphicsContext *LibretroGraphicsContext::CreateGraphicsContext()
|
||||
{
|
||||
LibretroGraphicsContext *ctx;
|
||||
|
@ -11,7 +11,7 @@
|
||||
class LibretroGraphicsContext : public GraphicsContext {
|
||||
public:
|
||||
LibretroGraphicsContext() {}
|
||||
~LibretroGraphicsContext() override {}
|
||||
~LibretroGraphicsContext() override { Shutdown();}
|
||||
|
||||
virtual bool Init() = 0;
|
||||
virtual void SetRenderTarget() {}
|
||||
@ -26,12 +26,14 @@ class LibretroGraphicsContext : public GraphicsContext {
|
||||
void SwapInterval(int interval) override {}
|
||||
void Resize() override {}
|
||||
|
||||
virtual void GotBackbuffer();
|
||||
virtual void LostBackbuffer();
|
||||
|
||||
virtual void CreateDrawContext() {}
|
||||
virtual void DestroyDrawContext()
|
||||
{
|
||||
if (!draw_)
|
||||
return;
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, -1, -1);
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
}
|
||||
@ -81,21 +83,6 @@ class LibretroD3D9Context : public LibretroHWRenderContext {
|
||||
GPUCore GetGPUCore() override { return GPUCORE_DIRECTX9; }
|
||||
const char *Ident() override { return "DirectX 9"; }
|
||||
};
|
||||
|
||||
class LibretroD3D11Context : public LibretroHWRenderContext {
|
||||
public:
|
||||
LibretroD3D11Context() : LibretroHWRenderContext(RETRO_HW_CONTEXT_DIRECT3D, 11) {}
|
||||
bool Init() override { return false; }
|
||||
|
||||
void CreateDrawContext() override
|
||||
{
|
||||
draw_ = Draw::T3DCreateD3D11Context(nullptr, nullptr, nullptr, nullptr, D3D_FEATURE_LEVEL_11_0, nullptr);
|
||||
draw_->CreatePresets();
|
||||
}
|
||||
|
||||
GPUCore GetGPUCore() override { return GPUCORE_DIRECTX11; }
|
||||
const char *Ident() override { return "DirectX 11"; }
|
||||
};
|
||||
#endif
|
||||
|
||||
class LibretroSoftwareContext : public LibretroGraphicsContext {
|
||||
|
@ -636,7 +636,8 @@ SOURCES_CXX += \
|
||||
$(GPUDIR)/D3D11/StencilBufferD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/TextureCacheD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/TextureScalerD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/VertexShaderGeneratorD3D11.cpp
|
||||
$(GPUDIR)/D3D11/VertexShaderGeneratorD3D11.cpp \
|
||||
$(LIBRETRODIR)/LibretroD3D11Context.cpp
|
||||
|
||||
SOURCES_CXX += \
|
||||
$(NATIVEDIR)/thin3d/thin3d_d3d9.cpp \
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <cassert>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
#include "base/timeutil.h"
|
||||
#include "Common/ChunkFile.h"
|
||||
|
60
libretro/libretro_d3d.h
Normal file
60
libretro/libretro_d3d.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this libretro API header (libretro_vulkan.h)
|
||||
* ---------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the
|
||||
* "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBRETRO_DIRECT3D_H__
|
||||
#define LIBRETRO_DIRECT3D_H__
|
||||
|
||||
#include "libretro.h"
|
||||
|
||||
#ifdef HAVE_D3D11
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <D3Dcompiler.h>
|
||||
|
||||
#define RETRO_HW_RENDER_INTERFACE_D3D11_VERSION 1
|
||||
|
||||
struct retro_hw_render_interface_d3d11
|
||||
{
|
||||
/* Must be set to RETRO_HW_RENDER_INTERFACE_D3D11. */
|
||||
enum retro_hw_render_interface_type interface_type;
|
||||
/* Must be set to RETRO_HW_RENDER_INTERFACE_D3D11_VERSION. */
|
||||
unsigned interface_version;
|
||||
|
||||
/* Opaque handle to the d3d11 backend in the frontend
|
||||
* which must be passed along to all function pointers
|
||||
* in this interface.
|
||||
*/
|
||||
void* handle;
|
||||
ID3D11Device *device;
|
||||
ID3D11DeviceContext *context;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
pD3DCompile D3DCompile;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* LIBRETRO_DIRECT3D_H__ */
|
Loading…
Reference in New Issue
Block a user