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) { TRACE("data %p, data_size %lu, filename %s, defines %p, include %p, entrypoint %s, " "target %s, sflags %#x, eflags %#x, shader %p, error_messages %p.\n", data, data_size, debugstr_a(filename), defines, include, debugstr_a(entrypoint), debugstr_a(target), sflags, eflags, shader, error_messages); return D3DCompile2(data, data_size, filename, defines, include, entrypoint, target, sflags, eflags, 0, NULL, 0, shader, error_messages); }
bool DXPixelShader::VInitShader(File* file) { HRESULT hr = S_OK; BYTE* data = new BYTE[VIX_LARGE_BUFSIZE]; file->Seek(0, FileSeek::End); size_t _size = file->Tell(); file->Seek(0, FileSeek::Set); file->Read(data, _size); //read all of the file into memory DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #ifdef _DEBUG // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. // Setting this flag improves the shader debugging experience, but still allows // the shaders to be optimized and to run exactly the way they will run in // the release configuration of this program. dwShaderFlags |= D3DCOMPILE_DEBUG; // Disable optimizations to further improve shader debugging dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* errorBlob = nullptr; hr = D3DCompile2(data, _size, nullptr, nullptr, nullptr, "main", "ps_5_0", NULL, NULL, NULL, NULL, NULL, &m_shaderBlob, &errorBlob); //hr = D3DReadFileToBlob(file->FilePath().c_str(), &m_shaderBlob); if (FAILED(hr)) { if (errorBlob) { OutputDebugStringA(reinterpret_cast<const char*>(errorBlob->GetBufferPointer())); errorBlob->Release(); } return false; } if (errorBlob) errorBlob->Release(); // Create the vertex shader hr = m_device->CreatePixelShader(m_shaderBlob->GetBufferPointer(), m_shaderBlob->GetBufferSize(), nullptr, &m_shader); if (FAILED(hr)) { ReleaseCOM(m_shaderBlob); return false; } return true; }
D3D11Context::ShaderCompileResult D3D11Context::compileShader (const ShaderCompileDesc& desc) { size_t sourceSize = desc.sourceSize; if (0 == sourceSize) sourceSize = strlen (desc.source); Hold<ID3DBlob> bytecode; Hold<ID3DBlob> error; if (FAILED (D3DCompile2 (desc.source, sourceSize, desc.name, desc.defines, desc.include, desc.entry, desc.target, desc.flags1, desc.flags2, desc.secondaryDataFlags, desc.secondaryData, desc.secondaryDataSize, bytecode, error))) { return ShaderCompileResult (nullptr, error.drop()); } return ShaderCompileResult (bytecode.drop(), error.drop()); }
bool D3D11PixelShader::VInitShader() { HRESULT hr = S_OK; BYTE* data = (BYTE*)m_data; DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #ifdef _DEBUG // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. // Setting this flag improves the shader debugging experience, but still allows // the shaders to be optimized and to run exactly the way they will run in // the release configuration of this program. dwShaderFlags |= D3DCOMPILE_DEBUG; // Disable optimizations to further improve shader debugging dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* errorBlob = nullptr; hr = D3DCompile2(data, strlen((char*)data), nullptr, nullptr, nullptr, "main", "ps_5_0", NULL, NULL, NULL, NULL, NULL, &m_blob, &errorBlob); if (FAILED(hr)) { if (errorBlob) { OutputDebugStringA(reinterpret_cast<const char*>(errorBlob->GetBufferPointer())); errorBlob->Release(); } return false; } if (errorBlob) errorBlob->Release(); // Create the vertex shader hr = m_device->CreatePixelShader(m_blob->GetBufferPointer(), m_blob->GetBufferSize(), nullptr, &m_shader); if (FAILED(hr)) { DirectX::ReleaseCOM(m_blob); return false; } return true; }
bool DXShaderCompiler::CompileShader(const std::string& source_file, const std::string& entry_point, const char* target, ShaderOpt opt_level, bool debug, const ShaderDefine* defines, size_t num_defines, std::vector<uint8_t>& output, YFileUtils::FileEnv* file_env) { std::string work_dir = YFileUtils::FilePath::DirPath(source_file); const std::vector<uint8_t>* source_data = GetFileData(source_file, file_env); std::vector<D3D_SHADER_MACRO> macros; for (size_t i = 0; i < num_defines; ++i) { macros.push_back({defines[i].define, defines[i].value}); } macros.push_back({NULL, NULL}); DXIncludeData include_data(work_dir, file_env); UINT flags1 = D3DCOMPILE_WARNINGS_ARE_ERRORS; switch (opt_level) { case kShaderOpt_None: flags1 |= D3DCOMPILE_SKIP_OPTIMIZATION; break; case kShaderOpt_Level0: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL0; break; case kShaderOpt_Level1: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL1; break; case kShaderOpt_Level2: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL2; break; case kShaderOpt_Level3: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL3; break; default: std::cerr << "Invalid Shader Opt: " << opt_level << std::endl; return false; } if (debug) { flags1 |= D3DCOMPILE_DEBUG; } ID3DBlob* code; ID3DBlob* error_msgs; HRESULT ret = D3DCompile2( source_data->data(), // in LPCVOID pSrcData, source_data->size(), // in SIZE_T SrcDataSize, source_file.c_str(), // in LPCSTR pSourceName, macros.data(), // in const D3D_SHADER_MACRO *pDefines, &include_data, // in ID3DInclude *pInclude, entry_point.c_str(), // in LPCSTR pEntrypoint, target, // in LPCSTR pTarget, flags1, // in UINT Flags1, 0, // in UINT Flags2, 0, // in UINT SecondaryDataFlags, NULL, // in LPCVOID pSecondaryData, 0, // in SIZE_T SecondaryDataSize, &code, // out ID3DBlob **ppCode, &error_msgs // out ID3DBlob **ppErrorMsgs ); if (FAILED(ret)) { std::cerr << "[ERROR] " << static_cast<const char*>(error_msgs->GetBufferPointer()) << std::endl; return false; } size_t code_size = code->GetBufferSize(); output.resize(code_size); memcpy(output.data(), code->GetBufferPointer(), code_size); return true; }
HRESULT Shader::CreateFromFile(const ShaderDesc& shaderDesc, const std::wstring& filename) { m_shaderDesc = shaderDesc; std::wstring filename_sourceCode = filename + L".hlsl"; std::wstring filename_byteCode = filename + L".csa"; UINT compilerFlags = 0; #if defined(_DEBUG) compilerFlags |= D3DCOMPILE_DEBUG; #endif const Renderer* pRenderer = Renderer::Get(); // Ladda källkoden. std::ifstream file(filename_sourceCode); if (!file.is_open()) { MessageBox(nullptr, L"Could not open shader file.", nullptr, MB_ICONERROR); return EXIT_FAILURE; } std::string buffer, data; while (std::getline(file, buffer)) data += buffer + "\n"; file.close(); //MessageBoxA(nullptr, data.c_str(), nullptr, MB_ICONINFORMATION); // // Kompilera vertex-shadern. // CComPtr<ID3DBlob> pVSBlob = nullptr; //if (!FileSystem::FileExists("AmbientOcclusion\\Shader.vs")) if (true) { std::cout << "Compiling vertex shader..." << std::endl; // Kompilera vertex-shadern. CComPtr<ID3DBlob> pErrors = nullptr; HRESULT hr = D3DCompile2(data.c_str(), data.length(), nullptr, nullptr, nullptr, "VS", "vs_5_0", compilerFlags, 0, 0, nullptr, 0, &pVSBlob, &pErrors); if (pErrors) { std::stringstream ss; ss << "Shader errors:\n\n"; ss << (const char*)pErrors->GetBufferPointer(); MessageBoxA(nullptr, ss.str().c_str(), nullptr, MB_ICONERROR); return EXIT_FAILURE; } if (pVSBlob == nullptr) { MessageBox(nullptr, L"Could not compile vertex shader. Dunno why.", nullptr, MB_ICONERROR); return EXIT_FAILURE; } // Spara maskinkoden till en fil så vi slipper kompilera om och om och om och om och om och om och om och om igen. D3DWriteBlobToFile(pVSBlob, L"AmbientOcclusion\\Shader.vs", TRUE); CComPtr<ID3DBlob> pVSDebugInfo = nullptr; D3DGetDebugInfo(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &pVSDebugInfo); if (pVSDebugInfo) { std::cout << "Vertex shader debug info:" << std::endl << (const char*)pVSDebugInfo->GetBufferPointer() << std::endl; } } else { std::cout << "Loading vertex shader from file..." << std::endl; // Ladda maskinkoden till blobben. D3DReadFileToBlob(L"AmbientOcclusion\\Shader.vs", &pVSBlob); } // Skapa vertex-shadern. HR(pRenderer->GetD3DDevice()->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &m_pVS)); // Skapa input-layouten. HRESULT hr = pRenderer->GetD3DDevice()->CreateInputLayout(&m_shaderDesc.vertexElementDescs[0], (UINT)m_shaderDesc.vertexElementDescs.size(), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &m_pInputLayout); if (hr == E_INVALIDARG) { MessageBox(nullptr, L"Din vertex-layout ser inte ut som den gör i shaderfilen.", nullptr, MB_ICONERROR); return hr; } HR(hr); // // Kompilera pixel-shadern. // CComPtr<ID3DBlob> pPSBlob = nullptr; //if (!FileSystem::FileExists("AmbientOcclusion\\Shader.ps")) if (true) { std::cout << "Compiling pixel shader..." << std::endl; CComPtr<ID3DBlob> pErrors = nullptr; HRESULT hr = D3DCompile2(data.c_str(), data.length(), nullptr, nullptr, nullptr, "PS", "ps_5_0", compilerFlags, 0, 0, nullptr, 0, &pPSBlob, &pErrors); if (pErrors) { std::stringstream ss; ss << "Shader errors:\n\n"; ss << (const char*)pErrors->GetBufferPointer(); MessageBoxA(nullptr, ss.str().c_str(), nullptr, MB_ICONERROR); return EXIT_FAILURE; } if (pPSBlob == nullptr) { MessageBox(nullptr, L"Could not compile pixel shader. Dunno why.", nullptr, MB_ICONERROR); return EXIT_FAILURE; } // Spara maskinkoden till en fil så vi slipper kompilera om och om igen. D3DWriteBlobToFile(pPSBlob, L"AmbientOcclusion\\Shader.ps", TRUE); CComPtr<ID3DBlob> pPSDebugInfo = nullptr; D3DGetDebugInfo(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), &pPSDebugInfo); if (pPSDebugInfo) { std::cout << "Pixel shader debug info:" << std::endl << (const char*)pPSDebugInfo->GetBufferPointer() << std::endl; pPSDebugInfo = nullptr; } } else { std::cout << "Loading pixel shader from file..." << std::endl; // Ladda maskinkoden till blobben. D3DReadFileToBlob(L"AmbientOcclusion\\Shader.ps", &pPSBlob); } HR(pRenderer->GetD3DDevice()->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &m_pPS)); // Skapa pixel-shadern. pPSBlob = nullptr; // Skapa konstantbuffertarna. m_constantBufferCount = (UINT)m_shaderDesc.constantBufferDescs.size(); m_pConstantBuffers = new ID3D11Buffer*[m_constantBufferCount]; for (unsigned int i = 0; i < m_constantBufferCount; i++) { D3D11_BUFFER_DESC cbd = { }; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cbd.ByteWidth = Singe::Math::RoundUp(m_shaderDesc.constantBufferDescs[i].constantBufferSize, 16); cbd.Usage = D3D11_USAGE_DYNAMIC; HR(pRenderer->GetD3DDevice()->CreateBuffer(&cbd, nullptr, &m_pConstantBuffers[i])); D3D11_MAPPED_SUBRESOURCE ms = { }; HR(pRenderer->GetD3DImmediateContext()->Map(m_pConstantBuffers[i], 0, D3D11_MAP_WRITE_DISCARD, 0, &ms)); pRenderer->GetD3DImmediateContext()->Unmap(m_pConstantBuffers[i], 0); } static const unsigned int MAX_VERTICES = 10000; static const unsigned int MAX_INDICES = 10000; m_pVertexData = new unsigned char[MAX_VERTICES * m_shaderDesc.vertexDataStride]; // Skapa vertexbufferten. D3D11_BUFFER_DESC vbd = { }; vbd.Usage = D3D11_USAGE_DEFAULT; vbd.ByteWidth = sizeof(m_shaderDesc.vertexDataStride) * MAX_VERTICES; vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; HR(pRenderer->GetD3DDevice()->CreateBuffer(&vbd, nullptr, &m_pVertexBuffer)); // Skapa den sekundära vertexbufferten. D3D11_BUFFER_DESC vbsd = { }; vbsd.Usage = D3D11_USAGE_STAGING; vbsd.ByteWidth = sizeof(m_shaderDesc.vertexDataStride) * MAX_VERTICES; vbsd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; HR(pRenderer->GetD3DDevice()->CreateBuffer(&vbsd, nullptr, &m_pVertexBufferStaging)); // Skapa indexbufferten. D3D11_BUFFER_DESC ibd = { }; ibd.Usage = D3D11_USAGE_DEFAULT; ibd.ByteWidth = sizeof(UINT) * MAX_INDICES; ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; HR(pRenderer->GetD3DDevice()->CreateBuffer(&ibd, nullptr, &m_pIndexBuffer)); // Skapa den sekundära indexbufferten. D3D11_BUFFER_DESC ibsd = { }; ibsd.Usage = D3D11_USAGE_STAGING; ibsd.ByteWidth = sizeof(UINT) * MAX_VERTICES; ibsd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; HR(pRenderer->GetD3DDevice()->CreateBuffer(&ibsd, nullptr, &m_pIndexBufferStaging)); return EXIT_SUCCESS; }