示例#1
0
bool TSRD3D11Effect::CompileFromMemory( unsigned char* _pByteCode, unsigned int _uiByteLength )
{

#if defined( D3D11_RENDERER )
		D3DCreateBlob( _uiByteLength, &m_pEffectBuffer );
#else
        D3D10CreateBlob( _uiByteLength, &m_pEffectBuffer );
#endif

    memcpy( m_pEffectBuffer->GetBufferPointer(), _pByteCode, _uiByteLength );

    // create the actual effect from the blob and start inspecting the constants used inside it..
#ifdef D3D10_RENDERER
    HRESULT hr = D3D10CreateEffectFromMemory( m_pEffectBuffer->GetBufferPointer(), m_pEffectBuffer->GetBufferSize(), 0, g_pD3DDevice, 0, &m_pD3DEffect );
#endif 

#ifdef D3D11_RENDERER
    HRESULT hr = D3DX11CreateEffectFromMemory( m_pEffectBuffer->GetBufferPointer(), m_pEffectBuffer->GetBufferSize(), 0, g_pD3DDevice, &m_pD3DEffect );
#endif
    if ( FAILED( hr ) )
    {
        TSRPrintln( "Failed to create effect from memory" );
    }
    BindConstants();
    return true;
}
示例#2
0
HRESULT WriteReadShader(ID3DBlob **ppSBlob, const wchar_t *const sTargetFileName)
{
	HRESULT hr;

	FILE *pFile;

#ifdef AUTSHADERS_SAVE_TO_FILE
	_wfopen_s(&pFile, sTargetFileName, L"wb");
	fwrite((*ppSBlob)->GetBufferPointer(), (*ppSBlob)->GetBufferSize(), 1, pFile);
	fclose(pFile);
#endif
	
	int nSize = 0;
	_wfopen_s(&pFile, sTargetFileName, L"rb");

	fseek(pFile, 0, SEEK_END);
	nSize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);
	
	*ppSBlob = NULL;
	V_RETURN(D3DCreateBlob(nSize, ppSBlob));

	fread_s((*ppSBlob)->GetBufferPointer(), nSize, nSize, 1, pFile);
	
	fclose(pFile);

	return S_OK;
}
示例#3
0
	//[-------------------------------------------------------]
	//[ Public methods                                        ]
	//[-------------------------------------------------------]
	VertexShaderHlsl::VertexShaderHlsl(Direct3D12Renderer &direct3D12Renderer, const uint8_t *bytecode, uint32_t numberOfBytes) :
		IVertexShader(direct3D12Renderer),
		mD3DBlobVertexShader(nullptr)
	{
		// Backup the vertex shader bytecode
		D3DCreateBlob(numberOfBytes, &mD3DBlobVertexShader);
		memcpy(mD3DBlobVertexShader->GetBufferPointer(), bytecode, numberOfBytes);
	}
示例#4
0
	//[-------------------------------------------------------]
	//[ Public methods                                        ]
	//[-------------------------------------------------------]
	TessellationControlShaderHlsl::TessellationControlShaderHlsl(Direct3D12Renderer &direct3D12Renderer, const uint8_t *bytecode, uint32_t numberOfBytes) :
		ITessellationControlShader(direct3D12Renderer),
		mD3DBlobHullShader(nullptr)
	{
		// Backup the hull shader bytecode
		D3DCreateBlob(numberOfBytes, &mD3DBlobHullShader);
		memcpy(mD3DBlobHullShader->GetBufferPointer(), bytecode, numberOfBytes);
	}
示例#5
0
	GeometryShader::GeometryShader( GeometryShader const& shader ) : Shader(), m_shader(0)
	{
		memory::SafeRelease(&m_bytecode);
		memory::SafeRelease(&m_shader);
		
		m_name = shader.m_name;

		D3DCreateBlob(shader.m_bytecode->GetBufferSize(), &m_bytecode);
		memcpy(m_bytecode->GetBufferPointer(), shader.m_bytecode->GetBufferPointer(), m_bytecode->GetBufferSize());
		g_renderer.GetDevice()->CreateGeometryShader(m_bytecode->GetBufferPointer(), m_bytecode->GetBufferSize(), 0, &m_shader);
	}
示例#6
0
	GeometryShader	&GeometryShader::operator=( GeometryShader const& shader )
	{
		if (this != &shader)
		{
			memory::SafeRelease(&m_bytecode);
			memory::SafeRelease(&m_shader);

			m_name = shader.m_name;

			D3DCreateBlob(shader.m_bytecode->GetBufferSize(), &m_bytecode);
			memcpy(m_bytecode->GetBufferPointer(), shader.m_bytecode->GetBufferPointer(), m_bytecode->GetBufferSize());
			g_renderer.GetDevice()->CreateGeometryShader(m_bytecode->GetBufferPointer(), m_bytecode->GetBufferSize(), 0, &m_shader);
		}
		return *this;
	}
示例#7
0
HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
        const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
        const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages)
{
    FIXME("data %p, data_size %lu, filename %s, defines %p, include %p, entrypoint %s,\n"
            "target %s, sflags %#x, eflags %#x, shader %p, error_messages %p stub!\n",
            data, data_size, debugstr_a(filename), defines, include, debugstr_a(entrypoint),
            debugstr_a(target), sflags, eflags, shader, error_messages);

    TRACE("Shader source:\n%s\n", debugstr_an(data, data_size));

    if (error_messages)
        D3DCreateBlob(1, error_messages); /* zero fill used as string end */

    return D3DERR_INVALIDCALL;
}
示例#8
0
ID3D10Blob * Shader::CompileFromCachedBinary(const std::string & cachedBinaryFilePath)
{
	std::ifstream cache(cachedBinaryFilePath, std::ios::in | std::ios::binary | std::ios::ate);
	const size_t shaderBinarySize = cache.tellg();
	void* pBuffer = calloc(1, shaderBinarySize);
	cache.seekg(0);
	cache.read(reinterpret_cast<char*>(pBuffer), shaderBinarySize);
	cache.close();

	ID3D10Blob* pBlob = { nullptr };
	D3DCreateBlob(shaderBinarySize, &pBlob);
	memcpy(pBlob->GetBufferPointer(), pBuffer, shaderBinarySize);
	free(pBuffer);

	return pBlob;
}
示例#9
0
HRESULT  LoadShaderBinaryFromFile(const std::string& filename, ID3DBlob **pBlob)
{
	std::ifstream fin(filename, std::ios::binary);

	fin.seekg(0, std::ios_base::end);
	std::size_t size = (std::size_t)fin.tellg();

	char * buf = new char[size];
	fin.seekg(0, std::ios_base::beg);

	fin.read(buf, size);
	fin.close();

	D3DCreateBlob(size, pBlob);
	memcpy((*pBlob)->GetBufferPointer(), buf, size);
	delete[] buf;

	return S_OK;
}
示例#10
0
文件: compiler.c 项目: DeltaYang/wine
HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename,
        const D3D_SHADER_MACRO *defines, ID3DInclude *include,
        ID3DBlob **shader, ID3DBlob **error_messages)
{
    HRESULT hr;
    ID3DBlob *buffer;

    TRACE("data %p, size %lu, filename %s, defines %p, include %p, shader %p, error_messages %p\n",
          data, size, debugstr_a(filename), defines, include, shader, error_messages);

    if (!data)
        return E_INVALIDARG;

    EnterCriticalSection(&wpp_mutex);

    if (shader) *shader = NULL;
    if (error_messages) *error_messages = NULL;

    hr = preprocess_shader(data, size, filename, defines, include, error_messages);

    if (SUCCEEDED(hr))
    {
        if (shader)
        {
            hr = D3DCreateBlob(wpp_output_size, &buffer);
            if (FAILED(hr))
                goto cleanup;
            CopyMemory(ID3D10Blob_GetBufferPointer(buffer), wpp_output, wpp_output_size);
            *shader = buffer;
        }
        else
            hr = E_INVALIDARG;
    }

cleanup:
    HeapFree(GetProcessHeap(), 0, wpp_output);
    LeaveCriticalSection(&wpp_mutex);
    return hr;
}
PixelShaderBinary::PixelShaderBinary(const std::string& filepath)
{
	std::ifstream file(filepath, std::ifstream::binary);
	if(!file)
		throw std::runtime_error("Opening file '" + filepath + "'failed!");

	//std::string content((std::istreambuf_iterator<char>(file)), (std::istreambuf_iterator<char>()));

	file.seekg(0, std::ifstream::end);
	std::streamoff size = file.tellg();
	D3DCreateBlob(size, m_ShaderBinary.rebind());
	file.seekg(0, std::ifstream::beg);
	file.read(static_cast<char*>(m_ShaderBinary->GetBufferPointer()), size);
	/*
	com_ptr<ID3DBlob> errors;
	HRESULT result = D3DCompile(content.c_str(),
								content.size(),
								NULL,
								NULL,
								NULL,
								"main",
								"ps_4_0",
								D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL0,
								0,
								m_ShaderBinary.rebind(),
								errors.rebind());

	if (FAILED(result))
	{			
		throw std::runtime_error("Compile shader '" + filepath + "' failed with error message: "
									+ static_cast<char*>(errors->GetBufferPointer()));
	}
	*/


}
示例#12
0
文件: compiler.c 项目: DeltaYang/wine
static HRESULT compile_shader(const char *preproc_shader, const char *target, const char *entrypoint,
        ID3DBlob **shader_blob, ID3DBlob **error_messages)
{
    struct bwriter_shader *shader;
    char *messages = NULL;
    HRESULT hr;
    DWORD *res, size, major, minor;
    ID3DBlob *buffer;
    char *pos;
    enum shader_type shader_type;
    const struct target_info *info;

    TRACE("Preprocessed shader source: %s\n", debugstr_a(preproc_shader));

    TRACE("Checking compilation target %s\n", debugstr_a(target));
    info = get_target_info(target);
    if (!info)
    {
        FIXME("Unknown compilation target %s\n", debugstr_a(target));
        return D3DERR_INVALIDCALL;
    }
    else
    {
        if (!info->support)
        {
            FIXME("Compilation target %s not yet supported\n", debugstr_a(target));
            return D3DERR_INVALIDCALL;
        }
        else
        {
            shader_type = info->type;
            major = info->sm_major;
            minor = info->sm_minor;
        }
    }

    shader = parse_hlsl_shader(preproc_shader, shader_type, major, minor, entrypoint, &messages);

    if (messages)
    {
        TRACE("Compiler messages:\n");
        TRACE("%s\n", debugstr_a(messages));

        TRACE("Shader source:\n");
        TRACE("%s\n", debugstr_a(preproc_shader));

        if (error_messages)
        {
            const char *preproc_messages = *error_messages ? ID3D10Blob_GetBufferPointer(*error_messages) : NULL;

            size = strlen(messages) + (preproc_messages ? strlen(preproc_messages) : 0) + 1;
            hr = D3DCreateBlob(size, &buffer);
            if (FAILED(hr))
            {
                HeapFree(GetProcessHeap(), 0, messages);
                if (shader) SlDeleteShader(shader);
                return hr;
            }
            pos = ID3D10Blob_GetBufferPointer(buffer);
            if (preproc_messages)
            {
                memcpy(pos, preproc_messages, strlen(preproc_messages) + 1);
                pos += strlen(preproc_messages);
            }
            memcpy(pos, messages, strlen(messages) + 1);

            if (*error_messages) ID3D10Blob_Release(*error_messages);
            *error_messages = buffer;
        }
        HeapFree(GetProcessHeap(), 0, messages);
    }

    if (!shader)
    {
        ERR("HLSL shader parsing failed.\n");
        return D3DXERR_INVALIDDATA;
    }

    hr = SlWriteBytecode(shader, 9, &res, &size);
    SlDeleteShader(shader);
    if (FAILED(hr))
    {
        ERR("SlWriteBytecode failed with error 0x%08x.\n", hr);
        return D3DXERR_INVALIDDATA;
    }

    if (shader_blob)
    {
        hr = D3DCreateBlob(size, &buffer);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, res);
            return hr;
        }
        memcpy(ID3D10Blob_GetBufferPointer(buffer), res, size);
        *shader_blob = buffer;
    }

    HeapFree(GetProcessHeap(), 0, res);

    return S_OK;
}
示例#13
0
文件: compiler.c 项目: DeltaYang/wine
static HRESULT assemble_shader(const char *preproc_shader,
        ID3DBlob **shader_blob, ID3DBlob **error_messages)
{
    struct bwriter_shader *shader;
    char *messages = NULL;
    HRESULT hr;
    DWORD *res, size;
    ID3DBlob *buffer;
    char *pos;

    shader = SlAssembleShader(preproc_shader, &messages);

    if (messages)
    {
        TRACE("Assembler messages:\n");
        TRACE("%s\n", debugstr_a(messages));

        TRACE("Shader source:\n");
        TRACE("%s\n", debugstr_a(preproc_shader));

        if (error_messages)
        {
            const char *preproc_messages = *error_messages ? ID3D10Blob_GetBufferPointer(*error_messages) : NULL;

            size = strlen(messages) + (preproc_messages ? strlen(preproc_messages) : 0) + 1;
            hr = D3DCreateBlob(size, &buffer);
            if (FAILED(hr))
            {
                HeapFree(GetProcessHeap(), 0, messages);
                if (shader) SlDeleteShader(shader);
                return hr;
            }
            pos = ID3D10Blob_GetBufferPointer(buffer);
            if (preproc_messages)
            {
                CopyMemory(pos, preproc_messages, strlen(preproc_messages) + 1);
                pos += strlen(preproc_messages);
            }
            CopyMemory(pos, messages, strlen(messages) + 1);

            if (*error_messages) ID3D10Blob_Release(*error_messages);
            *error_messages = buffer;
        }
        HeapFree(GetProcessHeap(), 0, messages);
    }

    if (shader == NULL)
    {
        ERR("Asm reading failed\n");
        return D3DXERR_INVALIDDATA;
    }

    hr = SlWriteBytecode(shader, 9, &res, &size);
    SlDeleteShader(shader);
    if (FAILED(hr))
    {
        ERR("SlWriteBytecode failed with 0x%08x\n", hr);
        return D3DXERR_INVALIDDATA;
    }

    if (shader_blob)
    {
        hr = D3DCreateBlob(size, &buffer);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, res);
            return hr;
        }
        CopyMemory(ID3D10Blob_GetBufferPointer(buffer), res, size);
        *shader_blob = buffer;
    }

    HeapFree(GetProcessHeap(), 0, res);

    return S_OK;
}
示例#14
0
文件: compiler.c 项目: DeltaYang/wine
static HRESULT preprocess_shader(const void *data, SIZE_T data_size, const char *filename,
        const D3D_SHADER_MACRO *defines, ID3DInclude *include, ID3DBlob **error_messages)
{
    int ret;
    HRESULT hr = S_OK;
    const D3D_SHADER_MACRO *def = defines;

    static const struct wpp_callbacks wpp_callbacks =
    {
        wpp_lookup_mem,
        wpp_open_mem,
        wpp_close_mem,
        wpp_read_mem,
        wpp_write_mem,
        wpp_error,
        wpp_warning,
    };

    if (def != NULL)
    {
        while (def->Name != NULL)
        {
            wpp_add_define(def->Name, def->Definition);
            def++;
        }
    }
    current_include = include;
    includes_size = 0;

    wpp_output_size = wpp_output_capacity = 0;
    wpp_output = NULL;

    wpp_set_callbacks(&wpp_callbacks);
    wpp_messages_size = wpp_messages_capacity = 0;
    wpp_messages = NULL;
    current_shader.buffer = data;
    current_shader.size = data_size;
    initial_filename = filename ? filename : "";

    ret = wpp_parse(initial_filename, NULL);
    if (!wpp_close_output())
        ret = 1;
    if (ret)
    {
        TRACE("Error during shader preprocessing\n");
        if (wpp_messages)
        {
            int size;
            ID3DBlob *buffer;

            TRACE("Preprocessor messages:\n%s\n", debugstr_a(wpp_messages));

            if (error_messages)
            {
                size = strlen(wpp_messages) + 1;
                hr = D3DCreateBlob(size, &buffer);
                if (FAILED(hr))
                    goto cleanup;
                CopyMemory(ID3D10Blob_GetBufferPointer(buffer), wpp_messages, size);
                *error_messages = buffer;
            }
        }
        if (data)
            TRACE("Shader source:\n%s\n", debugstr_an(data, data_size));
        hr = E_FAIL;
    }

cleanup:
    /* Remove the previously added defines */
    if (defines != NULL)
    {
        while (defines->Name != NULL)
        {
            wpp_del_define(defines->Name);
            defines++;
        }
    }
    HeapFree(GetProcessHeap(), 0, wpp_messages);
    return hr;
}
示例#15
0
文件: blob.c 项目: r6144/wine
HRESULT d3dcompiler_get_blob_part(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob)
{
    struct dxbc src_dxbc, dst_dxbc;
    HRESULT hr;
    unsigned int i, count;

    if (!data || !data_size || flags || !blob)
    {
        WARN("Invalid arguments: data %p, data_size %lu, flags %#x, blob %p\n", data, data_size, flags, blob);
        return D3DERR_INVALIDCALL;
    }

    if (part > D3D_BLOB_TEST_COMPILE_PERF
            || (part < D3D_BLOB_TEST_ALTERNATE_SHADER && part > D3D_BLOB_XNA_SHADER))
    {
        WARN("Invalid D3D_BLOB_PART: part %s\n", debug_d3dcompiler_d3d_blob_part(part));
        return D3DERR_INVALIDCALL;
    }

    hr = dxbc_parse(data, data_size, &src_dxbc);
    if (FAILED(hr))
    {
        WARN("Failed to parse blob part\n");
        return hr;
    }

    hr = dxbc_init(&dst_dxbc, 0);
    if (FAILED(hr))
    {
        dxbc_destroy(&src_dxbc);
        WARN("Failed to init dxbc\n");
        return hr;
    }

    for (i = 0; i < src_dxbc.count; ++i)
    {
        struct dxbc_section *section = &src_dxbc.sections[i];

        if (check_blob_part(section->tag, part))
        {
            hr = dxbc_add_section(&dst_dxbc, section->tag, section->data, section->data_size);
            if (FAILED(hr))
            {
                dxbc_destroy(&src_dxbc);
                dxbc_destroy(&dst_dxbc);
                WARN("Failed to add section to dxbc\n");
                return hr;
            }
        }
    }

    count = dst_dxbc.count;

    switch(part)
    {
    case D3D_BLOB_INPUT_SIGNATURE_BLOB:
    case D3D_BLOB_OUTPUT_SIGNATURE_BLOB:
    case D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB:
    case D3D_BLOB_DEBUG_INFO:
    case D3D_BLOB_LEGACY_SHADER:
    case D3D_BLOB_XNA_PREPASS_SHADER:
    case D3D_BLOB_XNA_SHADER:
        if (count != 1) count = 0;
        break;

    case D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB:
        if (count != 2) count = 0;
        break;

    case D3D_BLOB_ALL_SIGNATURE_BLOB:
        if (count != 3) count = 0;
        break;

    default:
        FIXME("Unhandled D3D_BLOB_PART %s.\n", debug_d3dcompiler_d3d_blob_part(part));
        break;
    }

    if (count == 0)
    {
        dxbc_destroy(&src_dxbc);
        dxbc_destroy(&dst_dxbc);
        WARN("Nothing to write into the blob (count = 0)\n");
        return E_FAIL;
    }

    /* some parts aren't full DXBCs, they contain only the data */
    if (count == 1 && (part == D3D_BLOB_DEBUG_INFO || part == D3D_BLOB_LEGACY_SHADER || part == D3D_BLOB_XNA_PREPASS_SHADER
                       || part == D3D_BLOB_XNA_SHADER))
    {
        hr = D3DCreateBlob(dst_dxbc.sections[0].data_size, blob);
        if (SUCCEEDED(hr))
        {
            memcpy(ID3D10Blob_GetBufferPointer(*blob), dst_dxbc.sections[0].data, dst_dxbc.sections[0].data_size);
        }
        else
        {
            WARN("Could not create blob\n");
        }
    }
    else
    {
        hr = dxbc_write_blob(&dst_dxbc, blob);
        if (FAILED(hr))
        {
            WARN("Failed to write blob part\n");
        }
    }

    dxbc_destroy(&src_dxbc);
    dxbc_destroy(&dst_dxbc);

    return hr;
}
示例#16
0
bool ComputeShader::Init(TCHAR* shaderFile, TCHAR* blobFileAppendix, char* pFunctionName, D3D10_SHADER_MACRO* pDefines,
                         ID3D11Device* d3dDevice, ID3D11DeviceContext*d3dContext)
{
    HRESULT hr = S_OK;
    mD3DDevice = d3dDevice;
    mD3DDeviceContext = d3dContext;

    ID3DBlob* pCompiledShader = nullptr;
    ID3DBlob* pErrorBlob = nullptr;

    FILE* fShaderBlob = nullptr;

    TCHAR blobFilename[300];
    if(blobFileAppendix != nullptr)
    {
        size_t l1 = _tcslen(shaderFile);
        size_t l2 = _tcslen(_tcsrchr(shaderFile, _T('.')));
        _tcsncpy_s(blobFilename, shaderFile, l1 - l2);

        _tcscat_s(blobFilename, _T("_"));
        _tcscat_s(blobFilename, blobFileAppendix);
        _tcscat_s(blobFilename, _T(".blob"));

        //MessageBox(0, blobFilename, L"", 0);

        _tfopen_s(&fShaderBlob, blobFilename, _T("rb"));
    }

    DWORD dwShaderFlags =	D3DCOMPILE_ENABLE_STRICTNESS |
                            D3DCOMPILE_IEEE_STRICTNESS |
                            //D3DCOMPILE_WARNINGS_ARE_ERRORS |
                            D3DCOMPILE_PREFER_FLOW_CONTROL;

#if defined(DEBUG) || defined(_DEBUG)
    dwShaderFlags |= D3DCOMPILE_DEBUG;
    dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#else
    dwShaderFlags |= D3DCOMPILE_OPTIMIZATION_LEVEL3;
#endif

    if(fShaderBlob == nullptr)
    {
        //hr = D3DX11CompileFromFile(shaderFile, pDefines, nullptr, pFunctionName, "cs_5_0",
        //dwShaderFlags, nullptr, nullptr, &pCompiledShader, &pErrorBlob, nullptr);

        hr = D3DCompileFromFile(shaderFile, pDefines, D3D_COMPILE_STANDARD_FILE_INCLUDE, pFunctionName, "cs_5_0",
                                dwShaderFlags, NULL, &pCompiledShader, &pErrorBlob);

        if(hr == S_OK)
        {
            if(blobFileAppendix != nullptr)
            {
                _tfopen_s(&fShaderBlob, blobFilename, _T("wb"));

                if(fShaderBlob != nullptr)
                {
                    size_t size = pCompiledShader->GetBufferSize();
                    fwrite(&size, sizeof(size_t), 1, fShaderBlob);
                    fwrite(pCompiledShader->GetBufferPointer(), size, 1, fShaderBlob);
                    fclose(fShaderBlob);
                }
            }
        }
    }
    else
    {
        int size = 0;
        fread_s(&size, sizeof(int), sizeof(int), 1, fShaderBlob);

        if(D3DCreateBlob(size, &pCompiledShader) == S_OK)
        {
            fread_s(pCompiledShader->GetBufferPointer(), size, size, 1, fShaderBlob);
        }

        fclose(fShaderBlob);
    }
    if (pErrorBlob)
    {
        OutputDebugStringA((char*)pErrorBlob->GetBufferPointer());
    }

    if(hr == S_OK)
    {
        hr = mD3DDevice->CreateComputeShader(pCompiledShader->GetBufferPointer(),
                                             pCompiledShader->GetBufferSize(), nullptr, &mShader);
    }

    SAFE_RELEASE(pErrorBlob);
    SAFE_RELEASE(pCompiledShader);

    return (hr == S_OK);
}
示例#17
0
bool TSRD3D11Effect::Compile( const char* _pFileName, const char* _pSuffix, TSRShaderMacro* _pMacros )
{
#ifdef D3D10_RENDERER
    const char* pVersionName = "fx_4_0";
#elif defined ( D3D11_RENDERER )
    const char* pVersionName = "fx_5_0";

	TSRD3D11GraphicsSubSystem* pD3D11GraphicsSubSystem = ( TSRD3D11GraphicsSubSystem* ) Graphics();
	
	switch ( pD3D11GraphicsSubSystem->m_FeatureLevel )
	{
	case D3D_FEATURE_LEVEL_11_0:
		pVersionName = "fx_5_0";
		break;
	case D3D_FEATURE_LEVEL_10_1:
	//	pVersionName = "fx_4_1";
		//break;
	case D3D_FEATURE_LEVEL_10_0:
		pVersionName = "fx_4_0";
		break;
	case D3D_FEATURE_LEVEL_9_3:
	case D3D_FEATURE_LEVEL_9_2:
	case D3D_FEATURE_LEVEL_9_1:
		pVersionName = "fx_3_0";
		break;
	}
	
#endif 

    D3D_SHADER_MACRO* pMacros = ( D3D_SHADER_MACRO* ) _pMacros;

    // formulate the compiled shader name...
    string compiledShaderName = "cache/";
    compiledShaderName        += _pFileName;
    compiledShaderName        += ".";
    compiledShaderName        += pVersionName;
    compiledShaderName        += _pSuffix;
    compiledShaderName        += ".fxobj";

    
#ifdef ALWAYS_COMPILE_SHADERS
    bool NeedToCompile = true;
#else
    bool NeedToCompile = TSRFileSystem::FileNeedsRebuild( _pFileName, compiledShaderName.c_str() );
#endif // ALWAYS_COMPILE_SHADERS

#ifndef NEVER_COMPILE_SHADERS
	 
    if ( NeedToCompile )
    {
        ID3D10Blob* pErrors = 0;
        DWORD dwShaderFlags = D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY;// | D3D10_SHADER_DEBUG;

        // compile the source...
#if defined( D3D11_RENDERER ) && !defined( LEGACY_D3D11 )
		pVersionName = "fx_5_0";
		wchar_t wFileName[ 256 ];
		MultiByteToWideChar( CP_ACP, 0, _pFileName, -1, wFileName, 1000 );
		HRESULT hr = D3DCompileFromFile( wFileName, pMacros, D3D_COMPILE_STANDARD_FILE_INCLUDE, 0, pVersionName, dwShaderFlags, 0, &m_pEffectBuffer, &pErrors );
#else
        HRESULT hr = D3DCompileFromFile( _pFileName, pMacros, 0, 0, pVersionName, dwShaderFlags, 0, NULL, &m_pEffectBuffer, &pErrors, NULL );
#endif 
        if( FAILED( hr ) )
        {
            TSRPrintln( "Failed to compile effect %s", _pFileName );
            TSRPrintln( ( char* ) pErrors->GetBufferPointer() );
            return false;
        }
#ifdef _DEBUG
        // save the effect blob...to cache it...
        TSRFileStream* fpNewCompiledShader = TSRFileSystem::OpenFileStream( compiledShaderName.c_str(), "w+b" );
        int bufferSize = ( int ) m_pEffectBuffer->GetBufferSize();
        fwrite( m_pEffectBuffer->GetBufferPointer(), bufferSize, 1, fpNewCompiledShader );
        fclose( fpNewCompiledShader );
#endif
    }
    // load the already precompiled blob
    else
#endif // NEVER_COMPILE_SHADER
    {
        TSRFileStream* fp = TSRFileSystem::OpenFileStream( compiledShaderName.c_str(), "rb" );
        int bufferSize = fp->GetSize();
#if defined( D3D11_RENDERER )
		D3DCreateBlob( bufferSize, &m_pEffectBuffer );
#else
        D3D10CreateBlob( bufferSize, &m_pEffectBuffer );
#endif
        fread( m_pEffectBuffer->GetBufferPointer(), bufferSize, 1, fp );
        fclose( fp );
    }

    // create the actual effect from the blob and start inspecting the constants used inside it..
#ifdef D3D10_RENDERER
    HRESULT hr = D3D10CreateEffectFromMemory( m_pEffectBuffer->GetBufferPointer(), m_pEffectBuffer->GetBufferSize(), 0, g_pD3DDevice, 0, &m_pD3DEffect );
#endif 

#ifdef D3D11_RENDERER
    HRESULT hr = D3DX11CreateEffectFromMemory( m_pEffectBuffer->GetBufferPointer(), m_pEffectBuffer->GetBufferSize(), 0, g_pD3DDevice, &m_pD3DEffect );
#endif

    if ( FAILED( hr ) )
    {
        TSRPrintln( "Failed to create effect %s from memory", _pFileName );
    }
    BindConstants();
    return true;
}