void InitUtils() { util_vbuf = new UtilVertexBuffer(0x4000); float border[4] = { 0.f, 0.f, 0.f, 0.f }; D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler); if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__); else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state"); samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler); if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__); else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state"); // cached data used to avoid unnecessarily reloading the vertex buffers memset(&tex_quad_data, 0, sizeof(tex_quad_data)); memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data)); memset(&draw_quad_data, 0, sizeof(draw_quad_data)); memset(&clear_quad_data, 0, sizeof(clear_quad_data)); // make sure to properly load the vertex data whenever the corresponding functions get called the first time stq_observer = stsq_observer = cq_observer = clearq_observer = true; util_vbuf->AddWrapObserver(&stq_observer); util_vbuf->AddWrapObserver(&stsq_observer); util_vbuf->AddWrapObserver(&cq_observer); util_vbuf->AddWrapObserver(&clearq_observer); font.Init(); }
void InitUtils() { util_vbuf = new UtilVertexBuffer(0x4000); float border[4] = { 0.f, 0.f, 0.f, 0.f }; D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler); if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__); else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state"); samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler); if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__); else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state"); // cached data used to avoid unnecessarily reloading the vertex buffers memset(&tex_quad_data, 0, sizeof(tex_quad_data)); memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data)); memset(&draw_quad_data, 0, sizeof(draw_quad_data)); memset(&clear_quad_data, 0, sizeof(clear_quad_data)); // make sure to properly load the vertex data whenever the corresponding functions get called the first time stq_observer = stsq_observer = cq_observer = clearq_observer = true; util_vbuf->AddWrapObserver(&stq_observer); util_vbuf->AddWrapObserver(&stsq_observer); util_vbuf->AddWrapObserver(&cq_observer); util_vbuf->AddWrapObserver(&clearq_observer); font.Init(); // Create resources for encoder quads // Create vertex quad D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(ENCODER_QUAD_VERTS), D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE); D3D11_SUBRESOURCE_DATA srd = { ENCODER_QUAD_VERTS, 0, 0 }; hr = D3D::device->CreateBuffer(&bd, &srd, &s_encoderQuad); CHECK(SUCCEEDED(hr), "create encoder quad buffer"); // Create vertex shader D3DBlob* blob; D3D::CompileVertexShader(ENCODER_VS, sizeof(ENCODER_VS), &blob); s_encoderVShader = D3D::CreateVertexShaderFromByteCode(blob); CHECK(SUCCEEDED(hr), "create encoder vertex shader"); // Create input layout hr = D3D::device->CreateInputLayout(ENCODER_QUAD_LAYOUT_DESC, sizeof(ENCODER_QUAD_LAYOUT_DESC) / sizeof(D3D11_INPUT_ELEMENT_DESC), blob->Data(), blob->Size(), &s_encoderQuadLayout); CHECK(SUCCEEDED(hr), "create encoder input layout"); blob->Release(); // Create vertex shader for encoder quads with texture coords s_encoderTexVShader = D3D::CompileAndCreateVertexShader(ENCODER_TEX_VS, sizeof(ENCODER_TEX_VS)); }
void Television::Init() { #ifdef USE_D3D11 HRESULT hr; // Create YUYV texture for real XFB mode // Initialize the texture with YCbCr black // // Some games use narrower XFB widths (Nintendo titles are fond of 608), // so the sampler's BorderColor won't cover the right side // (see sampler state below) const unsigned int MAX_XFB_SIZE = 2 * (MAX_XFB_WIDTH)* MAX_XFB_HEIGHT; std::vector<u8> fill(MAX_XFB_SIZE); for (size_t i = 0; i < MAX_XFB_SIZE / sizeof(u32); ++i) reinterpret_cast<u32*>(fill.data())[i] = 0x80108010; D3D11_SUBRESOURCE_DATA srd = { fill.data(), 2 * (MAX_XFB_WIDTH), 0 }; // This texture format is designed for YUYV data. D3D11_TEXTURE2D_DESC t2dd = CD3D11_TEXTURE2D_DESC( DXGI_FORMAT_G8R8_G8B8_UNORM, MAX_XFB_WIDTH, MAX_XFB_HEIGHT, 1, 1); hr = D3D::device->CreateTexture2D(&t2dd, &srd, &m_yuyvTexture); CHECK(SUCCEEDED(hr), "create tv yuyv texture"); D3D::SetDebugObjectName(m_yuyvTexture, "tv yuyv texture"); // Create shader resource view for YUYV texture D3D11_SHADER_RESOURCE_VIEW_DESC srvd = CD3D11_SHADER_RESOURCE_VIEW_DESC( m_yuyvTexture, D3D11_SRV_DIMENSION_TEXTURE2D, DXGI_FORMAT_G8R8_G8B8_UNORM); hr = D3D::device->CreateShaderResourceView(m_yuyvTexture, &srvd, &m_yuyvTextureSRV); CHECK(SUCCEEDED(hr), "create tv yuyv texture srv"); D3D::SetDebugObjectName(m_yuyvTextureSRV, "tv yuyv texture srv"); // Create YUYV-decoding pixel shader m_pShader = D3D::CompileAndCreatePixelShader(YUYV_DECODER_PS); CHECK(m_pShader != nullptr, "compile and create yuyv decoder pixel shader"); D3D::SetDebugObjectName(m_pShader, "yuyv decoder pixel shader"); // Create sampler state and set border color // // The default sampler border color of { 0.f, 0.f, 0.f, 0.f } // creates a green border around the image - see issue 6483 // (remember, the XFB is being interpreted as YUYV, and 0,0,0,0 // is actually two green pixels in YUYV - black should be 16,128,16,128, // but we reverse the order to match DXGI_FORMAT_G8R8_G8B8_UNORM's ordering) float border[4] = { 128.0f / 255.0f, 16.0f / 255.0f, 128.0f / 255.0f, 16.0f / 255.0f }; D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f); hr = D3D::device->CreateSamplerState(&samDesc, &m_sampler_state); CHECK(SUCCEEDED(hr), "create yuyv decoder sampler state"); D3D::SetDebugObjectName(m_sampler_state, "yuyv decoder sampler state"); #endif }
ID3D11SamplerState* StateCache::Get(SamplerState state) { std::lock_guard<std::mutex> guard(m_lock); auto it = m_sampler.find(state.hex); if (it != m_sampler.end()) return it->second; D3D11_SAMPLER_DESC sampdc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); if (state.mipmap_filter == SamplerState::Filter::Linear) { if (state.min_filter == SamplerState::Filter::Linear) sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; else sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ? D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; } else { if (state.min_filter == SamplerState::Filter::Linear) sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ? D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT : D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; else sampdc.Filter = (state.mag_filter == SamplerState::Filter::Linear) ? D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_POINT; } static constexpr std::array<D3D11_TEXTURE_ADDRESS_MODE, 3> address_modes = { {D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_WRAP, D3D11_TEXTURE_ADDRESS_MIRROR}}; sampdc.AddressU = address_modes[static_cast<u32>(state.wrap_u.Value())]; sampdc.AddressV = address_modes[static_cast<u32>(state.wrap_v.Value())]; sampdc.MaxLOD = state.max_lod / 16.f; sampdc.MinLOD = state.min_lod / 16.f; sampdc.MipLODBias = (s32)state.lod_bias / 256.f; if (state.anisotropic_filtering) { sampdc.Filter = D3D11_FILTER_ANISOTROPIC; sampdc.MaxAnisotropy = 1u << g_ActiveConfig.iMaxAnisotropy; } ID3D11SamplerState* res = nullptr; HRESULT hr = D3D::device->CreateSamplerState(&sampdc, &res); if (FAILED(hr)) PanicAlert("Fail %s %d\n", __FILE__, __LINE__); D3D::SetDebugObjectName(res, "sampler state used to emulate the GX pipeline"); m_sampler.emplace(state.hex, res); return res; }
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; }
ID3D11SamplerState* StateCache::Get(SamplerState state) { auto it = m_sampler.find(state.packed); if (it != m_sampler.end()) { return it->second; } const unsigned int d3dMipFilters[4] = { TexMode0::TEXF_NONE, TexMode0::TEXF_POINT, TexMode0::TEXF_LINEAR, TexMode0::TEXF_NONE, //reserved }; const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] = { D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_WRAP, D3D11_TEXTURE_ADDRESS_MIRROR, D3D11_TEXTURE_ADDRESS_WRAP //reserved }; D3D11_SAMPLER_DESC sampdc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); unsigned int mip = d3dMipFilters[state.min_filter & 3]; if (state.max_anisotropy) { sampdc.Filter = D3D11_FILTER_ANISOTROPIC; sampdc.MaxAnisotropy = (u32)state.max_anisotropy; } else if (state.min_filter & 4) // linear min filter { if (state.mag_filter) // linear mag filter { if (mip == TexMode0::TEXF_NONE) sampdc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; else if (mip == TexMode0::TEXF_POINT) sampdc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; else if (mip == TexMode0::TEXF_LINEAR) sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; } else // point mag filter { if (mip == TexMode0::TEXF_NONE) sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; else if (mip == TexMode0::TEXF_POINT) sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; else if (mip == TexMode0::TEXF_LINEAR) sampdc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; } } else // point min filter { if (state.mag_filter) // linear mag filter { if (mip == TexMode0::TEXF_NONE) sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; else if (mip == TexMode0::TEXF_POINT) sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; else if (mip == TexMode0::TEXF_LINEAR) sampdc.Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR; } else // point mag filter { if (mip == TexMode0::TEXF_NONE) sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; else if (mip == TexMode0::TEXF_POINT) sampdc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; else if (mip == TexMode0::TEXF_LINEAR) sampdc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; } } sampdc.AddressU = d3dClamps[state.wrap_s]; sampdc.AddressV = d3dClamps[state.wrap_t]; sampdc.MaxLOD = (mip == TexMode0::TEXF_NONE) ? 0.0f : (float)state.max_lod / 16.f; sampdc.MinLOD = (float)state.min_lod / 16.f; sampdc.MipLODBias = (s32)state.lod_bias / 32.0f; ID3D11SamplerState* res = nullptr; HRESULT hr = D3D::device->CreateSamplerState(&sampdc, &res); if (FAILED(hr)) PanicAlert("Fail %s %d\n", __FILE__, __LINE__); D3D::SetDebugObjectName((ID3D11DeviceChild*)res, "sampler state used to emulate the GX pipeline"); m_sampler.insert(std::make_pair(state.packed, res)); return res; }
void Texture::loadFromFile(const std::string &filename) { ID3DBlob* vsBuffer, *psBuffer = 0; D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; CompileD3DShader("Shaders/TextureMap.fx", "VS_Main", "vs_4_0", &vsBuffer); CompileD3DShader("Shaders/TextureMap.fx", "PS_Main", "ps_4_0", &psBuffer); DirectX::ThrowIfFailed( _dev->CreateVertexShader(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), 0, &solidColorVS) ); DirectX::ThrowIfFailed( _dev->CreatePixelShader(psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(), 0, &solidColorPS) ); unsigned int totalLayoutElements = ARRAYSIZE(solidColorLayout); DirectX::ThrowIfFailed( _dev->CreateInputLayout(solidColorLayout, totalLayoutElements, vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), &inputLayout) ); D3DX11CreateShaderResourceViewFromFile(_dev.Get(), filename.c_str(), 0, 0, &colorMap, 0); ID3D11Resource *resource; ID3D11Texture2D *texture2D; D3D11_TEXTURE2D_DESC textureDesc; colorMap->GetResource(&resource); resource->QueryInterface<ID3D11Texture2D>(&texture2D); texture2D->GetDesc(&textureDesc); _textureWidth = static_cast<float>(textureDesc.Width); _textureHeight = static_cast<float>(textureDesc.Height); ID3D11Resource* colorTex; colorMap->GetResource(&colorTex); D3D11_TEXTURE2D_DESC colorTexDesc; ((ID3D11Texture2D*)colorTex)->GetDesc(&colorTexDesc); colorTex->Release(); ID3D11RasterizerState *rasterize; D3D11_RASTERIZER_DESC rasterizerDesc; ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC)); rasterizerDesc.AntialiasedLineEnable = false; rasterizerDesc.CullMode = D3D11_CULL_NONE; rasterizerDesc.DepthBias = 0; rasterizerDesc.DepthBiasClamp = 0.0f; rasterizerDesc.DepthClipEnable = true; rasterizerDesc.FillMode = D3D11_FILL_SOLID; rasterizerDesc.FrontCounterClockwise = false; rasterizerDesc.MultisampleEnable = false; rasterizerDesc.ScissorEnable = false; rasterizerDesc.SlopeScaledDepthBias = 0.0f; _dev->CreateRasterizerState(&rasterizerDesc, &rasterize); _devcon->RSSetState(rasterize); // transparence D3D11_BLEND_DESC blendDesc; ZeroMemory(&blendDesc, sizeof(blendDesc)); blendDesc.RenderTarget[0].BlendEnable = TRUE; blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[0].RenderTargetWriteMask = 0x0f; float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; _dev->CreateBlendState(&blendDesc, alphaBlendState.GetAddressOf()); _devcon->OMSetBlendState(alphaBlendState.Get(), blendFactor, 0xFFFFFFFF); D3D11_SAMPLER_DESC desc = CD3D11_SAMPLER_DESC(CD3D11_DEFAULT()); _dev->CreateSamplerState(&desc, &colorMapSampler); }
bool D3D11Context::startup (void* hwnd) { UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef _DEBUG flags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, }; if (m_failed (::D3D11CreateDevice (nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, flags, featureLevels, numElementsInArray (featureLevels), D3D11_SDK_VERSION, device, &featureLevel, contextIM))) { if (m_failed (::D3D11CreateDevice (nullptr, D3D_DRIVER_TYPE_WARP, nullptr, flags, featureLevels, numElementsInArray (featureLevels), D3D11_SDK_VERSION, device, &featureLevel, contextIM))) return false; } Hold<IDXGIDevice2> dxgiDevice; if (m_failed (device.as (dxgiDevice))) return false; Hold<IDXGIAdapter> dxgiAdapter; if (m_failed (dxgiDevice->GetAdapter (dxgiAdapter))) return false; Hold<IDXGIFactory2> dxgiFactory; if (m_failed (dxgiAdapter->GetParent (__uuidof (IDXGIFactory2), dxgiFactory))) return false; DXGI_SWAP_CHAIN_DESC1 desc; desc.Width = 0; desc.Height = 0; desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; desc.Stereo = false; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.BufferCount = 2; desc.Scaling = DXGI_SCALING_STRETCH; // DXGI_SCALING_NONE is not supported on Windows7 desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; desc.Flags = 0; if (m_failed (dxgiFactory->CreateSwapChainForHwnd (device, (HWND)hwnd, &desc, nullptr, nullptr, swapchain))) return false; Hold<ID3D11Texture2D> backBuf; if (m_failed (swapchain->GetBuffer (0, __uuidof (ID3D11Texture2D), backBuf))) return false; if (m_failed (device->CreateRenderTargetView (backBuf, nullptr, backBufRTView))) return false; RECT rect; ::GetClientRect ((HWND)hwnd, &rect); if (m_isnull (depthBuf.set (createTexture2DRT (rect.right - rect.left, rect.bottom - rect.top, 1, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_D32_FLOAT)))) return false; if (m_isnull (depthBufDSView.set (createDepthStencilView (depthBuf, 0, DXGI_FORMAT_D32_FLOAT)))) return false; if (m_isnull (depthBufSRView.set (createShaderResourceView (depthBuf, DXGI_FORMAT_R32_FLOAT)))) return false; // common sampler states { D3D11_SAMPLER_DESC _ = CD3D11_SAMPLER_DESC (D3D11_DEFAULT); _.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; _.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; _.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; _.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; if (m_isnull (sampWrapLinear.set (createSamplerState (_)))) return false; } { D3D11_SAMPLER_DESC _ = CD3D11_SAMPLER_DESC (D3D11_DEFAULT); _.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; _.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; _.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; _.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; if (m_isnull (sampWrapPoint.set (createSamplerState (_)))) return false; } { D3D11_SAMPLER_DESC _ = CD3D11_SAMPLER_DESC (D3D11_DEFAULT); _.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; _.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; _.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; _.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; if (m_isnull (sampClampLinear.set (createSamplerState (_)))) return false; } { D3D11_SAMPLER_DESC _ = CD3D11_SAMPLER_DESC (D3D11_DEFAULT); _.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; _.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; _.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; _.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; if (m_isnull (sampClampPoint.set (createSamplerState (_)))) return false; } // common rasterizer state { D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT); _.CullMode = D3D11_CULL_NONE; _.FrontCounterClockwise = FALSE; if (m_isnull (rastCullNone.set (createRasterizerState (_)))) return false; } { D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT); _.CullMode = D3D11_CULL_FRONT; _.FrontCounterClockwise = FALSE; if (m_isnull (rastCWCullFront.set (createRasterizerState (_)))) return false; } { D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT); _.CullMode = D3D11_CULL_BACK; _.FrontCounterClockwise = FALSE; if (m_isnull (rastCWCullBack.set (createRasterizerState (_)))) return false; } { D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT); _.CullMode = D3D11_CULL_FRONT; _.FrontCounterClockwise = TRUE; if (m_isnull (rastCCWCullFront.set (createRasterizerState (_)))) return false; } { D3D11_RASTERIZER_DESC _ = CD3D11_RASTERIZER_DESC (D3D11_DEFAULT); _.CullMode = D3D11_CULL_BACK; _.FrontCounterClockwise = TRUE; if (m_isnull (rastCCWCullBack.set (createRasterizerState (_)))) return false; } // common depth stencil state { D3D11_DEPTH_STENCIL_DESC _ = CD3D11_DEPTH_STENCIL_DESC (D3D11_DEFAULT); _.DepthEnable = TRUE; _.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; if (m_isnull (depthTestOnWriteOn.set (createDepthStencilState (_)))) return false; } { D3D11_DEPTH_STENCIL_DESC _ = CD3D11_DEPTH_STENCIL_DESC (D3D11_DEFAULT); _.DepthEnable = TRUE; _.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; if (m_isnull (depthTestOnWriteOff.set (createDepthStencilState (_)))) return false; } { D3D11_DEPTH_STENCIL_DESC _ = CD3D11_DEPTH_STENCIL_DESC (D3D11_DEFAULT); _.DepthEnable = FALSE; _.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; if (m_isnull (depthTestOffWriteOn.set (createDepthStencilState (_)))) return false; } { D3D11_DEPTH_STENCIL_DESC _ = CD3D11_DEPTH_STENCIL_DESC (D3D11_DEFAULT); _.DepthEnable = FALSE; _.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; if (m_isnull (depthTestOffWriteOff.set (createDepthStencilState (_)))) return false; } return true; }