mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Works with D3D11, except the depth texturing case
This commit is contained in:
1 parent
2fa9b0d0c7
commit
e345a6ba3c
18 files changed
+90
-465
No files matched your search
@@ -1500,8 +1500,6 @@ set(GPU_D3D9
|
||||
)
|
||||
|
||||
set(GPU_D3D11
|
||||
GPU/D3D11/DepalettizeShaderD3D11.cpp
|
||||
GPU/D3D11/DepalettizeShaderD3D11.h
|
||||
GPU/D3D11/DrawEngineD3D11.cpp
|
||||
GPU/D3D11/DrawEngineD3D11.h
|
||||
GPU/D3D11/FramebufferManagerD3D11.cpp
|
||||
|
||||
@@ -61,6 +61,9 @@ bool DepalShaderCache::GenerateVertexShader(char *buffer, const ShaderLanguageDe
|
||||
writer.BeginVSMain(vsInputs, Slice<UniformDef>::empty(), varyings);
|
||||
writer.C(" v_texcoord0 = a_texcoord0;\n");
|
||||
writer.C(" gl_Position = vec4(a_position, 0.0, 1.0);\n");
|
||||
if (strlen(lang.viewportYSign)) {
|
||||
writer.F(" gl_Position.y *= %s1.0;\n", lang.viewportYSign);
|
||||
}
|
||||
writer.EndVSMain(varyings);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
@@ -297,6 +297,7 @@ public:
|
||||
virtual void InvalidateLastTexture() = 0;
|
||||
virtual void Clear(bool delete_them);
|
||||
virtual void NotifyConfigChanged();
|
||||
virtual void ApplySamplingParams(const SamplerCacheKey &key) = 0;
|
||||
|
||||
// FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to,
|
||||
// so that it can invalidate TexCacheEntries pointed at those addresses.
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
// Copyright (c) 2014- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <map>
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Data/Convert/ColorConv.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "GPU/D3D11/TextureCacheD3D11.h"
|
||||
#include "GPU/D3D11/DepalettizeShaderD3D11.h"
|
||||
#include "GPU/D3D11/D3D11Util.h"
|
||||
#include "GPU/Common/DepalettizeShaderCommon.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SHADERLOG
|
||||
#endif
|
||||
|
||||
static const char *depalVShaderHLSL = R"(
|
||||
struct VS_IN {
|
||||
float3 a_position : POSITION;
|
||||
float2 a_texcoord0 : TEXCOORD0;
|
||||
};
|
||||
struct VS_OUT {
|
||||
float2 Texcoord : TEXCOORD0;
|
||||
float4 Position : SV_Position;
|
||||
};
|
||||
VS_OUT main(VS_IN input) {
|
||||
VS_OUT output;
|
||||
output.Texcoord = input.a_texcoord0;
|
||||
output.Position = float4(input.a_position, 1.0);
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
|
||||
static const D3D11_INPUT_ELEMENT_DESC g_DepalVertexElements[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, },
|
||||
};
|
||||
|
||||
DepalShaderCacheD3D11::DepalShaderCacheD3D11(Draw::DrawContext *draw) {
|
||||
std::string errorMessage;
|
||||
std::vector<uint8_t> vsByteCode;
|
||||
device_ = (ID3D11Device *)draw->GetNativeObject(Draw::NativeObject::DEVICE);
|
||||
context_ = (ID3D11DeviceContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT);
|
||||
featureLevel_ = (D3D_FEATURE_LEVEL)draw->GetNativeObject(Draw::NativeObject::FEATURE_LEVEL);
|
||||
vertexShader_ = CreateVertexShaderD3D11(device_, depalVShaderHLSL, strlen(depalVShaderHLSL), &vsByteCode, featureLevel_);
|
||||
ASSERT_SUCCESS(device_->CreateInputLayout(g_DepalVertexElements, ARRAY_SIZE(g_DepalVertexElements), vsByteCode.data(), vsByteCode.size(), &inputLayout_));
|
||||
}
|
||||
|
||||
DepalShaderCacheD3D11::~DepalShaderCacheD3D11() {
|
||||
Clear();
|
||||
vertexShader_->Release();
|
||||
inputLayout_->Release();
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView *DepalShaderCacheD3D11::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut, bool expandTo32bit) {
|
||||
const u32 clutId = GetClutID(clutFormat, clutHash);
|
||||
|
||||
auto oldtex = texCache_.find(clutId);
|
||||
if (oldtex != texCache_.end()) {
|
||||
oldtex->second->lastFrame = gpuStats.numFlips;
|
||||
return oldtex->second->view;
|
||||
}
|
||||
|
||||
int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;
|
||||
int bpp = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 4 : 2;
|
||||
DXGI_FORMAT dstFmt;
|
||||
uint32_t *expanded = nullptr;
|
||||
if (expandTo32bit && clutFormat != GE_CMODE_32BIT_ABGR8888) {
|
||||
expanded = new uint32_t[texturePixels];
|
||||
switch (clutFormat) {
|
||||
case GE_CMODE_16BIT_ABGR4444:
|
||||
ConvertRGBA4444ToRGBA8888(expanded, (const uint16_t *)rawClut, texturePixels);
|
||||
break;
|
||||
case GE_CMODE_16BIT_ABGR5551:
|
||||
ConvertRGBA5551ToRGBA8888(expanded, (const uint16_t *)rawClut, texturePixels);
|
||||
break;
|
||||
case GE_CMODE_16BIT_BGR5650:
|
||||
ConvertRGB565ToRGBA8888(expanded, (const uint16_t *)rawClut, texturePixels);
|
||||
break;
|
||||
}
|
||||
rawClut = expanded;
|
||||
dstFmt = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
bpp = 4;
|
||||
}
|
||||
else {
|
||||
dstFmt = GetClutDestFormatD3D11(clutFormat);
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc{};
|
||||
desc.Width = texturePixels;
|
||||
desc.Height = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = dstFmt;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA data{};
|
||||
data.pSysMem = rawClut;
|
||||
// Regardless of format, the CLUT should always be 1024 bytes.
|
||||
data.SysMemPitch = texturePixels * bpp;
|
||||
|
||||
DepalTextureD3D11 *tex = new DepalTextureD3D11();
|
||||
// TODO: Look into 1D textures
|
||||
ASSERT_SUCCESS(device_->CreateTexture2D(&desc, &data, &tex->texture));
|
||||
ASSERT_SUCCESS(device_->CreateShaderResourceView(tex->texture, nullptr, &tex->view));
|
||||
tex->lastFrame = gpuStats.numFlips;
|
||||
texCache_[clutId] = tex;
|
||||
|
||||
if (expandTo32bit) {
|
||||
delete[] expanded;
|
||||
}
|
||||
return tex->view;
|
||||
}
|
||||
|
||||
void DepalShaderCacheD3D11::Clear() {
|
||||
for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) {
|
||||
shader->second->pixelShader->Release();
|
||||
delete shader->second;
|
||||
}
|
||||
cache_.clear();
|
||||
|
||||
for (auto tex = texCache_.begin(); tex != texCache_.end(); ++tex) {
|
||||
delete tex->second;
|
||||
}
|
||||
texCache_.clear();
|
||||
}
|
||||
|
||||
void DepalShaderCacheD3D11::Decimate() {
|
||||
for (auto tex = texCache_.begin(); tex != texCache_.end();) {
|
||||
if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) {
|
||||
delete tex->second;
|
||||
texCache_.erase(tex++);
|
||||
} else {
|
||||
++tex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ID3D11PixelShader *DepalShaderCacheD3D11::GetDepalettizePixelShader(uint32_t clutMode, GEBufferFormat pixelFormat) {
|
||||
u32 id = GenerateShaderID(clutMode, pixelFormat);
|
||||
|
||||
auto shader = cache_.find(id);
|
||||
if (shader != cache_.end()) {
|
||||
return shader->second->pixelShader;
|
||||
}
|
||||
|
||||
char *buffer = new char[2048];
|
||||
|
||||
GenerateDepalShader(buffer, pixelFormat, HLSL_D3D11);
|
||||
|
||||
ID3D11PixelShader *pshader = CreatePixelShaderD3D11(device_, buffer, strlen(buffer), featureLevel_);
|
||||
|
||||
if (!pshader) {
|
||||
ERROR_LOG(G3D, "Failed to compile depal pixel shader");
|
||||
delete[] buffer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DepalShaderD3D11 *depal = new DepalShaderD3D11();
|
||||
depal->pixelShader = pshader;
|
||||
depal->code = buffer;
|
||||
|
||||
cache_[id] = depal;
|
||||
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
return depal->pixelShader;
|
||||
}
|
||||
|
||||
std::vector<std::string> DepalShaderCacheD3D11::DebugGetShaderIDs(DebugShaderType type) {
|
||||
std::vector<std::string> ids;
|
||||
for (auto &iter : cache_) {
|
||||
ids.push_back(StringFromFormat("%08x", iter.first));
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
std::string DepalShaderCacheD3D11::DebugGetShaderString(std::string idstr, DebugShaderType type, DebugShaderStringType stringType) {
|
||||
uint32_t id;
|
||||
sscanf(idstr.c_str(), "%08x", &id);
|
||||
auto iter = cache_.find(id);
|
||||
if (iter == cache_.end())
|
||||
return "";
|
||||
switch (stringType) {
|
||||
case SHADER_STRING_SHORT_DESC:
|
||||
return idstr;
|
||||
case SHADER_STRING_SOURCE_CODE:
|
||||
return iter->second->code;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright (c) 2017- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "Common/GPU/thin3d.h"
|
||||
#include "GPU/Common/DepalettizeShaderCommon.h"
|
||||
|
||||
class DepalShaderD3D11 {
|
||||
public:
|
||||
ID3D11PixelShader *pixelShader;
|
||||
std::string code;
|
||||
};
|
||||
|
||||
class DepalTextureD3D11 {
|
||||
public:
|
||||
~DepalTextureD3D11() {
|
||||
if (texture)
|
||||
texture->Release();
|
||||
if (view)
|
||||
view->Release();
|
||||
}
|
||||
ID3D11Texture2D *texture;
|
||||
ID3D11ShaderResourceView *view;
|
||||
int lastFrame;
|
||||
};
|
||||
|
||||
// Caches both shaders and palette textures.
|
||||
class DepalShaderCacheD3D11 : public DepalShaderCacheCommon {
|
||||
public:
|
||||
DepalShaderCacheD3D11(Draw::DrawContext *draw);
|
||||
~DepalShaderCacheD3D11();
|
||||
|
||||
// This also uploads the palette and binds the correct texture.
|
||||
ID3D11PixelShader *GetDepalettizePixelShader(uint32_t clutMode, GEBufferFormat pixelFormat);
|
||||
ID3D11VertexShader *GetDepalettizeVertexShader() { return vertexShader_; }
|
||||
ID3D11InputLayout *GetInputLayout() { return inputLayout_; }
|
||||
ID3D11ShaderResourceView *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut, bool expandTo32bit);
|
||||
void Clear();
|
||||
void Decimate();
|
||||
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type);
|
||||
std::string DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType);
|
||||
|
||||
private:
|
||||
ID3D11Device *device_;
|
||||
ID3D11DeviceContext *context_;
|
||||
D3D_FEATURE_LEVEL featureLevel_;
|
||||
ID3D11VertexShader *vertexShader_ = nullptr;
|
||||
ID3D11InputLayout *inputLayout_ = nullptr;
|
||||
|
||||
std::map<u32, DepalShaderD3D11 *> cache_;
|
||||
std::map<u32, DepalTextureD3D11 *> texCache_;
|
||||
};
|
||||
@@ -64,7 +64,7 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw)
|
||||
textureCache_ = textureCacheD3D11_;
|
||||
drawEngineCommon_ = &drawEngine_;
|
||||
shaderManager_ = shaderManagerD3D11_;
|
||||
depalShaderCache_ = new DepalShaderCacheD3D11(draw);
|
||||
depalShaderCache_ = new DepalShaderCache(draw);
|
||||
drawEngine_.SetShaderManager(shaderManagerD3D11_);
|
||||
drawEngine_.SetTextureCache(textureCacheD3D11_);
|
||||
drawEngine_.SetFramebufferManager(framebufferManagerD3D11_);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/D3D11/DrawEngineD3D11.h"
|
||||
#include "GPU/D3D11/DepalettizeShaderD3D11.h"
|
||||
#include "GPU/Common/DepalettizeCommon.h"
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
|
||||
class FramebufferManagerD3D11;
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
|
||||
FramebufferManagerD3D11 *framebufferManagerD3D11_;
|
||||
TextureCacheD3D11 *textureCacheD3D11_;
|
||||
DepalShaderCacheD3D11 *depalShaderCache_;
|
||||
DepalShaderCache *depalShaderCache_;
|
||||
DrawEngineD3D11 drawEngine_;
|
||||
ShaderManagerD3D11 *shaderManagerD3D11_;
|
||||
};
|
||||
+71
-158
@@ -31,7 +31,7 @@
|
||||
#include "GPU/D3D11/TextureCacheD3D11.h"
|
||||
#include "GPU/D3D11/FramebufferManagerD3D11.h"
|
||||
#include "GPU/D3D11/ShaderManagerD3D11.h"
|
||||
#include "GPU/D3D11/DepalettizeShaderD3D11.h"
|
||||
#include "GPU/Common/DepalettizeCommon.h"
|
||||
#include "GPU/D3D11/D3D11Util.h"
|
||||
#include "GPU/Common/FramebufferManagerCommon.h"
|
||||
#include "GPU/Common/TextureDecoder.h"
|
||||
@@ -245,6 +245,11 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) {
|
||||
context_->PSSetSamplers(0, 1, &state);
|
||||
}
|
||||
|
||||
void TextureCacheD3D11::ApplySamplingParams(const SamplerCacheKey &key) {
|
||||
ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, key);
|
||||
context_->PSSetSamplers(0, 1, &state);
|
||||
}
|
||||
|
||||
void TextureCacheD3D11::Unbind() {
|
||||
ID3D11ShaderResourceView *nullView = nullptr;
|
||||
context_->PSSetShaderResources(0, 1, &nullView);
|
||||
@@ -257,188 +262,96 @@ void TextureCacheD3D11::BindAsClutTexture(Draw::Texture *tex) {
|
||||
context_->PSSetSamplers(3, 1, &stockD3D11.samplerPoint2DWrap);
|
||||
}
|
||||
|
||||
class TextureShaderApplierD3D11 {
|
||||
public:
|
||||
struct Pos {
|
||||
Pos(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {
|
||||
}
|
||||
Pos() {
|
||||
}
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
struct UV {
|
||||
UV(float u_, float v_) : u(u_), v(v_) {
|
||||
}
|
||||
UV() {
|
||||
}
|
||||
|
||||
float u;
|
||||
float v;
|
||||
};
|
||||
|
||||
struct PosUV {
|
||||
Pos pos;
|
||||
UV uv;
|
||||
};
|
||||
|
||||
TextureShaderApplierD3D11(ID3D11DeviceContext *context, ID3D11PixelShader *pshader, ID3D11Buffer *dynamicBuffer, float bufferW, float bufferH, int renderW, int renderH, float xoff, float yoff)
|
||||
: 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 },
|
||||
{ -1, -1, 0 },
|
||||
{ 1, -1, 0 },
|
||||
};
|
||||
static const UV uv[4] = {
|
||||
{ 0, 0 },
|
||||
{ 1, 0 },
|
||||
{ 0, 1 },
|
||||
{ 1, 1 },
|
||||
};
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
verts_[i].pos = pos[i];
|
||||
verts_[i].pos.x += xoff;
|
||||
verts_[i].pos.y += yoff;
|
||||
verts_[i].uv = uv[i];
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyBounds(const KnownVertexBounds &bounds, u32 uoff, u32 voff, float xoff, float yoff) {
|
||||
// If min is not < max, then we don't have values (wasn't set during decode.)
|
||||
if (bounds.minV < bounds.maxV) {
|
||||
const float invWidth = 1.0f / bufferW_;
|
||||
const float invHeight = 1.0f / bufferH_;
|
||||
// Inverse of half = double.
|
||||
const float invHalfWidth = invWidth * 2.0f;
|
||||
const float invHalfHeight = invHeight * 2.0f;
|
||||
|
||||
const int u1 = bounds.minU + uoff;
|
||||
const int v1 = bounds.minV + voff;
|
||||
const int u2 = bounds.maxU + uoff;
|
||||
const int v2 = bounds.maxV + voff;
|
||||
|
||||
const float left = u1 * invHalfWidth - 1.0f + xoff;
|
||||
const float right = u2 * invHalfWidth - 1.0f + xoff;
|
||||
const float top = (bufferH_ - v1) * invHalfHeight - 1.0f + yoff;
|
||||
const float bottom = (bufferH_ - v2) * invHalfHeight - 1.0f + yoff;
|
||||
|
||||
float z = 0.0f;
|
||||
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, 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) {
|
||||
context_->PSSetShader(pshader_, 0, 0);
|
||||
context_->VSSetShader(vshader, 0, 0);
|
||||
context_->IASetInputLayout(decl);
|
||||
}
|
||||
|
||||
void Shade() {
|
||||
D3D11_VIEWPORT vp{ 0.0f, 0.0f, (float)renderW_, (float)renderH_, 0.0f, 1.0f };
|
||||
context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], nullptr, 0xFFFFFFFF);
|
||||
context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0xFF);
|
||||
context_->RSSetState(stockD3D11.rasterStateNoCull);
|
||||
context_->RSSetViewports(1, &vp);
|
||||
context_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
context_->IASetVertexBuffers(0, 1, &vbuffer_, &stride_, &offset_);
|
||||
context_->Draw(4, 0);
|
||||
gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE);
|
||||
}
|
||||
|
||||
protected:
|
||||
ID3D11DeviceContext *context_;
|
||||
ID3D11PixelShader *pshader_;
|
||||
ID3D11Buffer *vbuffer_;
|
||||
PosUV verts_[4];
|
||||
UINT stride_ = sizeof(PosUV);
|
||||
UINT offset_ = 0;
|
||||
float bufferW_;
|
||||
float bufferH_;
|
||||
int renderW_;
|
||||
int renderH_;
|
||||
};
|
||||
|
||||
void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) {
|
||||
ID3D11PixelShader *pshader = nullptr;
|
||||
DepalShader *depalShader = nullptr;
|
||||
uint32_t clutMode = gstate.clutformat & 0xFFFFFF;
|
||||
bool need_depalettize = IsClutFormat(texFormat);
|
||||
|
||||
bool depth = channel == NOTIFY_FB_DEPTH;
|
||||
if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) {
|
||||
pshader = depalShaderCache_->GetDepalettizePixelShader(clutMode, depth ? GE_FORMAT_DEPTH16 : framebuffer->drawnFormat);
|
||||
bool useShaderDepal = framebufferManager_->GetCurrentRenderVFB() != framebuffer && (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300) || gstate_c.Supports(GPU_SUPPORTS_GLSL_330)) && !depth;
|
||||
if (!gstate_c.Supports(GPU_SUPPORTS_32BIT_INT_FSHADER)) {
|
||||
useShaderDepal = false;
|
||||
depth = false; // Can't support this
|
||||
}
|
||||
|
||||
if (pshader) {
|
||||
bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS);
|
||||
if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) {
|
||||
if (useShaderDepal) {
|
||||
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
|
||||
|
||||
// Very icky conflation here of native and thin3d rendering. This will need careful work per backend in BindAsClutTexture.
|
||||
Draw::Texture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBufRaw_);
|
||||
BindAsClutTexture(clutTexture);
|
||||
|
||||
framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET);
|
||||
SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
|
||||
samplerKey.magFilt = false;
|
||||
samplerKey.minFilt = false;
|
||||
samplerKey.mipEnable = false;
|
||||
ApplySamplingParams(samplerKey);
|
||||
|
||||
// Since we started/ended render passes, might need these.
|
||||
gstate_c.Dirty(DIRTY_DEPAL);
|
||||
gstate_c.SetUseShaderDepal(true);
|
||||
gstate_c.depalFramebufferFormat = framebuffer->drawnFormat;
|
||||
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
|
||||
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;
|
||||
CheckAlphaResult alphaStatus = CheckCLUTAlpha((const uint8_t *)clutBuf_, clutFormat, clutTotalColors);
|
||||
gstate_c.SetTextureFullAlpha(alphaStatus == CHECKALPHA_FULL);
|
||||
|
||||
draw_->InvalidateCachedState();
|
||||
InvalidateLastTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
depalShader = depalShaderCache_->GetDepalettizeShader(clutMode, depth ? GE_FORMAT_DEPTH16 : framebuffer->drawnFormat);
|
||||
gstate_c.SetUseShaderDepal(false);
|
||||
}
|
||||
|
||||
if (depalShader) {
|
||||
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
|
||||
ID3D11ShaderResourceView *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_, expand32);
|
||||
Draw::Texture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBufRaw_);
|
||||
Draw::Framebuffer *depalFBO = framebufferManager_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
draw_->BindTexture(0, nullptr);
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "Depal");
|
||||
|
||||
Draw::Framebuffer *depalFBO = framebufferManagerD3D11_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
shaderManager_->DirtyLastShader();
|
||||
draw_->SetScissorRect(0, 0, (int)framebuffer->renderWidth, (int)framebuffer->renderHeight);
|
||||
Draw::Viewport vp{ 0.0f, 0.0f, (float)framebuffer->renderWidth, (float)framebuffer->renderHeight, 0.0f, 1.0f };
|
||||
draw_->SetViewports(1, &vp);
|
||||
|
||||
// Not sure why or if we need this here - we're not about to actually draw using draw_, just use its framebuffer binds.
|
||||
draw_->InvalidateCachedState();
|
||||
TextureShaderApplier shaderApply(draw_, depalShader, framebuffer->bufferWidth, framebuffer->bufferHeight, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset);
|
||||
shaderApply.Use();
|
||||
|
||||
float xoff = -0.5f / framebuffer->renderWidth;
|
||||
float yoff = 0.5f / framebuffer->renderHeight;
|
||||
|
||||
TextureShaderApplierD3D11 shaderApply(context_, pshader, framebufferManagerD3D11_->GetDynamicQuadBuffer(), framebuffer->bufferWidth, framebuffer->bufferHeight, framebuffer->renderWidth, framebuffer->renderHeight, xoff, yoff);
|
||||
shaderApply.ApplyBounds(gstate_c.vertBounds, gstate_c.curTextureXOffset, gstate_c.curTextureYOffset, xoff, yoff);
|
||||
shaderApply.Use(depalShaderCache_->GetDepalettizeVertexShader(), depalShaderCache_->GetInputLayout());
|
||||
|
||||
ID3D11ShaderResourceView *nullTexture = nullptr;
|
||||
context_->PSSetShaderResources(0, 1, &nullTexture); // In case the target was used in the last draw call. Happens in Sega Rally.
|
||||
draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "ApplyTextureFramebuffer_DepalShader");
|
||||
// BindAsClutTexture(clutTexture);
|
||||
context_->PSSetShaderResources(1, 1, &clutTexture);
|
||||
context_->PSSetSamplers(1, 1, &stockD3D11.samplerPoint2DWrap);
|
||||
draw_->BindFramebufferAsTexture(framebuffer->fbo, 0, depth ? Draw::FB_DEPTH_BIT : Draw::FB_COLOR_BIT, 0);
|
||||
context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DWrap);
|
||||
Draw::SamplerState *nearest = depalShaderCache_->GetSampler();
|
||||
draw_->BindSamplerStates(0, 1, &nearest);
|
||||
draw_->BindSamplerStates(1, 1, &nearest);
|
||||
draw_->BindTexture(1, clutTexture);
|
||||
|
||||
shaderApply.Shade();
|
||||
|
||||
context_->PSSetShaderResources(0, 1, &nullTexture); // Make D3D11 validation happy. Really of no consequence since we rebind anyway.
|
||||
framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer");
|
||||
framebufferManager_->RebindFramebuffer("ApplyTextureFramebuffer");
|
||||
|
||||
draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0);
|
||||
|
||||
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
|
||||
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;
|
||||
|
||||
CheckAlphaResult alphaStatus = CheckAlpha(clutBuf_, GetClutDestFormatD3D11(clutFormat), clutTotalColors);
|
||||
CheckAlphaResult alphaStatus = CheckCLUTAlpha((const uint8_t *)clutBufRaw_, clutFormat, clutTotalColors);
|
||||
gstate_c.SetTextureFullAlpha(alphaStatus == CHECKALPHA_FULL);
|
||||
|
||||
draw_->InvalidateCachedState();
|
||||
shaderManager_->DirtyLastShader();
|
||||
} else {
|
||||
framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer");
|
||||
framebufferManager_->RebindFramebuffer("ApplyTextureFramebuffer");
|
||||
framebufferManager_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET);
|
||||
|
||||
gstate_c.SetUseShaderDepal(false);
|
||||
gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650);
|
||||
}
|
||||
|
||||
SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
|
||||
ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey);
|
||||
context_->PSSetSamplers(0, 1, &state);
|
||||
ApplySamplingParams(samplerKey);
|
||||
|
||||
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
|
||||
draw_->InvalidateCachedState();
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
struct VirtualFramebuffer;
|
||||
|
||||
class FramebufferManagerD3D11;
|
||||
class DepalShaderCacheD3D11;
|
||||
class DepalShaderCache;
|
||||
class ShaderManagerD3D11;
|
||||
|
||||
class SamplerCacheD3D11 {
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
void StartFrame();
|
||||
|
||||
void SetFramebufferManager(FramebufferManagerD3D11 *fbManager);
|
||||
void SetDepalShaderCache(DepalShaderCacheD3D11 *dpCache) {
|
||||
void SetDepalShaderCache(DepalShaderCache *dpCache) {
|
||||
depalShaderCache_ = dpCache;
|
||||
}
|
||||
void SetShaderManager(ShaderManagerD3D11 *sm) {
|
||||
@@ -66,6 +66,7 @@ protected:
|
||||
void Unbind() override;
|
||||
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
|
||||
void BindAsClutTexture(Draw::Texture *tex) override;
|
||||
void ApplySamplingParams(const SamplerCacheKey &key) override;
|
||||
|
||||
private:
|
||||
DXGI_FORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
|
||||
@@ -91,7 +92,7 @@ private:
|
||||
ID3D11Buffer *depalConstants_;
|
||||
|
||||
FramebufferManagerD3D11 *framebufferManagerD3D11_;
|
||||
DepalShaderCacheD3D11 *depalShaderCache_;
|
||||
DepalShaderCache *depalShaderCache_;
|
||||
ShaderManagerD3D11 *shaderManager_;
|
||||
|
||||
};
|
||||
|
||||
@@ -71,7 +71,7 @@ protected:
|
||||
void BindAsClutTexture(Draw::Texture *tex) override;
|
||||
|
||||
private:
|
||||
void ApplySamplingParams(const SamplerCacheKey &key);
|
||||
void ApplySamplingParams(const SamplerCacheKey &key) override;
|
||||
Draw::DataFormat GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
|
||||
|
||||
void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override;
|
||||
|
||||
@@ -362,7 +362,6 @@
|
||||
<ClInclude Include="Common\VertexDecoderCommon.h" />
|
||||
<ClInclude Include="Common\VertexShaderGenerator.h" />
|
||||
<ClInclude Include="D3D11\D3D11Util.h" />
|
||||
<ClInclude Include="D3D11\DepalettizeShaderD3D11.h" />
|
||||
<ClInclude Include="D3D11\DrawEngineD3D11.h" />
|
||||
<ClInclude Include="D3D11\FramebufferManagerD3D11.h" />
|
||||
<ClInclude Include="D3D11\GPU_D3D11.h" />
|
||||
@@ -505,7 +504,6 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="Common\VertexShaderGenerator.cpp" />
|
||||
<ClCompile Include="D3D11\D3D11Util.cpp" />
|
||||
<ClCompile Include="D3D11\DepalettizeShaderD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\DrawEngineD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\FramebufferManagerD3D11.cpp" />
|
||||
<ClCompile Include="D3D11\GPU_D3D11.cpp" />
|
||||
|
||||
@@ -195,9 +195,6 @@
|
||||
<ClInclude Include="D3D11\DrawEngineD3D11.h">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3D11\DepalettizeShaderD3D11.h">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3D11\D3D11Util.h">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClInclude>
|
||||
@@ -443,9 +440,6 @@
|
||||
<ClCompile Include="D3D11\DrawEngineD3D11.cpp">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3D11\DepalettizeShaderD3D11.cpp">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3D11\D3D11Util.cpp">
|
||||
<Filter>D3D11</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -400,6 +400,10 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) {
|
||||
gstate_c.SetUseShaderDepal(false);
|
||||
}
|
||||
|
||||
void TextureCacheVulkan::ApplySamplingParams(const SamplerCacheKey &key) {
|
||||
curSampler_ = samplerCache_.GetOrCreateSampler(key);
|
||||
}
|
||||
|
||||
void TextureCacheVulkan::Unbind() {
|
||||
imageView_ = VK_NULL_HANDLE;
|
||||
curSampler_ = VK_NULL_HANDLE;
|
||||
|
||||
@@ -103,6 +103,7 @@ protected:
|
||||
void Unbind() override;
|
||||
void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override;
|
||||
void BindAsClutTexture(Draw::Texture *tex) override;
|
||||
void ApplySamplingParams(const SamplerCacheKey &key) override;
|
||||
|
||||
private:
|
||||
void LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePtr, int rowPitch, int level, int scaleFactor, VkFormat dstFmt);
|
||||
|
||||
@@ -404,7 +404,6 @@
|
||||
<ClInclude Include="..\..\GPU\Common\VertexDecoderCommon.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\VertexShaderGenerator.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\D3D11Util.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\DepalettizeShaderD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\DrawEngineD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\FramebufferManagerD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\GPU_D3D11.h" />
|
||||
@@ -466,7 +465,6 @@
|
||||
<ClCompile Include="..\..\GPU\Common\VertexDecoderX86.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\VertexShaderGenerator.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\D3D11Util.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\DepalettizeShaderD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\DrawEngineD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\FramebufferManagerD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\GPU_D3D11.cpp" />
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
<ClCompile Include="..\..\GPU\Common\VertexDecoderCommon.cpp" />
|
||||
<ClCompile Include="..\..\GPU\Common\VertexDecoderX86.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\D3D11Util.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\DepalettizeShaderD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\DrawEngineD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\FramebufferManagerD3D11.cpp" />
|
||||
<ClCompile Include="..\..\GPU\D3D11\GPU_D3D11.cpp" />
|
||||
@@ -81,7 +80,6 @@
|
||||
<ClInclude Include="..\..\GPU\Common\TransformCommon.h" />
|
||||
<ClInclude Include="..\..\GPU\Common\VertexDecoderCommon.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\D3D11Util.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\DepalettizeShaderD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\DrawEngineD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\FramebufferManagerD3D11.h" />
|
||||
<ClInclude Include="..\..\GPU\D3D11\GPU_D3D11.h" />
|
||||
|
||||
@@ -751,7 +751,6 @@ SOURCES_CXX += \
|
||||
$(GPUDIR)/Directx9/TextureCacheDX9.cpp
|
||||
|
||||
SOURCES_CXX += \
|
||||
$(GPUDIR)/D3D11/DepalettizeShaderD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/DrawEngineD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/FramebufferManagerD3D11.cpp \
|
||||
$(GPUDIR)/D3D11/GPU_D3D11.cpp \
|
||||
|
||||
Reference in new issue
Block a user