Ejemplo n.º 1
0
int compileHLSLToD3D9(const char* from, const char* to, const std::map<std::string, int>& attributes) {
	LPD3DXBUFFER errors;
	LPD3DXBUFFER shader;
	LPD3DXCONSTANTTABLE table;
	HRESULT hr = D3DXCompileShaderFromFileA(from, nullptr, nullptr, "main", isVertexShader(from) ? "vs_2_0" : "ps_2_0", 0, &shader, &errors, &table);
	if (FAILED(hr)) hr = D3DXCompileShaderFromFileA(from, nullptr, nullptr, "main", isVertexShader(from) ? "vs_3_0" : "ps_3_0", 0, &shader, &errors, &table);
	if (errors != nullptr) std::cerr << (char*)errors->GetBufferPointer();
	if (!FAILED(hr)) {
		std::ofstream file(to, std::ios_base::binary);

		file.put(attributes.size());
		for (std::map<std::string, int>::const_iterator attribute = attributes.begin(); attribute != attributes.end(); ++attribute) {
			file << attribute->first.c_str();
			file.put(0);
			file.put(attribute->second);
		}

		D3DXCONSTANTTABLE_DESC desc;
		table->GetDesc(&desc);
		file.put(desc.Constants);
		for (UINT i = 0; i < desc.Constants; ++i) {
			D3DXHANDLE handle = table->GetConstant(nullptr, i);
			D3DXCONSTANT_DESC descriptions[10];
			UINT count = 10;
			table->GetConstantDesc(handle, descriptions, &count);
			if (count > 1) std::cerr << "Error: Number of descriptors for one constant is greater than one." << std::endl;
			for (UINT i2 = 0; i2 < count; ++i2) {
				char regtype;
				switch (descriptions[i2].RegisterSet) {
				case D3DXRS_BOOL:
					regtype = 'b';
					break;
				case D3DXRS_INT4:
					regtype = 'i';
					break;
				case D3DXRS_FLOAT4:
					regtype = 'f';
					break;
				case D3DXRS_SAMPLER:
					regtype = 's';
					break;
				}
				//std::cout << descriptions[i2].Name << " " << regtype << descriptions[i2].RegisterIndex << " " << descriptions[i2].RegisterCount << std::endl;
				file << descriptions[i2].Name;
				file.put(0);
				file.put(regtype);
				file.put(descriptions[i2].RegisterIndex);
				file.put(descriptions[i2].RegisterCount);
			}
		}
		DWORD* data = (DWORD*)shader->GetBufferPointer();
		for (unsigned i = 0; i < shader->GetBufferSize() / 4; ++i) {
			if ((data[i] & 0xffff) == 0xfffe) { //comment token
				unsigned size = (data[i] >> 16) & 0xffff;
				i += size;
			}
			else file.write((char*)&data[i], 4);
Ejemplo n.º 2
0
		HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO * pDefines,
		        LPD3DXINCLUDE pInclude, LPCSTR pFunctionName,
		        LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER * ppShader, LPD3DXBUFFER * ppErrorMsgs,
		        LPD3DXCONSTANTTABLE * ppConstantTable)
		{
			// wondering what I'm doing here?
			// see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader()

			#if ( D3DX_SDK_VERSION < 24 )
			// directly link functions, old d3d sdks didn't try to load external dlls
			// when linking to the d3dx9.lib
			#ifdef _MSC_VER
#pragma comment (lib, "d3dx9.lib")
			#endif

			// invoke static linked function
			return D3DXCompileShaderFromFileA(pSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs,
			                                  ppConstantTable);
			#else
			{
				// try to load shader functions from the dll and print error if failed.

				// D3DXCompileShaderFromFileA
				typedef HRESULT(WINAPI * D3DXCompileShaderFromFileFunction)(LPCSTR pSrcFile,
				        CONST D3DXMACRO * pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName,
				        LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER * ppShader, LPD3DXBUFFER * ppErrorMsgs,
				        LPD3DXCONSTANTTABLE * ppConstantTable);

				static bool LoadFailed = false;
				static D3DXCompileShaderFromFileFunction pFn = 0;

				if (!pFn && !LoadFailed)
				{
					// try to load dll
					io::path strDllName = "d3dx9_";
					strDllName += (int)D3DX_SDK_VERSION;
					strDllName += ".dll";

					HMODULE hMod = LoadLibrary(strDllName.c_str());
					if (hMod)
					{ pFn = (D3DXCompileShaderFromFileFunction)GetProcAddress(hMod, "D3DXCompileShaderFromFileA"); }

					if (!pFn)
					{
						LoadFailed = true;
						os::Printer::log("Could not load shader function D3DXCompileShaderFromFileA from dll, shaders disabled",
						                 strDllName.c_str(), ELL_ERROR);
					}
				}

				if (pFn)
				{
					// call already loaded function
					return (*pFn)(pSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable);
				}
			}
			#endif // D3DX_SDK_VERSION < 24

			return 0;
		}
Ejemplo n.º 3
0
HRESULT MyCreateEffectFromFile(TCHAR *fName, DWORD dwShaderFlags, ID3D11Device *pDevice, ID3DX11Effect **pEffect)
{
    char fNameChar[1024];
	CharToOem(fName, fNameChar);
	ID3DXBuffer *pShader;
	HRESULT hr;
	ID3DXBuffer *pErrors;
	if (FAILED(D3DXCompileShaderFromFileA(fNameChar, NULL, NULL, NULL, "fx_5_0", 0, &pShader, &pErrors, NULL)))
	{
		MessageBoxA(NULL, (char *)pErrors->GetBufferPointer(), "Error", MB_OK);
		return E_FAIL;
	}
    V_RETURN(D3DX11CreateEffectFromMemory(pShader->GetBufferPointer(), pShader->GetBufferSize(), dwShaderFlags, pDevice, pEffect));

	SAFE_RELEASE(pErrors);
	SAFE_RELEASE(pShader);

    return S_OK;
}
Ejemplo n.º 4
0
bool PrepareShader() 
{ 
	ID3DXBuffer *shader ; 
	ID3DXBuffer *errorBuffer ; 

	// Compile shader from file, Shader.txt must exist in current directory, and it must contain
	// the "Main" function
	HRESULT hr = D3DXCompileShaderFromFileA("torus.fx", 0, 0, "Main", "ps_2_0",  
		D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, &shader, &errorBuffer, NULL) ; 

	// output any error messages 
	if( errorBuffer ) 
	{ 
		MessageBoxA(0, (char*)errorBuffer->GetBufferPointer(), 0, 0); 
		errorBuffer->Release() ; 
	} 

	if(FAILED(hr)) 
	{ 
		MessageBox(0, L"D3DXCompileShaderFromFile() - FAILED", 0, 0); 
		return false; 
	} 

	// Create pixel shader 
	hr = g_pd3dDevice->CreatePixelShader((DWORD*)shader->GetBufferPointer(), &g_pPixelShader) ; 

	// handling error 
	if(FAILED(hr)) 
	{ 
		MessageBox(0, L"CreatePixelShader - FAILED", 0, 0); 
		return false; 
	} 

	// Release DX buffer
	shader->Release() ; 

	return true ;
} 
Ejemplo n.º 5
0
bool compileHLSLShaderDx9(bx::CommandLine& _cmdLine, const std::string& _code, bx::WriterI* _writer)
{
	BX_TRACE("DX9");

	const char* profile = _cmdLine.findOption('p', "profile");
	if (NULL == profile)
	{
		fprintf(stderr, "Shader profile must be specified.\n");
		return false;
	}

	bool debug = _cmdLine.hasArg('\0', "debug");

	uint32_t flags = 0;
	flags |= debug ? D3DXSHADER_DEBUG : 0;
	flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DXSHADER_AVOID_FLOW_CONTROL : 0;
	flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DXSHADER_NO_PRESHADER : 0;
	flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DXSHADER_PARTIALPRECISION : 0;
	flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DXSHADER_PREFER_FLOW_CONTROL : 0;
	flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY : 0;

	bool werror = _cmdLine.hasArg('\0', "Werror");

	uint32_t optimization = 3;
	if (_cmdLine.hasArg(optimization, 'O') )
	{
		optimization = bx::uint32_min(optimization, BX_COUNTOF(s_optimizationLevelDx9)-1);
		flags |= s_optimizationLevelDx9[optimization];
	}
	else
	{
		flags |= D3DXSHADER_SKIPOPTIMIZATION;
	}

	BX_TRACE("Profile: %s", profile);
	BX_TRACE("Flags: 0x%08x", flags);

	LPD3DXBUFFER code;
	LPD3DXBUFFER errorMsg;
	LPD3DXCONSTANTTABLE constantTable;

	HRESULT hr;

	// Output preprocessed shader so that HLSL can be debugged via GPA
	// or PIX. Compiling through memory won't embed preprocessed shader
	// file path.
	if (debug)
	{
		std::string hlslfp = _cmdLine.findOption('o');
		hlslfp += ".hlsl";
		writeFile(hlslfp.c_str(), _code.c_str(), (int32_t)_code.size() );

		hr = D3DXCompileShaderFromFileA(hlslfp.c_str()
			, NULL
			, NULL
			, "main"
			, profile
			, flags
			, &code
			, &errorMsg
			, &constantTable
			);
	}
	else
	{
		hr = D3DXCompileShader(_code.c_str()
			, (uint32_t)_code.size()
			, NULL
			, NULL
			, "main"
			, profile
			, flags
			, &code
			, &errorMsg
			, &constantTable
			);
	}

	if (FAILED(hr)
	|| (werror && NULL != errorMsg) )
	{
		const char* log = (const char*)errorMsg->GetBufferPointer();

		char source[1024];
		int32_t line = 0;
		int32_t column = 0;
		int32_t start = 0;
		int32_t end = INT32_MAX;

		if (3 == sscanf(log, "%[^(](%u,%u):", source, &line, &column)
		&&  0 != line)
		{
			start = bx::uint32_imax(1, line-10);
			end = start + 20;
		}

		printCode(_code.c_str(), line, start, end);
		fprintf(stderr, "Error: 0x%08x %s\n", (uint32_t)hr, log);
		errorMsg->Release();
		return false;
	}

	UniformArray uniforms;

	if (NULL != constantTable)
	{
		D3DXCONSTANTTABLE_DESC desc;
		hr = constantTable->GetDesc(&desc);
		if (FAILED(hr) )
		{
			fprintf(stderr, "Error 0x%08x\n", (uint32_t)hr);
			return false;
		}

		BX_TRACE("Creator: %s 0x%08x", desc.Creator, (uint32_t /*mingw warning*/)desc.Version);
		BX_TRACE("Num constants: %d", desc.Constants);
		BX_TRACE("#   cl ty RxC   S  By Name");

		for (uint32_t ii = 0; ii < desc.Constants; ++ii)
		{
			D3DXHANDLE handle = constantTable->GetConstant(NULL, ii);
			D3DXCONSTANT_DESC constDesc;
			uint32_t count;
			constantTable->GetConstantDesc(handle, &constDesc, &count);
			BX_TRACE("%3d %2d %2d [%dx%d] %d %3d %s[%d] c%d (%d)"
				, ii
				, constDesc.Class
				, constDesc.Type
				, constDesc.Rows
				, constDesc.Columns
				, constDesc.StructMembers
				, constDesc.Bytes
				, constDesc.Name
				, constDesc.Elements
				, constDesc.RegisterIndex
				, constDesc.RegisterCount
				);

			UniformType::Enum type = findUniformTypeDx9(constDesc);
			if (UniformType::Count != type)
			{
				Uniform un;
				un.name = '$' == constDesc.Name[0] ? constDesc.Name+1 : constDesc.Name;
				un.type = type;
				un.num = constDesc.Elements;
				un.regIndex = constDesc.RegisterIndex;
				un.regCount = constDesc.RegisterCount;
				uniforms.push_back(un);
			}
		}
	}

	uint16_t count = (uint16_t)uniforms.size();
	bx::write(_writer, count);

	uint32_t fragmentBit = profile[0] == 'p' ? BGFX_UNIFORM_FRAGMENTBIT : 0;
	for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
	{
		const Uniform& un = *it;
		uint8_t nameSize = (uint8_t)un.name.size();
		bx::write(_writer, nameSize);
		bx::write(_writer, un.name.c_str(), nameSize);
		uint8_t type = un.type|fragmentBit;
		bx::write(_writer, type);
		bx::write(_writer, un.num);
		bx::write(_writer, un.regIndex);
		bx::write(_writer, un.regCount);

		BX_TRACE("%s, %s, %d, %d, %d"
			, un.name.c_str()
			, getUniformTypeName(un.type)
			, un.num
			, un.regIndex
			, un.regCount
			);
	}

	uint16_t shaderSize = (uint16_t)code->GetBufferSize();
	bx::write(_writer, shaderSize);
	bx::write(_writer, code->GetBufferPointer(), shaderSize);
	uint8_t nul = 0;
	bx::write(_writer, nul);

	if (_cmdLine.hasArg('\0', "disasm") )
	{
		LPD3DXBUFFER disasm;
		D3DXDisassembleShader( (const DWORD*)code->GetBufferPointer()
			, false
			, NULL
			, &disasm
			);

		if (NULL != disasm)
		{
			std::string disasmfp = _cmdLine.findOption('o');
			disasmfp += ".disasm";

			writeFile(disasmfp.c_str(), disasm->GetBufferPointer(), disasm->GetBufferSize() );
			disasm->Release();
		}
	}

	if (NULL != code)
	{
		code->Release();
	}

	if (NULL != errorMsg)
	{
		errorMsg->Release();
	}

	if (NULL != constantTable)
	{
		constantTable->Release();
	}

	return true;
}