Skip to content

Commit

Permalink
feat: #98 Add gpu read-write buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Jul 23, 2020
1 parent f55198c commit 5b0e345
Show file tree
Hide file tree
Showing 14 changed files with 335 additions and 15 deletions.
42 changes: 42 additions & 0 deletions Projects/Irrlicht/Include/IRWBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2020 Pham Hong Duc
// This file is part of the "Skylicht Engine"
// Upgrade GPU Compute Shader feature

#ifndef __IRR_IRW_BUFFER_H_INCLUDED__
#define __IRR_IRW_BUFFER_H_INCLUDED__

#include "IrrCompileConfig.h"

#include "IReferenceCounted.h"
#include "IImage.h"
#include "dimension2d.h"
#include "EDriverTypes.h"
#include "path.h"
#include "matrix4.h"

namespace irr
{
namespace video
{
class IRWBuffer : public virtual IReferenceCounted
{
public:
IRWBuffer(ECOLOR_FORMAT format, u32 numElements) :
DriverType(EDT_NULL),
Format(format),
NumElements(numElements)
{
}

E_DRIVER_TYPE getDriverType() const { return DriverType; };

protected:

E_DRIVER_TYPE DriverType;
ECOLOR_FORMAT Format;
u32 NumElements;
};
}
}

#endif
10 changes: 10 additions & 0 deletions Projects/Irrlicht/Include/IVideoDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "SExposedVideoData.h"

#include "IHardwareBuffer.h"
#include "IRWBuffer.h"

namespace irr
{
Expand Down Expand Up @@ -1108,6 +1109,15 @@ namespace video
const core::position2d<s32>& pos,
const core::dimension2d<u32>& size) =0;

//! Creates a buffer stored on gpu
/**
\param format pixel data.
\param number of pixels
\return The gpu buffer object.
If you no longer need the image, you should call IImage::drop().
See IReferenceCounted::drop() for more information. */
virtual IRWBuffer* createRWBuffer(video::ECOLOR_FORMAT format, u32 numElements) = 0;

//! Event handler for resize events. Only used by the engine internally.
/** Used to notify the driver that the window was resized.
Usually, there is no need to call this method. */
Expand Down
8 changes: 7 additions & 1 deletion Projects/Irrlicht/Source/CD3D11Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "CD3D11Texture.h"
#include "CD3D11HardwareBuffer.h"
#include "CD3D11VideoRT.h"

#include "CD3D11RWBuffer.h"

inline void unpack_texureBlendFunc(irr::video::E_BLEND_FACTOR &srcFact, irr::video::E_BLEND_FACTOR &dstFact,
irr::video::E_MODULATE_FUNC &modulo, irr::u32& alphaSource, const irr::f32 param)
Expand Down Expand Up @@ -1412,6 +1412,12 @@ namespace irr
return new CD3D11TextureCube(this, "TextureCube", imageX1, imageX2, imageY1, imageY2, imageZ1, imageZ2);
}

//! creates a buffer stored on gpu
IRWBuffer* CD3D11Driver::createRWBuffer(video::ECOLOR_FORMAT format, u32 numElements)
{
return new CD3D11RWBuffer(this, format, numElements);
}

void CD3D11Driver::setViewPort(const core::rect<s32>& area)
{
core::dimension2du size = getCurrentRenderTargetSize();
Expand Down
4 changes: 4 additions & 0 deletions Projects/Irrlicht/Source/CD3D11Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace video
friend class CD3D11TextureCube;
friend class CD3D11TextureArray;
friend class CD3D11VideoRT;
friend class CD3D11RWBuffer;

//! constructor
CD3D11Driver(const irr::SIrrlichtCreationParameters& params,
Expand Down Expand Up @@ -220,6 +221,9 @@ namespace video

virtual ITexture* getTextureArray(IImage** images, u32 num);

//! creates a buffer stored on gpu
virtual IRWBuffer* createRWBuffer(video::ECOLOR_FORMAT format, u32 numElements);

//! Clears the ZBuffer.
virtual void clearZBuffer();

Expand Down
73 changes: 73 additions & 0 deletions Projects/Irrlicht/Source/CD3D11RWBuffer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (C) 2020 Pham Hong Duc
// This file is part of the "Skylicht Engine"
// Upgrade GPU Compute Shader feature

#include "pch.h"
#include "IrrCompileConfig.h"
#include "CD3D11Driver.h"
#include "CD3D11RWBuffer.h"

#ifdef _IRR_COMPILE_WITH_DIRECT3D_11_

#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE

#include "irrOS.h"

namespace irr
{
namespace video
{
CD3D11RWBuffer::CD3D11RWBuffer(CD3D11Driver *driver, ECOLOR_FORMAT format, u32 numElements) :
IRWBuffer(format, numElements),
Driver(driver)
{
DriverType = EDT_DIRECT3D11;

D3DFormat = Driver->getD3DFormatFromColorFormat(format);
u32 bytePerPixel = Driver->getBitsPerPixel(D3DFormat) / 8;

Device = driver->getExposedVideoData().D3D11.D3DDev11;
if (Device)
{
Device->AddRef();
Device->GetImmediateContext(&Context);
}

D3D11_BUFFER_DESC bufferDesc;
bufferDesc.ByteWidth = bytePerPixel * numElements;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
Device->CreateBuffer(&bufferDesc, NULL, &Buffer);

D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = D3DFormat;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvDesc.Buffer.ElementOffset = 0;
srvDesc.Buffer.ElementWidth = numElements;
Device->CreateShaderResourceView(Buffer, &srvDesc, &SRView);

D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = D3DFormat;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = 0;
uavDesc.Buffer.NumElements = numElements;
Device->CreateUnorderedAccessView(Buffer, &uavDesc, &UAView);
}

CD3D11RWBuffer::~CD3D11RWBuffer()
{
SRView->Release();
UAView->Release();
Buffer->Release();

Context->Release();
Device->Release();
}
}
}

#endif
46 changes: 46 additions & 0 deletions Projects/Irrlicht/Source/CD3D11RWBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (C) 2020 Pham Hong Duc
// This file is part of the "Skylicht Engine"
// Upgrade GPU Compute Shader feature

#ifndef __C_DIRECTX11_RWBUFFER_H_INCLUDED__
#define __C_DIRECTX11_RWBUFFER_H_INCLUDED__

#include "IrrCompileConfig.h"

#ifdef _IRR_WINDOWS_
#ifdef _IRR_COMPILE_WITH_DIRECT3D_11_

#include "IRWBuffer.h"

namespace irr
{
namespace video
{
class CD3D11Driver;

class CD3D11RWBuffer : public IRWBuffer
{
public:
CD3D11RWBuffer(CD3D11Driver *driver, ECOLOR_FORMAT format, u32 numElements);

~CD3D11RWBuffer();

protected:

CD3D11Driver *Driver;

ID3D11Device* Device;
ID3D11DeviceContext* Context;

ID3D11Buffer* Buffer;
ID3D11ShaderResourceView* SRView;
ID3D11UnorderedAccessView* UAView;

DXGI_FORMAT D3DFormat;
};
}
}

#endif
#endif
#endif
7 changes: 4 additions & 3 deletions Projects/Irrlicht/Source/CNullDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,6 @@ void CNullDriver::addTexture(video::ITexture* texture)
}
}


//! looks if the image is already loaded
video::ITexture* CNullDriver::findTexture(const io::path& filename)
{
Expand Down Expand Up @@ -842,7 +841,10 @@ ITexture* CNullDriver::addTexture(const core::dimension2d<u32>& size,
return t;
}


IRWBuffer* CNullDriver::createRWBuffer(video::ECOLOR_FORMAT format, u32 numElements)
{
return NULL;
}

//! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
Expand Down Expand Up @@ -2677,7 +2679,6 @@ bool CNullDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enab
return false;
}


//! Enable/disable a clipping plane.
void CNullDriver::enableClipPlane(u32 index, bool enable)
{
Expand Down
4 changes: 4 additions & 0 deletions Projects/Irrlicht/Source/CNullDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ namespace video
bool clearZBuffer,
SColor color) _IRR_OVERRIDE_;

//! creates a buffer stored on gpu
virtual IRWBuffer* createRWBuffer(video::ECOLOR_FORMAT format, u32 numElements) _IRR_OVERRIDE_;

//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;

Expand Down Expand Up @@ -660,6 +663,7 @@ namespace video

core::array<SSurface> Textures;
core::array<IVideoRenderTarget*> VRTs;
core::array<IRWBuffer*> RWBuffers;

struct SOccQuery
{
Expand Down
51 changes: 51 additions & 0 deletions Projects/Skylicht/Lightmapper/Source/Lightmapper/CGPUBaker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
!@
MIT License
Copyright (c) 2020 Skylicht Technology CO., LTD
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This file is part of the "Skylicht Engine".
https://github.com/skylicht-lab/skylicht-engine
!#
*/

#include "pch.h"
#include "CGPUBaker.h"

namespace Skylicht
{
namespace Lightmapper
{
CGPUBaker::CGPUBaker()
{
m_shBuffer = getVideoDriver()->createRWBuffer(video::ECF_A32B32G32R32F, MAX_NUM_THREAD * 9);
}

CGPUBaker::~CGPUBaker()
{
if (m_shBuffer != NULL)
m_shBuffer->drop();
}

bool CGPUBaker::canUseGPUBaker()
{
if (getVideoDriver()->getDriverType() == video::EDT_DIRECT3D11 && m_shBuffer != NULL)
return true;

return false;
}
}
}
51 changes: 51 additions & 0 deletions Projects/Skylicht/Lightmapper/Source/Lightmapper/CGPUBaker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
!@
MIT License
Copyright (c) 2020 Skylicht Technology CO., LTD
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This file is part of the "Skylicht Engine".
https://github.com/skylicht-lab/skylicht-engine
!#
*/

#pragma once

#include "CSH9.h"
#include "Camera/CCamera.h"
#include "RenderPipeline/IRenderPipeline.h"
#include "Entity/CEntityManager.h"

#include "CMTBaker.h"

namespace Skylicht
{
namespace Lightmapper
{
class CGPUBaker : public CMTBaker
{
protected:
IRWBuffer *m_shBuffer;

public:
CGPUBaker();

virtual ~CGPUBaker();

bool canUseGPUBaker();
};
}
}
Loading

0 comments on commit 5b0e345

Please sign in to comment.