void Dx11BlendState::Update(ID3D11Device* deviceInterface) { if(!dirty) return; // удалить предыдущий объект blendState = 0; try { D3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); // пока не реализовано desc.AlphaToCoverageEnable = FALSE; // пока смешивание общее для всех таргетов desc.IndependentBlendEnable = FALSE; D3D11_RENDER_TARGET_BLEND_DESC& d = desc.RenderTarget[0]; d.BlendEnable = enable; d.SrcBlend = ConvertColorSource(sourceColor); d.DestBlend = ConvertColorSource(destColor); d.BlendOp = ConvertOperation(colorOperation); d.SrcBlendAlpha = ConvertAlphaSource(sourceAlpha); d.DestBlendAlpha = ConvertAlphaSource(destAlpha); d.BlendOpAlpha = ConvertOperation(alphaOperation); if(FAILED(deviceInterface->CreateBlendState(&desc, &blendState))) THROW("Can't create blend state"); dirty = false; } catch(Exception* exception) { THROW_SECONDARY("Can't update DirectX blend state", exception); } }
void XFBEncoder::Init() { HRESULT hr; // Create output texture // The pixel shader can generate one YUYV entry per pixel. One YUYV entry // is created for every two EFB pixels. D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC( DXGI_FORMAT_R8G8B8A8_UNORM, MAX_XFB_WIDTH/2, MAX_XFB_HEIGHT, 1, 1, D3D11_BIND_RENDER_TARGET); hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_out); CHECK(SUCCEEDED(hr), "create xfb encoder output texture"); D3D::SetDebugObjectName(m_out, "xfb encoder output texture"); // Create output render target view D3D11_RENDER_TARGET_VIEW_DESC rtvd = CD3D11_RENDER_TARGET_VIEW_DESC(m_out, D3D11_RTV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM); hr = D3D::device->CreateRenderTargetView(m_out, &rtvd, &m_outRTV); CHECK(SUCCEEDED(hr), "create xfb encoder output texture rtv"); D3D::SetDebugObjectName(m_outRTV, "xfb encoder output rtv"); // Create output staging buffer t2dd.Usage = D3D11_USAGE_STAGING; t2dd.BindFlags = 0; t2dd.CPUAccessFlags = D3D11_CPU_ACCESS_READ; hr = D3D::device->CreateTexture2D(&t2dd, nullptr, &m_outStage); CHECK(SUCCEEDED(hr), "create xfb encoder output staging buffer"); D3D::SetDebugObjectName(m_outStage, "xfb encoder output staging buffer"); // Create constant buffer for uploading params to shaders D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(XFBEncodeParams), D3D11_BIND_CONSTANT_BUFFER); hr = D3D::device->CreateBuffer(&bd, nullptr, &m_encodeParams); CHECK(SUCCEEDED(hr), "create xfb encode params buffer"); D3D::SetDebugObjectName(m_encodeParams, "xfb encoder params buffer"); // Create vertex quad bd = CD3D11_BUFFER_DESC(sizeof(QUAD_VERTS), D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE); D3D11_SUBRESOURCE_DATA srd = { QUAD_VERTS, 0, 0 }; hr = D3D::device->CreateBuffer(&bd, &srd, &m_quad); CHECK(SUCCEEDED(hr), "create xfb encode quad vertex buffer"); D3D::SetDebugObjectName(m_quad, "xfb encoder quad vertex buffer"); // Create vertex shader D3DBlob* bytecode = nullptr; if (!D3D::CompileVertexShader(XFB_ENCODE_VS, &bytecode)) { ERROR_LOG(VIDEO, "XFB encode vertex shader failed to compile"); return; } hr = D3D::device->CreateVertexShader(bytecode->Data(), bytecode->Size(), nullptr, &m_vShader); CHECK(SUCCEEDED(hr), "create xfb encode vertex shader"); D3D::SetDebugObjectName(m_vShader, "xfb encoder vertex shader"); // Create input layout for vertex quad using bytecode from vertex shader hr = D3D::device->CreateInputLayout(QUAD_LAYOUT_DESC, sizeof(QUAD_LAYOUT_DESC)/sizeof(D3D11_INPUT_ELEMENT_DESC), bytecode->Data(), bytecode->Size(), &m_quadLayout); CHECK(SUCCEEDED(hr), "create xfb encode quad vertex layout"); D3D::SetDebugObjectName(m_quadLayout, "xfb encoder quad layout"); bytecode->Release(); // Create pixel shader m_pShader = D3D::CompileAndCreatePixelShader(XFB_ENCODE_PS); if (!m_pShader) { ERROR_LOG(VIDEO, "XFB encode pixel shader failed to compile"); return; } D3D::SetDebugObjectName(m_pShader, "xfb encoder pixel shader"); // Create blend state D3D11_BLEND_DESC bld = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); hr = D3D::device->CreateBlendState(&bld, &m_xfbEncodeBlendState); CHECK(SUCCEEDED(hr), "create xfb encode blend state"); D3D::SetDebugObjectName(m_xfbEncodeBlendState, "xfb encoder blend state"); // Create depth state D3D11_DEPTH_STENCIL_DESC dsd = CD3D11_DEPTH_STENCIL_DESC(CD3D11_DEFAULT()); dsd.DepthEnable = FALSE; hr = D3D::device->CreateDepthStencilState(&dsd, &m_xfbEncodeDepthState); CHECK(SUCCEEDED(hr), "create xfb encode depth state"); D3D::SetDebugObjectName(m_xfbEncodeDepthState, "xfb encoder depth state"); // Create rasterizer state D3D11_RASTERIZER_DESC rd = CD3D11_RASTERIZER_DESC(CD3D11_DEFAULT()); rd.CullMode = D3D11_CULL_NONE; rd.DepthClipEnable = FALSE; hr = D3D::device->CreateRasterizerState(&rd, &m_xfbEncodeRastState); CHECK(SUCCEEDED(hr), "create xfb encode rasterizer state"); D3D::SetDebugObjectName(m_xfbEncodeRastState, "xfb encoder rast state"); // Create EFB texture sampler D3D11_SAMPLER_DESC sd = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); // FIXME: Should we really use point sampling here? sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; hr = D3D::device->CreateSamplerState(&sd, &m_efbSampler); CHECK(SUCCEEDED(hr), "create xfb encode texture sampler"); D3D::SetDebugObjectName(m_efbSampler, "xfb encoder texture sampler"); }
bool InitD3D11QuadRendering( RENDERER_SETTINGS * settings ) { ID3DBlob * pCode = NULL; ID3DBlob * pErrors = NULL; if (D3DCompile( defaultVertexShader, strlen(defaultVertexShader), NULL, NULL, NULL, "main", "vs_4_0", NULL, NULL, &pCode, &pErrors ) != S_OK) { printf("[Renderer] D3DCompile failed\n"); return false; } if (pDevice->CreateVertexShader( pCode->GetBufferPointer(), pCode->GetBufferSize(), NULL, &pVertexShader ) != S_OK) { printf("[Renderer] CreateVertexShader failed\n"); return false; } ////////////////////////////////////////////////////////////////////////// static float pQuad[] = { -1.0, -1.0, 0.5, 0.0, 0.0, -1.0, 1.0, 0.5, 0.0, 1.0, 1.0, -1.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 1.0, 1.0, }; D3D11_BUFFER_DESC desc; ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC)); desc.ByteWidth = sizeof(float) * 5 * 4; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA subData; ZeroMemory(&subData, sizeof(D3D11_SUBRESOURCE_DATA)); subData.pSysMem = pQuad; if (pDevice->CreateBuffer(&desc, &subData, &pFullscreenQuadVB) != S_OK) { printf("[Renderer] CreateBuffer failed\n"); return false; } static D3D11_INPUT_ELEMENT_DESC pQuadDesc[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT , 0, 3 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0}, }; if (pDevice->CreateInputLayout( pQuadDesc, 2, pCode->GetBufferPointer(), pCode->GetBufferSize(), &pFullscreenQuadLayout) != S_OK) { printf("[Renderer] CreateInputLayout failed\n"); return false; } ////////////////////////////////////////////////////////////////////////// D3D11_VIEWPORT viewport; ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = settings->nWidth; viewport.Height = settings->nHeight; pContext->RSSetViewports(1, &viewport); ////////////////////////////////////////////////////////////////////////// D3D11_SAMPLER_DESC sampDesc = CD3D11_SAMPLER_DESC( CD3D11_DEFAULT() ); sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; if (pDevice->CreateSamplerState( &sampDesc, &pFullscreenQuadSamplerState ) != S_OK) return false; ////////////////////////////////////////////////////////////////////////// D3D11_BUFFER_DESC cbDesc; ZeroMemory( &cbDesc, sizeof(D3D11_BUFFER_DESC) ); cbDesc.ByteWidth = sizeof( pFullscreenQuadConstants ); cbDesc.Usage = D3D11_USAGE_DYNAMIC; cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; ZeroMemory( &subData, sizeof(D3D11_SUBRESOURCE_DATA) ); subData.pSysMem = &pFullscreenQuadConstants; if (pDevice->CreateBuffer( &cbDesc, &subData, &pFullscreenQuadConstantBuffer ) != S_OK) return false; ////////////////////////////////////////////////////////////////////////// D3D11_BLEND_DESC blendDesc = CD3D11_BLEND_DESC( CD3D11_DEFAULT() ); if (pDevice->CreateBlendState( &blendDesc, &pFullscreenQuadBlendState ) != S_OK) return false; D3D11_RASTERIZER_DESC rastDesc = CD3D11_RASTERIZER_DESC( CD3D11_DEFAULT() ); if (pDevice->CreateRasterizerState( &rastDesc, &pFullscreenQuadRasterizerState ) != S_OK) return false; return true; }
Asteroids::Asteroids(AsteroidsSimulation* asteroids, GUI* gui, bool warp) : mAsteroids(asteroids) , mGUI(gui) , mSwapChain(nullptr) , mDevice(nullptr) , mDeviceCtxt(nullptr) , mRenderTarget(nullptr) , mRenderTargetView(nullptr) , mDepthStencilView(nullptr) , mDepthStencilState(nullptr) , mInputLayout(nullptr) , mIndexBuffer(nullptr) , mVertexBuffer(nullptr) , mVertexShader(nullptr) , mPixelShader(nullptr) , mDrawConstantBuffer(nullptr) , mSkyboxVertexShader(nullptr) , mSkyboxPixelShader(nullptr) , mSkyboxConstantBuffer(nullptr) , mSamplerState(nullptr) { memset(&mViewPort, 0, sizeof(mViewPort)); memset(&mScissorRect, 0, sizeof(mScissorRect)); memset(mTextures, 0, sizeof(mTextures)); memset(mTextureSRVs, 0, sizeof(mTextureSRVs)); // Create device and swap chain { IDXGIAdapter* adapter = nullptr; D3D_DRIVER_TYPE driverType = ( warp ) ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_HARDWARE; HMODULE swModule = NULL; UINT flags = 0; D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 }; UINT numFeatureLevels = ARRAYSIZE(featureLevels); UINT sdkVersion = D3D11_SDK_VERSION; #ifdef _DEBUG flags = flags | D3D11_CREATE_DEVICE_DEBUG; #endif auto hr = D3D11CreateDevice(adapter, driverType, swModule, flags, featureLevels, numFeatureLevels, sdkVersion, &mDevice, nullptr, &mDeviceCtxt); if (FAILED(hr)) { // Try again without the debug flag... flags = flags & ~D3D11_CREATE_DEVICE_DEBUG; ThrowIfFailed(D3D11CreateDevice(adapter, driverType, swModule, flags, featureLevels, numFeatureLevels, sdkVersion, &mDevice, nullptr, &mDeviceCtxt)); } } // create pipeline state { D3D11_INPUT_ELEMENT_DESC inputDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc), g_asteroid_vs, sizeof(g_asteroid_vs), &mInputLayout)); { D3D11_DEPTH_STENCIL_DESC desc = CD3D11_DEPTH_STENCIL_DESC(D3D11_DEFAULT); desc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL; ThrowIfFailed(mDevice->CreateDepthStencilState(&desc, &mDepthStencilState)); } { CD3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); ThrowIfFailed(mDevice->CreateBlendState(&desc, &mBlendState)); // Premultiplied over blend desc.RenderTarget[0].BlendEnable = TRUE; desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; ThrowIfFailed(mDevice->CreateBlendState(&desc, &mSpriteBlendState)); } ThrowIfFailed(mDevice->CreateVertexShader(g_asteroid_vs, sizeof(g_asteroid_vs), NULL, &mVertexShader)); ThrowIfFailed(mDevice->CreatePixelShader(g_asteroid_ps_d3d11, sizeof(g_asteroid_ps_d3d11), NULL, &mPixelShader)); } // create skybox pipeline state { D3D11_INPUT_ELEMENT_DESC inputDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "UVFACE", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc), g_skybox_vs, sizeof(g_skybox_vs), &mSkyboxInputLayout)); ThrowIfFailed(mDevice->CreateVertexShader(g_skybox_vs, sizeof(g_skybox_vs), NULL, &mSkyboxVertexShader)); ThrowIfFailed(mDevice->CreatePixelShader(g_skybox_ps, sizeof(g_skybox_ps), NULL, &mSkyboxPixelShader)); } // Sprites and fonts { D3D11_INPUT_ELEMENT_DESC inputDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "UV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc), g_sprite_vs, sizeof(g_sprite_vs), &mSpriteInputLayout)); ThrowIfFailed(mDevice->CreateVertexShader(g_sprite_vs, sizeof(g_sprite_vs), NULL, &mSpriteVertexShader)); ThrowIfFailed(mDevice->CreatePixelShader(g_sprite_ps, sizeof(g_sprite_ps), NULL, &mSpritePixelShader)); ThrowIfFailed(mDevice->CreatePixelShader(g_font_ps, sizeof(g_font_ps), NULL, &mFontPixelShader)); } // Create draw constant buffer { D3D11_BUFFER_DESC desc = {}; desc.Usage = D3D11_USAGE_DYNAMIC; desc.ByteWidth = sizeof(DrawConstantBuffer); desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; ThrowIfFailed(mDevice->CreateBuffer(&desc, nullptr, &mDrawConstantBuffer)); } // Create skybox constant buffer { D3D11_BUFFER_DESC desc = {}; desc.Usage = D3D11_USAGE_DYNAMIC; desc.ByteWidth = sizeof(SkyboxConstantBuffer); desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; ThrowIfFailed(mDevice->CreateBuffer(&desc, nullptr, &mSkyboxConstantBuffer)); } // Create sampler { D3D11_SAMPLER_DESC desc = {}; desc.Filter = D3D11_FILTER_ANISOTROPIC; desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; desc.MinLOD = -D3D11_FLOAT32_MAX; desc.MaxLOD = D3D11_FLOAT32_MAX; desc.MipLODBias = 0.0f; desc.MaxAnisotropy = TEXTURE_ANISO; desc.ComparisonFunc = D3D11_COMPARISON_NEVER; ThrowIfFailed(mDevice->CreateSamplerState(&desc, &mSamplerState)); } CreateMeshes(); InitializeTextureData(); CreateGUIResources(); // Load textures ThrowIfFailed(CreateDDSTextureFromFile(mDevice, L"starbox_1024.dds", &mSkyboxSRV, true)); }
bool StateHolder::Initialize(ID3D11Device* device) { // Raster states std::function<CD3D11_RASTERIZER_DESC()> rasterGenerators[RST_Count] = { []() -> CD3D11_RASTERIZER_DESC { CD3D11_RASTERIZER_DESC desc((CD3D11_DEFAULT())); desc.CullMode = D3D11_CULL_BACK; desc.FillMode = D3D11_FILL_SOLID; desc.FrontCounterClockwise = FALSE; return desc; }, []() -> CD3D11_RASTERIZER_DESC { CD3D11_RASTERIZER_DESC desc((CD3D11_DEFAULT())); desc.CullMode = D3D11_CULL_BACK; desc.FillMode = D3D11_FILL_SOLID; desc.FrontCounterClockwise = TRUE; return desc; }, []() -> CD3D11_RASTERIZER_DESC { CD3D11_RASTERIZER_DESC desc((CD3D11_DEFAULT())); desc.CullMode = D3D11_CULL_BACK; desc.FillMode = D3D11_FILL_WIREFRAME; desc.FrontCounterClockwise = FALSE; return desc; }, []() -> CD3D11_RASTERIZER_DESC { CD3D11_RASTERIZER_DESC desc((CD3D11_DEFAULT())); desc.CullMode = D3D11_CULL_BACK; desc.FillMode = D3D11_FILL_WIREFRAME; desc.FrontCounterClockwise = TRUE; return desc; }, }; for (auto gen = 0; gen < RST_Count; ++gen) { if (FAILED(device->CreateRasterizerState(&rasterGenerators[gen](), m_RasterStates[gen].Receive()))) { SLOG(Sev_Error, Fac_Rendering, "Unable to create raster state!"); return false; } } // Blend states std::function<CD3D11_BLEND_DESC()> blendGenerators[BLST_Count] = { []() -> CD3D11_BLEND_DESC { CD3D11_BLEND_DESC desc((CD3D11_DEFAULT())); for (unsigned i = 0; i < 8; ++i) { desc.RenderTarget[i].RenderTargetWriteMask = 0; } return desc; }, []() -> CD3D11_BLEND_DESC { CD3D11_BLEND_DESC desc((CD3D11_DEFAULT())); desc.AlphaToCoverageEnable = true; desc.RenderTarget[0].BlendEnable = true; return desc; }, }; for (auto gen = 0; gen < BLST_Count; ++gen) { if (FAILED(device->CreateBlendState(&blendGenerators[gen](), m_BlendStates[gen].Receive()))) { SLOG(Sev_Error, Fac_Rendering, "Unable to create blend state!"); return false; } } // Depth states std::function<CD3D11_DEPTH_STENCIL_DESC()> depthGenerators[DSST_Count] = { []()->CD3D11_DEPTH_STENCIL_DESC { CD3D11_DEPTH_STENCIL_DESC desc((CD3D11_DEFAULT())); desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; return desc; }, []()->CD3D11_DEPTH_STENCIL_DESC { CD3D11_DEPTH_STENCIL_DESC desc((CD3D11_DEFAULT())); desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; desc.DepthFunc = D3D11_COMPARISON_ALWAYS; return desc; }, }; for (auto gen = 0; gen < DSST_Count; ++gen) { if (FAILED(device->CreateDepthStencilState(&depthGenerators[gen](), m_DepthStates[gen].Receive()))) { SLOG(Sev_Error, Fac_Rendering, "Unable to create depth-stencil state!"); return false; } } return true; }
ID3D11BlendState* StateCache::Get(BlendState state) { if (!state.blend_enable) { state.src_blend = D3D11_BLEND_ONE; state.dst_blend = D3D11_BLEND_ZERO; state.blend_op = D3D11_BLEND_OP_ADD; state.use_dst_alpha = false; } auto it = m_blend.find(state.packed); if (it != m_blend.end()) return it->second; D3D11_BLEND_DESC blenddc = CD3D11_BLEND_DESC(CD3D11_DEFAULT()); blenddc.AlphaToCoverageEnable = FALSE; blenddc.IndependentBlendEnable = FALSE; blenddc.RenderTarget[0].BlendEnable = state.blend_enable; blenddc.RenderTarget[0].RenderTargetWriteMask = (u32)state.write_mask; blenddc.RenderTarget[0].SrcBlend = state.src_blend; blenddc.RenderTarget[0].DestBlend = state.dst_blend; blenddc.RenderTarget[0].BlendOp = state.blend_op; blenddc.RenderTarget[0].SrcBlendAlpha = state.src_blend; blenddc.RenderTarget[0].DestBlendAlpha = state.dst_blend; blenddc.RenderTarget[0].BlendOpAlpha = state.blend_op; if (blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_SRC_COLOR) blenddc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; else if (blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_INV_SRC_COLOR) blenddc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; else if (blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_DEST_COLOR) blenddc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA; else if (blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_INV_DEST_COLOR) blenddc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; else blenddc.RenderTarget[0].SrcBlendAlpha = blenddc.RenderTarget[0].SrcBlend; if (blenddc.RenderTarget[0].DestBlend == D3D11_BLEND_SRC_COLOR) blenddc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA; else if (blenddc.RenderTarget[0].DestBlend == D3D11_BLEND_INV_SRC_COLOR) blenddc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; else if (blenddc.RenderTarget[0].DestBlend == D3D11_BLEND_DEST_COLOR) blenddc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA; else if (blenddc.RenderTarget[0].DestBlend == D3D11_BLEND_INV_DEST_COLOR) blenddc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; else blenddc.RenderTarget[0].DestBlendAlpha = blenddc.RenderTarget[0].DestBlend; if (state.use_dst_alpha) { // Colors should blend against SRC1_ALPHA if (blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_SRC_ALPHA) blenddc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC1_ALPHA; else if (blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_INV_SRC_ALPHA) blenddc.RenderTarget[0].SrcBlend = D3D11_BLEND_INV_SRC1_ALPHA; // Colors should blend against SRC1_ALPHA if (blenddc.RenderTarget[0].DestBlend == D3D11_BLEND_SRC_ALPHA) blenddc.RenderTarget[0].DestBlend = D3D11_BLEND_SRC1_ALPHA; else if (blenddc.RenderTarget[0].DestBlend == D3D11_BLEND_INV_SRC_ALPHA) blenddc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC1_ALPHA; blenddc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blenddc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blenddc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; } ID3D11BlendState* res = nullptr; HRESULT hr = D3D::device->CreateBlendState(&blenddc, &res); if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); D3D::SetDebugObjectName((ID3D11DeviceChild*)res, "blend state used to emulate the GX pipeline"); m_blend.insert(std::make_pair(state.packed, res)); return res; }
bool InitD3D11GUIRendering( RENDERER_SETTINGS * settings ) { ID3DBlob * pCode = NULL; ID3DBlob * pErrors = NULL; if (D3DCompile( defaultGUIPixelShader, strlen(defaultGUIPixelShader), NULL, NULL, NULL, "main", "ps_4_0", NULL, NULL, &pCode, &pErrors ) != S_OK) { printf("[Renderer] D3DCompile (PS) failed\n"); return false; } if (pDevice->CreatePixelShader( pCode->GetBufferPointer(), pCode->GetBufferSize(), NULL, &pGUIPixelShader ) != S_OK) { printf("[Renderer] CreatePixelShader failed\n"); return false; } if (D3DCompile( defaultGUIVertexShader, strlen(defaultGUIVertexShader), NULL, NULL, NULL, "main", "vs_4_0", NULL, NULL, &pCode, &pErrors ) != S_OK) { printf("[Renderer] D3DCompile (VS) failed\n"); return false; } if (pDevice->CreateVertexShader( pCode->GetBufferPointer(), pCode->GetBufferSize(), NULL, &pGUIVertexShader ) != S_OK) { printf("[Renderer] CreateVertexShader failed\n"); return false; } D3D11_BUFFER_DESC desc; ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC)); desc.ByteWidth = sizeof(float) * 7 * GUIQUADVB_SIZE; desc.Usage = D3D11_USAGE_DYNAMIC; desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; if (pDevice->CreateBuffer(&desc, NULL, &pGUIQuadVB) != S_OK) { printf("[Renderer] CreateBuffer (VB) failed\n"); return false; } static D3D11_INPUT_ELEMENT_DESC pGUIDesc[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR" , 0, DXGI_FORMAT_R8G8B8A8_UNORM , 0, 3 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT , 0, 4 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT , 0, 6 * sizeof(float), D3D11_INPUT_PER_VERTEX_DATA, 0}, }; if (pDevice->CreateInputLayout( pGUIDesc, 4, pCode->GetBufferPointer(), pCode->GetBufferSize(), &pGUIQuadLayout) != S_OK) { printf("[Renderer] CreateInputLayout failed\n"); return false; } D3D11_BUFFER_DESC cbDesc; ZeroMemory( &cbDesc, sizeof(D3D11_BUFFER_DESC) ); cbDesc.ByteWidth = sizeof( float ) * 4 * 4 * 2; cbDesc.Usage = D3D11_USAGE_DYNAMIC; cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; MatrixOrthoOffCenterLH( pGUIMatrix, 0, nWidth, nHeight, 0, -1.0f, 1.0f ); D3D11_SUBRESOURCE_DATA subData; ZeroMemory( &subData, sizeof(D3D11_SUBRESOURCE_DATA) ); subData.pSysMem = &pGUIMatrix; if (pDevice->CreateBuffer( &cbDesc, &subData, &pGUIConstantBuffer ) != S_OK) { printf("[Renderer] CreateBuffer (CB) failed\n"); return false; } D3D11_BLEND_DESC blendDesc = CD3D11_BLEND_DESC( CD3D11_DEFAULT() ); blendDesc.RenderTarget[0].BlendEnable = true; blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; if (pDevice->CreateBlendState( &blendDesc, &pGUIBlendState ) != S_OK) return false; D3D11_RASTERIZER_DESC rastDesc = CD3D11_RASTERIZER_DESC( CD3D11_DEFAULT() ); rastDesc.ScissorEnable = true; if (pDevice->CreateRasterizerState( &rastDesc, &pGUIRasterizerState ) != S_OK) return false; return true; }