Explorar o código

fix problems with dx11 multithreading

Kolja Strohm hai 1 semana
pai
achega
40f483950b
Modificáronse 5 ficheiros con 89 adicións e 9 borrados
  1. 34 2
      DX11GraphicsApi.cpp
  2. 4 0
      DXBuffer.cpp
  3. 1 1
      GraphicsApi.h
  4. 22 3
      Shader.cpp
  5. 28 3
      Texture.cpp

+ 34 - 2
DX11GraphicsApi.cpp

@@ -305,7 +305,9 @@ void DirectX11::initialize(
     vp->Height = (float)this->backBufferSize.y;
     vp->MinDepth = 0.0f;
     vp->MaxDepth = 1.0f;
+    deviceLock.lock();
     d3d11Context->RSSetViewports(1, vp);
+    deviceLock.unlock();
 
     // Create the render target view with the back buffer pointer.
     deviceLock.lock();
@@ -388,7 +390,9 @@ void DirectX11::initialize(
             MB_ICONERROR);
         return;
     }
+    deviceLock.lock();
     d3d11Context->OMSetDepthStencilState(depthStencilState, 1);
+    deviceLock.unlock();
 
     // Initialize the depth stencil view.
     D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
@@ -414,7 +418,9 @@ void DirectX11::initialize(
             MB_ICONERROR);
         return;
     }
+    deviceLock.lock();
     d3d11Context->OMSetRenderTargets(1, &rtview, dsView);
+    deviceLock.unlock();
 
     D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;
     // Clear the second depth stencil state before setting the parameters.
@@ -523,13 +529,15 @@ void DirectX11::initialize(
 
     deviceLock.lock();
     d3d11Device->CreateBlendState(&blendState, &blendStateAlphaBlend);
-    deviceLock.unlock();
     d3d11Context->OMSetBlendState(blendStateAlphaBlend, 0, 0xFFFFFFFF);
+    deviceLock.unlock();
 
     // Setup Render Objekt
 
     vertexShader->useShader();
+    deviceLock.lock();
     d3d11Context->PSSetSamplers(0, 1, &sampleState);
+    deviceLock.unlock();
     pixelShader->useShader();
 
     D3D11_RASTERIZER_DESC rasterDesc;
@@ -559,9 +567,9 @@ void DirectX11::initialize(
     rasterDesc.SlopeScaledDepthBias = 0.0f;
     deviceLock.lock();
     d3d11Device->CreateRasterizerState(&rasterDesc, &meshRS);
-    deviceLock.unlock();
 
     d3d11Context->RSSetState(texturRS);
+    deviceLock.unlock();
 
     Image* b = new Image();
     b->newImage(10, 10, 0xFFFFFFFF);
@@ -680,8 +688,11 @@ void DirectX11::beginFrame(bool fill2D, bool fill3D, int fillColor)
         color[1] = ((fillColor >> 8) & 0xFF) / 255.f;  // G
         color[2] = (fillColor & 0xFF) / 255.f;         // B
         color[3] = ((fillColor >> 24) & 0xFF) / 255.f; // A
+        deviceLock.lock();
         d3d11Context->ClearRenderTargetView(rtview, color);
+        deviceLock.unlock();
     }
+    deviceLock.lock();
     // Bind the render target view and depth stencil buffer to the output render
     // pipeline.
     d3d11Context->OMSetRenderTargets(1, &rtview, dsView);
@@ -690,6 +701,7 @@ void DirectX11::beginFrame(bool fill2D, bool fill3D, int fillColor)
         dsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
     // Set the depth stencil state.
     d3d11Context->OMSetDepthStencilState(depthStencilState, 1);
+    deviceLock.unlock();
 }
 
 void DirectX11::renderObject(Model3D* zObj)
@@ -714,7 +726,9 @@ void DirectX11::renderObject(Model3D* zObj)
         = (unsigned)zObj->zModelData()->zDXVertexBuffer()->getElementLength();
     ID3D11Buffer* vBuffer
         = ((DX11Buffer*)zObj->zModelData()->zDXVertexBuffer())->zBuffer();
+    deviceLock.lock();
     d3d11Context->IASetVertexBuffers(0, 1, &vBuffer, &es, &offset);
+    deviceLock.unlock();
     Model3DTexture* zTexture = zObj->zTexture();
     int ind = 0;
     int current = 0;
@@ -725,7 +739,9 @@ void DirectX11::renderObject(Model3D* zObj)
         if (zEffectTexture && zEffectTexture->needsUpdate())
             zEffectTexture->updateTextur();
         v[0] = *zEffectTexture;
+        deviceLock.lock();
         d3d11Context->PSSetShaderResources(3, 1, v);
+        deviceLock.unlock();
         TextureEffect e = {1, zObj->getEffectPercentage()};
         if (pixelShader)
             pixelShader->fillConstBuffer((char*)&e, 3, sizeof(TextureEffect));
@@ -741,9 +757,11 @@ void DirectX11::renderObject(Model3D* zObj)
         f = DXGI_FORMAT_R16_UINT;
     if (zObj->zModelData()->zDXIndexBuffer()->getElementLength() == 1)
         f = DXGI_FORMAT_R8_UINT;
+    deviceLock.lock();
     d3d11Context->IASetIndexBuffer(
         ((DX11Buffer*)zObj->zModelData()->zDXIndexBuffer())->zBuffer(), f, 0);
     d3d11Context->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+    deviceLock.unlock();
     zObj->beforeRender(this, vertexShader, pixelShader);
     for (auto i = zObj->zModelData()->getPolygons(); i; ++i)
     {
@@ -757,11 +775,14 @@ void DirectX11::renderObject(Model3D* zObj)
                 v[0] = *(DX11Texture*)t;
                 v[1] = *diffuseLights;
                 v[2] = *pointLights;
+                deviceLock.lock();
                 d3d11Context->PSSetShaderResources(0, 3, v);
                 d3d11Context->DrawIndexed(i->indexAnz, current, 0);
+                deviceLock.unlock();
             }
             else
             {
+                deviceLock.lock();
                 d3d11Context->RSSetState(meshRS);
                 ID3D11ShaderResourceView* v[3];
                 v[0] = *(DX11Texture*)defaultTexture;
@@ -770,6 +791,7 @@ void DirectX11::renderObject(Model3D* zObj)
                 d3d11Context->PSSetShaderResources(0, 3, v);
                 d3d11Context->DrawIndexed(i->indexAnz, current, 0);
                 d3d11Context->RSSetState(texturRS);
+                deviceLock.unlock();
             }
         }
         ind++;
@@ -810,7 +832,9 @@ bool DirectX11::isInFrustrum(
 
 void DirectX11::renderKamera(Cam3D* zKamera)
 {
+    deviceLock.lock();
     d3d11Context->RSSetViewports(1, (D3D11_VIEWPORT*)zKamera->zViewPort());
+    deviceLock.unlock();
 
     Mat4<float> tmp = zKamera->getProjectionMatrix() * zKamera->getViewMatrix();
 
@@ -962,16 +986,20 @@ void DirectX11::renderKamera(Cam3D* zKamera, Texture* zTarget)
     deviceLock.unlock();
     if (result != S_OK)
         throw "could not create render target view for given texture";
+    deviceLock.lock();
     d3d11Context->OMSetRenderTargets(1, &texturRtView, txtDsView);
 
     float color[4] = {0, 0, 0, 0};
     d3d11Context->ClearRenderTargetView(texturRtView, color);
     d3d11Context->ClearDepthStencilView(
         txtDsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
+    deviceLock.unlock();
     renderKamera(zKamera);
     result = d3d11SpawChain->Present(0, 0);
     if (result != S_OK) throw "could not present the rendered content";
+    deviceLock.lock();
     d3d11Context->OMSetRenderTargets(1, &rtview, dsView);
+    deviceLock.unlock();
     texturRtView->Release();
     txtDsView->Release();
     txtDepthStencilBuffer->Release();
@@ -980,11 +1008,15 @@ void DirectX11::renderKamera(Cam3D* zKamera, Texture* zTarget)
 void DirectX11::presentFrame()
 {
     // Set the depth stencil state.
+    deviceLock.lock();
     d3d11Context->OMSetDepthStencilState(depthDisabledStencilState, 1);
+    deviceLock.unlock();
 
     uiTexture->updateTextur();
 
+    deviceLock.lock();
     d3d11Context->RSSetViewports(1, vp);
+    deviceLock.unlock();
 
     float screenAspect = (float)backBufferSize.x / (float)backBufferSize.y;
     Mat4<float> view

+ 4 - 0
DXBuffer.cpp

@@ -117,15 +117,19 @@ void DX11Buffer::copyToGPU(int byteCount)
     {
         HRESULT res;
         D3D11_MAPPED_SUBRESOURCE map;
+        deviceLock.lock();
         if ((description->Usage | D3D11_USAGE_DYNAMIC) == description->Usage)
             res = context->Map(
                 buffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &map);
         else
             res = context->Map(buffer, 0, D3D11_MAP::D3D11_MAP_WRITE, 0, &map);
+        deviceLock.unlock();
         if (res == S_OK)
         {
             memcpy(map.pData, data, byteCount);
+            deviceLock.lock();
             context->Unmap(buffer, 0);
+            deviceLock.unlock();
             changed = 0;
         }
         else

+ 1 - 1
GraphicsApi.h

@@ -170,7 +170,6 @@ namespace Framework
     {
     private:
         ID3D11Device* d3d11Device;
-        Critical deviceLock;
         ID3D11DeviceContext* d3d11Context;
         IDXGISwapChain* d3d11SpawChain;
         Texture* uiTexture;
@@ -200,6 +199,7 @@ namespace Framework
         DLLEXPORT virtual DXBuffer* createVertexBuffer() override;
 
     protected:
+        Critical deviceLock;
         ID3D11RasterizerState* texturRS;
         ID3D11RasterizerState* meshRS;
         DLLEXPORT virtual DX11VertexShader* initializeVertexShader(

+ 22 - 3
Shader.cpp

@@ -154,9 +154,16 @@ void DX11PixelShader::useShader()
         if (!((DX11Buffer*)constBuffers->z(i))->zBuffer())
             constBuffers->z(i)->copyToGPU();
         ID3D11Buffer* buf = ((DX11Buffer*)constBuffers->z(i))->zBuffer();
+        deviceLock.lock();
         context->PSSetConstantBuffers(i, 1, &buf);
+        deviceLock.unlock();
+    }
+    if (pixelShader)
+    {
+        deviceLock.lock();
+        context->PSSetShader(pixelShader, 0, 0);
+        deviceLock.unlock();
     }
-    if (pixelShader) context->PSSetShader(pixelShader, 0, 0);
 }
 
 // Contents of the VertexShader class
@@ -228,8 +235,20 @@ void DX11VertexShader::useShader()
         if (!((DX11Buffer*)constBuffers->z(i))->zBuffer())
             constBuffers->z(i)->copyToGPU();
         ID3D11Buffer* buf = ((DX11Buffer*)constBuffers->z(i))->zBuffer();
+        deviceLock.lock();
         context->VSSetConstantBuffers(i, 1, &buf);
+        deviceLock.unlock();
+    }
+    if (inputLayout)
+    {
+        deviceLock.lock();
+        context->IASetInputLayout(inputLayout);
+        deviceLock.unlock();
+    }
+    if (vertexShader)
+    {
+        deviceLock.lock();
+        context->VSSetShader(vertexShader, 0, 0);
+        deviceLock.unlock();
     }
-    if (inputLayout) context->IASetInputLayout(inputLayout);
-    if (vertexShader) context->VSSetShader(vertexShader, 0, 0);
 }

+ 28 - 3
Texture.cpp

@@ -140,26 +140,32 @@ bool DX11Texture::updateTextur()
         changed = 0;
         if (useMips)
         {
+            deviceLock.lock();
             context->UpdateSubresource(txt,
                 0,
                 0,
                 bild->getBuffer(),
                 4 * bild->getWidth(),
                 4 * bild->getWidth() * bild->getHeight());
+            deviceLock.unlock();
         }
         else
         {
             D3D11_MAPPED_SUBRESOURCE buffer;
+            deviceLock.lock();
             context->Map(
                 txt, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &buffer);
             int* bgBuff = bild->getBuffer();
             int tmpBr = 4 * bild->getWidth();
             for (int y = 0, pitch = 0, bry = 0; y < bild->getHeight();
                 ++y, pitch += buffer.RowPitch, bry += bild->getWidth())
+            {
                 memcpy(&((BYTE*)buffer.pData)[pitch],
                     (void*)&(bgBuff[bry]),
                     tmpBr);
+            }
             context->Unmap(txt, 0);
+            deviceLock.unlock();
         }
     }
     if (!view || lastGr != bild->getSize())
@@ -175,7 +181,12 @@ bool DX11Texture::updateTextur()
         HRESULT r = device->CreateShaderResourceView(txt, &resourceDesk, &view);
         deviceLock.unlock();
         if (r != S_OK) return 0;
-        if (context && useMips) context->GenerateMips(view);
+        if (context && useMips)
+        {
+            deviceLock.lock();
+            context->GenerateMips(view);
+            deviceLock.unlock();
+        }
     }
     lastGr = bild->getSize();
 #endif
@@ -232,22 +243,36 @@ void DX11Texture::copyToImage(Image* zB)
     deviceLock.lock();
     HRESULT r = device->CreateTexture2D(&tempBufferDesc, 0, &tmpTxt);
     deviceLock.unlock();
-    if (r != S_OK) throw "could not create resource copy with cpu read access";
+    if (r != S_OK)
+    {
+        throw "could not create resource copy with cpu read access";
+    }
+    deviceLock.lock();
     context->CopyResource(tmpTxt, txt);
+    deviceLock.unlock();
     zB->newImage(bild->getWidth(), bild->getHeight(), 0);
     D3D11_MAPPED_SUBRESOURCE buffer;
+    deviceLock.lock();
     r = context->Map(tmpTxt, 0, D3D11_MAP::D3D11_MAP_READ, 0, &buffer);
-    if (r != S_OK) throw "could not access recource copy";
+    deviceLock.unlock();
+    if (r != S_OK)
+    {
+        throw "could not access recource copy";
+    }
     int* bgBuff = zB->getBuffer();
     int tmpBr = 4 * zB->getWidth();
     for (int y = 0, pitch = 0, bry = 0; y < zB->getHeight();
         ++y, pitch += buffer.RowPitch, bry += zB->getWidth())
+    {
         memcpy((void*)&(bgBuff[bry]), &((BYTE*)buffer.pData)[pitch], tmpBr);
+    }
     for (int i = 0; i < zB->getWidth() * zB->getHeight(); i++)
     {
         if (bgBuff[i]) bgBuff[i] |= 0xFF000000;
     }
+    deviceLock.lock();
     context->Unmap(tmpTxt, 0);
+    deviceLock.unlock();
     tmpTxt->Release();
 #endif
 }