// Extern function for shader compilation HRESULT CompileShader(_In_ LPCWSTR srcFile, _In_ LPCSTR entryPoint, _In_ LPCSTR profile, _Outptr_ ID3DBlob** blob) { if (!srcFile || !entryPoint || !profile || !blob) return E_INVALIDARG; *blob = nullptr; UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _DEBUG ) flags |= D3DCOMPILE_DEBUG; #endif const D3D_SHADER_MACRO defines[] = { "EXAMPLE_DEFINE", "1", NULL, NULL }; ID3DBlob* shaderBlob = nullptr; ID3DBlob* errorBlob = nullptr; HRESULT hr = D3DCompileFromFile(srcFile, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, entryPoint, profile, flags, 0, &shaderBlob, &errorBlob); if (FAILED(hr)) { if (errorBlob) { OutputDebugStringA((char*)errorBlob->GetBufferPointer()); errorBlob->Release(); } if (shaderBlob) shaderBlob->Release(); return hr; } *blob = shaderBlob; return hr; }
bool ShaderClass::createGeometryShader(ID3D11Device* pDevice, WCHAR* fileName, CHAR* EntryPoint, ID3D11GeometryShader** ppGShader) { HRESULT hr; // Initialie Geometry shader ID3D10Blob* geometryShaderBuffer; ID3D10Blob* errorMessages; hr = D3DCompileFromFile( fileName, NULL, NULL, EntryPoint, "gs_5_0", 0, 0, &geometryShaderBuffer, &errorMessages); if (FAILED(hr)) { // If the shader failed to compile it should have writen something to the error message. if (errorMessages) { OutputShaderErrorMessage(errorMessages, fileName); return false; } // If there was nothing in the error message then it simply could not find the shader file itself. else { MessageBox(0, fileName, L"Missing Shader File", MB_OK); return false; } } // Create the geometry shader from the buffer. hr = pDevice->CreateGeometryShader(geometryShaderBuffer->GetBufferPointer(), geometryShaderBuffer->GetBufferSize(), NULL, ppGShader); if (FAILED(hr)) { MessageBox(0, L"Failed to create geometry shader", 0, MB_OK); return false; } geometryShaderBuffer->Release(); return true; }
//Helper for compiling compute shaders taken from DirectX documentation HRESULT CompileComputeShader(_In_ LPCWSTR srcFile, _In_ LPCSTR entryPoint, _In_ ID3D11Device* device, _Outptr_ ID3DBlob** blob) { if (!srcFile || !entryPoint || !device || !blob) return E_INVALIDARG; *blob = nullptr; UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _DEBUG ) flags |= D3DCOMPILE_DEBUG; #endif // We generally prefer to use the higher CS shader profile when possible as CS 5.0 is better performance on 11-class hardware LPCSTR profile = (device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0) ? "cs_5_0" : "cs_4_0"; const D3D_SHADER_MACRO defines[] = { "EXAMPLE_DEFINE", "1", NULL, NULL }; ID3DBlob* shaderBlob = nullptr; ID3DBlob* errorBlob = nullptr; HRESULT hr = D3DCompileFromFile(srcFile, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, entryPoint, profile, flags, 0, &shaderBlob, &errorBlob); if (FAILED(hr)) { if (errorBlob) { OutputDebugStringA((char*)errorBlob->GetBufferPointer()); errorBlob->Release(); } if (shaderBlob) shaderBlob->Release(); return hr; } *blob = shaderBlob; return hr; }
int ShaderClass::CreatePixelShader(ID3D11PixelShader** ppPS, WCHAR* fileName, char* EntryPoint) { HRESULT hr; // Initialie Pixel shader ID3D10Blob* pixelShaderBuffer; ID3D10Blob* errorMessages; hr = D3DCompileFromFile( fileName, NULL, NULL, EntryPoint, "ps_5_0", 0, 0, &pixelShaderBuffer, &errorMessages); if (FAILED(hr)) { // If the shader failed to compile it should have writen something to the error message. if (errorMessages) { OutputShaderErrorMessage(errorMessages, fileName); return -26; } // If there was nothing in the error message then it simply could not find the shader file itself. else { MessageBox(0, fileName, L"Missing Shader File", MB_OK); return -27; } } // Create the pixel shader from the buffer. hr = SystemClass::GetInstance()->mGrapInst->GetDevice()->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, ppPS); if (FAILED(hr)) { MessageBox(0, L"Failed to create pixel shader", 0, MB_OK); return -28; } pixelShaderBuffer->Release(); return 0; }
/* * Class: org_lwjgl_d3d11_impl_d3dcompiler * Method: nD3DCompileFromFile * Signature: (JJJJJIIJJ)I */ extern "C" JNIEXPORT jint JNICALL Java_org_lwjgl_d3d11_impl_d3dcompiler_nD3DCompileFromFile (JNIEnv * env, jclass clazz, jlong fileNamePtr, jlong definesPtr, jlong includePtr, jlong entryPointPtr, jlong targetPtr, jint flags1, jint flags2, jlong codeOutPtr, jlong errorMsgsOutPtr) { const char* fileNameCStr = (const char*)(intptr_t)fileNamePtr; size_t fileNameSize = strlen(fileNameCStr) + 1; wchar_t* wstr = (wchar_t*)malloc(sizeof(wchar_t) * fileNameSize); mbstowcs(wstr, fileNameCStr, fileNameSize); const D3D_SHADER_MACRO* defines = (const D3D_SHADER_MACRO*)(intptr_t)definesPtr; ID3DInclude* include = (ID3DInclude*)includePtr; LPCSTR entryPoint = (LPCSTR)(intptr_t)entryPointPtr; LPCSTR target = (LPCSTR)(intptr_t)targetPtr; UINT Flags1 = (UINT)flags1; UINT Flags2 = (UINT)flags2; ID3DBlob** codeOut = (ID3DBlob**)(intptr_t)codeOutPtr; ID3DBlob** errorMsgsOut = (ID3DBlob**)(intptr_t)errorMsgsOutPtr; HRESULT res = D3DCompileFromFile(wstr, defines, include, entryPoint, target, Flags1, Flags2, codeOut, errorMsgsOut); free(wstr); return (jint)res; }
ComPtr<ID3DBlob> afCompileShader(const char* name, const char* entryPoint, const char* target) { char path[MAX_PATH]; sprintf_s(path, sizeof(path), "%s.hlsl", name); // sprintf_s(path, sizeof(path), "hlsl/%s.hlsl", name); #ifdef _DEBUG UINT flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; #endif ComPtr<ID3DBlob> blob, err; WCHAR wname[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, path, -1, wname, dimof(wname)); D3DCompileFromFile(wname, nullptr, nullptr, entryPoint, target, flags, 0, &blob, &err); if (err) { MessageBoxA(nullptr, (const char*)err->GetBufferPointer(), name, MB_OK | MB_ICONERROR); } return blob; }
std::shared_ptr<Shader> Shader::CreateFromFile(RenderDevice* device, ShaderType type, const char* filePath) { std::shared_ptr<Shader> shader; CComPtr<ID3DBlob> errorBlob; CComPtr<ID3DBlob> shaderBlob; if (SUCCEEDED(D3DCompileFromFile(convert(filePath).c_str(), nullptr, nullptr, D3D11::ToShaderEntryPoint(type), D3D11::ToShaderLevel(type), 0, 0, &shaderBlob, &errorBlob))) { std::string debugName = filePath; shader = Shader::CreateFromBlob(device, type, shaderBlob, "Shader: " + debugName); } else { const char* errorText = (const char*)errorBlob->GetBufferPointer(); TalonLog(errorText); } return shader; }
int EffectSystemD3D11::CreateEffect(const char *path) { // 先把char转成wchar_t int wchar_size = MultiByteToWideChar(CP_ACP, 0, path, -1, nullptr, 0); wchar_t *wchar_path = new wchar_t[wchar_size]; ZeroMemory(wchar_path, wchar_size); MultiByteToWideChar(CP_ACP, 0, path, -1, wchar_path, wchar_size); // compile DWORD flags = D3DCOMPILE_ENABLE_STRICTNESS; #ifdef PE_DEBUG_MODE flags |= D3DCOMPILE_DEBUG; #endif ID3DBlob *effectBlob = nullptr; ID3DBlob *errorBlob = nullptr; // dx11只能使用fx_5_0 HRESULT hr = D3DCompileFromFile(wchar_path, nullptr, nullptr, nullptr, "fx_5_0", flags, 0, &effectBlob, &errorBlob); if (FAILED(hr)) { if (errorBlob != nullptr){ LogSystem::GetInstance().Log("编译%s出错, D3D Error:%s", path, (char*)errorBlob->GetBufferPointer()); errorBlob->Release(); } return -1; } if (errorBlob != nullptr){ errorBlob->Release(); } // create effect ID3DX11Effect *effect; hr = D3DX11CreateEffectFromMemory(effectBlob->GetBufferPointer(), effectBlob->GetBufferSize(), 0, mDevice, &effect); if (FAILED(hr)) { LogSystem::GetInstance().Log("创建%s出错", path); return -1; } mEffects.push_back(effect); return (mEffects.size() - 1); }
HRESULT GenerationShader::compileShaderFromFile(WCHAR * FileName, LPCSTR EntryPoint, LPCSTR ShaderModel, ID3DBlob ** Outblob) { HRESULT hr = S_OK; DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _DEBUG ) // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders. // Setting this flag improves the shader debug output, 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; dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* errorBlob; //DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; hr = D3DCompileFromFile(FileName, NULL, NULL, EntryPoint, ShaderModel, dwShaderFlags, NULL, Outblob, &errorBlob); if (FAILED(hr)) { if (errorBlob != NULL) { OutputDebugStringA((char*)errorBlob->GetBufferPointer()); } if (errorBlob) { errorBlob->Release(); } return hr; } if (errorBlob) errorBlob->Release(); return S_OK; }
void ShaderFactory::compileShaderStage( const LPCWSTR &p_sourceFile, const string &p_entryPoint, const string &p_profile, ID3DBlob** p_blob ) { HRESULT res = S_OK; ID3DBlob* blobError = NULL; ID3DBlob* shaderBlob = NULL; *p_blob = NULL; DWORD compileFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined(DEBUG) || defined(_DEBUG) compileFlags |= D3DCOMPILE_DEBUG; compileFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; //compileFlags |= D3DCOMPILE_WARNINGS_ARE_ERRORS; #else compileFlags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; #endif // Compile the programs // vertex res = D3DCompileFromFile(p_sourceFile, 0, D3D_COMPILE_STANDARD_FILE_INCLUDE, (LPCTSTR)p_entryPoint.c_str(), (LPCTSTR)p_profile.c_str(), compileFlags, 0, &shaderBlob, &blobError); if ( FAILED(res) ) { if (blobError!=NULL) throw D3DException(blobError,__FILE__,__FUNCTION__,__LINE__); else throw D3DException(res,__FILE__,__FUNCTION__,__LINE__); return; } *p_blob = shaderBlob; }
HRESULT Technique::setPixelShader(LPCWSTR filename, LPCSTR entryPoint, LPCSTR shaderModel, ID3D11Device* g_pd3dDevice){ HRESULT hr = S_OK; DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined( DEBUG ) || defined( _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; #endif ID3DBlob* pPSBlob = nullptr; ID3DBlob* pErrorBlob = nullptr; hr = D3DCompileFromFile(filename, nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, entryPoint, shaderModel, dwShaderFlags, 0, &pPSBlob, &pErrorBlob); if (FAILED(hr)) { if (pErrorBlob) { std::ofstream fout("Shader_Debug.txt"); fout << reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer()); OutputDebugStringA(reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer())); pErrorBlob->Release(); } } if (pErrorBlob) pErrorBlob->Release(); hr = g_pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader); if (FAILED(hr)) { pPSBlob->Release(); } pPSBlob->Release(); return hr; }
void Effect::ReadShaderFile(std::wstring filename, ID3DBlob **blob, char* target, char* entryPoint) { HRESULT hr; ID3DBlob* errMsg; hr = D3DCompileFromFile( filename.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, entryPoint, target, D3DCOMPILE_DEBUG, 0, blob, &errMsg ); #ifdef DEBUG if (errMsg) { Debug::Log((char*)errMsg->GetBufferPointer()); errMsg->Release(); } #endif HR(hr); }
HRESULT CompileShaderFromFile( WCHAR const* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3D10Blob** ppBlobOut ) { 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 ID3D10Blob* pErrorBlob = nullptr; HRESULT hr = D3DCompileFromFile( szFileName, nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, szEntryPoint, szShaderModel, dwShaderFlags, 0, ppBlobOut, &pErrorBlob ); if( FAILED(hr) ) { if( pErrorBlob ) { OutputDebugStringA( reinterpret_cast<const char*>( pErrorBlob->GetBufferPointer() ) ); MessageBoxA( nullptr, "The shader cannot be compiled. Check output for error info.", "Error", MB_OK ); } } #ifdef _DEBUG else { OutputDebugStringA( "Shader compilation successful\n" ); } #endif if( pErrorBlob ) { pErrorBlob->Release(); } return hr; }
HRESULT ShaderProgram::_compileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut ) { HRESULT hr = S_OK; 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* pErrorBlob = nullptr; // D3D_COMPILE_STANDARD_FILE_INCLUDE macro makes the compiler capable of interpreting #include directive. hr = D3DCompileFromFile( szFileName, nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, szEntryPoint, szShaderModel, dwShaderFlags, 0, ppBlobOut, &pErrorBlob ); _processError( hr, pErrorBlob ); return hr; }
void PixelShader::Initialize(GraphicsSystem& gs, const wchar_t* pFileName, const char* pEntryPoint, const char* pPixelShaderModel) { DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; #if defined(_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. shaderFlags |= D3DCOMPILE_DEBUG; #endif ID3DBlob* pShaderBlob = nullptr; ID3DBlob* pErrorBlob = nullptr; HRESULT hr = D3DCompileFromFile(pFileName, nullptr, nullptr, pEntryPoint, pPixelShaderModel, shaderFlags, 0, &pShaderBlob, &pErrorBlob); if (FAILED(hr) && pErrorBlob != nullptr) { OutputDebugStringA((char*)pErrorBlob->GetBufferPointer()); } SafeRelease(pErrorBlob); // Create pixel buffer hr = gs.GetDevice()->CreatePixelShader(pShaderBlob->GetBufferPointer(), pShaderBlob->GetBufferSize(), nullptr, &mpPixelShader); SafeRelease(pShaderBlob); }
bool LightShader::initializeShader(ID3D11Device * device, HWND hwnd, const WCHAR * vsFilename, const WCHAR * psFilename) { ID3D10Blob* errorBlob; ID3D10Blob* vertexShaderBlob; ID3D10Blob* pixelShaderBlob; UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; #if _DEBUG flags |= D3DCOMPILE_DEBUG; #endif // Compile the vertex shader code. if (FAILED(D3DCompileFromFile(vsFilename, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, "DiffuseLightVertexShader", Globals::VERTEX_SHADER_VERSION, flags, 0, &vertexShaderBlob, &errorBlob))) { if (errorBlob) { outputShaderErrorMessage(errorBlob, hwnd, vsFilename); } else { MessageBox(hwnd, vsFilename, L"Missing Vertex Shader File", MB_OK); } return false; } if (FAILED(D3DCompileFromFile(psFilename, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, "DiffuseLightPixelShader", Globals::PIXEL_SHADER_VERSION, flags, 0, &pixelShaderBlob, &errorBlob))) { if (errorBlob) { outputShaderErrorMessage(errorBlob, hwnd, psFilename); } else { MessageBox(hwnd, psFilename, L"Missing Pixel Shader File", MB_OK); } return false; } // Create the vertex shader from the buffer. if (FAILED(device->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &vertexShader))) { MessageBox(NULL, L"Error creating Vertex Shader", L"ERROR", MB_OK); return false; } // Create the pixel shader from the buffer. if (FAILED(device->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &pixelShader))) { MessageBox(NULL, L"Error creating Pixel Shader", L"ERROR", MB_OK); return false; } if (FAILED(initInputLayout(device, vertexShaderBlob))) { MessageBox(NULL, L"Error creating Input Layout Buffer", L"ERROR", MB_OK); return false; } safeRelease(vertexShaderBlob); safeRelease(pixelShaderBlob); if (FAILED(initMatrixBuffer(device))) { MessageBox(NULL, L"Error creating Constant (Matrix) Buffer", L"ERROR", MB_OK); return false; } if (FAILED(initSamplerState(device))) { MessageBox(NULL, L"Error creating Sampler Shader", L"ERROR", MB_OK); return false; } if (FAILED(initLightBuffer(device))) { return false; } return true; }
bool Shader::initialize( comptr<ID3D11Device> const device, const std::string& coreFname) { comptr<ID3D10Blob> errorMessage; std::string vFilename = IOManager::get().getFormatPath(IOManager::VER) + "v_" + coreFname; std::string pFilename = IOManager::get().getFormatPath(IOManager::PIX) + "p_" + coreFname; /* Vertex shader compilation */ HRESULT result; result = D3DCompileFromFile( util::stringToWString(vFilename).c_str(), NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, d3dconst::SHADER_FUNC, d3dconst::VS_PROFILE, D3D10_SHADER_ENABLE_STRICTNESS, NULL, &m_pVSBuffer, &errorMessage); if (FAILED(result)) { if (errorMessage) { std::wstring compileError = L"Shader compile error: " + util::stringToWString(vFilename); char* errorDesc = static_cast<char*>(errorMessage->GetBufferPointer()); MessageBox(NULL, errorDesc, "Fatal Error", MB_ICONERROR); } else { std::string missingFile = "Missing shader file: " + vFilename; MessageBox(NULL, missingFile.c_str(), "Fatal Error", MB_ICONERROR); } return false; } /* Vertex shader creation */ HR(device->CreateVertexShader( m_pVSBuffer->GetBufferPointer(), m_pVSBuffer->GetBufferSize(), NULL, &m_pVertexShader)); /* Pixel shader compilation */ result = D3DCompileFromFile( util::stringToWString(pFilename).c_str(), NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, d3dconst::SHADER_FUNC, d3dconst::PS_PROFILE, D3D10_SHADER_ENABLE_STRICTNESS, NULL, &m_pPSBuffer, &errorMessage); if (FAILED(result)) { if (errorMessage) { std::wstring compileError = L"Shader compile error: " + util::stringToWString(pFilename); char* errorDesc = static_cast<char*>(errorMessage->GetBufferPointer()); MessageBox(NULL, errorDesc, "Fatal Error", MB_ICONERROR); } else { std::string missingFile = "Missing shader file: " + pFilename; MessageBox(NULL, missingFile.c_str(), "Fatal Error", MB_ICONERROR); } return false; } /* Pixel shader creation */ HR(device->CreatePixelShader( m_pPSBuffer->GetBufferPointer(), m_pPSBuffer->GetBufferSize(), NULL, &m_pPixelShader)); /* Initialize constant matrix buffer */ D3D11_BUFFER_DESC mcbd = {}; mcbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; mcbd.ByteWidth = sizeof(MatrixBuffer); mcbd.CPUAccessFlags = 0; mcbd.Usage = D3D11_USAGE_DEFAULT; mcbd.StructureByteStride = 0; mcbd.MiscFlags = 0; HR(device->CreateBuffer(&mcbd, NULL, &m_pMatrixBuffer)); /* Initialize constant color buffer */ mcbd.ByteWidth = sizeof(ColorBuffer); HR(device->CreateBuffer(&mcbd, NULL, &m_pColorBuffer)); return true; }
// Load the sample assets. void D3D1211on12::LoadAssets() { // Create an empty root signature. { CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> error; ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_d3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature))); } // Create the pipeline state, which includes compiling and loading shaders. { ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; #if DEBUG // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); // Define the vertex input layout. D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; // Describe and create the graphics pipeline state object (PSO). D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; psoDesc.pRootSignature = m_rootSignature.Get(); psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() }; psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() }; psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; ThrowIfFailed(m_d3d12Device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); } ThrowIfFailed(m_d3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[m_frameIndex].Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList))); // Create D2D/DWrite objects for rendering text. { ThrowIfFailed(m_d2dDeviceContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &m_textBrush)); ThrowIfFailed(m_dWriteFactory->CreateTextFormat( L"Verdana", NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 50, L"en-us", &m_textFormat )); ThrowIfFailed(m_textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER)); ThrowIfFailed(m_textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER)); } ComPtr<ID3D12Resource> vertexBufferUpload; // Create the vertex buffer. { // Define the geometry for a triangle. Vertex triangleVertices[] = { { { 0.0f, 0.25f * m_aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, { { 0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, { { -0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } }; const UINT vertexBufferSize = sizeof(triangleVertices); ThrowIfFailed(m_d3d12Device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_vertexBuffer))); ThrowIfFailed(m_d3d12Device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&vertexBufferUpload))); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the vertex buffer. D3D12_SUBRESOURCE_DATA vertexData = {}; vertexData.pData = reinterpret_cast<UINT8*>(triangleVertices); vertexData.RowPitch = vertexBufferSize; vertexData.SlicePitch = vertexData.RowPitch; UpdateSubresources<1>(m_commandList.Get(), m_vertexBuffer.Get(), vertexBufferUpload.Get(), 0, 0, 1, &vertexData); m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.StrideInBytes = sizeof(Vertex); m_vertexBufferView.SizeInBytes = vertexBufferSize; } // Close the command list and execute it to begin the vertex buffer copy into // the default heap. ThrowIfFailed(m_commandList->Close()); ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Create synchronization objects and wait until assets have been uploaded to the GPU. { ThrowIfFailed(m_d3d12Device->CreateFence(m_fenceValues[m_frameIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_fence.GetAddressOf()))); m_fenceValues[m_frameIndex]++; // Create an event handle to use for frame synchronization. m_fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); if (m_fenceEvent == nullptr) { ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); } // Wait for the command list to execute; we are reusing the same command // list in our main loop but for now, we just want to wait for setup to // complete before continuing. WaitForGpu(); } }
void pipeline::InitShaders(){ HRESULT error; // load and compile the two shaders error = D3DCompileFromFile(L"shaders.hlsl", 0, 0, "VShader", "vs_5_0", 0, 0, &VS, 0); if (FAILED(error)) { MessageBox(NULL,L"OH NOES VShader Compile!",L"QUIT",NULL); } error = D3DCompileFromFile(L"shaders.hlsl", 0, 0, "PShader", "ps_5_0", 0, 0, &PS, 0); if (FAILED(error)) { MessageBox(NULL,L"OH NOES PShader Compile!",L"QUIT",NULL); } error = D3DCompileFromFile(L"shaders.hlsl", 0, 0, "VShaderTex", "vs_4_0", 0, 0, &VSTex, &bloberror); if (FAILED(error)) { MessageBox(NULL,L"OH NOES VShaderTex Compile!",L"QUIT",NULL); } error = D3DCompileFromFile(L"shaders.hlsl", 0, 0, "PShaderTex", "ps_4_0", 0, 0, &PSTex, 0); if (FAILED(error)) { MessageBox(NULL,L"OH NOES PShaderTex Compile!!",L"QUIT",NULL); } //char* errortext = (char*)bloberror->GetBufferPointer(); // encapsulate both shaders into shader objects std::ostringstream os; error = Device->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS); //MessageBox(NULL,(LPCWSTR)os.str().c_str(),(LPCWSTR)os.str().c_str(),NULL); os << (LONG)error; if (FAILED(error)) { MessageBoxA(NULL,os.str().c_str(),"QUIT",NULL); } error = Device->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS); //if (FAILED(error)) { MessageBox(NULL,L"OH NOES PS CREATE!",L"QUIT",NULL); } os << (LONG)error; if (FAILED(error)) { MessageBoxA(NULL,os.str().c_str(),"QUIT",NULL); } error = Device->CreateVertexShader(VSTex->GetBufferPointer(), VSTex->GetBufferSize(), NULL, &pVSTex); //if (FAILED(error)) { MessageBox(NULL,L"OH NOES VSTEX CREATE!",L"QUIT",NULL); } os << (LONG)error; if (FAILED(error)) { MessageBoxA(NULL,os.str().c_str(),"QUIT",NULL); } error = Device->CreatePixelShader(PSTex->GetBufferPointer(), PSTex->GetBufferSize(), NULL, &pPSTex); //if (FAILED(error)) { MessageBox(NULL,L"OH NOES PSTEXT CREATE!",L"QUIT",NULL); } os << (LONG)error; if (FAILED(error)) { MessageBoxA(NULL,os.str().c_str(),"QUIT",NULL); } //load the picture to a shader resource view error = CreateWICTextureFromFile(Device, devcon, L"./images/aship.JPEG",nullptr,&shiptexture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES WICLOADER BRICKS!",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/aprojectile.png",nullptr,&projtexture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES WICLOADER SHIP",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/aasteroid.png",nullptr,&asttexture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES WICLOADER SHIP",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/alvl1back1.png",nullptr,&lvl1back1texture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES LVL1BACK1",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/alvl1back2.png",nullptr,&lvl1back2texture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES LVL1BACK2",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/alvl1back3.png",nullptr,&lvl1back3texture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES LVL1BACK3",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/alvl1back4.png",nullptr,&lvl1back4texture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES LVL1BACK4",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/gameovertext.tif",nullptr,&gameovertexture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES gameover",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/armourtext.tif",nullptr,&armourtexttexture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES armourtext",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/shieldtext.tif",nullptr,&shieldtexttexture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES shieldtext",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/0text.tif",nullptr,&text0texture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES 0text",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/1text.tif",nullptr,&text1texture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES 1text",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/2text.tif",nullptr,&text2texture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES 2text",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/3text.tif",nullptr,&text3texture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES 3text",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/shield.tif",nullptr,&shieldtexture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES shield",L"QUIT",NULL); } error = CreateWICTextureFromFile(Device, devcon, L"./images/levelcleartext.tif",nullptr,&levelcompletetexture); if (FAILED(error)) { MessageBox(NULL,L"OH NOES levelcleartext",L"QUIT",NULL); } //sampler description D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(samplerDesc)); samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.MaxAnisotropy = 0; // Specify how texture coordinates outside of the range 0..1 are resolved. samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; // Use no special MIP clamping or bias. samplerDesc.MipLODBias = 0.0f; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; // Don't use a comparison function. samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; // Border address mode is not used, so this parameter is ignored. samplerDesc.BorderColor[0] = 0.0f; samplerDesc.BorderColor[1] = 0.0f; samplerDesc.BorderColor[2] = 0.0f; samplerDesc.BorderColor[3] = 0.0f; //make the sampler error = Device->CreateSamplerState(&samplerDesc,&pSampler); if (FAILED(error)) { MessageBox(NULL,L"OH NOES SAMPLER!",L"QUIT",NULL); } //set shader resource to that made from picture and set sampler //set inputlayouy D3D11_INPUT_ELEMENT_DESC InputDescTex[2] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0} }; D3D11_INPUT_ELEMENT_DESC InputDescColor[2] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0} }; error = Device->CreateInputLayout(InputDescTex, 2, VSTex->GetBufferPointer(), VSTex->GetBufferSize(), &InputLayout); //error = Device->CreateInputLayout(InputDescColor, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &InputLayout); if (FAILED(error)) { MessageBox(NULL,L"OH NOES INPUTLAYOUT iedtex!",L"QUIT",NULL); } D3D11_BLEND_DESC BlendStateDesc; ZeroMemory(&BlendStateDesc, sizeof(D3D10_BLEND_DESC)); BlendStateDesc.RenderTarget[0].BlendEnable = TRUE; BlendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; BlendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; BlendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; BlendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; BlendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; BlendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; BlendStateDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; float blendFactor[] = {0.0f, 0.0f, 0.0f, 0.0f}; Device->CreateBlendState(&BlendStateDesc, &pBlendState); devcon->OMSetBlendState(pBlendState,blendFactor,0xffffffff); devcon->VSSetShader(pVSTex, 0, 0); devcon->PSSetShader(pPSTex, 0, 0); //devcon->VSSetShader(pVS, 0, 0); //devcon->PSSetShader(pPS, 0, 0); devcon->PSSetSamplers(0,1,&pSampler); devcon->IASetInputLayout(InputLayout); }
void Triangle::init_shader(ComPtr<ID3D12Device> pD3D12Device) { CD3DX12_DESCRIPTOR_RANGE ranges[1]; CD3DX12_ROOT_PARAMETER rootParameters[1]; ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_VERTEX); // Allow input layout and deny uneccessary access to certain pipeline stages. D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS; //Create a root signature CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, rootSignatureFlags); ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> error; D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); pD3D12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_pRootSignature)); //Create the pipeline state, which includes compiling and loading shaders ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; #ifdef _DEBUG // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif D3DCompileFromFile(L"triangle.vsh", nullptr, nullptr, "VS_MAIN", "vs_5_0", compileFlags, 0, &vertexShader, nullptr); D3DCompileFromFile(L"triangle.psh", nullptr, nullptr, "PS_MAIN", "ps_5_0", compileFlags, 0, &pixelShader, nullptr); // Define the vertex input layout. D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; //Descrbe and create the graphics pipeline state object (PSO) D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = {inputElementDescs, _countof(inputElementDescs) }; psoDesc.pRootSignature = m_pRootSignature.Get(); psoDesc.VS = {vertexShader->GetBufferPointer(), vertexShader->GetBufferSize() }; psoDesc.PS = {pixelShader->GetBufferPointer(), pixelShader->GetBufferSize() }; psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; HRESULT res = pD3D12Device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pPipelineState)); assert(res == S_OK); }
// Load the sample assets. void D3D12HeterogeneousMultiadapter::LoadAssets() { // Create the root signatures. { CD3DX12_ROOT_PARAMETER rootParameters[2]; rootParameters[0].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_VERTEX); rootParameters[1].InitAsConstantBufferView(1, 0, D3D12_SHADER_VISIBILITY_PIXEL); CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> error; ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_devices[Primary]->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature))); CD3DX12_DESCRIPTOR_RANGE ranges[1]; ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); CD3DX12_ROOT_PARAMETER blurRootParameters[3]; blurRootParameters[0].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_PIXEL); blurRootParameters[1].InitAsDescriptorTable(_countof(ranges), ranges, D3D12_SHADER_VISIBILITY_PIXEL); blurRootParameters[2].InitAsConstantBufferView(1, 0, D3D12_SHADER_VISIBILITY_PIXEL); CD3DX12_STATIC_SAMPLER_DESC staticPointSampler(0); staticPointSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; staticPointSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; CD3DX12_STATIC_SAMPLER_DESC staticLinearSampler(1); staticLinearSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; staticLinearSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; D3D12_STATIC_SAMPLER_DESC staticSamplers[] = { staticPointSampler, staticLinearSampler }; rootSignatureDesc.Init(_countof(blurRootParameters), blurRootParameters, _countof(staticSamplers), staticSamplers, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_devices[Secondary]->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_blurRootSignature))); } // Create the pipeline states, which includes compiling and loading shaders. { ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; ComPtr<ID3DBlob> vertexShaderBlur; ComPtr<ID3DBlob> pixelShaderBlurU; ComPtr<ID3DBlob> pixelShaderBlurV; ComPtr<ID3DBlob> error; #if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VShader", "vs_5_0", compileFlags, 0, &vertexShader, &error)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PShader", "ps_5_0", compileFlags, 0, &pixelShader, &error)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"blurShaders.hlsl").c_str(), nullptr, nullptr, "VSSimpleBlur", "vs_5_0", compileFlags, 0, &vertexShaderBlur, &error)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"blurShaders.hlsl").c_str(), nullptr, nullptr, "PSSimpleBlurU", "ps_5_0", compileFlags, 0, &pixelShaderBlurU, &error)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"blurShaders.hlsl").c_str(), nullptr, nullptr, "PSSimpleBlurV", "ps_5_0", compileFlags, 0, &pixelShaderBlurV, &error)); // Define the vertex input layouts. const D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, }; const D3D12_INPUT_ELEMENT_DESC blurInputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, }; // Describe and create the graphics pipeline state objects (PSOs). D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; psoDesc.pRootSignature = m_rootSignature.Get(); psoDesc.VS = CD3DX12_SHADER_BYTECODE(vertexShader.Get()); psoDesc.PS = CD3DX12_SHADER_BYTECODE(pixelShader.Get()); psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT; psoDesc.SampleDesc.Count = 1; ThrowIfFailed(m_devices[Primary]->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); psoDesc.InputLayout = { blurInputElementDescs, _countof(blurInputElementDescs) }; psoDesc.pRootSignature = m_blurRootSignature.Get(); psoDesc.VS = CD3DX12_SHADER_BYTECODE(vertexShaderBlur.Get()); psoDesc.PS = CD3DX12_SHADER_BYTECODE(pixelShaderBlurU.Get()); psoDesc.DepthStencilState.DepthEnable = false; psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN; ThrowIfFailed(m_devices[Secondary]->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_blurPipelineStates[0]))); psoDesc.PS = CD3DX12_SHADER_BYTECODE(pixelShaderBlurV.Get()); ThrowIfFailed(m_devices[Secondary]->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_blurPipelineStates[1]))); } // Create the command lists. ThrowIfFailed(m_devices[Primary]->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_directCommandAllocators[Primary][m_frameIndex].Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_directCommandLists[Primary]))); ThrowIfFailed(m_devices[Primary]->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, m_copyCommandAllocators[m_frameIndex].Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_copyCommandList))); ThrowIfFailed(m_copyCommandList->Close()); ThrowIfFailed(m_devices[Secondary]->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_directCommandAllocators[Secondary][m_frameIndex].Get(), m_blurPipelineStates[0].Get(), IID_PPV_ARGS(&m_directCommandLists[Secondary]))); // Note: ComPtr's are CPU objects but these resources need to stay in scope until // the command list that references them has finished executing on the GPU. // We will flush the GPU at the end of this method to ensure the resources are not // prematurely destroyed. ComPtr<ID3D12Resource> vertexBufferUpload; ComPtr<ID3D12Resource> fullscreenQuadVertexBufferUpload; // Create the vertex buffer for the primary adapter. { // Define the geometry for a triangle. Vertex triangleVertices[] = { { { 0.0f, TriangleHalfWidth, TriangleDepth } }, { { TriangleHalfWidth, -TriangleHalfWidth, TriangleDepth } }, { { -TriangleHalfWidth, -TriangleHalfWidth, TriangleDepth } } }; const UINT vertexBufferSize = sizeof(triangleVertices); ThrowIfFailed(m_devices[Primary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_vertexBuffer))); ThrowIfFailed(m_devices[Primary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&vertexBufferUpload))); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the vertex buffer. D3D12_SUBRESOURCE_DATA vertexData = {}; vertexData.pData = reinterpret_cast<UINT8*>(triangleVertices); vertexData.RowPitch = vertexBufferSize; vertexData.SlicePitch = vertexData.RowPitch; UpdateSubresources<1>(m_directCommandLists[Primary].Get(), m_vertexBuffer.Get(), vertexBufferUpload.Get(), 0, 0, 1, &vertexData); m_directCommandLists[Primary]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.StrideInBytes = sizeof(Vertex); m_vertexBufferView.SizeInBytes = sizeof(triangleVertices); } // Create the vertex buffer for the secondary adapter. { // Define the geometry for a fullscreen triangle. VertexPositionUV quadVertices[] = { { { -1.0f, -1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f } }, // Bottom left. { { -1.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f } }, // Top left. { { 1.0f, -1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f } }, // Bottom right. { { 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f } }, // Top right. }; const UINT vertexBufferSize = sizeof(quadVertices); ThrowIfFailed(m_devices[Secondary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_fullscreenQuadVertexBuffer))); ThrowIfFailed(m_devices[Secondary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&fullscreenQuadVertexBufferUpload))); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the vertex buffer. D3D12_SUBRESOURCE_DATA vertexData = {}; vertexData.pData = reinterpret_cast<UINT8*>(quadVertices); vertexData.RowPitch = vertexBufferSize; vertexData.SlicePitch = vertexData.RowPitch; UpdateSubresources<1>(m_directCommandLists[Secondary].Get(), m_fullscreenQuadVertexBuffer.Get(), fullscreenQuadVertexBufferUpload.Get(), 0, 0, 1, &vertexData); m_directCommandLists[Secondary]->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_fullscreenQuadVertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); // Initialize the vertex buffer view. m_fullscreenQuadVertexBufferView.BufferLocation = m_fullscreenQuadVertexBuffer->GetGPUVirtualAddress(); m_fullscreenQuadVertexBufferView.StrideInBytes = sizeof(VertexPositionUV); m_fullscreenQuadVertexBufferView.SizeInBytes = sizeof(quadVertices); } // Create the depth stencil view. { D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {}; depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT; depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE; const CD3DX12_CLEAR_VALUE clearValue(DXGI_FORMAT_D32_FLOAT, 1.0f, 0); ThrowIfFailed(m_devices[Primary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_D32_FLOAT, m_width, m_height, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL), D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearValue, IID_PPV_ARGS(&m_depthStencil) )); m_devices[Primary]->CreateDepthStencilView(m_depthStencil.Get(), &depthStencilDesc, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); } // Create the constant buffers. { { const UINT64 constantBufferSize = sizeof(ConstantBufferData) * MaxTriangleCount * FrameCount; ThrowIfFailed(m_devices[Primary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(constantBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_constantBuffer))); // Setup constant buffer data. for (UINT n = 0; n < MaxTriangleCount; n++) { m_constantBufferData[n].velocity = XMFLOAT4(GetRandomFloat(0.01f, 0.02f), 0.0f, 0.0f, 0.0f); m_constantBufferData[n].offset = XMFLOAT4(GetRandomFloat(-5.0f, -1.5f), GetRandomFloat(-1.0f, 1.0f), GetRandomFloat(0.0f, 2.0f), 0.0f); m_constantBufferData[n].color = XMFLOAT4(GetRandomFloat(0.5f, 1.0f), GetRandomFloat(0.5f, 1.0f), GetRandomFloat(0.5f, 1.0f), 1.0f); XMStoreFloat4x4(&m_constantBufferData[n].projection, XMMatrixTranspose(XMMatrixPerspectiveFovLH(XM_PIDIV4, m_aspectRatio, 0.01f, 20.0f))); } // Map the constant buffer. We don't unmap this until the app closes. // Keeping things mapped for the lifetime of the resource is okay. CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. ThrowIfFailed(m_constantBuffer->Map(0, &readRange, reinterpret_cast<void**>(&m_pCbvDataBegin))); memcpy(m_pCbvDataBegin, &m_constantBufferData[0], constantBufferSize / FrameCount); } { const UINT64 workloadConstantBufferSize = sizeof(WorkloadConstantBufferData) * FrameCount; ThrowIfFailed(m_devices[Primary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(workloadConstantBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_workloadConstantBuffer))); // Setup constant buffer data. m_workloadConstantBufferData.loopCount = m_psLoopCount; // Map the constant buffer. We don't unmap this until the app closes. // Keeping things mapped for the lifetime of the resource is okay. CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. ThrowIfFailed(m_workloadConstantBuffer->Map(0, &readRange, reinterpret_cast<void**>(&m_pWorkloadCbvDataBegin))); memcpy(m_pWorkloadCbvDataBegin, &m_workloadConstantBufferData, workloadConstantBufferSize / FrameCount); } { const UINT64 blurWorkloadConstantBufferSize = sizeof(WorkloadConstantBufferData) * FrameCount; ThrowIfFailed(m_devices[Secondary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(blurWorkloadConstantBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_blurWorkloadConstantBuffer))); // Setup constant buffer data. m_blurWorkloadConstantBufferData.loopCount = m_blurPSLoopCount; // Map the constant buffer. We don't unmap this until the app closes. // Keeping things mapped for the lifetime of the resource is okay. CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. ThrowIfFailed(m_blurWorkloadConstantBuffer->Map(0, &readRange, reinterpret_cast<void**>(&m_pBlurWorkloadCbvDataBegin))); memcpy(m_pBlurWorkloadCbvDataBegin, &m_blurWorkloadConstantBufferData, blurWorkloadConstantBufferSize / FrameCount); } { ThrowIfFailed(m_devices[Secondary]->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(sizeof(BlurConstantBufferData)), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_blurConstantBuffer))); // Map the constant buffer. CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. ThrowIfFailed(m_blurConstantBuffer->Map(0, &readRange, reinterpret_cast<void**>(&m_pBlurCbvDataBegin))); // Setup constant buffer data. m_pBlurCbvDataBegin[0].offset = 0.5f; m_pBlurCbvDataBegin[0].textureDimensions.x = static_cast<float>(m_width); m_pBlurCbvDataBegin[0].textureDimensions.y = static_cast<float>(m_height); // Unmap the constant buffer because we don't update this again. // If we ever do, it should be buffered by the number of frames like other constant buffers. const CD3DX12_RANGE emptyRange(0, 0); m_blurConstantBuffer->Unmap(0, &emptyRange); m_pBlurCbvDataBegin = nullptr; } } // Close the command lists and execute them to begin the vertex buffer copies into the default heaps. for (UINT i = 0; i < GraphicsAdaptersCount; i++) { ThrowIfFailed(m_directCommandLists[i]->Close()); ID3D12CommandList* ppCommandLists[] = { m_directCommandLists[i].Get() }; m_directCommandQueues[i]->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); } // Create synchronization objects and wait until assets have been uploaded to the GPU. // We use a cross-adapter fence for handling Signals and Waits between adapters. // We use regular fences for things that don't need to be cross adapter because they don't need the additional overhead associated with being cross-adapter. { // Fence used to control CPU pacing. ThrowIfFailed(m_devices[Secondary]->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_frameFence))); // Fence used by the primary adapter to signal its copy queue that it has completed rendering. // When this is signaled, the primary adapter's copy queue can begin copying to the cross-adapter shared resource. ThrowIfFailed(m_devices[Primary]->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_renderFence))); // Cross-adapter shared fence used by both adapters. // Used by the primary adapter to signal the secondary adapter that it has completed copying to the cross-adapter shared resource. // When this is signaled, the secondary adapter can begin its work. ThrowIfFailed(m_devices[Primary]->CreateFence(0, D3D12_FENCE_FLAG_SHARED | D3D12_FENCE_FLAG_SHARED_CROSS_ADAPTER, IID_PPV_ARGS(&m_crossAdapterFences[Primary]))); // For now, require GENERIC_ALL access. HANDLE fenceHandle = nullptr; ThrowIfFailed(m_devices[Primary]->CreateSharedHandle( m_crossAdapterFences[Primary].Get(), nullptr, GENERIC_ALL, nullptr, &fenceHandle)); HRESULT openSharedHandleResult = m_devices[Secondary]->OpenSharedHandle(fenceHandle, IID_PPV_ARGS(&m_crossAdapterFences[Secondary])); // We can close the handle after opening the cross-adapter shared fence. CloseHandle(fenceHandle); ThrowIfFailed(openSharedHandleResult); for (UINT i = 0; i < GraphicsAdaptersCount; i++) { // Create an event handle to use for frame synchronization. m_fenceEvents[i] = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); if (m_fenceEvents == nullptr) { ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); } // Wait for the command list to execute; we are reusing the same command // list in our main loop but for now, we just want to wait for setup to // complete before continuing. WaitForGpu(static_cast<GraphicsAdapter>(i)); } } }
//test code to compile Test.hlsl bool Renderer::createShadersAndInputLayouts(void) { UINT flags1 = 0; #if _DEBUG flags1 |= D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_DEBUG; #endif ID3DBlob *vShaderCode = nullptr; ID3DBlob *pShaderCode = nullptr; ID3DBlob *gShaderCode = nullptr; ID3DBlob *errorCode = nullptr; HRESULT res; D3D11_INPUT_ELEMENT_DESC positionInputElement; positionInputElement.AlignedByteOffset = 0; positionInputElement.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; positionInputElement.InputSlot = 0; positionInputElement.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; positionInputElement.InstanceDataStepRate = 0; positionInputElement.SemanticName = "POSITION"; positionInputElement.SemanticIndex = 0; //create Texture shaders------------------------------------------------------------------------------------------------------------ if(FAILED(D3DCompileFromFile(GetShaderPath(L"Texture.hlsl").data(), nullptr, nullptr, "VShader", "vs_5_0", flags1, 0, &vShaderCode, &errorCode))) { SafeRelease<ID3DBlob>(&vShaderCode); if(errorCode) { OutputDebugStringA((LPCSTR)errorCode->GetBufferPointer()); SafeRelease<ID3DBlob>(&errorCode); } return false; } if(FAILED(D3DCompileFromFile(GetShaderPath(L"Texture.hlsl").data(), nullptr, nullptr, "PShader", "ps_5_0", flags1, 0, &pShaderCode, &errorCode))) { SafeRelease<ID3DBlob>(&pShaderCode); if(errorCode) { OutputDebugStringA((LPCSTR)errorCode->GetBufferPointer()); SafeRelease<ID3DBlob>(&errorCode); } return false; } if(FAILED(this->device->CreatePixelShader(pShaderCode->GetBufferPointer(), pShaderCode->GetBufferSize(), nullptr, &this->texturePShader))) { OutputDebugString("\n create texture pixel shader failed \n"); return false; } if(FAILED(this->device->CreateVertexShader(vShaderCode->GetBufferPointer(), vShaderCode->GetBufferSize(), nullptr, &this->textureVShader))) { OutputDebugString("\n create texture vertex shader failed \n"); return false; } D3D11_INPUT_ELEMENT_DESC textureInputElement; textureInputElement.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; textureInputElement.Format = DXGI_FORMAT_R32G32_FLOAT; textureInputElement.InputSlot = 0; textureInputElement.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; textureInputElement.InstanceDataStepRate = 0; textureInputElement.SemanticIndex = 0; textureInputElement.SemanticName = "TEXCOORD"; D3D11_INPUT_ELEMENT_DESC textureShaderInput[] = {positionInputElement, textureInputElement}; if(FAILED(this->device->CreateInputLayout(textureShaderInput, 2, vShaderCode->GetBufferPointer(), vShaderCode->GetBufferSize(), &this->textureInputLayout))) { OutputDebugString("\n Create textureShaderInput failed \n"); return false; } SafeRelease<ID3DBlob>(&vShaderCode); SafeRelease<ID3DBlob>(&pShaderCode); //create color shaders and input layout --------------------------------------------------------------------------------------------- if(FAILED(D3DCompileFromFile(GetShaderPath(L"Colored.hlsl").data(), nullptr, nullptr, "VShader", "vs_5_0", flags1, 0, &vShaderCode, &errorCode))) { SafeRelease<ID3DBlob>(&vShaderCode); if(errorCode) { OutputDebugStringA((LPCSTR)errorCode->GetBufferPointer()); SafeRelease<ID3DBlob>(&errorCode); } return false; } if(FAILED(D3DCompileFromFile(GetShaderPath(L"Colored.hlsl").data(), nullptr, nullptr, "PShader", "ps_5_0", flags1, 0, &pShaderCode, &errorCode))) { SafeRelease<ID3DBlob>(&pShaderCode); if(errorCode) { OutputDebugStringA((LPCSTR)errorCode->GetBufferPointer()); SafeRelease<ID3DBlob>(&errorCode); } return false; } if(FAILED(this->device->CreatePixelShader(pShaderCode->GetBufferPointer(), pShaderCode->GetBufferSize(), nullptr, &this->colorPShader))) { OutputDebugString("\n create colored pixel shader failed \n"); return false; } if(FAILED(this->device->CreateVertexShader(vShaderCode->GetBufferPointer(), vShaderCode->GetBufferSize(), nullptr, &this->colorVShader))) { OutputDebugString("\n create colored vertex shader failed \n"); return false; } D3D11_INPUT_ELEMENT_DESC colorIEArr[1] = {positionInputElement}; if(FAILED(this->device->CreateInputLayout(colorIEArr, 1, vShaderCode->GetBufferPointer(), vShaderCode->GetBufferSize(), &this->colorInputLayout))) { OutputDebugString("\n create colorIEArr failed \n"); return false; } SafeRelease<ID3DBlob>(&vShaderCode); SafeRelease<ID3DBlob>(&pShaderCode); return true; }
// Load the sample assets. void D3D12HelloTexture::LoadAssets() { // Create the root signature. { CD3DX12_DESCRIPTOR_RANGE ranges[1]; ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); CD3DX12_ROOT_PARAMETER rootParameters[1]; rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); D3D12_STATIC_SAMPLER_DESC sampler = {}; sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.MipLODBias = 0; sampler.MaxAnisotropy = 0; sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; sampler.MinLOD = 0.0f; sampler.MaxLOD = D3D12_FLOAT32_MAX; sampler.ShaderRegister = 0; sampler.RegisterSpace = 0; sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 1, &sampler, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> error; ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature))); } // Create the pipeline state, which includes compiling and loading shaders. { ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; #ifdef _DEBUG // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); // Define the vertex input layout. D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; // Describe and create the graphics pipeline state object (PSO). D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; psoDesc.pRootSignature = m_rootSignature.Get(); psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() }; psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() }; psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); } // Create the command list. ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList))); // Create the vertex buffer. { // Define the geometry for a triangle. Vertex triangleVertices[] = { { { 0.0f, 0.25f * m_aspectRatio, 0.0f }, { 0.5f, 0.0f } }, { { 0.25f, -0.25f * m_aspectRatio, 0.0f }, { 1.0f, 1.0f } }, { { -0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 1.0f } } }; const UINT vertexBufferSize = sizeof(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_vertexBuffer))); // Copy the triangle data to the vertex buffer. UINT8* pVertexDataBegin; ThrowIfFailed(m_vertexBuffer->Map(0, nullptr, reinterpret_cast<void**>(&pVertexDataBegin))); memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices)); m_vertexBuffer->Unmap(0, nullptr); // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.StrideInBytes = sizeof(Vertex); m_vertexBufferView.SizeInBytes = vertexBufferSize; } // Create an upload heap to load the texture onto the GPU. ComPtr's are CPU objects // but this heap needs to stay in scope until the GPU work is complete. We will // synchronize with the GPU at the end of this method before the ComPtr is destroyed. ComPtr<ID3D12Resource> textureUploadHeap; // Create the texture. { // Describe and create a Texture2D. D3D12_RESOURCE_DESC textureDesc = {}; textureDesc.MipLevels = 1; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.Width = TextureWidth; textureDesc.Height = TextureHeight; textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE; textureDesc.DepthOrArraySize = 1; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &textureDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_texture))); const UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_texture.Get(), 0, 1); // Create the GPU upload buffer. ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&textureUploadHeap))); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. std::vector<UINT8> texture = GenerateTextureData(); D3D12_SUBRESOURCE_DATA textureData = {}; textureData.pData = &texture[0]; textureData.RowPitch = TextureWidth * TexturePixelSize; textureData.SlicePitch = textureData.RowPitch * TextureHeight; UpdateSubresources(m_commandList.Get(), m_texture.Get(), textureUploadHeap.Get(), 0, 0, 1, &textureData); m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_texture.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); // Describe and create a SRV for the texture. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; srvDesc.Format = textureDesc.Format; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; m_device->CreateShaderResourceView(m_texture.Get(), &srvDesc, m_srvHeap->GetCPUDescriptorHandleForHeapStart()); } // Close the command list and execute it to begin the initial GPU setup. ThrowIfFailed(m_commandList->Close()); ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Create synchronization objects and wait until assets have been uploaded to the GPU. { ThrowIfFailed(m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence))); m_fenceValue = 1; // Create an event handle to use for frame synchronization. m_fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); if (m_fenceEvent == nullptr) { ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); } // Wait for the command list to execute; we are reusing the same command // list in our main loop but for now, we just want to wait for setup to // complete before continuing. WaitForPreviousFrame(); } }
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; } } }
// Load the sample assets. void D3D12HelloTriangle::LoadAssets() { // Create an empty root signature. { CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> error; ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature))); } // Create the pipeline state, which includes compiling and loading shaders. { ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; #if defined(_DEBUG) // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); // Define the vertex input layout. D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; // Describe and create the graphics pipeline state object (PSO). D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; psoDesc.pRootSignature = m_rootSignature.Get(); psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() }; psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() }; psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); } // Create the command list. ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList))); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. ThrowIfFailed(m_commandList->Close()); // Create the vertex buffer. { // Define the geometry for a triangle. Vertex triangleVertices[] = { { { 0.0f, 0.25f * m_aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, { { 0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, { { -0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } }; const UINT vertexBufferSize = sizeof(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_vertexBuffer))); // Copy the triangle data to the vertex buffer. UINT8* pVertexDataBegin; CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. ThrowIfFailed(m_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin))); memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices)); m_vertexBuffer->Unmap(0, nullptr); // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.StrideInBytes = sizeof(Vertex); m_vertexBufferView.SizeInBytes = vertexBufferSize; } // Create synchronization objects and wait until assets have been uploaded to the GPU. { ThrowIfFailed(m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence))); m_fenceValue = 1; // Create an event handle to use for frame synchronization. m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); if (m_fenceEvent == nullptr) { ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); } // Wait for the command list to execute; we are reusing the same command // list in our main loop but for now, we just want to wait for setup to // complete before continuing. WaitForPreviousFrame(); } }
void dx::initialise() { gDX.activeContextState = nullptr; gDX.activeDisplayList = nullptr; gDX.activeDisplayListSize = 0; gDX.activeDisplayListOffset = 0; for (auto i = 0; i < GX2_NUM_MRT_BUFFER; ++i) { gDX.activeColorBuffer[i] = nullptr; } gDX.activeDepthBuffer = nullptr; gDX.state.primitiveRestartIdx = 0xFFFFFFFF; gDX.viewport.Width = static_cast<float>(platform::ui::getWindowWidth()); gDX.viewport.Height = static_cast<float>(platform::ui::getWindowHeight()); gDX.viewport.MaxDepth = 1.0f; gDX.scissorRect.right = static_cast<LONG>(platform::ui::getWindowWidth()); gDX.scissorRect.bottom = static_cast<LONG>(platform::ui::getWindowHeight()); // Enable the D3D12 debug layer. { ComPtr<ID3D12Debug> debugController; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) { debugController->EnableDebugLayer(); } } ComPtr<IDXGIFactory4> factory; ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory))); // Always use WARP for now... static const bool USE_WARP_DEVICE = true; if (USE_WARP_DEVICE) { ComPtr<IDXGIAdapter> warpAdapter; ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter))); ThrowIfFailed(D3D12CreateDevice( warpAdapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&gDX.device) )); } else { ThrowIfFailed(D3D12CreateDevice( nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&gDX.device) )); } // Describe and create the command queue. D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; ThrowIfFailed(gDX.device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&gDX.commandQueue))); // Describe and create the swap chain. DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; swapChainDesc.BufferCount = gDX.FrameCount; swapChainDesc.BufferDesc.Width = platform::ui::getWindowWidth(); swapChainDesc.BufferDesc.Height = platform::ui::getWindowHeight(); swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; swapChainDesc.OutputWindow = reinterpret_cast<HWND>(platform::ui::getWindowHandle()); swapChainDesc.SampleDesc.Count = 1; swapChainDesc.Windowed = TRUE; ComPtr<IDXGISwapChain> swapChain; ThrowIfFailed(factory->CreateSwapChain( gDX.commandQueue.Get(), // Swap chain needs the queue so that it can force a flush on it. &swapChainDesc, &swapChain )); ThrowIfFailed(swapChain.As(&gDX.swapChain)); gDX.frameIndex = gDX.swapChain->GetCurrentBackBufferIndex(); // Create descriptor heaps. { // Describe and create a render target view (RTV) descriptor heap. D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; rtvHeapDesc.NumDescriptors = gDX.FrameCount + 128; rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; gDX.rtvHeap = new DXHeap(gDX.device.Get(), rtvHeapDesc); // Describe and create a depth stencil view (DSV) descriptor heap. D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {}; dsvHeapDesc.NumDescriptors = 128; dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; gDX.dsvHeap = new DXHeap(gDX.device.Get(), dsvHeapDesc); // Describe and create a constant buffer view (CBV), Shader resource // view (SRV), and unordered access view (UAV) descriptor heap. D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {}; srvHeapDesc.NumDescriptors = 2048; srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; gDX.srvHeap = new DXHeap(gDX.device.Get(), srvHeapDesc); } // Create frame resources. { // Create a RTV for each frame. for (UINT n = 0; n < gDX.FrameCount; n++) { ThrowIfFailed(gDX.swapChain->GetBuffer(n, IID_PPV_ARGS(&gDX.renderTargets[n]))); gDX.scanbufferRtv[n] = gDX.rtvHeap->alloc(); gDX.device->CreateRenderTargetView(gDX.renderTargets[n].Get(), nullptr, *gDX.scanbufferRtv[n]); } } // Create command allocators. { for (UINT n = 0; n < gDX.FrameCount; n++) { ThrowIfFailed(gDX.device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&gDX.commandAllocator[n]))); } } // Create the root signature. { CD3DX12_DESCRIPTOR_RANGE ranges[GX2_NUM_SAMPLERS]; CD3DX12_ROOT_PARAMETER rootParameters[GX2_NUM_SAMPLERS + GX2_NUM_UNIFORMBLOCKS]; uint32_t paramIdx = 0; for (auto i = 0; i < GX2_NUM_UNIFORMBLOCKS; ++i) { gDX.cbvIndex[i] = paramIdx; rootParameters[paramIdx++].InitAsConstantBufferView(i, 0, D3D12_SHADER_VISIBILITY_ALL); } for (auto i = 0; i < GX2_NUM_SAMPLERS; ++i) { gDX.srvIndex[i] = paramIdx; ranges[i].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, i); rootParameters[paramIdx++].InitAsDescriptorTable(1, &ranges[i], D3D12_SHADER_VISIBILITY_ALL); } D3D12_STATIC_SAMPLER_DESC samplers[GX2_NUM_SAMPLERS]; for (int i = 0; i < GX2_NUM_SAMPLERS; ++i) { auto &sampler = samplers[i] = {}; sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER; sampler.MipLODBias = 0; sampler.MaxAnisotropy = 0; sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER; sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; sampler.MinLOD = 0.0f; sampler.MaxLOD = D3D12_FLOAT32_MAX; sampler.ShaderRegister = i; sampler.RegisterSpace = 0; sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; } CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(_countof(rootParameters), rootParameters, GX2_NUM_SAMPLERS, samplers, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> error; ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(gDX.device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&gDX.rootSignature))); } // Create the pipeline state, which includes compiling and loading shaders. { ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; #ifdef _DEBUG // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif ThrowIfFailed(D3DCompileFromFile(L"resources/shaders/screendraw.hlsl", nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); ThrowIfFailed(D3DCompileFromFile(L"resources/shaders/screendraw.hlsl", nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); // Define the vertex input layout. D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; { D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; psoDesc.pRootSignature = gDX.rootSignature.Get(); psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() }; psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() }; psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; ThrowIfFailed(gDX.device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&gDX.emuPipelineState))); } } gDX.pipelineMgr = new DXPipelineMgr(); // Create the command list. gDX.frameIndex = gDX.swapChain->GetCurrentBackBufferIndex(); ThrowIfFailed(gDX.device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, gDX.commandAllocator[gDX.frameIndex].Get(), gDX.emuPipelineState.Get(), IID_PPV_ARGS(&gDX.commandList))); { #define SCREENSPACE(x, y) { -1 + ((x) / (float)platform::ui::getWindowWidth()) * 2, 1 - ((y) / (float)platform::ui::getWindowHeight()) * 2, 0.0f } float tvX = 0; float tvY = 0; float tvWidth = static_cast<float>(platform::ui::getTvWidth()); float tvHeight = static_cast<float>(platform::ui::getTvHeight()); float drcX = (tvWidth - static_cast<float>(platform::ui::getDrcWidth())) / 2.0f; float drcY = tvHeight; float drcWidth = static_cast<float>(platform::ui::getDrcWidth()); float drcHeight = static_cast<float>(platform::ui::getDrcHeight()); struct Vertex { XMFLOAT3 pos; XMFLOAT2 uv; } triangleVertices[] = { { SCREENSPACE(tvX, tvY + tvHeight),{ 0.0f, 1.0f } }, { SCREENSPACE(tvX, tvY),{ 0.0f, 0.0f } }, { SCREENSPACE(tvX + tvWidth, tvY + tvHeight),{ 1.0f, 1.0f } }, { SCREENSPACE(tvX + tvWidth, tvY),{ 1.0f, 0.0f } }, { SCREENSPACE(drcX, drcY + drcHeight),{ 0.0f, 1.0f } }, { SCREENSPACE(drcX, drcY),{ 0.0f, 0.0f } }, { SCREENSPACE(drcX + drcWidth, drcY + drcHeight),{ 1.0f, 1.0f } }, { SCREENSPACE(drcX + drcWidth, drcY),{ 1.0f, 0.0f } }, }; #undef SCREENSPACE const UINT vertexBufferSize = sizeof(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. ThrowIfFailed(gDX.device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&gDX.vertexBuffer))); // Copy the triangle data to the vertex buffer. UINT8* pVertexDataBegin; ThrowIfFailed(gDX.vertexBuffer->Map(0, nullptr, reinterpret_cast<void**>(&pVertexDataBegin))); memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices)); gDX.vertexBuffer->Unmap(0, nullptr); // Initialize the vertex buffer view. gDX.vertexBufferView.BufferLocation = gDX.vertexBuffer->GetGPUVirtualAddress(); gDX.vertexBufferView.StrideInBytes = sizeof(Vertex); gDX.vertexBufferView.SizeInBytes = vertexBufferSize; } // 10MB Temporary Vertex Buffer gDX.ppcVertexBuffer = new DXDynBuffer(gDX.device.Get(), 10 * 1024 * 1024); // Close the command list and execute it to begin the initial GPU setup. ThrowIfFailed(gDX.commandList->Close()); ID3D12CommandList* ppCommandLists[] = { gDX.commandList.Get() }; gDX.commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Create synchronization objects. { ThrowIfFailed(gDX.device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&gDX.fence))); // Create an event handle to use for frame synchronization. gDX.fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); if (gDX.fenceEvent == nullptr) { ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); } // Wait for frame completion gDX.swapCount++; const uint64_t fenceValue = gDX.swapCount; ThrowIfFailed(gDX.commandQueue->Signal(gDX.fence.Get(), fenceValue)); if (gDX.fence->GetCompletedValue() < gDX.swapCount) { ThrowIfFailed(gDX.fence->SetEventOnCompletion(gDX.swapCount, gDX.fenceEvent)); WaitForSingleObject(gDX.fenceEvent, INFINITE); } } _beginFrame(); }
// Load the sample assets. void D3D12HelloConstBuffers::LoadAssets() { // Create a root signature consisting of a single CBV parameter. { CD3DX12_DESCRIPTOR_RANGE ranges[1]; CD3DX12_ROOT_PARAMETER rootParameters[1]; ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_VERTEX); // Allow input layout and deny uneccessary access to certain pipeline stages. D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS | D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS; CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, rootSignatureFlags); ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> error; ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature))); } // Create the pipeline state, which includes compiling and loading shaders. { ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; #if DEBUG // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = 0; #endif ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); // Define the vertex input layout. D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } }; // Describe and create the graphics pipeline state object (PSO). D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; psoDesc.pRootSignature = m_rootSignature.Get(); psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() }; psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() }; psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState.DepthEnable = FALSE; psoDesc.DepthStencilState.StencilEnable = FALSE; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); } // Create the command list. ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_commandList))); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. ThrowIfFailed(m_commandList->Close()); // Create the vertex buffer. { // Define the geometry for a triangle. Vertex triangleVertices[] = { { { 0.0f, 0.25f * m_aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, { { 0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, { { -0.25f, -0.25f * m_aspectRatio, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } }; const UINT vertexBufferSize = sizeof(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_vertexBuffer))); // Copy the triangle data to the vertex buffer. UINT8* pVertexDataBegin; ThrowIfFailed(m_vertexBuffer->Map(0, nullptr, reinterpret_cast<void**>(&pVertexDataBegin))); memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices)); m_vertexBuffer->Unmap(0, nullptr); // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.StrideInBytes = sizeof(Vertex); m_vertexBufferView.SizeInBytes = vertexBufferSize; } // Create the constant buffer. { ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(1024 * 64), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_constantBuffer))); // Describe and create a constant buffer view. D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; cbvDesc.BufferLocation = m_constantBuffer->GetGPUVirtualAddress(); cbvDesc.SizeInBytes = (sizeof(ConstantBuffer) + 255) & ~255; // CB size is required to be 256-byte aligned. m_device->CreateConstantBufferView(&cbvDesc, m_cbvHeap->GetCPUDescriptorHandleForHeapStart()); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. ZeroMemory(&m_constantBufferData, sizeof(m_constantBufferData)); ThrowIfFailed(m_constantBuffer->Map(0, nullptr, reinterpret_cast<void**>(&m_pCbvDataBegin))); memcpy(m_pCbvDataBegin, &m_constantBufferData, sizeof(m_constantBufferData)); } // Create and record the bundle. { ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_BUNDLE, m_bundleAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&m_bundle))); m_bundle->SetDescriptorHeaps(1, m_cbvHeap.GetAddressOf()); m_bundle->SetGraphicsRootSignature(m_rootSignature.Get()); m_bundle->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_bundle->IASetVertexBuffers(0, 1, &m_vertexBufferView); m_bundle->SetGraphicsRootDescriptorTable(0, m_cbvHeap->GetGPUDescriptorHandleForHeapStart()); m_bundle->DrawInstanced(3, 1, 0, 0); ThrowIfFailed(m_bundle->Close()); } // Create synchronization objects and wait until assets have been uploaded to the GPU. { ThrowIfFailed(m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence))); m_fenceValue = 1; // Create an event handle to use for frame synchronization. m_fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); if (m_fenceEvent == nullptr) { ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); } // Wait for the command list to execute; we are reusing the same command // list in our main loop but for now, we just want to wait for setup to // complete before continuing. WaitForPreviousFrame(); } }
void CubeDemo::initialize() { SetCurrentDirectory(Utility::ExecutableDirectory().c_str()); UINT shaderFlags = 0; #if defined(DEBUG) || defined(_DEBUG) shaderFlags |= D3DCOMPILE_DEBUG; shaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3D10Blob * compiledShader = nullptr; ID3D10Blob * errorMessages = nullptr; HRESULT hr = D3DCompileFromFile(L"Content\\Effects\\BasicEffect.fx", nullptr, nullptr, nullptr, "fx_5_0", shaderFlags, 0, &compiledShader, &errorMessages); //if (errorMessages != nullptr) //{ // char * message = (char*)errorMessages->GetBufferPointer(); // GameException ex((wchar_t*)errorMessages->GetBufferPointer(), hr); // ReleaseObject(errorMessages); // throw ex; // //ReleaseObject(compiledShader); //} if (FAILED(hr)) { throw GameException(L"D3DX11CompileFromFile() failed.", hr); } hr = D3DX11CreateEffectFromMemory(compiledShader->GetBufferPointer(), compiledShader->GetBufferSize(), 0, mGame->device(), &mEffect); if (FAILED(hr)) { throw GameException(L"D3DX11CreateEffectFromMemory() failed", hr); } ReleaseObject(compiledShader); mTechnique = mEffect->GetTechniqueByName("main11"); if (mTechnique == nullptr) { throw GameException(L"ID3D11Effect::GetTechniqueByName() unable to find techique main11.", hr); } mPass = mTechnique->GetPassByName("p0"); if (mPass == nullptr) { throw GameException(L"ID3D11EffectTechnique::GetPassByName() unable to find pass p0", hr); } ID3DX11EffectVariable * variable = mEffect->GetVariableByName("WorldViewProjection"); if (variable == nullptr) { throw GameException(L"ID3DX11Effect::GetVariableByName() unable to find variable WorldViewProjection"); } mWvpVariable = variable->AsMatrix(); if (!mWvpVariable->IsValid()) { throw GameException(L"Invaild effect variable cast"); } D3DX11_PASS_DESC passDesc; mPass->GetDesc(&passDesc); D3D11_INPUT_ELEMENT_DESC inputElementDescriptions[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; if (FAILED(hr = mGame->device()->CreateInputLayout(inputElementDescriptions, ARRAYSIZE(inputElementDescriptions), passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &mInputLayout))) { throw GameException(L"ID3D11Device::CreateInputLayout() failed", hr); } BasicEffectVertex vertices[] = { BasicEffectVertex(XMFLOAT4(-1.0f, 1.0f, -1.0f, 1.0f), XMFLOAT4(reinterpret_cast<float*>(&Colors::RED))), BasicEffectVertex(XMFLOAT4(1.0f, 1.0f, -1.0f, 1.0f), XMFLOAT4(reinterpret_cast<float*>(&Colors::GREEN))), BasicEffectVertex(XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f), XMFLOAT4(reinterpret_cast<float*>(&Colors::BLACK))) , BasicEffectVertex(XMFLOAT4(-1.0f, 1.0f, 1.0f, 1.0f), XMFLOAT4(reinterpret_cast<float*>(&Colors::WHITE))), BasicEffectVertex(XMFLOAT4(-1.0f,- 1.0f, 1.0f, 1.0f), XMFLOAT4(reinterpret_cast<float*>(&Colors::YELLOW))), BasicEffectVertex(XMFLOAT4(+1.0f, -1.0f, +1.0f, 1.0f), XMFLOAT4(reinterpret_cast<float*>(&Colors::BLACK))), BasicEffectVertex(XMFLOAT4(1.0f, -1.0f, -1.0f, 1.0f), XMFLOAT4(reinterpret_cast<float*>(&Colors::CYAN))), BasicEffectVertex(XMFLOAT4(-1.0f, -1.0f, -1.0f, 1.0f), XMFLOAT4(reinterpret_cast<float*>(&Colors::GREEN))) }; D3D11_BUFFER_DESC vertexBufferDesc; ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc)); vertexBufferDesc.ByteWidth = sizeof(BasicEffectVertex)* ARRAYSIZE(vertices); vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA vertexSubResourceData; ZeroMemory(&vertexSubResourceData, sizeof(vertexSubResourceData)); vertexSubResourceData.pSysMem = vertices; if (FAILED(mGame->device()->CreateBuffer(&vertexBufferDesc, &vertexSubResourceData, &mVertexBuffer))) { throw GameException(L"ID3D11Device::CreateBuffer() failed"); } UINT indices[] = { 0,1,2, 0,2,3, 4,5,6, 4,6,7, 3,2,5, 3,5,4, 2,1,6, 2,6,5, 1,7,6, 1,0,7, 0,3,4, 0,4,7, }; D3D11_BUFFER_DESC indexBufferDesc; ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc)); indexBufferDesc.ByteWidth = sizeof(indices); indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; D3D11_SUBRESOURCE_DATA indexSubResourceData; ZeroMemory(&indexSubResourceData, sizeof(indexSubResourceData)); indexSubResourceData.pSysMem = indices; if (FAILED(mGame->device()->CreateBuffer(&indexBufferDesc, &indexSubResourceData, &mIndexBuffer))) { throw GameException(L"ID3D11Device::CreateBuffer() failed"); } mCamera->setPosition(0.0f, 0.0f, 5.0f); }
// Load the sample assets. void D3D12Multithreading::LoadAssets() { // Create the root signature. { CD3DX12_DESCRIPTOR_RANGE ranges[4]; // Perfomance TIP: Order from most frequent to least frequent. ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 2, 1); // 2 frequently changed diffuse + normal textures - using registers t1 and t2. ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0); // 1 frequently changed constant buffer. ranges[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0); // 1 infrequently changed shadow texture - starting in register t0. ranges[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 2, 0); // 2 static samplers. CD3DX12_ROOT_PARAMETER rootParameters[4]; rootParameters[0].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_PIXEL); rootParameters[1].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_ALL); rootParameters[2].InitAsDescriptorTable(1, &ranges[2], D3D12_SHADER_VISIBILITY_PIXEL); rootParameters[3].InitAsDescriptorTable(1, &ranges[3], D3D12_SHADER_VISIBILITY_PIXEL); CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; rootSignatureDesc.Init(_countof(rootParameters), rootParameters, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); ComPtr<ID3DBlob> signature; ComPtr<ID3DBlob> error; ThrowIfFailed(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error)); ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature))); } // Create the pipeline state, which includes loading shaders. { ComPtr<ID3DBlob> vertexShader; ComPtr<ID3DBlob> pixelShader; #ifdef _DEBUG // Enable better shader debugging with the graphics debugging tools. UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; #else UINT compileFlags = D3DCOMPILE_OPTIMIZATION_LEVEL3; #endif ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr)); ThrowIfFailed(D3DCompileFromFile(GetAssetFullPath(L"shaders.hlsl").c_str(), nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr)); D3D12_INPUT_LAYOUT_DESC inputLayoutDesc; inputLayoutDesc.pInputElementDescs = SampleAssets::StandardVertexDescription; inputLayoutDesc.NumElements = _countof(SampleAssets::StandardVertexDescription); CD3DX12_DEPTH_STENCIL_DESC depthStencilDesc(D3D12_DEFAULT); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL; depthStencilDesc.StencilEnable = FALSE; // Describe and create the PSO for rendering the scene. D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = inputLayoutDesc; psoDesc.pRootSignature = m_rootSignature.Get(); psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()), vertexShader->GetBufferSize() }; psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()), pixelShader->GetBufferSize() }; psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoDesc.DepthStencilState = depthStencilDesc; psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.DSVFormat = DXGI_FORMAT_D32_FLOAT; psoDesc.SampleDesc.Count = 1; ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineState))); // Alter the description and create the PSO for rendering // the shadow map. The shadow map does not use a pixel // shader or render targets. psoDesc.PS.pShaderBytecode = 0; psoDesc.PS.BytecodeLength = 0; psoDesc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN; psoDesc.NumRenderTargets = 0; ThrowIfFailed(m_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_pipelineStateShadowMap))); } // Create temporary command list for initial GPU setup. ComPtr<ID3D12GraphicsCommandList> commandList; ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator.Get(), m_pipelineState.Get(), IID_PPV_ARGS(&commandList))); // Create render target views (RTVs). CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart()); for (UINT i = 0; i < FrameCount; i++) { ThrowIfFailed(m_swapChain->GetBuffer(i, IID_PPV_ARGS(&m_renderTargets[i]))); m_device->CreateRenderTargetView(m_renderTargets[i].Get(), nullptr, rtvHandle); rtvHandle.Offset(1, m_rtvDescriptorSize); } // Create the depth stencil. { CD3DX12_RESOURCE_DESC shadowTextureDesc( D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, static_cast<UINT>(m_viewport.Width), static_cast<UINT>(m_viewport.Height), 1, 1, DXGI_FORMAT_D32_FLOAT, 1, 0, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL | D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE); D3D12_CLEAR_VALUE clearValue; // Performance tip: Tell the runtime at resource creation the desired clear value. clearValue.Format = DXGI_FORMAT_D32_FLOAT; clearValue.DepthStencil.Depth = 1.0f; clearValue.DepthStencil.Stencil = 0; ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &shadowTextureDesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearValue, IID_PPV_ARGS(&m_depthStencil))); // Create the depth stencil view. m_device->CreateDepthStencilView(m_depthStencil.Get(), nullptr, m_dsvHeap->GetCPUDescriptorHandleForHeapStart()); } // Load scene assets. UINT fileSize = 0; UINT8* pAssetData; ThrowIfFailed(ReadDataFromFile(GetAssetFullPath(SampleAssets::DataFileName).c_str(), &pAssetData, &fileSize)); // Create the vertex buffer. { ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_vertexBuffer))); { ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::VertexDataSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_vertexBufferUpload))); // Copy data to the upload heap and then schedule a copy // from the upload heap to the vertex buffer. D3D12_SUBRESOURCE_DATA vertexData = {}; vertexData.pData = pAssetData + SampleAssets::VertexDataOffset; vertexData.RowPitch = SampleAssets::VertexDataSize; vertexData.SlicePitch = vertexData.RowPitch; PIXBeginEvent(commandList.Get(), 0, L"Copy vertex buffer data to default resource..."); UpdateSubresources<1>(commandList.Get(), m_vertexBuffer.Get(), m_vertexBufferUpload.Get(), 0, 0, 1, &vertexData); commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER)); PIXEndEvent(commandList.Get()); } // Initialize the vertex buffer view. m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress(); m_vertexBufferView.SizeInBytes = SampleAssets::VertexDataSize; m_vertexBufferView.StrideInBytes = SampleAssets::StandardVertexStride; } // Create the index buffer. { ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_indexBuffer))); { ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(SampleAssets::IndexDataSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_indexBufferUpload))); // Copy data to the upload heap and then schedule a copy // from the upload heap to the index buffer. D3D12_SUBRESOURCE_DATA indexData = {}; indexData.pData = pAssetData + SampleAssets::IndexDataOffset; indexData.RowPitch = SampleAssets::IndexDataSize; indexData.SlicePitch = indexData.RowPitch; PIXBeginEvent(commandList.Get(), 0, L"Copy index buffer data to default resource..."); UpdateSubresources<1>(commandList.Get(), m_indexBuffer.Get(), m_indexBufferUpload.Get(), 0, 0, 1, &indexData); commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER)); PIXEndEvent(commandList.Get()); } // Initialize the index buffer view. m_indexBufferView.BufferLocation = m_indexBuffer->GetGPUVirtualAddress(); m_indexBufferView.SizeInBytes = SampleAssets::IndexDataSize; m_indexBufferView.Format = SampleAssets::StandardIndexFormat; } // Create shader resources. { // Get the CBV SRV descriptor size for the current device. const UINT cbvSrvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); // Get a handle to the start of the descriptor heap. CD3DX12_CPU_DESCRIPTOR_HANDLE cbvSrvHandle(m_cbvSrvHeap->GetCPUDescriptorHandleForHeapStart()); { // Describe and create 2 null SRVs. Null descriptors are needed in order // to achieve the effect of an "unbound" resource. D3D12_SHADER_RESOURCE_VIEW_DESC nullSrvDesc = {}; nullSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; nullSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; nullSrvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; nullSrvDesc.Texture2D.MipLevels = 1; nullSrvDesc.Texture2D.MostDetailedMip = 0; nullSrvDesc.Texture2D.ResourceMinLODClamp = 0.0f; m_device->CreateShaderResourceView(nullptr, &nullSrvDesc, cbvSrvHandle); cbvSrvHandle.Offset(cbvSrvDescriptorSize); m_device->CreateShaderResourceView(nullptr, &nullSrvDesc, cbvSrvHandle); cbvSrvHandle.Offset(cbvSrvDescriptorSize); } // Create each texture and SRV descriptor. const UINT srvCount = _countof(SampleAssets::Textures); PIXBeginEvent(commandList.Get(), 0, L"Copy diffuse and normal texture data to default resources..."); for (int i = 0; i < srvCount; i++) { // Describe and create a Texture2D. const SampleAssets::TextureResource &tex = SampleAssets::Textures[i]; CD3DX12_RESOURCE_DESC texDesc( D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, tex.Width, tex.Height, 1, static_cast<UINT16>(tex.MipLevels), tex.Format, 1, 0, D3D12_TEXTURE_LAYOUT_UNKNOWN, D3D12_RESOURCE_FLAG_NONE); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &texDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_textures[i]))); { const UINT subresourceCount = texDesc.DepthOrArraySize * texDesc.MipLevels; UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_textures[i].Get(), 0, subresourceCount); ThrowIfFailed(m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_textureUploads[i]))); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. D3D12_SUBRESOURCE_DATA textureData = {}; textureData.pData = pAssetData + tex.Data->Offset; textureData.RowPitch = tex.Data->Pitch; textureData.SlicePitch = tex.Data->Size; UpdateSubresources(commandList.Get(), m_textures[i].Get(), m_textureUploads[i].Get(), 0, 0, subresourceCount, &textureData); commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_textures[i].Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)); } // Describe and create an SRV. D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; srvDesc.Format = tex.Format; srvDesc.Texture2D.MipLevels = tex.MipLevels; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.ResourceMinLODClamp = 0.0f; m_device->CreateShaderResourceView(m_textures[i].Get(), &srvDesc, cbvSrvHandle); // Move to the next descriptor slot. cbvSrvHandle.Offset(cbvSrvDescriptorSize); } PIXEndEvent(commandList.Get()); } free(pAssetData); // Create the samplers. { // Get the sampler descriptor size for the current device. const UINT samplerDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); // Get a handle to the start of the descriptor heap. CD3DX12_CPU_DESCRIPTOR_HANDLE samplerHandle(m_samplerHeap->GetCPUDescriptorHandleForHeapStart()); // Describe and create the wrapping sampler, which is used for // sampling diffuse/normal maps. D3D12_SAMPLER_DESC wrapSamplerDesc = {}; wrapSamplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; wrapSamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; wrapSamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; wrapSamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; wrapSamplerDesc.MinLOD = 0; wrapSamplerDesc.MaxLOD = D3D12_FLOAT32_MAX; wrapSamplerDesc.MipLODBias = 0.0f; wrapSamplerDesc.MaxAnisotropy = 1; wrapSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; wrapSamplerDesc.BorderColor[0] = wrapSamplerDesc.BorderColor[1] = wrapSamplerDesc.BorderColor[2] = wrapSamplerDesc.BorderColor[3] = 0; m_device->CreateSampler(&wrapSamplerDesc, samplerHandle); // Move the handle to the next slot in the descriptor heap. samplerHandle.Offset(samplerDescriptorSize); // Describe and create the point clamping sampler, which is // used for the shadow map. D3D12_SAMPLER_DESC clampSamplerDesc = {}; clampSamplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; clampSamplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; clampSamplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; clampSamplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; clampSamplerDesc.MipLODBias = 0.0f; clampSamplerDesc.MaxAnisotropy = 1; clampSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; clampSamplerDesc.BorderColor[0] = clampSamplerDesc.BorderColor[1] = clampSamplerDesc.BorderColor[2] = clampSamplerDesc.BorderColor[3] = 0; clampSamplerDesc.MinLOD = 0; clampSamplerDesc.MaxLOD = D3D12_FLOAT32_MAX; m_device->CreateSampler(&clampSamplerDesc, samplerHandle); } // Create lights. for (int i = 0; i < NumLights; i++) { // Set up each of the light positions and directions (they all start // in the same place). m_lights[i].position = { 0.0f, 15.0f, -30.0f, 1.0f }; m_lights[i].direction = { 0.0, 0.0f, 1.0f, 0.0f }; m_lights[i].falloff = { 800.0f, 1.0f, 0.0f, 1.0f }; m_lights[i].color = { 0.7f, 0.7f, 0.7f, 1.0f }; XMVECTOR eye = XMLoadFloat4(&m_lights[i].position); XMVECTOR at = XMVectorAdd(eye, XMLoadFloat4(&m_lights[i].direction)); XMVECTOR up = { 0, 1, 0 }; m_lightCameras[i].Set(eye, at, up); } // Close the command list and use it to execute the initial GPU setup. ThrowIfFailed(commandList->Close()); ID3D12CommandList* ppCommandLists[] = { commandList.Get() }; m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Create frame resources. for (int i = 0; i < FrameCount; i++) { m_frameResources[i] = new FrameResource(m_device.Get(), m_pipelineState.Get(), m_pipelineStateShadowMap.Get(), m_dsvHeap.Get(), m_cbvSrvHeap.Get(), &m_viewport, i); m_frameResources[i]->WriteConstantBuffers(&m_viewport, &m_camera, m_lightCameras, m_lights); } m_currentFrameResourceIndex = 0; m_pCurrentFrameResource = m_frameResources[m_currentFrameResourceIndex]; // Create synchronization objects and wait until assets have been uploaded to the GPU. { ThrowIfFailed(m_device->CreateFence(m_fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence))); m_fenceValue++; // Create an event handle to use for frame synchronization. m_fenceEvent = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS); if (m_fenceEvent == nullptr) { ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError())); } // Wait for the command list to execute; we are reusing the same command // list in our main loop but for now, we just want to wait for setup to // complete before continuing. // Signal and increment the fence value. const UINT64 fenceToWaitFor = m_fenceValue; ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fenceToWaitFor)); m_fenceValue++; // Wait until the fence is completed. ThrowIfFailed(m_fence->SetEventOnCompletion(fenceToWaitFor, m_fenceEvent)); WaitForSingleObject(m_fenceEvent, INFINITE); } }
bool FogFX::InitialiseShader(ID3D11Device* device, HWND hwnd, WCHAR* sFilename) { bool result; unsigned int numElements; ID3D10Blob* errorMessage; ID3D10Blob* vertexShaderBuffer; ID3D10Blob* pixelShaderBuffer; D3D11_INPUT_ELEMENT_DESC polygonLayout[2]; D3D11_BUFFER_DESC constantBufferDesc; D3D11_SAMPLER_DESC samplerDesc; D3D11_BUFFER_DESC fogBufferDesc; numElements = 0; errorMessage = 0; vertexShaderBuffer = nullptr; pixelShaderBuffer = nullptr; // Read Vertex Shader result = D3DCompileFromFile(sFilename, NULL, NULL, "VS", "vs_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, &vertexShaderBuffer, &errorMessage); if (FAILED(result)) { if (errorMessage) OutputShaderErrorMessage(errorMessage, hwnd, sFilename); else MessageBox(hwnd, sFilename, L"Missing VS", MB_OK); return false; } //Create the vertex shader from the buffer result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &_pVertexShader); if (FAILED(result)) return false; // Read Pixel Shader result = D3DCompileFromFile(sFilename, NULL, NULL, "PS", "ps_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, &pixelShaderBuffer, &errorMessage); if (FAILED(result)) { if (errorMessage) OutputShaderErrorMessage(errorMessage, hwnd, sFilename); else MessageBox(hwnd, sFilename, L"Missing PS", MB_OK); return false; } result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &_pPixelShader); if (FAILED(result)) return false; // Create the Input Layour description polygonLayout[0].SemanticName = "POSITION"; polygonLayout[0].SemanticIndex = 0; polygonLayout[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; polygonLayout[0].InputSlot = 0; polygonLayout[0].AlignedByteOffset = 0; polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; polygonLayout[0].InstanceDataStepRate = 0; polygonLayout[1].SemanticName = "TEXCOORD"; polygonLayout[1].SemanticIndex = 0; polygonLayout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; polygonLayout[1].InputSlot = 0; polygonLayout[1].AlignedByteOffset = 0; polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; polygonLayout[1].InstanceDataStepRate = 0; numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]); result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &_pInputLayout); if (FAILED(result)) return false; vertexShaderBuffer->Release(); pixelShaderBuffer->Release(); constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; constantBufferDesc.ByteWidth = sizeof(ConstantBuffer); constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; constantBufferDesc.MiscFlags = 0; constantBufferDesc.StructureByteStride = 0; if (FAILED(result)) return false; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.MipLODBias = 0.0f; samplerDesc.MaxAnisotropy = 1; samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; samplerDesc.BorderColor[0] = 0; samplerDesc.BorderColor[1] = 0; samplerDesc.BorderColor[2] = 0; samplerDesc.BorderColor[3] = 0; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; result = device->CreateSamplerState(&samplerDesc, &_pSamplerState); if (FAILED(result)) return false; fogBufferDesc.Usage = D3D11_USAGE_DYNAMIC; fogBufferDesc.ByteWidth = sizeof(FogConstantBuffer); fogBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; fogBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; fogBufferDesc.MiscFlags = 0; fogBufferDesc.StructureByteStride = 0; result = device->CreateBuffer(&fogBufferDesc, NULL, &_pFogBuffer); if (FAILED(result)) return false; return true; }