From d1aa69acd0ff9d5da899f85872413182fc16996e Mon Sep 17 00:00:00 2001 From: turanszkij Date: Fri, 1 Dec 2017 14:38:49 +0000 Subject: [PATCH] gpu ringbuffer access through volatile, instancing updates, tessellator critical fix --- WickedEngine/wiFont.cpp | 58 +++++++++++++++++++++++++----------- WickedEngine/wiFont.h | 2 +- WickedEngine/wiLoader.h | 53 +++++++++++++++++++++++++++------ WickedEngine/wiRenderer.cpp | 59 ++++++++++++++++++++++++------------- WickedEngine/wiVersion.cpp | 2 +- 5 files changed, 125 insertions(+), 49 deletions(-) diff --git a/WickedEngine/wiFont.cpp b/WickedEngine/wiFont.cpp index c8394ba5a..97839ab2e 100644 --- a/WickedEngine/wiFont.cpp +++ b/WickedEngine/wiFont.cpp @@ -192,7 +192,7 @@ void wiFont::CleanUpStatic() } -void wiFont::ModifyGeo(Vertex* vertexList, const std::wstring& text, wiFontProps props, int style) +void wiFont::ModifyGeo(volatile Vertex* vertexList, const std::wstring& text, wiFontProps props, int style) { size_t vertexCount = text.length() * 4; @@ -225,32 +225,54 @@ void wiFont::ModifyGeo(Vertex* vertexList, const std::wstring& text, wiFontProps compatible = true; } + HALF h0 = XMConvertFloatToHalf(0.0f); + if (compatible) { int characterWidth = (int)(lookup.pixelWidth * relativeSize); - vertexList[i + 0].Pos = XMFLOAT2((float)pos, (float)line); - vertexList[i + 1].Pos = XMFLOAT2((float)pos + (float)characterWidth, (float)line); - vertexList[i + 2].Pos = XMFLOAT2((float)pos, (float)line + (float)lineHeight); - vertexList[i + 3].Pos = XMFLOAT2((float)pos + (float)characterWidth, (float)line + (float)lineHeight); + HALF h1 = XMConvertFloatToHalf(1.0f); + HALF hl = XMConvertFloatToHalf(lookup.left); + HALF hr = XMConvertFloatToHalf(lookup.right); - vertexList[i + 0].Tex = XMHALF2(lookup.left, 0); - vertexList[i + 1].Tex = XMHALF2(lookup.right, 0); - vertexList[i + 2].Tex = XMHALF2(lookup.left, 1); - vertexList[i + 3].Tex = XMHALF2(lookup.right, 1); + vertexList[i + 0].Pos.x = (float)pos; + vertexList[i + 0].Pos.y = (float)line; + vertexList[i + 1].Pos.x = (float)pos + (float)characterWidth; + vertexList[i + 1].Pos.y = (float)line; + vertexList[i + 2].Pos.x = (float)pos; + vertexList[i + 2].Pos.y = (float)line + (float)lineHeight; + vertexList[i + 3].Pos.x = (float)pos + (float)characterWidth; + vertexList[i + 3].Pos.y = (float)line + (float)lineHeight; + + vertexList[i + 0].Tex.x = hl; + vertexList[i + 0].Tex.y = h0; + vertexList[i + 1].Tex.x = hr; + vertexList[i + 1].Tex.y = h0; + vertexList[i + 2].Tex.x = hl; + vertexList[i + 2].Tex.y = h1; + vertexList[i + 3].Tex.x = hr; + vertexList[i + 3].Tex.y = h1; pos += characterWidth + props.spacingX; } else { - vertexList[i + 0].Pos = XMFLOAT2(0, 0); - vertexList[i + 0].Tex = XMHALF2(0.0f, 0.0f); - vertexList[i + 1].Pos = XMFLOAT2(0, 0); - vertexList[i + 1].Tex = XMHALF2(0.0f, 0.0f); - vertexList[i + 2].Pos = XMFLOAT2(0, 0); - vertexList[i + 2].Tex = XMHALF2(0.0f, 0.0f); - vertexList[i + 3].Pos = XMFLOAT2(0, 0); - vertexList[i + 3].Tex = XMHALF2(0.0f, 0.0f); + vertexList[i + 0].Pos.x = 0; + vertexList[i + 0].Pos.y = 0; + vertexList[i + 0].Tex.x = h0; + vertexList[i + 0].Tex.y = h0; + vertexList[i + 1].Pos.x = 0; + vertexList[i + 1].Pos.y = 0; + vertexList[i + 1].Tex.x = h0; + vertexList[i + 1].Tex.y = h0; + vertexList[i + 2].Pos.x = 0; + vertexList[i + 2].Pos.y = 0; + vertexList[i + 2].Tex.x = h0; + vertexList[i + 2].Tex.y = h0; + vertexList[i + 3].Pos.x = 0; + vertexList[i + 3].Pos.y = 0; + vertexList[i + 3].Tex.x = h0; + vertexList[i + 3].Tex.y = h0; } } } @@ -291,7 +313,7 @@ void wiFont::Draw(GRAPHICSTHREAD threadID, bool scissorTest) device->BindBlendState(blendState, threadID); UINT vboffset; - Vertex* textBuffer = (Vertex*)device->AllocateFromRingBuffer(vertexBuffer, sizeof(Vertex) * text.length() * 4, vboffset, threadID); + volatile Vertex* textBuffer = (volatile Vertex*)device->AllocateFromRingBuffer(vertexBuffer, sizeof(Vertex) * text.length() * 4, vboffset, threadID); ModifyGeo(textBuffer, text, newProps, style); device->InvalidateBufferAccess(vertexBuffer, threadID); diff --git a/WickedEngine/wiFont.h b/WickedEngine/wiFont.h index ef052f415..2b03e654a 100644 --- a/WickedEngine/wiFont.h +++ b/WickedEngine/wiFont.h @@ -87,7 +87,7 @@ private: static std::vector fontStyles; - static void ModifyGeo(Vertex* vertexList, const std::wstring& text, wiFontProps props, int style); + static void ModifyGeo(volatile Vertex* vertexList, const std::wstring& text, wiFontProps props, int style); public: static void Initialize(); diff --git a/WickedEngine/wiLoader.h b/WickedEngine/wiLoader.h index b77433057..a91a7fb0b 100644 --- a/WickedEngine/wiLoader.h +++ b/WickedEngine/wiLoader.h @@ -45,12 +45,32 @@ GFX_STRUCT Instance Instance(const XMFLOAT4X4& matIn, float dither = 0.0f, const XMFLOAT3& color = XMFLOAT3(1, 1, 1)){ Create(matIn, dither, color); } - inline void Create(const XMFLOAT4X4& matIn, float dither = 0.0f, const XMFLOAT3& color = XMFLOAT3(1, 1, 1)) + inline void Create(const XMFLOAT4X4& matIn, float dither = 0.0f, const XMFLOAT3& color = XMFLOAT3(1, 1, 1)) volatile { - mat0 = XMFLOAT4A(matIn._11, matIn._21, matIn._31, matIn._41); - mat1 = XMFLOAT4A(matIn._12, matIn._22, matIn._32, matIn._42); - mat2 = XMFLOAT4A(matIn._13, matIn._23, matIn._33, matIn._43); - color_dither = XMFLOAT4A(color.x, color.y, color.z, dither); + //mat0 = XMFLOAT4A(matIn._11, matIn._21, matIn._31, matIn._41); + //mat1 = XMFLOAT4A(matIn._12, matIn._22, matIn._32, matIn._42); + //mat2 = XMFLOAT4A(matIn._13, matIn._23, matIn._33, matIn._43); + //color_dither = XMFLOAT4A(color.x, color.y, color.z, dither); + + mat0.x = matIn._11; + mat0.y = matIn._21; + mat0.z = matIn._31; + mat0.w = matIn._41; + + mat1.x = matIn._12; + mat1.y = matIn._22; + mat1.z = matIn._32; + mat1.w = matIn._42; + + mat2.x = matIn._13; + mat2.y = matIn._23; + mat2.z = matIn._33; + mat2.w = matIn._43; + + color_dither.x = color.x; + color_dither.y = color.y; + color_dither.z = color.z; + color_dither.w = dither; } ALIGN_16 @@ -66,11 +86,26 @@ GFX_STRUCT InstancePrev { Create(matIn); } - inline void Create(const XMFLOAT4X4& matIn) + inline void Create(const XMFLOAT4X4& matIn) volatile { - mat0 = XMFLOAT4A(matIn._11, matIn._21, matIn._31, matIn._41); - mat1 = XMFLOAT4A(matIn._12, matIn._22, matIn._32, matIn._42); - mat2 = XMFLOAT4A(matIn._13, matIn._23, matIn._33, matIn._43); + //mat0 = XMFLOAT4A(matIn._11, matIn._21, matIn._31, matIn._41); + //mat1 = XMFLOAT4A(matIn._12, matIn._22, matIn._32, matIn._42); + //mat2 = XMFLOAT4A(matIn._13, matIn._23, matIn._33, matIn._43); + + mat0.x = matIn._11; + mat0.y = matIn._21; + mat0.z = matIn._31; + mat0.w = matIn._41; + + mat1.x = matIn._12; + mat1.y = matIn._22; + mat1.z = matIn._32; + mat1.w = matIn._42; + + mat2.x = matIn._13; + mat2.y = matIn._23; + mat2.z = matIn._33; + mat2.w = matIn._43; } ALIGN_16 diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index e8f129e85..37ed5aa6c 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -4073,6 +4073,11 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle device->BindBlendState(blendStates[BSTYPE_TRANSPARENT], threadID); } + const bool advancedVBRequest = + shaderType == SHADERTYPE_FORWARD || + shaderType == SHADERTYPE_DEFERRED || + shaderType == SHADERTYPE_TILEDFORWARD; + const bool easyTextureBind = shaderType == SHADERTYPE_TEXTURE || shaderType == SHADERTYPE_SHADOW || @@ -4092,7 +4097,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle bool impostorRenderSetup = false; // Assess the render params: - VLTYPES realVL = (shaderType == SHADERTYPE_DEPTHONLY || shaderType == SHADERTYPE_TEXTURE) ? VLTYPE_OBJECT_POS_TEX : VLTYPE_OBJECT_ALL; + VLTYPES realVL = advancedVBRequest ? VLTYPE_OBJECT_ALL : VLTYPE_OBJECT_POS_TEX; VSTYPES realVS = realVL == VLTYPE_OBJECT_POS_TEX ? VSTYPE_OBJECT_SIMPLE : VSTYPE_OBJECT_COMMON; PSTYPES realPS = PSTYPE_OBJECT_SIMPLEST; if (!wireRender) @@ -4143,7 +4148,9 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle bool instancePrevUpdated = false; UINT instancesOffset; - InstBuf* instances = (InstBuf*)device->AllocateFromRingBuffer(dynamicVertexBufferPool, sizeof(InstBuf)*visibleInstances.size(), instancesOffset, threadID); + size_t alloc_size = visibleInstances.size(); + alloc_size *= advancedVBRequest ? sizeof(InstBuf) : sizeof(Instance); + void* instances = device->AllocateFromRingBuffer(dynamicVertexBufferPool, alloc_size, instancesOffset, threadID); int k = 0; for (const Object* instance : visibleInstances) @@ -4161,14 +4168,19 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle XMMATRIX boxMat = mesh->aabb.getAsBoxMatrix(); XMStoreFloat4x4(&tempMat, boxMat*XMLoadFloat4x4(&instance->world)); - instances[k].instance.Create(tempMat, dither, instance->color); - if (shaderType == SHADERTYPE_FORWARD || shaderType == SHADERTYPE_TILEDFORWARD || shaderType == SHADERTYPE_DEFERRED) + if (advancedVBRequest) { + ((volatile InstBuf*)instances)[k].instance.Create(tempMat, dither, instance->color); + XMStoreFloat4x4(&tempMat, boxMat*XMLoadFloat4x4(&instance->worldPrev)); - instances[k].instancePrev.Create(tempMat); + ((volatile InstBuf*)instances)[k].instancePrev.Create(tempMat); instancePrevUpdated = true; } + else + { + ((volatile Instance*)instances)[k].Create(tempMat, dither, instance->color); + } ++k; } @@ -4178,7 +4190,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle if (k < 1) continue; - if (realVL == VLTYPE_OBJECT_POS_TEX) + if (!advancedVBRequest) { GPUBuffer* vbs[] = { &Mesh::impostorVB_POS, @@ -4188,7 +4200,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle UINT strides[] = { sizeof(Mesh::Vertex_POS), sizeof(Mesh::Vertex_TEX), - sizeof(InstBuf) + sizeof(Instance) }; UINT offsets[] = { 0, @@ -4320,7 +4332,9 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle bool forceAlphaTestForDithering = false; UINT instancesOffset; - InstBuf* instances = (InstBuf*)device->AllocateFromRingBuffer(dynamicVertexBufferPool, sizeof(InstBuf)*visibleInstances.size(), instancesOffset, threadID); + size_t alloc_size = visibleInstances.size(); + alloc_size *= advancedVBRequest ? sizeof(InstBuf) : sizeof(Instance); + void* instances = device->AllocateFromRingBuffer(dynamicVertexBufferPool, alloc_size, instancesOffset, threadID); int k = 0; for (const Object* instance : visibleInstances) @@ -4346,17 +4360,22 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle tempMat = __identityMat; else tempMat = instance->world; - instances[k].instance.Create(tempMat, dither, instance->color); - if (shaderType == SHADERTYPE_FORWARD || shaderType == SHADERTYPE_TILEDFORWARD || shaderType == SHADERTYPE_DEFERRED) + if (advancedVBRequest || tessellatorRequested) { + ((volatile InstBuf*)instances)[k].instance.Create(tempMat, dither, instance->color); + if (mesh->softBody) tempMat = __identityMat; else tempMat = instance->worldPrev; - instances[k].instancePrev.Create(tempMat); + ((volatile InstBuf*)instances)[k].instancePrev.Create(tempMat); instancePrevUpdated = true; } + else + { + ((volatile Instance*)instances)[k].Create(tempMat, dither, instance->color); + } ++k; } @@ -4408,7 +4427,11 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle { BOUNDVERTEXBUFFERTYPE boundVBType; - if (!tessellatorRequested && (shaderType == SHADERTYPE_DEPTHONLY || shaderType == SHADERTYPE_TEXTURE || shaderType == SHADERTYPE_SHADOW || shaderType == SHADERTYPE_SHADOWCUBE)) + if (advancedVBRequest || tessellatorRequested) + { + boundVBType = BOUNDVERTEXBUFFERTYPE::EVERYTHING; + } + else if (!tessellatorRequested && (shaderType == SHADERTYPE_DEPTHONLY || shaderType == SHADERTYPE_TEXTURE || shaderType == SHADERTYPE_SHADOW || shaderType == SHADERTYPE_SHADOWCUBE)) { // simple vertex buffers are used in some passes (note: tessellator requires more attributes) if ((shaderType == SHADERTYPE_DEPTHONLY || shaderType == SHADERTYPE_SHADOW || shaderType == SHADERTYPE_SHADOWCUBE) && !material->IsAlphaTestEnabled() && !forceAlphaTestForDithering) @@ -4421,10 +4444,6 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle boundVBType = BOUNDVERTEXBUFFERTYPE::POSITION_TEXCOORD; } } - else - { - boundVBType = BOUNDVERTEXBUFFERTYPE::EVERYTHING; - } // Only bind vertex buffers when the layout changes if (boundVBType != boundVBType_Prev) @@ -4440,7 +4459,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle }; UINT strides[] = { sizeof(Mesh::Vertex_POS), - sizeof(InstBuf) + sizeof(Instance) }; UINT offsets[] = { mesh->hasDynamicVB() ? mesh->bufferOffset_POS : 0, @@ -4459,7 +4478,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle UINT strides[] = { sizeof(Mesh::Vertex_POS), sizeof(Mesh::Vertex_TEX), - sizeof(InstBuf) + sizeof(Instance) }; UINT offsets[] = { mesh->hasDynamicVB() ? mesh->bufferOffset_POS : 0, @@ -4533,7 +4552,7 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle } HSTYPES realHS = GetHSTYPE(shaderType, material, tessellatorRequested); - if (prevHS = realHS) + if (prevHS != realHS) { prevHS = realHS; device->BindHS(hullShaders[realHS], threadID); @@ -6272,7 +6291,7 @@ void wiRenderer::CreateImpostor(Mesh* mesh) InstancePrev instancePrev; }; UINT instancesOffset; - InstBuf* buff = (InstBuf*)GetDevice()->AllocateFromRingBuffer(dynamicVertexBufferPool, sizeof(InstBuf), instancesOffset, threadID); + volatile InstBuf* buff = (volatile InstBuf*)GetDevice()->AllocateFromRingBuffer(dynamicVertexBufferPool, sizeof(InstBuf), instancesOffset, threadID); buff->instance.Create(__identity); buff->instancePrev.Create(__identity); GetDevice()->InvalidateBufferAccess(dynamicVertexBufferPool, threadID); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index bbb739803..b024f9e20 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 13; // minor bug fixes, alterations, refactors, updates - const int revision = 92; + const int revision = 93; long GetVersion()