void PixelShader::InitFromFile(std::string inFileName) { assert(FileUtil::FileExists(inFileName.c_str())); CleanUp(); DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; std::wstring filename = std::wstring(inFileName.begin(), inFileName.end()); #ifdef _DEBUG dwShaderFlags |= D3DCOMPILE_DEBUG; dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION; #endif ID3DBlob* pPSBlob = nullptr; ID3DBlob* pErrorBlob = nullptr; D3DCall(D3DCompileFromFile(filename.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, "PS", "ps_5_0", dwShaderFlags, 0, &pPSBlob, &pErrorBlob)); if (pErrorBlob) { OutputDebugStringA(reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer())); pErrorBlob->Release(); } ID3D11ShaderReflection* pPixelShaderReflection = NULL; D3DCall(D3DReflect(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pPixelShaderReflection)); D3D11_SHADER_DESC shader_desc; pPixelShaderReflection->GetDesc(&shader_desc); for (int i = 0; i < shader_desc.BoundResources; i++) { D3D11_SHADER_INPUT_BIND_DESC resource_desc; pPixelShaderReflection->GetResourceBindingDesc(i, &resource_desc); // FETCH RESOURCES switch (resource_desc.Type) { case D3D_SHADER_INPUT_TYPE::D3D_SIT_TEXTURE: mTextures[resource_desc.Name] = resource_desc.BindPoint; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_SAMPLER: mSamplers[resource_desc.Name] = resource_desc.BindPoint; break; case D3D_SHADER_INPUT_TYPE::D3D_SIT_CBUFFER: mConstantBuffers[resource_desc.Name] = resource_desc.BindPoint; break; default: break; } } D3DCall(theRenderContext.GetDevice()->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &mHandle)); pPSBlob->Release(); }
/** \fn ADMImage_To_argbSurface */ static bool ADMImage_To_argbSurface(ADMImage *pic, IDirect3DSurface9 *surface,ADMColorScalerFull *scaler) { D3DLOCKED_RECT lock; if (ADM_FAILED(D3DCall(IDirect3DSurface9,LockRect,surface,&lock, NULL, 0))) { ADM_warning("D3D Cannot lock surface\n"); return false; } // RGB uint8_t *src[3]; uint8_t *dst[3]; pic->GetReadPlanes(src); dst[0]=(uint8_t *)lock.pBits; dst[1]=dst[2]=NULL; int sourcePitch[3],dstPitch[3]; pic->GetPitches(sourcePitch); dstPitch[0]=lock.Pitch; dstPitch[1]=dstPitch[2]=0; scaler-> convertPlanes(sourcePitch,dstPitch, src, dst); if (ADM_FAILED(IDirect3DSurface9_UnlockRect(surface))) { ADM_warning("D3D Cannot unlock surface\n"); return false; } return true; }
/** \fn ADMImage_To_yv12Surface */ static bool ADMImage_To_yv12Surface(ADMImage *pic, IDirect3DSurface9 *surface) { D3DLOCKED_RECT lock;; if (ADM_FAILED(D3DCall(IDirect3DSurface9,LockRect,surface,&lock, NULL, 0))) { ADM_warning("D3D Cannot lock surface\n"); return false; } // copy uint8_t *dst=(uint8_t *)lock.pBits; int dStride=lock.Pitch; int width=pic->GetWidth(PLANAR_Y); int height=pic->GetHeight(PLANAR_Y); d3dBlit(pic, PLANAR_Y,dst,dStride,width,height); dst+=height*dStride; d3dBlit(pic, PLANAR_U,dst,dStride>>1,width>>1,height>>1); dst+=(height/2)*(dStride/2); d3dBlit(pic, PLANAR_V,dst,dStride>>1,width>>1,height>>1); if (ADM_FAILED(D3DCallNoArg(IDirect3DSurface9,UnlockRect,surface))) { ADM_warning("D3D Cannot unlock surface\n"); return false; } return true; }
/** \fn brief input is already a surface, in yv12 format */ bool dxvaRender::displayImage_surface(ADMImage *pic,admDx2Surface *surface) { // this does not work, both surfaces are coming from different device IDirect3DSurface9 *bBuffer; POINT point={0,0}; // OK ADM_info("surface duplicated\n"); if( ADM_FAILED(D3DCall(IDirect3DDevice9,GetBackBuffer,d3dDevice, 0, 0, D3DBACKBUFFER_TYPE_MONO, &bBuffer))) { ADM_warning("D3D Cannot create backBuffer\n"); return false; } // can we directly use the surface from dxva ? (can we at all ?) if (ADM_FAILED(D3DCall(IDirect3DDevice9,StretchRect,d3dDevice, surface->surface, NULL, bBuffer, NULL, D3DTEXF_LINEAR))) { ADM_warning("StretchRec yv12 failed\n"); // go to indirect route if(!pic->hwDownloadFromRef()) { ADM_warning("Failed to download yv12 from dxva\n"); return false; } // workaround : use default non bridged path if(useYV12) { return displayImage_yv12(pic); } return displayImage_argb(pic); } IDirect3DDevice9_BeginScene(d3dDevice); IDirect3DDevice9_EndScene(d3dDevice); if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0))) { ADM_warning("D3D Present failed\n"); } return true; }
/** \fn refresh \brief does not work correctly */ bool dxvaRender::refresh(void) { ADM_info("Refresh**\n"); #if 0 if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0))) { ADM_warning("D3D Present failed\n"); } #else D3DCallNoArg(IDirect3DDevice9,BeginScene,d3dDevice); D3DCallNoArg(IDirect3DDevice9,EndScene,d3dDevice); if( ADM_FAILED(D3DCall(IDirect3DDevice9,Present,d3dDevice, &targetRect, 0, 0, 0))) { ADM_warning("D3D Present failed\n"); } #endif return true; }
void Sampler::Init(SamplerFilter inFilter, SamplerAddressMode inAddressU, SamplerAddressMode inAddressV, int inMinLod, int inMaxLod) { CleanUp(); D3D11_SAMPLER_DESC* samp_desc = new D3D11_SAMPLER_DESC(); ZeroMemory(samp_desc, sizeof(D3D11_SAMPLER_DESC)); samp_desc->Filter = (D3D11_FILTER)inFilter; mFilter = inFilter; samp_desc->AddressU = (D3D11_TEXTURE_ADDRESS_MODE)inAddressU; mAddressModeU = inAddressU; samp_desc->AddressV = (D3D11_TEXTURE_ADDRESS_MODE)inAddressV; mAddressModeV = inAddressV; samp_desc->AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samp_desc->ComparisonFunc = D3D11_COMPARISON_NEVER; samp_desc->MinLOD = mMinLod = inMinLod; samp_desc->MaxLOD = mMaxLod = inMaxLod; D3DCall(theRenderContext.GetDevice()->CreateSamplerState(samp_desc, &mSamplerState)); assert(mSamplerState != nullptr); }
/** \fn setup \brief Allocate stuff for a given display with/height. It is called again each time the zoom is changed */ bool dxvaRender::setup() { D3DVIEWPORT9 viewPort = {0, 0, displayWidth, displayHeight, 0, 1}; ADM_info("D3D (re)Setting up \n"); D3DPRESENT_PARAMETERS presentationParameters; memset(&presentationParameters, 0, sizeof(presentationParameters)); presentationParameters.Windowed = TRUE; presentationParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; // We could use copy, but discard seems faster according to ms presentationParameters.Flags = D3DPRESENTFLAG_VIDEO; presentationParameters.hDeviceWindow = windowId; presentationParameters.BackBufferWidth = displayWidth; presentationParameters.BackBufferHeight = displayHeight; presentationParameters.MultiSampleType = D3DMULTISAMPLE_NONE; presentationParameters.PresentationInterval = D3DPRESENT_INTERVAL_ONE; presentationParameters.BackBufferFormat = displayMode.Format; presentationParameters.BackBufferCount = 1; presentationParameters.EnableAutoDepthStencil = FALSE; if( admD3D::isDirect9Ex()) { IDirect3DDevice9Ex *d3d9deviceex = NULL; if(ADM_FAILED(D3DCall(IDirect3D9Ex,CreateDeviceEx, ((IDirect3D9Ex *)d3dHandle), D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, presentationParameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentationParameters,NULL, &d3d9deviceex))) { ADM_warning("Failed to create D3D9Ex render device\n"); d3dDevice=NULL; } else { d3dDevice=(IDirect3DDevice9 *)d3d9deviceex; ADM_info("DXVA2Render : device created in D3D9Ex mode\n"); } } if(!d3dDevice) // fallback if D3D9Ex fails or not available { if(ADM_FAILED(D3DCall(IDirect3D9,CreateDevice, d3dHandle, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, presentationParameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentationParameters, &d3dDevice))) { ADM_warning("dxvaRender::Failed to create D3D render device\n"); return false; } } // D3DFORMAT yv12=(D3DFORMAT)MAKEFOURCC('Y','V','1','2'); // if( ADM_FAILED(D3DCall(IDirect3DDevice9,CreateOffscreenPlainSurface, d3dDevice, displayWidth,displayHeight, displayMode.Format, D3DPOOL_DEFAULT, &mySurface, NULL))) { ADM_warning("D3D Cannot create surface\n"); return false; } if( ADM_FAILED(D3DCall(IDirect3DDevice9,CreateOffscreenPlainSurface, d3dDevice, imageWidth,imageHeight, yv12, D3DPOOL_DEFAULT, &myYV12Surface, NULL))) { ADM_warning("D3D Cannot create surface\n"); return false; } // put some defaults D3DCall(IDirect3DDevice9,SetRenderState,d3dDevice, D3DRS_SRCBLEND, D3DBLEND_ONE); D3DCall(IDirect3DDevice9,SetRenderState,d3dDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); D3DCall(IDirect3DDevice9,SetRenderState,d3dDevice, D3DRS_ALPHAFUNC, D3DCMP_GREATER); D3DCall(IDirect3DDevice9,SetRenderState,d3dDevice, D3DRS_ALPHAREF, (DWORD)0x0); D3DCall(IDirect3DDevice9,SetRenderState,d3dDevice, D3DRS_LIGHTING, FALSE); D3DCall(IDirect3DDevice9,SetSamplerState,d3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); D3DCall(IDirect3DDevice9,SetSamplerState,d3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); // if(ADM_FAILED(D3DCall(IDirect3DDevice9,SetViewport,d3dDevice, &viewPort))) { ADM_warning("D3D Cannot set D3D viewport\n"); return false; } scaler=new ADMColorScalerFull(ADM_CS_BICUBIC,imageWidth,imageHeight,displayWidth,displayHeight, ADM_COLOR_YV12, ADM_COLOR_RGB32A ); videoBuffer=new uint8_t[displayWidth*displayHeight*4]; panScan.left =0; panScan.right =imageWidth-1; panScan.top =0; panScan.bottom=imageHeight-1; targetRect.left =0; targetRect.right =displayWidth-1; targetRect.top =0; targetRect.bottom=displayHeight-1; ADM_info("Setup done\n"); return true; }
/** \fn changeZoom */ bool dxvaRender::init( GUI_WindowInfo *window, uint32_t w, uint32_t h, float zoom) { ADM_info("Initializing dxva2/D3D render\n"); info=*window; baseInit(w,h,zoom); windowId=(HWND)window->systemWindowId; if(!d3dHandle) { ADM_warning("No D3DHandle\n"); return false; } if (ADM_FAILED(D3DCall(IDirect3D9,GetAdapterDisplayMode,d3dHandle, D3DADAPTER_DEFAULT, &displayMode))) { ADM_warning("Dxv2/D3D Render: Cannot get display mode\n"); return 0; } D3DCAPS9 deviceCapabilities; ADM_info("D3D Checking device capabilities\n"); if (ADM_FAILED(D3DCall(IDirect3D9,GetDeviceCaps,d3dHandle, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &deviceCapabilities))) { ADM_warning("Cannot get device capabilities"); return false; } int texture = deviceCapabilities.TextureCaps; ADM_info("Power of 2 : %d\n", (texture & D3DPTEXTURECAPS_POW2) && !(texture & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)); ADM_info("Square only: %d\n", (texture & D3DPTEXTURECAPS_SQUAREONLY)); // Check if we support YV12 D3DFORMAT fmt=displayMode.Format; D3DFORMAT yv12=(D3DFORMAT)MAKEFOURCC('Y','V','1','2'); if (ADM_FAILED(D3DCall(IDirect3D9,CheckDeviceFormatConversion, d3dHandle, // adapter D3DADAPTER_DEFAULT, // device type D3DDEVTYPE_HAL, // adapter format yv12, // render target format fmt))) // depth stencil format { useYV12=false; ADM_info("D3D YV12 not supported\n"); } else { useYV12=true; ADM_info("D3D YV12 is supported\n"); } if(!setup()) { ADM_warning("Dxva/D3D setup failed\n"); return false; } videoWidget=(ADM_Qvideo *)info.widget; videoWidget->useExternalRedraw(true); // deactivate Qt Double buffering videoWidget->setDrawer(this); ADM_info("Dxva (D3D) init successful, dxva render. w=%d, h=%d, zoom=%.4f, displayWidth=%d, displayHeight=%d\n",(int)w,(int)h,zoom,(int)displayWidth,(int)displayHeight); return true; }
void VertexShader::InitFromFile(std::string inFileName) { assert(FileUtil::FileExists(inFileName.c_str())); CleanUp(); DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; std::wstring filename = std::wstring(inFileName.begin(), inFileName.end()); #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* pVSBlob = nullptr; ID3DBlob* pErrorBlob = nullptr; D3DCall(D3DCompileFromFile(filename.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, "VS", "vs_5_0", dwShaderFlags, 0, &pVSBlob, &pErrorBlob)); if (pErrorBlob) { OutputDebugStringA(reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer())); pErrorBlob->Release(); } D3DCall(theRenderContext.GetDevice()->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &mHandle)); // Reflect shader info ID3D11ShaderReflection* pVertexShaderReflection = NULL; D3DCall(D3DReflect(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pVertexShaderReflection)); // Get shader info D3D11_SHADER_DESC shaderDesc; pVertexShaderReflection->GetDesc(&shaderDesc); // Read input layout description from shader info std::vector<D3D11_INPUT_ELEMENT_DESC> inputLayoutDesc; for (int i = 0; i < shaderDesc.InputParameters; i++) { D3D11_SIGNATURE_PARAMETER_DESC paramDesc; pVertexShaderReflection->GetInputParameterDesc(i, ¶mDesc); // fill out input element desc D3D11_INPUT_ELEMENT_DESC elementDesc; elementDesc.SemanticName = paramDesc.SemanticName; elementDesc.SemanticIndex = paramDesc.SemanticIndex; elementDesc.InputSlot = 0; if (i == 0) elementDesc.AlignedByteOffset = 0; else elementDesc.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; elementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elementDesc.InstanceDataStepRate = 0; // determine DXGI format if (paramDesc.Mask == 1) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32_FLOAT; } else if (paramDesc.Mask <= 3) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32_FLOAT; } else if (paramDesc.Mask <= 7) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; } else if (paramDesc.Mask <= 15) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; } //save element desc inputLayoutDesc.push_back(elementDesc); } // Try to create Input Layout D3DCall(theRenderContext.GetDevice()->CreateInputLayout(&inputLayoutDesc[0], inputLayoutDesc.size(), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &mVertexLayout)); //Free allocation shader reflection memory pVertexShaderReflection->Release(); pVSBlob->Release(); }