Fix DrawActiveTexture, now Buffered Rendering is starting to work

This commit is contained in:
Henrik Rydgård 2017-02-12 11:20:55 +01:00
parent 0ae06b0148
commit abbd6cb1d1
13 changed files with 190 additions and 108 deletions

View File

@ -57,6 +57,7 @@ void StockObjectsD3D11::Create(ID3D11Device *device) {
blend_desc.RenderTarget[0].RenderTargetWriteMask = i;
device->CreateBlendState(&blend_desc, &blendStateDisabledWithColorMask[i]);
}
D3D11_DEPTH_STENCIL_DESC depth_desc{};
depth_desc.DepthEnable = FALSE;
device->CreateDepthStencilState(&depth_desc, &depthStencilDisabled);
@ -72,11 +73,13 @@ void StockObjectsD3D11::Create(ID3D11Device *device) {
depth_desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depth_desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
device->CreateDepthStencilState(&depth_desc, &depthDisabledStencilWrite);
D3D11_RASTERIZER_DESC raster_desc{};
raster_desc.FillMode = D3D11_FILL_SOLID;
raster_desc.CullMode = D3D11_CULL_NONE;
raster_desc.ScissorEnable = FALSE;
device->CreateRasterizerState(&raster_desc, &rasterStateNoCull);
D3D11_SAMPLER_DESC sampler_desc{};
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
@ -85,6 +88,13 @@ void StockObjectsD3D11::Create(ID3D11Device *device) {
device->CreateSamplerState(&sampler_desc, &samplerPoint2DWrap);
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
device->CreateSamplerState(&sampler_desc, &samplerLinear2DWrap);
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
device->CreateSamplerState(&sampler_desc, &samplerPoint2DClamp);
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
device->CreateSamplerState(&sampler_desc, &samplerLinear2DClamp);
}
void StockObjectsD3D11::Destroy() {

View File

@ -78,6 +78,8 @@ public:
ID3D11RasterizerState *rasterStateNoCull;
ID3D11SamplerState *samplerPoint2DWrap;
ID3D11SamplerState *samplerLinear2DWrap;
ID3D11SamplerState *samplerPoint2DClamp;
ID3D11SamplerState *samplerLinear2DClamp;
};
extern StockObjectsD3D11 stockD3D11;

View File

@ -17,6 +17,7 @@
#include "math/lin/matrix4x4.h"
#include "ext/native/thin3d/thin3d.h"
#include "base/basictypes.h"
#include "Common/ColorConv.h"
#include "Core/Host.h"
@ -43,7 +44,7 @@
#include <xmmintrin.h>
#endif
static const char * vscode =
static const char *vscode =
"struct VS_IN {\n"
" float4 ObjPos : POSITION;\n"
" float2 Uv : TEXCOORD0;\n"
@ -59,10 +60,7 @@ static const char * vscode =
" return Out;\n"
"}\n";
//--------------------------------------------------------------------------------------
// Pixel shader
//--------------------------------------------------------------------------------------
static const char * pscode =
static const char *pscode =
"SamplerState samp : register(s0);\n"
"Texture2D<float4> tex : register(t0);\n"
"struct PS_IN {\n"
@ -73,21 +71,11 @@ static const char * pscode =
" return c;\n"
"}\n";
static const D3D11_INPUT_ELEMENT_DESC g_FramebufferVertexElements[] = {
static const D3D11_INPUT_ELEMENT_DESC g_QuadVertexElements[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, },
};
void FramebufferManagerD3D11::ClearBuffer(bool keepState) {
draw_->Clear(Draw::ClearFlag::COLOR | Draw::ClearFlag::DEPTH | Draw::ClearFlag::STENCIL, 0, ToScaledDepth(0), 0);
}
void FramebufferManagerD3D11::DisableState() {
context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], nullptr, 0xFFFFFFFF);
context_->RSSetState(stockD3D11.rasterStateNoCull);
context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0xFF);
}
FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
: FramebufferManagerCommon(draw),
drawPixelsTex_(0),
@ -102,20 +90,27 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw)
std::vector<uint8_t> bytecode;
std::string errorMsg;
pFramebufferVertexShader_ = CreateVertexShaderD3D11(device_, vscode, strlen(vscode), &bytecode);
pFramebufferPixelShader_ = CreatePixelShaderD3D11(device_, pscode, strlen(pscode));
device_->CreateInputLayout(g_FramebufferVertexElements, ARRAY_SIZE(g_FramebufferVertexElements), bytecode.data(), bytecode.size(), &pFramebufferVertexDecl_);
quadVertexShader_ = CreateVertexShaderD3D11(device_, vscode, strlen(vscode), &bytecode);
quadPixelShader_ = CreatePixelShaderD3D11(device_, pscode, strlen(pscode));
device_->CreateInputLayout(g_QuadVertexElements, ARRAY_SIZE(g_QuadVertexElements), bytecode.data(), bytecode.size(), &quadVertexDecl_);
float coord[20] = {
-1.0f,-1.0f, 0, 0,0,
1.0f,-1.0f, 0, 0,0,
1.0f,1.0f, 0, 0,0,
-1.0f,1.0f, 0, 0,0,
// STRIP geometry
static const float fsCoord[20] = {
-1.0f,-1.0f, 0.0f, 0.0f, 0.0f,
1.0f,-1.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
};
D3D11_BUFFER_DESC vb{};
vb.ByteWidth = 20 * 4;
vb.Usage = D3D11_USAGE_IMMUTABLE;
vb.CPUAccessFlags = 0;
vb.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA data{ fsCoord };
device_->CreateBuffer(&vb, &data, &fsQuadBuffer_);
vb.Usage = D3D11_USAGE_DYNAMIC;
vb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
device_->CreateBuffer(&vb, nullptr, &quadBuffer_);
}
FramebufferManagerD3D11::~FramebufferManagerD3D11() {
@ -123,21 +118,23 @@ FramebufferManagerD3D11::~FramebufferManagerD3D11() {
if (vbFullScreenRect_) {
vbFullScreenRect_->Release();
}
if (pFramebufferVertexShader_) {
pFramebufferVertexShader_->Release();
pFramebufferVertexShader_ = nullptr;
if (quadVertexShader_) {
quadVertexShader_->Release();
quadVertexShader_ = nullptr;
}
if (pFramebufferPixelShader_) {
pFramebufferPixelShader_->Release();
pFramebufferPixelShader_ = nullptr;
if (quadPixelShader_) {
quadPixelShader_->Release();
quadPixelShader_ = nullptr;
}
pFramebufferVertexDecl_->Release();
quadVertexDecl_->Release();
if (drawPixelsTex_) {
drawPixelsTex_->Release();
}
if (drawPixelsTexView_) {
drawPixelsTexView_->Release();
}
quadBuffer_->Release();
fsQuadBuffer_->Release();
// FBO cleanup
for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) {
@ -163,6 +160,16 @@ void FramebufferManagerD3D11::SetTextureCache(TextureCacheD3D11 *tc) {
textureCache_ = tc;
}
void FramebufferManagerD3D11::ClearBuffer(bool keepState) {
draw_->Clear(Draw::ClearFlag::COLOR | Draw::ClearFlag::DEPTH | Draw::ClearFlag::STENCIL, 0, ToScaledDepth(0), 0);
}
void FramebufferManagerD3D11::DisableState() {
context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], nullptr, 0xFFFFFFFF);
context_->RSSetState(stockD3D11.rasterStateNoCull);
context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0xFF);
}
void FramebufferManagerD3D11::MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) {
u8 *convBuf = NULL;
@ -281,7 +288,6 @@ void FramebufferManagerD3D11::DrawFramebufferToOutput(const u8 *srcPixels, GEBuf
}
void FramebufferManagerD3D11::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter) {
// TODO: StretchRect instead?
float coord[20] = {
x,y,0, u0,v0,
x + w,y,0, u1,v0,
@ -320,17 +326,30 @@ void FramebufferManagerD3D11::DrawActiveTexture(float x, float y, float w, float
coord[i * 5 + 1] = -(coord[i * 5 + 1] * invDestH - 1.0f - halfPixelY);
}
// The above code is for FAN geometry but we can only do STRIP. So rearrange it a little.
D3D11_MAPPED_SUBRESOURCE map;
context_->Map(quadBuffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
float *dest = (float *)map.pData;
memcpy(dest, coord, sizeof(float) * 5);
memcpy(dest + 5, coord + 5, sizeof(float) * 5);
memcpy(dest + 10, coord + 15, sizeof(float) * 5);
memcpy(dest + 15, coord + 10, sizeof(float) * 5);
context_->Unmap(quadBuffer_, 0);
context_->RSSetState(stockD3D11.rasterStateNoCull);
context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], nullptr, 0xFFFFFFFF);
context_->IASetInputLayout(pFramebufferVertexDecl_);
context_->PSSetShader(pFramebufferPixelShader_, 0, 0);
context_->VSSetShader(pFramebufferVertexShader_, 0, 0);
context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0);
context_->IASetInputLayout(quadVertexDecl_);
context_->PSSetShader(quadPixelShader_, 0, 0);
context_->VSSetShader(quadVertexShader_, 0, 0);
context_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
context_->PSSetSamplers(0, 1, linearFilter ? &stockD3D11.samplerLinear2DWrap : &stockD3D11.samplerPoint2DWrap);
context_->PSSetSamplers(0, 1, linearFilter ? &stockD3D11.samplerLinear2DClamp : &stockD3D11.samplerPoint2DClamp);
UINT stride = 20;
UINT offset = 0;
context_->IASetVertexBuffers(0, 1, &quadBuffer_, &stride, &offset);
context_->Draw(4, 0);
// TODO: DrawRectBuffer ?
shaderManager_->DirtyLastShader();
context_->Draw(2, 0);
}
void FramebufferManagerD3D11::RebindFramebuffer() {
@ -361,9 +380,9 @@ void FramebufferManagerD3D11::ReformatFramebufferFrom(VirtualFramebuffer *vfb, G
context_->OMSetDepthStencilState(stockD3D11.depthDisabledStencilWrite, 0xFF);
context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0], nullptr, 0xFFFFFFFF);
context_->RSSetState(stockD3D11.rasterStateNoCull);
context_->IASetInputLayout(pFramebufferVertexDecl_);
context_->PSSetShader(pFramebufferPixelShader_, nullptr, 0);
context_->VSSetShader(pFramebufferVertexShader_, nullptr, 0);
context_->IASetInputLayout(quadVertexDecl_);
context_->PSSetShader(quadPixelShader_, nullptr, 0);
context_->VSSetShader(quadVertexShader_, nullptr, 0);
context_->IASetVertexBuffers(0, 1, &vbFullScreenRect_, &vbFullScreenStride_, &vbFullScreenOffset_);
shaderManager_->DirtyLastShader();
D3D11_VIEWPORT vp{ 0.0f, 0.0f, (float)vfb->renderWidth, (float)vfb->renderHeight, 0.0f, 1.0f };
@ -404,13 +423,13 @@ void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, Virt
if (g_Config.bDisableSlowFramebufEffects) {
return;
}
/*
bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0;
bool matchingSize = src->width == dst->width && src->height == dst->height;
if (matchingDepthBuffer && matchingSize) {
// Doesn't work. Use a shader maybe?
draw_->BindBackbufferAsRenderTarget();
draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->width, src->height, 1, Draw::FB_DEPTH_BIT);
/*
LPDIRECT3DTEXTURE9 srcTex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(src->fbo, Draw::FB_DEPTH_BIT, 0);
LPDIRECT3DTEXTURE9 dstTex = (LPDIRECT3DTEXTURE9)draw_->GetFramebufferAPITexture(dst->fbo, Draw::FB_DEPTH_BIT, 0);
@ -448,9 +467,9 @@ void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, Virt
dstTex->UnlockRect(0);
}
}
RebindFramebuffer();
}*/
*/
}
}
void FramebufferManagerD3D11::BindFramebufferColor(int stage, VirtualFramebuffer *framebuffer, int flags) {
@ -527,10 +546,11 @@ void FramebufferManagerD3D11::CopyDisplayToOutput() {
if (useBufferedRendering_) {
// In buffered, we no longer clear the backbuffer before we start rendering.
ClearBuffer();
D3D11_VIEWPORT vp{ 0.0f, 0.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, 0.0f, 1.0f };
context_->RSSetViewports(1, &vp);
}
D3D11_VIEWPORT vp{ 0.0f, 0.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, 0.0f, 1.0f };
context_->RSSetViewports(1, &vp);
u32 offsetX = 0;
u32 offsetY = 0;
@ -630,19 +650,9 @@ void FramebufferManagerD3D11::CopyDisplayToOutput() {
if (1) {
const u32 rw = PSP_CoreParameter().pixelWidth;
const u32 rh = PSP_CoreParameter().pixelHeight;
bool result = draw_->BlitFramebuffer(vfb->fbo,
(LONG)(u0 * vfb->renderWidth), (LONG)(v0 * vfb->renderHeight), (LONG)(u1 * vfb->renderWidth), (LONG)(v1 * vfb->renderHeight),
nullptr,
(LONG)(x * rw / w), (LONG)(y * rh / h), (LONG)((x + w) * rw / w), (LONG)((y + h) * rh / h),
Draw::FB_COLOR_BIT,
g_Config.iBufFilter == SCALE_LINEAR ? Draw::FB_BLIT_LINEAR : Draw::FB_BLIT_NEAREST);
if (!result) {
ERROR_LOG_REPORT_ONCE(blit_fail, G3D, "fbo_blit_color failed on display");
D3D11_VIEWPORT vp{ 0.0f, 0.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, 0.0f, 1.0f };
context_->RSSetViewports(1, &vp);
DrawActiveTexture(x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, u0, v0, u1, v1, uvRotation, g_Config.iBufFilter == SCALE_LINEAR);
}
DrawActiveTexture(x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, u0, v0, u1, v1, uvRotation, g_Config.iBufFilter == SCALE_LINEAR);
}
/*
else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) {
// An additional pass, post-processing shader to the extra FBO.

View File

@ -110,9 +110,12 @@ private:
int drawPixelsTexW_;
int drawPixelsTexH_;
ID3D11VertexShader *pFramebufferVertexShader_;
ID3D11PixelShader *pFramebufferPixelShader_;
ID3D11InputLayout *pFramebufferVertexDecl_;
ID3D11VertexShader *quadVertexShader_;
ID3D11PixelShader *quadPixelShader_;
ID3D11InputLayout *quadVertexDecl_;
// Dynamic
ID3D11Buffer *quadBuffer_;
ID3D11Buffer *fsQuadBuffer_;
u8 *convBuf;

View File

@ -509,6 +509,8 @@ void GPU_D3D11::CheckGPUFeatures() {
features |= GPU_SUPPORTS_ANISOTROPY;
features |= GPU_SUPPORTS_OES_TEXTURE_NPOT;
// features |= GPU_SUPPORTS_ANY_COPY_IMAGE;
if (!g_Config.bHighQualityDepth) {
features |= GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT;
} else if (PSP_CoreParameter().compat.flags().PixelDepthRounding) {

View File

@ -198,12 +198,6 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
ViewportAndScissor vpAndScissor;
ConvertViewportAndScissor(useBufferedRendering,
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
vpAndScissor);
if (blendState.applyShaderBlending) {
if (ApplyShaderBlending()) {
// We may still want to do something about stencil -> alpha.
@ -357,22 +351,11 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
dynState.topology = primToD3D11[prim];
D3D11_VIEWPORT &vp = dynState.viewport;
vp.TopLeftX = vpAndScissor.viewportX;
vp.TopLeftY = vpAndScissor.viewportY;
vp.Width = vpAndScissor.viewportW;
vp.Height = vpAndScissor.viewportH;
vp.MinDepth = vpAndScissor.depthRangeMin;
vp.MaxDepth = vpAndScissor.depthRangeMax;
if (vpAndScissor.dirtyProj) {
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
D3D11_RECT &scissor = dynState.scissor;
scissor.left = vpAndScissor.scissorX;
scissor.top = vpAndScissor.scissorY;
scissor.right = vpAndScissor.scissorX + vpAndScissor.scissorW;
scissor.bottom = vpAndScissor.scissorY + vpAndScissor.scissorH;
ViewportAndScissor vpAndScissor;
ConvertViewportAndScissor(useBufferedRendering,
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
vpAndScissor);
float depthMin = vpAndScissor.depthRangeMin;
float depthMax = vpAndScissor.depthRangeMax;
@ -383,6 +366,26 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
gstate_c.Dirty(DIRTY_DEPTHRANGE);
}
D3D11_VIEWPORT &vp = dynState.viewport;
vp.TopLeftX = vpAndScissor.viewportX;
vp.TopLeftY = vpAndScissor.viewportY;
vp.Width = vpAndScissor.viewportW;
vp.Height = vpAndScissor.viewportH;
vp.MinDepth = depthMin;
vp.MaxDepth = depthMax;
if (vpAndScissor.dirtyProj) {
gstate_c.Dirty(DIRTY_PROJMATRIX);
}
context_->RSSetViewports(1, &vp);
/*
D3D11_RECT &scissor = dynState.scissor;
scissor.left = vpAndScissor.scissorX;
scissor.top = vpAndScissor.scissorY;
scissor.right = vpAndScissor.scissorX + vpAndScissor.scissorW;
scissor.bottom = vpAndScissor.scissorY + vpAndScissor.scissorH;
context_->RSSetScissorRects(0, &scissor);
*/
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
textureCache_->SetTexture();
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);

View File

@ -57,7 +57,7 @@
#define TEXCACHE_MIN_PRESSURE 16 * 1024 * 1024 // Total in VRAM
#define TEXCACHE_SECOND_MIN_PRESSURE 4 * 1024 * 1024
static const D3D11_INPUT_ELEMENT_DESC g_FramebufferVertexElements[] = {
static const D3D11_INPUT_ELEMENT_DESC g_QuadVertexElements[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12,},
};

View File

@ -1021,7 +1021,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX,
const bool xOverlap = src == dst && srcX2 > dstX1 && srcX1 < dstX2;
const bool yOverlap = src == dst && srcY2 > dstY1 && srcY1 < dstY2;
if (sameSize && sameDepth && srcInsideBounds && dstInsideBounds && !(xOverlap && yOverlap)) {
draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1);
draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, Draw::FB_COLOR_BIT);
return;
}
}

View File

@ -582,7 +582,7 @@ public:
// Copies data from the CPU over into the buffer, at a specific offset. This does not change the size of the buffer and cannot write outside it.
virtual void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) = 0;
virtual void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) = 0;
virtual void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) = 0;
virtual bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) = 0;
// These functions should be self explanatory.

View File

@ -45,7 +45,7 @@ public:
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override;
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
// These functions should be self explanatory.
@ -1117,18 +1117,41 @@ void D3D11DrawContext::Clear(int mask, uint32_t colorval, float depthVal, int st
}
}
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) {
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 channelBits) {
D3D11Framebuffer *src = (D3D11Framebuffer *)srcfb;
D3D11Framebuffer *dst = (D3D11Framebuffer *)dstfb;
// CopySubResource ?
ID3D11Texture2D *srcTex = nullptr;
ID3D11Texture2D *dstTex = nullptr;
switch (channelBits) {
case FB_COLOR_BIT:
srcTex = src->colorTex;
dstTex = dst->colorTex;
break;
case FB_DEPTH_BIT:
srcTex = src->depthStencilTex;
dstTex = dst->depthStencilTex;
break;
}
// TODO: Check for level too!
if (width == src->width && width == dst->width && height == src->height && height == dst->height && x == 0 && y == 0 && z == 0 && dstX == 0 && dstY == 0 && dstZ == 0) {
// Don't need to specify region. This might be faster, too.
context_->CopyResource(dstTex, srcTex);
return;
}
D3D11_BOX srcBox{
x, y, z, x+width, y+height, z+depth
};
context_->CopySubresourceRegion(dstTex, dstLevel, dstX, dstY, dstZ, srcTex, level, &srcBox);
}
bool D3D11DrawContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) {
D3D11Framebuffer *src = (D3D11Framebuffer *)srcfb;
D3D11Framebuffer *dst = (D3D11Framebuffer *)dstfb;
// Unfortunately D3D11 has no equivalent to this, gotta render a quad.
// Unfortunately D3D11 has no equivalent to this, gotta render a quad. Well, in some cases we can issue a copy instead.
return true;
}

View File

@ -478,7 +478,7 @@ public:
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override {}
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override {}
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
// These functions should be self explanatory.

View File

@ -469,7 +469,7 @@ public:
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override;
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
// These functions should be self explanatory.
@ -1506,29 +1506,41 @@ void OpenGLContext::BindFramebufferForRead(Framebuffer *fbo) {
fbo_bind_fb_target(true, fb->handle);
}
void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) {
void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) {
OpenGLFramebuffer *src = (OpenGLFramebuffer *)fbsrc;
OpenGLFramebuffer *dst = (OpenGLFramebuffer *)fbdst;
GLuint srcTex = 0;
GLuint dstTex = 0;
switch (channelBits) {
case FB_COLOR_BIT:
srcTex = src->color_texture;
dstTex = dst->color_texture;
break;
case FB_DEPTH_BIT:
srcTex = src->z_buffer ? src->z_buffer : src->z_stencil_buffer;
dstTex = dst->z_buffer ? dst->z_buffer : dst->z_stencil_buffer;
break;
}
#if defined(USING_GLES2)
#ifndef IOS
glCopyImageSubDataOES(
src->color_texture, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dst->color_texture, GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
srcTex, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dstTex, GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
width, height, depth);
return;
#endif
#else
if (gl_extensions.ARB_copy_image) {
glCopyImageSubData(
src->color_texture, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dst->color_texture, GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
srcTex, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dstTex, GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
width, height, depth);
return;
} else if (gl_extensions.NV_copy_image) {
// Older, pre GL 4.x NVIDIA cards.
glCopyImageSubDataNV(
src->color_texture, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dst->color_texture, GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
srcTex, GL_TEXTURE_2D, srcLevel, srcX, srcY, srcZ,
dstTex, GL_TEXTURE_2D, dstLevel, dstX, dstY, dstZ,
width, height, depth);
return;
}

View File

@ -340,7 +340,7 @@ public:
void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override;
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) override;
void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override;
bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override;
// These functions should be self explanatory.
@ -1280,17 +1280,34 @@ Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) {
return fb;
}
void VKContext::CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth) {}
bool VKContext::BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) { return true; }
void VKContext::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 channelBits) {
VKFramebuffer *src = (VKFramebuffer *)srcfb;
VKFramebuffer *dst = (VKFramebuffer *)dstfb;
}
bool VKContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) {
VKFramebuffer *src = (VKFramebuffer *)srcfb;
VKFramebuffer *dst = (VKFramebuffer *)dstfb;
return true;
}
// These functions should be self explanatory.
void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo) {}
void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo) {
VKFramebuffer *fb = (VKFramebuffer *)fbo;
}
// color must be 0, for now.
void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) {}
void VKContext::BindFramebufferForRead(Framebuffer *fbo) {}
void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) {
VKFramebuffer *fb = (VKFramebuffer *)fbo;
void VKContext::BindBackbufferAsRenderTarget() {}
uintptr_t VKContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) { return 0; }
}
void VKContext::BindFramebufferForRead(Framebuffer *fbo) { /* noop */ }
void VKContext::BindBackbufferAsRenderTarget() {
}
uintptr_t VKContext::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit, int attachment) {
return 0;
}
void VKContext::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) {
VKFramebuffer *fb = (VKFramebuffer *)fbo;