Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D3D11: Allow shader blend to self #11584

Merged
merged 3 commits into from
Nov 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions GPU/Common/FramebufferCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ enum BindFramebufferColorFlags {
BINDFBCOLOR_MAY_COPY = 1,
BINDFBCOLOR_MAY_COPY_WITH_UV = 3,
BINDFBCOLOR_APPLY_TEX_OFFSET = 4,
// Used when rendering to a temporary surface (e.g. not the current render target.)
BINDFBCOLOR_FORCE_SELF = 8,
};

enum DrawTextureFlags {
Expand Down
2 changes: 1 addition & 1 deletion GPU/D3D11/FramebufferManagerD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ void FramebufferManagerD3D11::BindFramebufferAsColorTexture(int stage, VirtualFr
} else {
draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0);
}
} else if (framebuffer != currentRenderVfb_) {
} else if (framebuffer != currentRenderVfb_ || (flags & BINDFBCOLOR_FORCE_SELF) != 0) {
draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0);
} else {
ERROR_LOG_REPORT_ONCE(d3d11SelfTexture, G3D, "Attempting to texture from target (src=%08x / target=%08x / flags=%d)", framebuffer->fb_address, currentRenderVfb_->fb_address, flags);
Expand Down
39 changes: 20 additions & 19 deletions GPU/D3D11/TextureCacheD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ class TextureShaderApplierD3D11 {
};

TextureShaderApplierD3D11(ID3D11DeviceContext *context, ID3D11PixelShader *pshader, ID3D11Buffer *dynamicBuffer, float bufferW, float bufferH, int renderW, int renderH, float xoff, float yoff)
: context_(context), pshader_(pshader), bufferW_(bufferW), bufferH_(bufferH), renderW_(renderW), renderH_(renderH) {
: context_(context), pshader_(pshader), vbuffer_(dynamicBuffer), bufferW_(bufferW), bufferH_(bufferH), renderW_(renderW), renderH_(renderH) {
static const Pos pos[4] = {
{ -1, 1, 0 },
{ 1, 1, 0 },
Expand All @@ -297,11 +297,6 @@ class TextureShaderApplierD3D11 {
verts_[i].pos.y += yoff;
verts_[i].uv = uv[i];
}
D3D11_MAPPED_SUBRESOURCE map;
context->Map(dynamicBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(map.pData, &verts_[0], 4 * 5 * sizeof(float));
context->Unmap(dynamicBuffer, 0);
vbuffer_ = dynamicBuffer;
}

void ApplyBounds(const KnownVertexBounds &bounds, u32 uoff, u32 voff, float xoff, float yoff) {
Expand All @@ -320,28 +315,34 @@ class TextureShaderApplierD3D11 {

const float left = u1 * invHalfWidth - 1.0f + xoff;
const float right = u2 * invHalfWidth - 1.0f + xoff;
const float top = v1 * invHalfHeight - 1.0f + yoff;
const float bottom = v2 * invHalfHeight - 1.0f + yoff;
const float top = (bufferH_ - v1) * invHalfHeight - 1.0f + yoff;
const float bottom = (bufferH_ - v2) * invHalfHeight - 1.0f + yoff;

float z = 0.0f;
// Points are: BL, BR, TL, TR.
verts_[0].pos = Pos(left, bottom, z);
verts_[1].pos = Pos(right, bottom, z);
verts_[2].pos = Pos(left, top, z);
verts_[3].pos = Pos(right, top, z);
verts_[0].pos = Pos(left, top, z);
verts_[1].pos = Pos(right, top, z);
verts_[2].pos = Pos(left, bottom, z);
verts_[3].pos = Pos(right, bottom, z);

// And also the UVs, same order.
const float uvleft = u1 * invWidth;
const float uvright = u2 * invWidth;
const float uvtop = v1 * invHeight;
const float uvbottom = v2 * invHeight;
verts_[0].uv = UV(uvleft, uvbottom);
verts_[1].uv = UV(uvright, uvbottom);
verts_[2].uv = UV(uvleft, uvtop);
verts_[3].uv = UV(uvright, uvtop);

verts_[0].uv = UV(uvleft, uvtop);
verts_[1].uv = UV(uvright, uvtop);
verts_[2].uv = UV(uvleft, uvbottom);
verts_[3].uv = UV(uvright, uvbottom);

// We need to reapply the texture next time since we cropped UV.
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
}

D3D11_MAPPED_SUBRESOURCE map;
context_->Map(vbuffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(map.pData, &verts_[0], 4 * 5 * sizeof(float));
context_->Unmap(vbuffer_, 0);
}

void Use(ID3D11VertexShader *vshader, ID3D11InputLayout *decl) {
Expand Down Expand Up @@ -398,11 +399,11 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra
shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset, xoff, yoff);
shaderApply.Use(depalShaderCache_->GetDepalettizeVertexShader(), depalShaderCache_->GetInputLayout());

draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
context_->PSSetShaderResources(3, 1, &clutTexture);
context_->PSSetSamplers(3, 1, &stockD3D11.samplerPoint2DWrap);
framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY);
framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY | BINDFBCOLOR_FORCE_SELF);
context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DWrap);
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE });
shaderApply.Shade();

framebufferManagerD3D11_->RebindFramebuffer();
Expand Down
30 changes: 15 additions & 15 deletions GPU/Directx9/TextureCacheDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,14 +320,14 @@ class TextureShaderApplierDX9 {
static const Pos pos[4] = {
{-1, 1, 0},
{ 1, 1, 0},
{ 1, -1, 0},
{-1, -1, 0},
{ 1, -1, 0},
};
static const UV uv[4] = {
{0, 0},
{1, 0},
{1, 1},
{0, 1},
{1, 1},
};

for (int i = 0; i < 4; ++i) {
Expand All @@ -354,25 +354,25 @@ class TextureShaderApplierDX9 {

const float left = u1 * invHalfWidth - 1.0f + xoff;
const float right = u2 * invHalfWidth - 1.0f + xoff;
const float top = v1 * invHalfHeight - 1.0f + yoff;
const float bottom = v2 * invHalfHeight - 1.0f + yoff;
const float top = (bufferH_ - v1) * invHalfHeight - 1.0f + yoff;
const float bottom = (bufferH_ - v2) * invHalfHeight - 1.0f + yoff;

float z = 0.0f;
// Points are: BL, BR, TR, TL.
verts_[0].pos = Pos(left, bottom, z);
verts_[1].pos = Pos(right, bottom, z);
verts_[2].pos = Pos(right, top, z);
verts_[3].pos = Pos(left, top, z);
verts_[0].pos = Pos(left, top, z);
verts_[1].pos = Pos(right, top, z);
verts_[2].pos = Pos(left, bottom, z);
verts_[3].pos = Pos(right, bottom, z);

// And also the UVs, same order.
const float uvleft = u1 * invWidth;
const float uvright = u2 * invWidth;
const float uvtop = v1 * invHeight;
const float uvbottom = v2 * invHeight;
verts_[0].uv = UV(uvleft, uvbottom);
verts_[1].uv = UV(uvright, uvbottom);
verts_[2].uv = UV(uvright, uvtop);
verts_[3].uv = UV(uvleft, uvtop);

verts_[0].uv = UV(uvleft, uvtop);
verts_[1].uv = UV(uvright, uvtop);
verts_[2].uv = UV(uvleft, uvbottom);
verts_[3].uv = UV(uvright, uvbottom);

// We need to reapply the texture next time since we cropped UV.
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
Expand All @@ -396,7 +396,7 @@ class TextureShaderApplierDX9 {

D3DVIEWPORT9 vp{ 0, 0, (DWORD)renderW_, (DWORD)renderH_, 0.0f, 1.0f };
device_->SetViewport(&vp);
HRESULT hr = device_->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts_, (3 + 2) * sizeof(float));
HRESULT hr = device_->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts_, (3 + 2) * sizeof(float));
if (FAILED(hr)) {
ERROR_LOG_REPORT(G3D, "Depal render failed: %08x", hr);
}
Expand Down Expand Up @@ -442,7 +442,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame
device_->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device_->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

framebufferManagerDX9_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY);
framebufferManagerDX9_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY | BINDFBCOLOR_FORCE_SELF);
device_->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device_->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device_->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
Expand Down
2 changes: 1 addition & 1 deletion GPU/GLES/TextureCacheGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram
shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset);
shaderApply.Use(render_, drawEngine_, shadeInputLayout_);

framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY);
framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY | BINDFBCOLOR_FORCE_SELF);
render_->BindTexture(TEX_SLOT_CLUT, clutTexture);
render_->SetTextureSampler(TEX_SLOT_CLUT, GL_REPEAT, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST, 0.0f);

Expand Down
2 changes: 1 addition & 1 deletion GPU/Vulkan/FramebufferVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, V
draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0);
}
return (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW);
} else if (framebuffer != currentRenderVfb_) {
} else if (framebuffer != currentRenderVfb_ || (flags & BINDFBCOLOR_FORCE_SELF) != 0) {
draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0);
return (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW);
} else {
Expand Down