From 3f4e14f50423603f39f70036a5dbe6fdcbc0bdd7 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 10 Feb 2017 11:25:24 +0100 Subject: [PATCH] D3D11: Lumines is now playable in non-buffered, with reverse colors. --- GPU/Common/ShaderUniforms.cpp | 22 ++++++++++--- GPU/Common/ShaderUniforms.h | 38 ++++++++++++++++------ GPU/D3D11/D3D11Util.h | 3 +- GPU/D3D11/DrawEngineD3D11.cpp | 13 ++++---- GPU/D3D11/FramebufferManagerD3D11.cpp | 3 +- GPU/D3D11/GPU_D3D11.cpp | 1 + GPU/D3D11/ShaderManagerD3D11.cpp | 2 +- GPU/D3D11/TextureCacheD3D11.cpp | 12 ++++--- GPU/Directx9/VertexShaderGeneratorDX9.cpp | 6 ++-- GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/VertexShaderGeneratorVulkan.cpp | 2 +- Windows/GPU/D3D11Context.cpp | 16 ++++++--- Windows/GPU/D3D11Context.h | 1 + 13 files changed, 83 insertions(+), 38 deletions(-) diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 4fc4fff050..e5acc7bc27 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -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()); } diff --git a/GPU/Common/ShaderUniforms.h b/GPU/Common/ShaderUniforms.h index afceaee4ca..17ec2955bb 100644 --- a/GPU/Common/ShaderUniforms.h +++ b/GPU/Common/ShaderUniforms.h @@ -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); diff --git a/GPU/D3D11/D3D11Util.h b/GPU/D3D11/D3D11Util.h index 83296a13e6..cbac7a972a 100644 --- a/GPU/D3D11/D3D11Util.h +++ b/GPU/D3D11/D3D11Util.h @@ -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_; diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 5e24b15156..a03cdc6139 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -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); } diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index c52a22ea7a..d0377ff320 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -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; } diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index db05a454c8..73700325e7 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -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() { diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index fe631c97c8..66067539aa 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -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); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 946bfe3ad5..7603aa27fc 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -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. diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index 15cd493a68..c5f8b734e5 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -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"); } diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index b36f47d4c2..ec2d62baf3 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -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) diff --git a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp index d121ad6431..32a4326d87 100644 --- a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp @@ -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(id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2)); diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 37e497010f..13a189a7f5 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -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(); diff --git a/Windows/GPU/D3D11Context.h b/Windows/GPU/D3D11Context.h index 927394c3c6..2b71ffbc63 100644 --- a/Windows/GPU/D3D11Context.h +++ b/Windows/GPU/D3D11Context.h @@ -45,6 +45,7 @@ private: #ifdef _DEBUG ID3D11Debug *d3dDebug_ = nullptr; + ID3D11InfoQueue *d3dInfoQueue_ = nullptr; #endif D3D_DRIVER_TYPE driverType_;