Beispiel #1
0
	static ID3DBlobPtr CompileShader(const char* shaderCode, size_t shaderLength, const char* shaderProfile) {
		ID3DBlobPtr blob = nullptr;
		ID3DBlobPtr errors = nullptr;
		HRESULT hr = D3DCompile(shaderCode, shaderLength, nullptr, nullptr, nullptr, "Main", shaderProfile, 0, 0, &blob, &errors);

		if (FAILED(hr)) {

			if (errors) {
				OutputDebugStringA((char*)errors->GetBufferPointer());
				errors->Release();
			}

			return nullptr;
		}

		return blob;
	}
void CreateRootSignature(ID3D12RootSignature** rootSignature, const D3D12_ROOT_SIGNATURE_DESC1& desc)
{
    D3D12_VERSIONED_ROOT_SIGNATURE_DESC versionedDesc = { };
    versionedDesc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1;
    versionedDesc.Desc_1_1 = desc;

    ID3DBlobPtr signature;
    ID3DBlobPtr error;
    HRESULT hr = D3D12SerializeVersionedRootSignature(&versionedDesc, &signature, &error);
    if(FAILED(hr))
    {
        const char* errString = error ? reinterpret_cast<const char*>(error->GetBufferPointer()) : "";

        #if UseAsserts_
            AssertMsg_(false, "Failed to create root signature: %s", errString);
        #else
            throw DXException(hr, MakeString(L"Failed to create root signature: %s", errString).c_str());
        #endif
    }

    DXCall(DX12::Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(rootSignature)));
}
Beispiel #3
0
static ID3DBlob* CompileShader(const wchar* path, const char* functionName, const char* profile,
                              const D3D_SHADER_MACRO* defines, bool forceOptimization,
                              vector<wstring>& filePaths)
{
    // Make a hash off the expanded shader code
    string shaderCode = GetExpandedShaderCode(path, filePaths);
    wstring cacheName = MakeShaderCacheName(shaderCode, functionName, profile, defines);

    if(FileExists(cacheName.c_str()))
    {
        File cacheFile(cacheName.c_str(), File::OpenRead);

        const uint64 shaderSize = cacheFile.Size();
        vector<uint8> compressedShader;
        compressedShader.resize(shaderSize);
        cacheFile.Read(shaderSize, compressedShader.data());

        ID3DBlob* decompressedShader[1] = { nullptr };
        uint32 indices[1] = { 0 };
        DXCall(D3DDecompressShaders(compressedShader.data(), shaderSize, 1, 0,
                                    indices, 0, decompressedShader, nullptr));

        return decompressedShader[0];
    }

    std::printf("Compiling shader %s %s %s\n", WStringToAnsi(GetFileName(path).c_str()).c_str(),
                profile, MakeDefinesString(defines).c_str());

    // Loop until we succeed, or an exception is thrown
    while(true)
    {
        UINT flags = D3DCOMPILE_WARNINGS_ARE_ERRORS;
        #ifdef _DEBUG
            flags |= D3DCOMPILE_DEBUG;
            if(forceOptimization == false)
                flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
        #endif

        ID3DBlob* compiledShader;
        ID3DBlobPtr errorMessages;
        HRESULT hr = D3DCompileFromFile(path, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, functionName,
                                        profile, flags, 0, &compiledShader, &errorMessages);

        if(FAILED(hr))
        {
            if(errorMessages)
            {
                wchar message[1024] = { 0 };
                char* blobdata = reinterpret_cast<char*>(errorMessages->GetBufferPointer());

                MultiByteToWideChar(CP_ACP, 0, blobdata, static_cast<int>(errorMessages->GetBufferSize()), message, 1024);
                std::wstring fullMessage = L"Error compiling shader file \"";
                fullMessage += path;
                fullMessage += L"\" - ";
                fullMessage += message;

                // Pop up a message box allowing user to retry compilation
                int retVal = MessageBoxW(nullptr, fullMessage.c_str(), L"Shader Compilation Error", MB_RETRYCANCEL);
                if(retVal != IDRETRY)
                    throw DXException(hr, fullMessage.c_str());

                #if EnableShaderCaching_
                    shaderCode = GetExpandedShaderCode(path);
                    cacheName = MakeShaderCacheName(shaderCode, functionName, profile, defines);
                #endif
            }
            else
            {
                _ASSERT(false);
                throw DXException(hr);
            }
        }
        else
        {
            // Compress the shader
            D3D_SHADER_DATA shaderData;
            shaderData.pBytecode = compiledShader->GetBufferPointer();
            shaderData.BytecodeLength = compiledShader->GetBufferSize();
            ID3DBlobPtr compressedShader;
            DXCall(D3DCompressShaders(1, &shaderData, D3D_COMPRESS_SHADER_KEEP_ALL_PARTS, &compressedShader));

            // Create the cache directory if it doesn't exist
            if(DirectoryExists(baseCacheDir.c_str()) == false)
                Win32Call(CreateDirectory(baseCacheDir.c_str(), nullptr));

            if(DirectoryExists(cacheDir.c_str()) == false)
                Win32Call(CreateDirectory(cacheDir.c_str(), nullptr));

            File cacheFile(cacheName.c_str(), File::OpenWrite);

            // Write the compiled shader to disk
            uint64 shaderSize = compressedShader->GetBufferSize();
            cacheFile.Write(shaderSize, compressedShader->GetBufferPointer());

            return compiledShader;
        }
    }
}
Beispiel #4
0
// code->bytecode
bool CompileShader(
	ShaderType type,
	const std::string& code,
	D3DBlob& blob,
	const D3D_SHADER_MACRO* pDefines,
	const char* pEntry, bool throwerror)
{
#if defined(_DEBUG) || defined(DEBUGFAST)
	UINT flags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#else
	UINT flags = D3DCOMPILE_SKIP_VALIDATION;
	if (type != DX11::D3D::ShaderType::Hull)
	{
		flags |= D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY | D3DCOMPILE_OPTIMIZATION_LEVEL3;
	}
	else
	{
		flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
	}
#endif
	
	char const *profile = nullptr;
	char const *sufix = nullptr;
	switch (type) {
	case DX11::D3D::ShaderType::Vertex:
		profile = D3D::VertexShaderVersionString();
		sufix = "vs";
		break;
	case DX11::D3D::ShaderType::Pixel:
		profile = D3D::PixelShaderVersionString();
		sufix = "ps";
		break;
	case DX11::D3D::ShaderType::Geometry:
		profile = D3D::GeometryShaderVersionString();
		sufix = "gs";
		break;
	case DX11::D3D::ShaderType::Hull:
		profile = D3D::HullShaderVersionString();
		sufix = "hs";
		break;
	case DX11::D3D::ShaderType::Domain:
		profile = D3D::DomainShaderVersionString();
		sufix = "ds";
		break;
	case DX11::D3D::ShaderType::Compute:
		profile = D3D::ComputeShaderVersionString();
		sufix = "cs";
		break;
	default:
		return false;
		break;
	}



	ID3DBlobPtr shaderBuffer;
	ID3DBlobPtr errorBuffer;
	HRESULT hr = HLSLCompiler::getInstance().CompileShader(code.c_str(),
		code.length(), nullptr, pDefines, nullptr, pEntry != nullptr ? pEntry : "main", profile,
		flags, 0, ToAddr(shaderBuffer), ToAddr(errorBuffer));

	if (errorBuffer)
	{
		INFO_LOG(VIDEO, "Shader compiler messages:\n%s",
			(const char*)errorBuffer->GetBufferPointer());
	}

	if (FAILED(hr))
	{
		static int num_failures = 0;
		std::string filename = StringFromFormat("%sbad_%s_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), sufix, num_failures++);
		std::ofstream file;
		OpenFStream(file, filename, std::ios_base::out);
		file << code;
		file << "\n";
		file << (const char*)errorBuffer->GetBufferPointer();
		file.close();
		if (throwerror)
		{
			PanicAlert("Failed to compile shader: %s\nDebug info (%s):\n%s",
				filename.c_str(),
				profile,
				(char*)errorBuffer->GetBufferPointer());
		}
		blob = nullptr;
	}
	else
	{
		blob = std::move(shaderBuffer);
	}

	return SUCCEEDED(hr);
}
static ID3DBlob* CompileShader(const wchar* path, const char* functionName, ShaderType type, ShaderProfile profile,
                              const D3D_SHADER_MACRO* defines, bool forceOptimization, GrowableList<wstring>& filePaths)
{
    if(FileExists(path) == false)
    {
        Assert_(false);
        throw Exception(L"Shader file " + std::wstring(path) + L" does not exist");
    }

    uint64 profileIdx = uint64(profile) * uint64(ShaderType::NumTypes) + uint64(type);
    Assert_(profileIdx < TotalNumProfiles);
    const char* profileString = ProfileStrings[profileIdx];

    // Make a hash off the expanded shader code
    string shaderCode = GetExpandedShaderCode(path, filePaths);
    wstring cacheName = MakeShaderCacheName(shaderCode, functionName, profileString, defines);

    if(FileExists(cacheName.c_str()))
    {
        File cacheFile(cacheName.c_str(), FileOpenMode::Read);

        const uint64 shaderSize = cacheFile.Size();
        Array<uint8> compressedShader;
        compressedShader.Init(shaderSize);
        cacheFile.Read(shaderSize, compressedShader.Data());

        ID3DBlob* decompressedShader[1] = { nullptr };
        uint32 indices[1] = { 0 };
        DXCall(D3DDecompressShaders(compressedShader.Data(), shaderSize, 1, 0,
                                    indices, 0, decompressedShader, nullptr));

        return decompressedShader[0];
    }

    WriteLog("Compiling %s shader %s_%s %s\n", TypeStrings[uint64(type)],
                WStringToAnsi(GetFileName(path).c_str()).c_str(),
                functionName, MakeDefinesString(defines).c_str());

    // Loop until we succeed, or an exception is thrown
    while(true)
    {
        UINT flags = D3DCOMPILE_WARNINGS_ARE_ERRORS;
        #ifdef _DEBUG
            flags |= D3DCOMPILE_DEBUG;
            // This is causing some shader bugs
            /*if(forceOptimization == false)
                flags |= D3DCOMPILE_SKIP_OPTIMIZATION;*/
        #endif

        ID3DBlob* compiledShader;
        ID3DBlobPtr errorMessages;
        FrameworkInclude include;
        HRESULT hr = D3DCompileFromFile(path, defines, &include, functionName,
                                        profileString, flags, 0, &compiledShader, &errorMessages);

        if(FAILED(hr))
        {
            if(errorMessages)
            {
                wchar message[1024] = { 0 };
                char* blobdata = reinterpret_cast<char*>(errorMessages->GetBufferPointer());

                MultiByteToWideChar(CP_ACP, 0, blobdata, static_cast<int>(errorMessages->GetBufferSize()), message, 1024);
                std::wstring fullMessage = L"Error compiling shader file \"";
                fullMessage += path;
                fullMessage += L"\" - ";
                fullMessage += message;

                // Pop up a message box allowing user to retry compilation
                int retVal = MessageBoxW(nullptr, fullMessage.c_str(), L"Shader Compilation Error", MB_RETRYCANCEL);
                if(retVal != IDRETRY)
                    throw DXException(hr, fullMessage.c_str());
            }
            else
            {
                Assert_(false);
                throw DXException(hr);
            }
        }
        else
        {
            // Compress the shader
            D3D_SHADER_DATA shaderData;
            shaderData.pBytecode = compiledShader->GetBufferPointer();
            shaderData.BytecodeLength = compiledShader->GetBufferSize();
            ID3DBlobPtr compressedShader;
            DXCall(D3DCompressShaders(1, &shaderData, D3D_COMPRESS_SHADER_KEEP_ALL_PARTS, &compressedShader));

            // Create the cache directory if it doesn't exist
            if(DirectoryExists(baseCacheDir.c_str()) == false)
                Win32Call(CreateDirectory(baseCacheDir.c_str(), nullptr));

            if(DirectoryExists(cacheDir.c_str()) == false)
                Win32Call(CreateDirectory(cacheDir.c_str(), nullptr));

            File cacheFile(cacheName.c_str(), FileOpenMode::Write);

            // Write the compiled shader to disk
            uint64 shaderSize = compressedShader->GetBufferSize();
            cacheFile.Write(shaderSize, compressedShader->GetBufferPointer());

            return compiledShader;
        }
    }
}