mirror of https://github.com/axmolengine/axmol.git
208 lines
4.9 KiB
C++
208 lines
4.9 KiB
C++
#include "EffekseerMaterialCompilerDX12.h"
|
|
#include <iostream>
|
|
|
|
#include "../3rdParty/LLGI/src/DX12/LLGI.CompilerDX12.h"
|
|
#include "../HLSLGenerator/ShaderGenerator.h"
|
|
|
|
#pragma comment(lib, "d3dcompiler.lib")
|
|
|
|
namespace Effekseer
|
|
{
|
|
|
|
static void Serialize(std::vector<uint8_t>& dst, const LLGI::CompilerResult& result)
|
|
{
|
|
|
|
uint32_t binarySize = 0;
|
|
|
|
binarySize += sizeof(uint32_t);
|
|
|
|
for (size_t i = 0; i < result.Binary.size(); i++)
|
|
{
|
|
binarySize += sizeof(uint32_t);
|
|
binarySize += (uint32_t)result.Binary[i].size();
|
|
}
|
|
|
|
dst.resize(binarySize);
|
|
|
|
uint32_t offset = 0;
|
|
uint32_t count = (uint32_t)result.Binary.size();
|
|
|
|
memcpy(dst.data() + offset, &count, sizeof(uint32_t));
|
|
offset += (uint32_t)sizeof(int32_t);
|
|
|
|
for (size_t i = 0; i < result.Binary.size(); i++)
|
|
{
|
|
uint32_t size = (uint32_t)result.Binary[i].size();
|
|
|
|
memcpy(dst.data() + offset, &size, sizeof(uint32_t));
|
|
offset += sizeof(int32_t);
|
|
|
|
memcpy(dst.data() + offset, result.Binary[i].data(), result.Binary[i].size());
|
|
offset += (uint32_t)result.Binary[i].size();
|
|
}
|
|
}
|
|
|
|
namespace DX12
|
|
{
|
|
|
|
} // namespace DX12
|
|
|
|
} // namespace Effekseer
|
|
|
|
namespace Effekseer
|
|
{
|
|
|
|
static const int32_t DX12_InstanceCount = 40;
|
|
|
|
class CompiledMaterialBinaryDX12 : public CompiledMaterialBinary, public ReferenceObject
|
|
{
|
|
private:
|
|
std::array<std::vector<uint8_t>, static_cast<int32_t>(MaterialShaderType::Max)> vertexShaders_;
|
|
|
|
std::array<std::vector<uint8_t>, static_cast<int32_t>(MaterialShaderType::Max)> pixelShaders_;
|
|
|
|
public:
|
|
CompiledMaterialBinaryDX12()
|
|
{
|
|
}
|
|
|
|
virtual ~CompiledMaterialBinaryDX12()
|
|
{
|
|
}
|
|
|
|
void SetVertexShaderData(MaterialShaderType type, const std::vector<uint8_t>& data)
|
|
{
|
|
vertexShaders_.at(static_cast<int>(type)) = data;
|
|
}
|
|
|
|
void SetPixelShaderData(MaterialShaderType type, const std::vector<uint8_t>& data)
|
|
{
|
|
pixelShaders_.at(static_cast<int>(type)) = data;
|
|
}
|
|
|
|
const uint8_t* GetVertexShaderData(MaterialShaderType type) const override
|
|
{
|
|
return vertexShaders_.at(static_cast<int>(type)).data();
|
|
}
|
|
|
|
int32_t GetVertexShaderSize(MaterialShaderType type) const override
|
|
{
|
|
return (int32_t)vertexShaders_.at(static_cast<int>(type)).size();
|
|
}
|
|
|
|
const uint8_t* GetPixelShaderData(MaterialShaderType type) const override
|
|
{
|
|
return pixelShaders_.at(static_cast<int>(type)).data();
|
|
}
|
|
|
|
int32_t GetPixelShaderSize(MaterialShaderType type) const override
|
|
{
|
|
return (int32_t)pixelShaders_.at(static_cast<int>(type)).size();
|
|
}
|
|
|
|
int AddRef() override
|
|
{
|
|
return ReferenceObject::AddRef();
|
|
}
|
|
|
|
int Release() override
|
|
{
|
|
return ReferenceObject::Release();
|
|
}
|
|
|
|
int GetRef() override
|
|
{
|
|
return ReferenceObject::GetRef();
|
|
}
|
|
};
|
|
|
|
CompiledMaterialBinary* MaterialCompilerDX12::Compile(MaterialFile* materialFile, int32_t maximumUniformCount, int32_t maximumTextureCount)
|
|
{
|
|
auto compiler = LLGI::CreateSharedPtr(new LLGI::CompilerDX12());
|
|
|
|
auto binary = new CompiledMaterialBinaryDX12();
|
|
|
|
auto convertToVectorVS = [compiler](const std::string& str) -> std::vector<uint8_t> {
|
|
std::vector<uint8_t> ret;
|
|
|
|
LLGI::CompilerResult result;
|
|
compiler->Compile(result, str.c_str(), LLGI::ShaderStageType::Vertex);
|
|
|
|
if (result.Binary.size() > 0)
|
|
{
|
|
Serialize(ret, result);
|
|
}
|
|
else
|
|
{
|
|
std::cout << "VertexShader Compile Error" << std::endl;
|
|
std::cout << str << std::endl;
|
|
std::cout << result.Message << std::endl;
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
auto convertToVectorPS = [compiler](const std::string& str) -> std::vector<uint8_t> {
|
|
std::vector<uint8_t> ret;
|
|
|
|
LLGI::CompilerResult result;
|
|
compiler->Compile(result, str.c_str(), LLGI::ShaderStageType::Pixel);
|
|
|
|
if (result.Binary.size() > 0)
|
|
{
|
|
Serialize(ret, result);
|
|
}
|
|
else
|
|
{
|
|
std::cout << "PixelShader Compile Error" << std::endl;
|
|
std::cout << str << std::endl;
|
|
std::cout << result.Message << std::endl;
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
auto saveBinary = [&materialFile, &binary, &convertToVectorVS, &convertToVectorPS, &maximumUniformCount, &maximumTextureCount](MaterialShaderType type) {
|
|
auto generator = DirectX::ShaderGenerator(DirectX::ShaderGeneratorTarget::DirectX12);
|
|
|
|
auto shader = generator.GenerateShader(materialFile, type, maximumUniformCount, maximumTextureCount, 0, DX12_InstanceCount);
|
|
binary->SetVertexShaderData(type, convertToVectorVS(shader.CodeVS));
|
|
binary->SetPixelShaderData(type, convertToVectorPS(shader.CodePS));
|
|
};
|
|
|
|
if (materialFile->GetHasRefraction())
|
|
{
|
|
saveBinary(MaterialShaderType::Refraction);
|
|
saveBinary(MaterialShaderType::RefractionModel);
|
|
}
|
|
|
|
saveBinary(MaterialShaderType::Standard);
|
|
saveBinary(MaterialShaderType::Model);
|
|
|
|
return binary;
|
|
}
|
|
|
|
CompiledMaterialBinary* MaterialCompilerDX12::Compile(MaterialFile* materialFile)
|
|
{
|
|
return Compile(materialFile, Effekseer::UserUniformSlotMax, Effekseer::UserTextureSlotMax);
|
|
}
|
|
|
|
} // namespace Effekseer
|
|
|
|
#ifdef __SHARED_OBJECT__
|
|
|
|
extern "C"
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
#define EFK_EXPORT __declspec(dllexport)
|
|
#else
|
|
#define EFK_EXPORT
|
|
#endif
|
|
|
|
EFK_EXPORT Effekseer::MaterialCompiler* EFK_STDCALL CreateCompiler()
|
|
{
|
|
return new Effekseer::MaterialCompilerDX12();
|
|
}
|
|
}
|
|
#endif |