D3D11: Lumines is now playable in non-buffered, with reverse colors.

This commit is contained in:
Henrik Rydgard 2017-02-10 11:25:24 +01:00
parent a8dc9360f0
commit 3f4e14f504
13 changed files with 83 additions and 38 deletions

View file

@ -7,13 +7,19 @@
#include "GPU/Math3D.h"
#include "Core/Reporting.h"
static void ConvertProjMatrixToVulkan(Matrix4x4 &in, bool invertedX, bool invertedY) {
static void ConvertProjMatrixToVulkan(Matrix4x4 &in) {
const Vec3 trans(0, 0, gstate_c.vpZOffset * 0.5f + 0.5f);
const Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f);
in.translateAndScale(trans, scale);
}
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms) {
static void ConvertProjMatrixToD3D11(Matrix4x4 &in) {
const Vec3 trans(0, 0, gstate_c.vpZOffset * 0.5f + 0.5f);
const Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f);
in.translateAndScale(trans, scale);
}
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport) {
if (dirtyUniforms & DIRTY_TEXENV) {
Uint8x3ToFloat4(ub->texEnvColor, gstate.texenvcolor);
}
@ -65,13 +71,21 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms) {
flippedMatrix[8] = -flippedMatrix[8];
flippedMatrix[12] = -flippedMatrix[12];
}
ConvertProjMatrixToVulkan(flippedMatrix, invertedX, invertedY);
if (flipViewport) {
ConvertProjMatrixToD3D11(flippedMatrix);
} else {
ConvertProjMatrixToVulkan(flippedMatrix);
}
CopyMatrix4x4(ub->proj, flippedMatrix.getReadPtr());
}
if (dirtyUniforms & DIRTY_PROJTHROUGHMATRIX) {
Matrix4x4 proj_through;
proj_through.setOrthoVulkan(0.0f, gstate_c.curRTWidth, 0, gstate_c.curRTHeight, 0, 1);
if (flipViewport) {
proj_through.setOrthoD3D(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0, 1);
} else {
proj_through.setOrthoVulkan(0.0f, gstate_c.curRTWidth, 0, gstate_c.curRTHeight, 0, 1);
}
CopyMatrix4x4(ub->proj_through, proj_through.getReadPtr());
}

View file

@ -69,7 +69,7 @@ R"( float4x4 u_proj;
float4x4 u_tex;
float4 u_uvscaleoffset;
float4 u_depthRange;
float3 u_fogcoef_stencilreplace;
float3 u_fogcoef;
float4 u_matambientalpha;
float3 u_fogcolor;
float3 u_texenv;
@ -98,7 +98,7 @@ struct UB_VS_Lights {
};
static const char *ub_vs_lightsStr =
R"( vec4 globalAmbient;
R"( vec4 u_ambient;
vec3 matdiffuse;
vec4 matspecular;
vec3 matemissive;
@ -114,18 +114,36 @@ R"( vec4 globalAmbient;
// HLSL code is shared so these names are changed to match those in DX9.
static const char *cb_vs_lightsStr =
R"( float4 globalAmbient;
R"( float4 u_ambient;
float3 u_matdiffuse;
float4 u_matspecular;
float3 u_matemissive;
float3 u_lightpos[4];
float3 u_lightdir[4];
float3 u_lightatt[4];
float3 u_lightpos0;
float3 u_lightpos1;
float3 u_lightpos2;
float3 u_lightpos3;
float3 u_lightdir0;
float3 u_lightdir1;
float3 u_lightdir2;
float3 u_lightdir3;
float3 u_lightatt0;
float3 u_lightatt1;
float3 u_lightatt2;
float3 u_lightatt3;
float u_lightangle[4];
float u_lightspotCoef[4];
float3 u_ambient[4];
float3 u_diffuse[4];
float3 u_specular[4];
float3 u_lightambient0;
float3 u_lightambient1;
float3 u_lightambient2;
float3 u_lightambient3;
float3 u_lightdiffuse0;
float3 u_lightdiffuse1;
float3 u_lightdiffuse2;
float3 u_lightdiffuse3;
float3 u_lightspecular0;
float3 u_lightspecular1;
float3 u_lightspecular2;
float3 u_lightspecular3;
)";
// With some cleverness, we could get away with uploading just half this when only the four first
@ -144,7 +162,7 @@ static const char *cb_vs_bonesStr =
R"( float4x4 m[8];
)";
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms);
void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport);
void LightUpdateUniforms(UB_VS_Lights *ub, uint64_t dirtyUniforms);
void BoneUpdateUniforms(UB_VS_Bones *ub, uint64_t dirtyUniforms);

View file

@ -44,8 +44,9 @@ public:
nextMapDiscard_ = true;
}
uint8_t *BeginPush(ID3D11DeviceContext *context, UINT *offset, size_t size) {
uint8_t *BeginPush(ID3D11DeviceContext *context, UINT *offset, size_t size, int align = 16) {
D3D11_MAPPED_SUBRESOURCE map;
pos_ = (pos_ + align - 1) & ~(align - 1);
context->Map(buffer_, 0, nextMapDiscard_ ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map);
nextMapDiscard_ = false;
*offset = (UINT)pos_;

View file

@ -587,6 +587,8 @@ void DrawEngineD3D11::DoFlush() {
if (useHWTransform) {
ID3D11Buffer *vb_ = nullptr;
ID3D11Buffer *ib_ = nullptr;
if (prim == GE_PRIM_TRIANGLE_FAN)
Crash();
int vertexCount = 0;
int maxIndex = 0;
@ -785,15 +787,13 @@ rotateVBO:
context_->IASetVertexBuffers(0, 1, &buf, &stride, &vOffset);
if (useElements) {
UINT iOffset;
int iSize = 2 * vertexCount;
int iSize = 2 * indexGen.VertexCount();
uint8_t *iptr = pushInds_->BeginPush(context_, &iOffset, iSize);
memcpy(iptr, decIndex, iSize);
pushInds_->EndPush(context_);
context_->IASetIndexBuffer(pushInds_->Buf(), DXGI_FORMAT_R16_UINT, iOffset);
context_->DrawIndexed(vertexCount, 0, 0);
// context_->DrawIndexedPrimitiveUP(glprim[prim], 0, maxIndex + 1, D3DPrimCount(glprim[prim], vertexCount), decIndex, D3DFMT_INDEX16, decoded, dec_->GetDecVtxFmt().stride);
} else {
// context_->DrawPrimitiveUP(glprim[prim], D3DPrimCount(glprim[prim], vertexCount), decoded, dec_->GetDecVtxFmt().stride);
context_->Draw(vertexCount, 0);
}
} else {
@ -873,7 +873,7 @@ rotateVBO:
UINT stride = sizeof(TransformedVertex);
UINT vOffset = 0;
int vSize = numTrans * dec_->GetDecVtxFmt().stride;
int vSize = maxIndex * stride;
uint8_t *vptr = pushVerts_->BeginPush(context_, &vOffset, vSize);
memcpy(vptr, drawBuffer, vSize);
pushVerts_->EndPush(context_);
@ -881,13 +881,12 @@ rotateVBO:
context_->IASetVertexBuffers(0, 1, &buf, &stride, &vOffset);
if (drawIndexed) {
UINT iOffset;
int iSize = 2 * (maxIndex + 1);
int iSize = sizeof(int16_t) * numTrans;
uint8_t *iptr = pushInds_->BeginPush(context_, &iOffset, iSize);
memcpy(iptr, inds, iSize);
pushInds_->EndPush(context_);
context_->IASetIndexBuffer(pushInds_->Buf(), DXGI_FORMAT_R16_UINT, iOffset);
context_->DrawIndexed(maxIndex + 1, 0, 0);
// context_->DrawIndexedPrimitiveUP(glprim[prim], 0, maxIndex, numTrans, inds, DXGI_FORMAT_R16_UINT, drawBuffer, sizeof(TransformedVertex));
context_->DrawIndexed(numTrans, 0, 0);
} else {
context_->Draw(numTrans, 0);
}

View file

@ -453,7 +453,8 @@ void FramebufferManagerD3D11::BindFramebufferColor(int stage, VirtualFramebuffer
}
if (!framebuffer->fbo || !useBufferedRendering_) {
context_->PSSetShaderResources(stage, 1, nullptr);
ID3D11ShaderResourceView *view = nullptr;
context_->PSSetShaderResources(stage, 1, &view);
gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE;
return;
}

View file

@ -557,6 +557,7 @@ void GPU_D3D11::DumpNextFrame() {
void GPU_D3D11::BeginFrame() {
ScheduleEvent(GPU_EVENT_BEGIN_FRAME);
gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX);
}
void GPU_D3D11::ReapplyGfxStateInternal() {

View file

@ -148,7 +148,7 @@ uint64_t ShaderManagerD3D11::UpdateUniforms() {
if (dirty != 0) {
D3D11_MAPPED_SUBRESOURCE map;
if (dirty & DIRTY_BASE_UNIFORMS) {
BaseUpdateUniforms(&ub_base, dirty);
BaseUpdateUniforms(&ub_base, dirty, true);
context_->Map(push_base, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(map.pData, &ub_base, sizeof(ub_base));
context_->Unmap(push_base, 0);

View file

@ -132,7 +132,8 @@ void TextureCacheD3D11::SetFramebufferManager(FramebufferManagerD3D11 *fbManager
}
void TextureCacheD3D11::Clear(bool delete_them) {
// context_->PSSetShaderResources(0, 1, nullptr);
// ID3D11ShaderResourceView *srv = nullptr;
// context_->PSSetShaderResources(0, 1, &srv);
lastBoundTexture = INVALID_TEX;
if (delete_them) {
for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ++iter) {
@ -182,7 +183,8 @@ void TextureCacheD3D11::Decimate() {
if (cacheSizeEstimate_ >= TEXCACHE_MIN_PRESSURE) {
const u32 had = cacheSizeEstimate_;
context_->PSSetShaderResources(0, 1, nullptr);
ID3D11ShaderResourceView *srv = nullptr;
context_->PSSetShaderResources(0, 1, &srv);
lastBoundTexture = INVALID_TEX;
int killAge = lowMemoryMode_ ? TEXTURE_KILL_AGE_LOWMEM : TEXTURE_KILL_AGE;
for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ) {
@ -603,7 +605,8 @@ void TextureCacheD3D11::SetTexture(bool force) {
u32 texaddr = gstate.getTextureAddress(0);
if (!Memory::IsValidAddress(texaddr)) {
// Bind a null texture and return.
context_->PSSetShaderResources(0, 1, nullptr);
ID3D11ShaderResourceView *srv = nullptr;
context_->PSSetShaderResources(0, 1, &srv);
lastBoundTexture = INVALID_TEX;
return;
}
@ -1000,7 +1003,8 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry, bool replaceIma
if (replaceImages) {
// Make sure it's not currently set.
context_->PSSetShaderResources(0, 1, nullptr);
ID3D11ShaderResourceView *srv = nullptr;
context_->PSSetShaderResources(0, 1, &srv);
}
// Seems to cause problems in Tactics Ogre.

View file

@ -254,7 +254,7 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l
}
WRITE(p, "VS_OUT main(VS_IN In) {\n");
WRITE(p, " VS_OUT Out = (VS_OUT)0; \n");
WRITE(p, " VS_OUT Out;\n");
if (!useHWTransform) {
// Simple pass-through of vertex data to fragment shader
if (doTexture) {
@ -304,13 +304,13 @@ void GenerateVertexShaderHLSL(const ShaderID &id, char *buffer, ShaderLanguage l
if (lang == HLSL_D3D11) {
WRITE(p, " float3 worldpos = mul(u_world, float4(In.position.xyz, 1.0)).xyz;\n");
if (hasNormal)
WRITE(p, " float3 worldnormal = normalize( mul(u_world, float4(%sIn.normal, 0.0)));\n", flipNormal ? "-" : "");
WRITE(p, " float3 worldnormal = normalize(mul(u_world, float4(%sIn.normal, 0.0))).xyz;\n", flipNormal ? "-" : "");
else
WRITE(p, " float3 worldnormal = float3(0.0, 0.0, 1.0);\n");
} else {
WRITE(p, " float3 worldpos = mul(float4(In.position.xyz, 1.0), u_world);\n");
if (hasNormal)
WRITE(p, " float3 worldnormal = normalize( mul(float4(%sIn.normal, 0.0), u_world));\n", flipNormal ? "-" : "");
WRITE(p, " float3 worldnormal = normalize(mul(float4(%sIn.normal, 0.0), u_world));\n", flipNormal ? "-" : "");
else
WRITE(p, " float3 worldnormal = float3(0.0, 0.0, 1.0);\n");
}

View file

@ -222,7 +222,7 @@ uint64_t ShaderManagerVulkan::UpdateUniforms() {
uint64_t dirty = gstate_c.GetDirtyUniforms();
if (dirty != 0) {
if (dirty & DIRTY_BASE_UNIFORMS)
BaseUpdateUniforms(&ub_base, dirty);
BaseUpdateUniforms(&ub_base, dirty, false);
if (dirty & DIRTY_LIGHT_UNIFORMS)
LightUpdateUniforms(&ub_lights, dirty);
if (dirty & DIRTY_BONE_UNIFORMS)

View file

@ -304,7 +304,7 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
bool distanceNeeded = false;
if (enableLighting) {
WRITE(p, " vec4 lightSum0 = light.globalAmbient * %s + vec4(light.matemissive, 0.0);\n", ambientStr);
WRITE(p, " vec4 lightSum0 = light.u_ambient * %s + vec4(light.matemissive, 0.0);\n", ambientStr);
for (int i = 0; i < 4; i++) {
GELightType type = static_cast<GELightType>(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2));

View file

@ -75,11 +75,10 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
#ifdef _DEBUG
if (SUCCEEDED(device_->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug_))) {
ID3D11InfoQueue *d3dInfoQueue = nullptr;
if (SUCCEEDED(d3dDebug_->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue))) {
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
if (SUCCEEDED(d3dDebug_->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue_))) {
d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
}
}
#endif
@ -112,9 +111,16 @@ void D3D11Context::Resize() {
}
void D3D11Context::Shutdown() {
#ifdef _DEBUG
d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, false);
d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, false);
d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, false);
#endif
#ifdef _DEBUG
d3dDebug_->ReportLiveDeviceObjects(D3D11_RLDO_SUMMARY | D3D11_RLDO_DETAIL);
#endif
d3dDebug_->Release();
d3dInfoQueue_->Release();
context_->ClearState();
context_->Flush();

View file

@ -45,6 +45,7 @@ private:
#ifdef _DEBUG
ID3D11Debug *d3dDebug_ = nullptr;
ID3D11InfoQueue *d3dInfoQueue_ = nullptr;
#endif
D3D_DRIVER_TYPE driverType_;