dx9, dx11: video shift support
Shift the framebuffer according to VO_STARTX and VO_STARTY. Issue #594 lr: draw overlay and manage shifting in dx11 context
This commit is contained in:
parent
b94200233d
commit
caec338d25
|
@ -462,10 +462,9 @@ bool DX11Renderer::Render()
|
|||
DrawOSD(false);
|
||||
theDX11Context.setFrameRendered();
|
||||
#else
|
||||
theDX11Context.drawOverlay(width, height);
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
deviceContext->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
deviceContext->PSSetShaderResources(0, 1, &fbTextureView.get());
|
||||
theDX11Context.presentFrame(fbTextureView, width, height);
|
||||
#endif
|
||||
frameRendered = true;
|
||||
frameRenderedOnce = true;
|
||||
|
@ -490,11 +489,18 @@ void DX11Renderer::displayFramebuffer()
|
|||
VO_BORDER_COL.getRGBColor(colors);
|
||||
colors[3] = 1.f;
|
||||
deviceContext->ClearRenderTargetView(theDX11Context.getRenderTarget(), colors);
|
||||
|
||||
float shiftX, shiftY;
|
||||
getVideoShift(shiftX, shiftY);
|
||||
shiftX *= 2.f / width;
|
||||
shiftY *= -2.f / height;
|
||||
|
||||
int outwidth = settings.display.width;
|
||||
int outheight = settings.display.height;
|
||||
float renderAR = aspectRatio;
|
||||
if (config::Rotate90) {
|
||||
std::swap(outwidth, outheight);
|
||||
std::swap(shiftX, shiftY);
|
||||
renderAR = 1 / renderAR;
|
||||
}
|
||||
float screenAR = (float)outwidth / outheight;
|
||||
|
@ -515,6 +521,9 @@ void DX11Renderer::displayFramebuffer()
|
|||
w *= 2.f / outwidth;
|
||||
y = y * 2.f / outheight - 1.f;
|
||||
h *= 2.f / outheight;
|
||||
// Shift
|
||||
x += shiftX;
|
||||
y += shiftY;
|
||||
deviceContext->OMSetBlendState(blendStates.getState(false), nullptr, 0xffffffff);
|
||||
quad->draw(fbTextureView, samplers->getSampler(config::TextureFiltering != 1), nullptr, x, y, w, h, config::Rotate90);
|
||||
#endif
|
||||
|
@ -953,11 +962,9 @@ void DX11Renderer::RenderFramebuffer(const FramebufferInfo& info)
|
|||
DrawOSD(false);
|
||||
theDX11Context.setFrameRendered();
|
||||
#else
|
||||
// FIXME won't look great on a 1x1 texture in case video output is disabled
|
||||
theDX11Context.drawOverlay(this->width, this->height);
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
deviceContext->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
deviceContext->PSSetShaderResources(0, 1, &dcfbTextureView.get());
|
||||
theDX11Context.presentFrame(dcfbTextureView, width, height);
|
||||
#endif
|
||||
frameRendered = true;
|
||||
frameRenderedOnce = true;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "dx11context_lr.h"
|
||||
#include <dxgi1_2.h>
|
||||
#include "rend/osd.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
|
||||
DX11Context theDX11Context;
|
||||
|
||||
|
@ -53,6 +54,9 @@ bool DX11Context::init(ID3D11Device *device, ID3D11DeviceContext *deviceContext,
|
|||
|
||||
shaders.init(pDevice, D3DCompile);
|
||||
overlay.init(pDevice, pDeviceContext, &shaders, &samplers);
|
||||
quad = std::make_unique<Quad>();
|
||||
quad->init(pDevice, pDeviceContext, &shaders);
|
||||
|
||||
bool success = checkTextureSupport();
|
||||
if (!success)
|
||||
term();
|
||||
|
@ -63,6 +67,11 @@ void DX11Context::term()
|
|||
{
|
||||
NOTICE_LOG(RENDERER, "DX11 Context terminating");
|
||||
GraphicsContext::instance = nullptr;
|
||||
blendStates.term();
|
||||
quad.reset();
|
||||
textureView.reset();
|
||||
renderTargetView.reset();
|
||||
texture.reset();
|
||||
overlay.term();
|
||||
samplers.term();
|
||||
shaders.term();
|
||||
|
@ -81,4 +90,77 @@ void DX11Context::drawOverlay(int width, int height)
|
|||
overlay.draw(width, height, true, true);
|
||||
}
|
||||
|
||||
ComPtr<ID3D11RenderTargetView>& DX11Context::getRenderTarget(int width, int height)
|
||||
{
|
||||
if (width != renderTargetWidth || height != renderTargetHeight || !renderTargetView)
|
||||
{
|
||||
renderTargetWidth = width;
|
||||
renderTargetHeight = height;
|
||||
texture.reset();
|
||||
renderTargetView.reset();
|
||||
D3D11_TEXTURE2D_DESC desc{};
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.ArraySize = 1;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
desc.MipLevels = 1;
|
||||
|
||||
HRESULT hr = pDevice->CreateTexture2D(&desc, nullptr, &texture.get());
|
||||
if (FAILED(hr))
|
||||
WARN_LOG(RENDERER, "Framebuffer texture(%d x %d) creation failed: %x", width, height, hr);
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc{};
|
||||
viewDesc.Format = desc.Format;
|
||||
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
viewDesc.Texture2D.MipLevels = 1;
|
||||
hr = pDevice->CreateShaderResourceView(texture, &viewDesc, &textureView.get());
|
||||
if (FAILED(hr))
|
||||
WARN_LOG(RENDERER, "DC Framebuffer texture view creation failed");
|
||||
|
||||
hr = pDevice->CreateRenderTargetView(texture, nullptr, &renderTargetView.get());
|
||||
if (FAILED(hr))
|
||||
WARN_LOG(RENDERER, "Framebuffer render target creation failed");
|
||||
|
||||
FLOAT black[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
pDeviceContext->ClearRenderTargetView(renderTargetView, black);
|
||||
}
|
||||
return renderTargetView;
|
||||
}
|
||||
|
||||
void DX11Context::presentFrame(ComPtr<ID3D11ShaderResourceView>& textureView, int width, int height)
|
||||
{
|
||||
ComPtr<ID3D11RenderTargetView> renderTarget = getRenderTarget(width, height);
|
||||
pDeviceContext->OMSetRenderTargets(1, &renderTarget.get(), nullptr);
|
||||
|
||||
D3D11_VIEWPORT vp{};
|
||||
vp.Width = (FLOAT)width;
|
||||
vp.Height = (FLOAT)height;
|
||||
vp.MinDepth = 0.f;
|
||||
vp.MaxDepth = 1.f;
|
||||
pDeviceContext->RSSetViewports(1, &vp);
|
||||
|
||||
const D3D11_RECT r = { 0, 0, width, height };
|
||||
pDeviceContext->RSSetScissorRects(1, &r);
|
||||
float colors[4];
|
||||
VO_BORDER_COL.getRGBColor(colors);
|
||||
colors[3] = 1.f;
|
||||
pDeviceContext->ClearRenderTargetView(renderTarget, colors);
|
||||
|
||||
float shiftX, shiftY;
|
||||
getVideoShift(shiftX, shiftY);
|
||||
shiftX *= 2.f / width;
|
||||
shiftY *= -2.f / height;
|
||||
|
||||
pDeviceContext->OMSetBlendState(blendStates.getState(false), nullptr, 0xffffffff);
|
||||
quad->draw(textureView, samplers.getSampler(false), nullptr, -1 + shiftX, -1 + shiftY, 2, 2, false);
|
||||
drawOverlay(width, height);
|
||||
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
pDeviceContext->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
pDeviceContext->PSSetShaderResources(0, 1, &this->textureView.get());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "dx11_shaders.h"
|
||||
#include "dx11_texture.h"
|
||||
#include "wsi/context.h"
|
||||
#include "dx11_renderstate.h"
|
||||
#include "dx11_quad.h"
|
||||
|
||||
class DX11Context : public GraphicsContext
|
||||
{
|
||||
|
@ -37,6 +39,7 @@ public:
|
|||
const ComPtr<ID3D11Device>& getDevice() const { return pDevice; }
|
||||
const ComPtr<ID3D11DeviceContext>& getDeviceContext() const { return pDeviceContext; }
|
||||
const pD3DCompile getCompiler() const { return this->D3DCompile; }
|
||||
void presentFrame(ComPtr<ID3D11ShaderResourceView>& textureView, int width, int height);
|
||||
|
||||
std::string getDriverName() override { return ""; }
|
||||
std::string getDriverVersion() override { return ""; }
|
||||
|
@ -65,6 +68,7 @@ public:
|
|||
|
||||
private:
|
||||
bool checkTextureSupport();
|
||||
ComPtr<ID3D11RenderTargetView>& getRenderTarget(int width, int height);
|
||||
|
||||
ComPtr<ID3D11Device> pDevice;
|
||||
ComPtr<ID3D11DeviceContext> pDeviceContext;
|
||||
|
@ -74,6 +78,14 @@ private:
|
|||
DX11Shaders shaders;
|
||||
Samplers samplers;
|
||||
DX11Overlay overlay;
|
||||
ComPtr<ID3D11Texture2D> texture;
|
||||
ComPtr<ID3D11ShaderResourceView> textureView;
|
||||
ComPtr<ID3D11RenderTargetView> renderTargetView;
|
||||
int renderTargetWidth = 0;
|
||||
int renderTargetHeight = 0;
|
||||
BlendStates blendStates;
|
||||
std::unique_ptr<Quad> quad;
|
||||
|
||||
D3D_FEATURE_LEVEL featureLevel{};
|
||||
bool supportedTexFormats[5] {}; // indexed by TextureType enum
|
||||
|
||||
|
|
|
@ -671,10 +671,9 @@ struct DX11OITRenderer : public DX11Renderer
|
|||
DrawOSD(false);
|
||||
theDX11Context.setFrameRendered();
|
||||
#else
|
||||
theDX11Context.drawOverlay(width, height);
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
deviceContext->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
deviceContext->PSSetShaderResources(0, 1, &fbTextureView.get());
|
||||
theDX11Context.presentFrame(fbTextureView, width, height);
|
||||
#endif
|
||||
frameRendered = true;
|
||||
frameRenderedOnce = true;
|
||||
|
|
|
@ -1147,7 +1147,9 @@ void D3DRenderer::displayFramebuffer()
|
|||
else
|
||||
dx = (int)roundf(settings.display.width * (1 - aspectRatio / screenAR) / 2.f);
|
||||
|
||||
if (!config::Rotate90)
|
||||
float shiftX, shiftY;
|
||||
getVideoShift(shiftX, shiftY);
|
||||
if (!config::Rotate90 && shiftX == 0 && shiftY == 0)
|
||||
{
|
||||
RECT rs { 0, 0, (long)width, (long)height };
|
||||
RECT rd { dx, dy, settings.display.width - dx, settings.display.height - dy };
|
||||
|
@ -1166,8 +1168,9 @@ void D3DRenderer::displayFramebuffer()
|
|||
device->SetSamplerState(0, D3DSAMP_MAGFILTER, config::TextureFiltering == 1 ? D3DTEXF_POINT : D3DTEXF_LINEAR);
|
||||
|
||||
glm::mat4 identity = glm::identity<glm::mat4>();
|
||||
glm::mat4 projection = glm::translate(glm::vec3(-1.f / settings.display.width, 1.f / settings.display.height, 0))
|
||||
* glm::rotate((float)M_PI_2, glm::vec3(0, 0, 1));
|
||||
glm::mat4 projection = glm::translate(glm::vec3(-1.f / settings.display.width, 1.f / settings.display.height, 0));
|
||||
if (config::Rotate90)
|
||||
projection *= glm::rotate((float)M_PI_2, glm::vec3(0, 0, 1));
|
||||
|
||||
device->SetTransform(D3DTS_WORLD, (const D3DMATRIX *)&identity[0][0]);
|
||||
device->SetTransform(D3DTS_VIEW, (const D3DMATRIX *)&identity[0][0]);
|
||||
|
@ -1189,6 +1192,11 @@ void D3DRenderer::displayFramebuffer()
|
|||
1, 1, 0.5f, 1, 0,
|
||||
1, -1, 0.5f, 1, 1,
|
||||
};
|
||||
coords[0] = coords[5] = -1.f + shiftX * 2.f / width;
|
||||
coords[10] = coords[15] = coords[0] + 2;
|
||||
coords[1] = coords[11] = 1.f - shiftY * 2.f / height;
|
||||
coords[6] = coords[16] = coords[1] - 2;
|
||||
|
||||
device->SetTexture(0, framebufferTexture);
|
||||
device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(float) * 5);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue