bool Texture::Create(UINT w, UINT h, const void* bits) { bool ret = false; mWidth = w; mHeight = h; ID3D11Device* device = gCore.GetDevice(); CHECK(device); D3D11_TEXTURE2D_DESC textureDesc; ZeroMemory(&textureDesc, sizeof(textureDesc)); textureDesc.Width = w; textureDesc.Height = h; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.SampleDesc.Count = 1; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; textureDesc.CPUAccessFlags = 0; textureDesc.MiscFlags = 0; if (bits) { D3D11_SUBRESOURCE_DATA subres; subres.pSysMem = bits; subres.SysMemPitch = w * 4; subres.SysMemSlicePitch = 0; // Not needed since this is a 2d texture CHECK(SUCCEEDED(device->CreateTexture2D(&textureDesc, &subres, &mPtr))); } else { CHECK(SUCCEEDED(device->CreateTexture2D(&textureDesc, nullptr, &mPtr))); } D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; shaderResourceViewDesc.Format = textureDesc.Format; shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shaderResourceViewDesc.Texture2D.MostDetailedMip = 0; shaderResourceViewDesc.Texture2D.MipLevels = 1; CHECK(SUCCEEDED(device->CreateShaderResourceView(mPtr, &shaderResourceViewDesc, &mSRV))); D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(samplerDesc)); 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.ComparisonFunc = D3D11_COMPARISON_NEVER; samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; CHECK(SUCCEEDED(device->CreateSamplerState(&samplerDesc, &mSampler))); ret = true; Exit0: return ret; }
void initAll(ID3D11Device& device, ID3D11DeviceContext& context, ShaderResources& shaderResources) { assert(shaderResources.mDiffuseMapSRV == nullptr); assert(shaderResources.mCSResultsSRV == nullptr); assert(shaderResources.mCSResultsUAV == nullptr); ID3D11Resource* texture = nullptr; // // Diffuse Map // HRESULT result = CreateDDSTextureFromFile(&device, L"Resources/Textures/brick.dds", &texture, &shaderResources.mDiffuseMapSRV); DxErrorChecker(result); texture->Release(); // // Create compute shader texture // D3D11_TEXTURE2D_DESC groupResultsTexDesc; groupResultsTexDesc.Width = 512; groupResultsTexDesc.Height = 512; groupResultsTexDesc.MipLevels = 1; groupResultsTexDesc.ArraySize = 1; groupResultsTexDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; groupResultsTexDesc.SampleDesc.Count = 1; groupResultsTexDesc.SampleDesc.Quality = 0; groupResultsTexDesc.Usage = D3D11_USAGE_DEFAULT; groupResultsTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS; groupResultsTexDesc.CPUAccessFlags = 0; groupResultsTexDesc.MiscFlags = 0; ID3D11Texture2D* groupResultsTex = nullptr; assert(Globals::gDirect3DData.mDevice); result = device.CreateTexture2D(&groupResultsTexDesc, 0, &groupResultsTex); DxErrorChecker(result); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; result = device.CreateTexture2D(&groupResultsTexDesc, 0, &groupResultsTex); result = device.CreateShaderResourceView(groupResultsTex, &srvDesc, &shaderResources.mCSResultsSRV); D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; uavDesc.Texture2D.MipSlice = 0; result = device.CreateUnorderedAccessView(groupResultsTex, &uavDesc, &shaderResources.mCSResultsUAV); // Views save a reference to the texture so we can release our reference. groupResultsTex->Release(); }
bool Texture::LoadXOR() { width_ = height_ = 256; unsigned char *buf = new unsigned char[width_*height_*4]; for (int y = 0; y < 256; y++) { for (int x = 0; x < 256; x++) { buf[(y*width_ + x)*4 + 0] = x^y; buf[(y*width_ + x)*4 + 1] = x^y; buf[(y*width_ + x)*4 + 2] = x^y; buf[(y*width_ + x)*4 + 3] = 0xFF; } } GL_CHECK(); ID3D11Device *ctx; D3D11_TEXTURE2D_DESC desc; desc.Width = width_; desc.Height = height_; desc.MipLevels = 0; desc.ArraySize = 1; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.Usage = D3D11_USAGE_DEFAULT; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; if (FAILED(ctx->CreateTexture2D(&desc, 0, &tex_))) { FLOG("Failed creating XOR texture"); } SetTextureParameters(ZIM_GEN_MIPS); GL_CHECK(); delete [] buf; return true; }
static bool grabFrameD3D11(IDXGISwapChain *swap) { ID3D11Device *device = 0; ID3D11DeviceContext *context = 0; ID3D11Texture2D *tex = 0, *captureTex = 0; if (FAILED(swap->GetBuffer(0, IID_ID3D11Texture2D, (void**)&tex))) return false; D3D11_TEXTURE2D_DESC desc; tex->GetDevice(&device); tex->GetDesc(&desc); // re-creating the capture staging texture each frame is definitely not the most efficient // way to handle things, but it frees me of all kind of resource management trouble, so // here goes... desc.MipLevels = 1; desc.ArraySize = 1; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.MiscFlags = 0; if(FAILED(device->CreateTexture2D(&desc,0,&captureTex))) printLog("video/d3d11: couldn't create staging texture for gpu->cpu download!\n"); else setCaptureResolution(desc.Width,desc.Height); device->GetImmediateContext(&context); context->CopySubresourceRegion(captureTex,0,0,0,0,tex,0,0); D3D11_MAPPED_SUBRESOURCE mapped; bool grabOk = false; if(captureTex && SUCCEEDED(context->Map(captureTex,0,D3D11_MAP_READ,0,&mapped))) { switch(desc.Format) { case DXGI_FORMAT_R8G8B8A8_UNORM: blitAndFlipRGBAToCaptureData((unsigned char *) mapped.pData,mapped.RowPitch); grabOk = true; break; default: printLog("video/d3d11: unsupported backbuffer format, can't grab pixels!\n"); break; } context->Unmap(captureTex,0); } tex->Release(); if(captureTex) captureTex->Release(); context->Release(); device->Release(); return grabOk; }
void checkPixelsUsingD3D(bool usingPresentPathFast) { ASSERT_NE(nullptr, mOffscreenSurfaceD3D11Texture); D3D11_TEXTURE2D_DESC textureDesc = {0}; ID3D11Device *device; ID3D11DeviceContext *context; mOffscreenSurfaceD3D11Texture->GetDesc(&textureDesc); mOffscreenSurfaceD3D11Texture->GetDevice(&device); device->GetImmediateContext(&context); ASSERT_NE(nullptr, device); ASSERT_NE(nullptr, context); textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; textureDesc.Usage = D3D11_USAGE_STAGING; textureDesc.BindFlags = 0; textureDesc.MiscFlags = 0; ID3D11Texture2D *cpuTexture = nullptr; ASSERT_TRUE(SUCCEEDED(device->CreateTexture2D(&textureDesc, nullptr, &cpuTexture))); context->CopyResource(cpuTexture, mOffscreenSurfaceD3D11Texture); D3D11_MAPPED_SUBRESOURCE mappedSubresource; context->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mappedSubresource); ASSERT_EQ(static_cast<UINT>(mWindowWidth * 4), mappedSubresource.RowPitch); ASSERT_EQ(static_cast<UINT>(mWindowWidth * mWindowWidth * 4), mappedSubresource.DepthPitch); angle::GLColor *byteData = reinterpret_cast<angle::GLColor *>(mappedSubresource.pData); // Note that the texture is in BGRA format, although the GLColor struct is RGBA GLColor expectedTopLeftPixel = GLColor(0, 0, 255, 255); // Red GLColor expectedTopRightPixel = GLColor(0, 255, 0, 255); // Green GLColor expectedBottomLeftPixel = GLColor(255, 0, 0, 255); // Blue GLColor expectedBottomRightPixel = GLColor(0, 255, 255, 255); // Red + Green if (usingPresentPathFast) { // Invert the expected values GLColor tempTopLeft = expectedTopLeftPixel; GLColor tempTopRight = expectedTopRightPixel; expectedTopLeftPixel = expectedBottomLeftPixel; expectedTopRightPixel = expectedBottomRightPixel; expectedBottomLeftPixel = tempTopLeft; expectedBottomRightPixel = tempTopRight; } EXPECT_EQ(expectedTopLeftPixel, byteData[0]); EXPECT_EQ(expectedTopRightPixel, byteData[(mWindowWidth - 1)]); EXPECT_EQ(expectedBottomLeftPixel, byteData[(mWindowWidth - 1) * mWindowWidth]); EXPECT_EQ(expectedBottomRightPixel, byteData[(mWindowWidth - 1) * mWindowWidth + (mWindowWidth - 1)]); context->Unmap(cpuTexture, 0); SafeRelease(cpuTexture); SafeRelease(device); SafeRelease(context); }
void Image11::createStagingTexture() { if (mStagingTexture) { return; } ID3D11Texture2D *newTexture = NULL; int lodOffset = 1; DXGI_FORMAT dxgiFormat = getDXGIFormat(); ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures /* if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3 && dxgiFormat == DXGI_FORMAT_A8_UNORM) dxgiFormat = DXGI_FORMAT_B8G8R8A8_UNORM; */ if (mWidth != 0 && mHeight != 0) { GLsizei width = mWidth; GLsizei height = mHeight; // adjust size if needed for compressed textures gl::MakeValidSize(false, d3d11::IsCompressed(dxgiFormat), &width, &height, &lodOffset); ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE2D_DESC desc; desc.Width = width; desc.Height = height; desc.MipLevels = lodOffset + 1; desc.ArraySize = 1; desc.Format = dxgiFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture); if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); ERR("Creating image failed."); return gl::error(GL_OUT_OF_MEMORY); } } mStagingTexture = newTexture; mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); mDirty = false; }
bool CDXVAContext::CreateSurfaces(D3D11_VIDEO_DECODER_DESC format, unsigned int count, unsigned int alignment, ID3D11VideoDecoderOutputView **surfaces) const { HRESULT hr = S_OK; ID3D11Device* pDevice = g_Windowing.Get3D11Device(); ID3D11DeviceContext1* pContext = g_Windowing.GetImmediateContext(); unsigned bindFlags = D3D11_BIND_DECODER; if (g_Windowing.IsFormatSupport(format.OutputFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) bindFlags |= D3D11_BIND_SHADER_RESOURCE; CD3D11_TEXTURE2D_DESC texDesc(format.OutputFormat, FFALIGN(format.SampleWidth, alignment), FFALIGN(format.SampleHeight, alignment), count, 1, bindFlags); ID3D11Texture2D *texture = nullptr; if (FAILED(pDevice->CreateTexture2D(&texDesc, NULL, &texture))) { CLog::LogF(LOGERROR, "failed creating decoder texture array."); return false; } D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC vdovDesc; vdovDesc.DecodeProfile = format.Guid; vdovDesc.Texture2D.ArraySlice = 0; vdovDesc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D; float clearColor[] = { 0.0625f, 0.5f, 0.5f, 1.0f }; // black color in YUV size_t i; for (i = 0; i < count; ++i) { vdovDesc.Texture2D.ArraySlice = D3D11CalcSubresource(0, i, texDesc.MipLevels); hr = m_service->CreateVideoDecoderOutputView(texture, &vdovDesc, &surfaces[i]); if (FAILED(hr)) { CLog::LogF(LOGERROR, "failed creating surfaces."); break; } pContext->ClearView(surfaces[i], clearColor, nullptr, 0); } SAFE_RELEASE(texture); if (FAILED(hr)) { for (size_t j = 0; j < i; ++j) SAFE_RELEASE(surfaces[j]); } return SUCCEEDED(hr); }
void D11State::newTexture(unsigned int w, unsigned int h) { HRESULT hr; ods("D3D11: newTex %d %d", w, h); if (pTexture) { pTexture->Release(); pTexture = NULL; } if (pSRView) { pSRView->Release(); pSRView = NULL; } D3D11_TEXTURE2D_DESC desc; ZeroMemory(&desc, sizeof(desc)); desc.Width = w; desc.Height = h; desc.MipLevels = desc.ArraySize = 1; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DYNAMIC; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; hr = pDevice->CreateTexture2D(&desc, NULL, &pTexture); if (FAILED(hr)) { pTexture = NULL; ods("D3D11: Failed to create texture."); return; } D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(srvDesc)); srvDesc.Format = desc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = desc.MipLevels; hr = pDevice->CreateShaderResourceView(pTexture, &srvDesc, &pSRView); if (FAILED(hr)) { pSRView = NULL; pTexture->Release(); pTexture = NULL; ods("D3D11: Failed to create resource view."); return; } }
bool D3D11DepthStencilBuffer::Create(int w, int h, G_FORMAT format) { D3D11_TEXTURE2D_DESC td; ZeroMemory(&td, sizeof(td)); td.ArraySize = 1; td.BindFlags = D3D11_BIND_DEPTH_STENCIL; td.CPUAccessFlags = 0; td.Format = D3D11Format::Convert(format); td.Width = w; td.Height = h; td.MipLevels = 1; td.ArraySize = 1; td.MiscFlags = 0; td.SampleDesc.Count = 1; td.SampleDesc.Quality = 0; td.Usage = D3D11_USAGE_DEFAULT; ID3D11Device* pDevice = NULL; m_pContext->GetDevice(&pDevice); if(FAILED(pDevice->CreateTexture2D(&td, NULL, &m_pBuffer))) { pDevice->Release(); return DepthStencilBufferPtr(); } D3D11_DEPTH_STENCIL_VIEW_DESC d; ZeroMemory(&d, sizeof(d)); d.Format = D3D11Format::Convert(format); d.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; d.Flags = 0; d.Texture2D.MipSlice = 0; if(FAILED(pDevice->CreateDepthStencilView( m_pBuffer, &d, &m_pDepthStencilView))) { pDevice->Release(); return false; } pDevice->Release(); return true; }
bool CDXVAContext::CreateSurfaces(D3D11_VIDEO_DECODER_DESC format, unsigned int count, unsigned int alignment, ID3D11VideoDecoderOutputView **surfaces) { HRESULT hr = S_OK; ID3D11Device* pDevice = g_Windowing.Get3D11Device(); CD3D11_TEXTURE2D_DESC texDesc(format.OutputFormat, FFALIGN(format.SampleWidth, alignment), FFALIGN(format.SampleHeight, alignment), count, 1, D3D11_BIND_DECODER); ID3D11Texture2D *texture = nullptr; if (FAILED(pDevice->CreateTexture2D(&texDesc, NULL, &texture))) { CLog::Log(LOGERROR, "%s - failed creating decoder texture array", __FUNCTION__); return false; } D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC vdovDesc = {0}; vdovDesc.DecodeProfile = format.Guid; vdovDesc.Texture2D.ArraySlice = 0; vdovDesc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D; size_t i; for (i = 0; i < count; ++i) { vdovDesc.Texture2D.ArraySlice = D3D11CalcSubresource(0, i, texDesc.MipLevels); hr = m_service->CreateVideoDecoderOutputView(texture, &vdovDesc, &surfaces[i]); if (FAILED(hr)) { CLog::Log(LOGERROR, "%s - failed creating surfaces", __FUNCTION__); break; } } SAFE_RELEASE(texture); if (FAILED(hr)) { for (size_t j = 0; j < i; ++j) SAFE_RELEASE(surfaces[j]); } return SUCCEEDED(hr); }
bool TextureCube<RendererTypeDX11>::LoadTextureData(std::vector<const BYTE *> &buffers) { TEXTURE_DESC &desc = this->GetDesc(); const Size &size = this->GetSize(); mTextureParams.Width = size.width; mTextureParams.Height = size.height; int faceSize = size.width * size.height * 4; D3D11_SUBRESOURCE_DATA textureData[6]; for(int i = 0; i < 6; i++) { textureData[i].pSysMem = &buffers[0][faceSize * i]; textureData[i].SysMemPitch = size.width * TextureFormatNumComponents[desc.Format]; textureData[i].SysMemSlicePitch = faceSize; } ID3D11Device *device = this->GetDevice()->GetD3D11Device(); HRESULT hr = device->CreateTexture2D(&mTextureParams, textureData, &mDXTexture); if(hr != S_OK) { // TODO: Error handling throw "Error Creating D3D11 Texture!"; } ID3D11ShaderResourceView *resourceView; D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc; memset(&resourceViewDesc, 0, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC)); resourceViewDesc.Format = mTextureParams.Format; resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; resourceViewDesc.TextureCube.MipLevels = 1; resourceViewDesc.TextureCube.MostDetailedMip = 0; hr = device->CreateShaderResourceView(mDXTexture, &resourceViewDesc, &resourceView); if(hr != S_OK) { // TODO: Error handling throw "Error Creating D3D11 Texture Resource View!"; } this->SetTextureResource(resourceView); }
ID3D11Texture2D* DxAssist::CreateTexture( uint w, uint h, DXGI_FORMAT format /*= DXGI_FORMAT_R8G8B8A8_UNORM*/, D3D11_USAGE usage /*= D3D11_USAGE_DEFAULT*/, UINT bindFlags /*= (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)*/ ) { HRESULT hr = E_FAIL; ID3D11Device* device = m_device; ID3D11DeviceContext* deviceContext = m_deviceContext; ID3D11Texture2D* texture = 0; D3D11_TEXTURE2D_DESC texdesc; ASSERT(device); ASSERT(deviceContext); // Create the rendered texture. memset(&texdesc, 0, sizeof(texdesc)); texdesc.Width = w; texdesc.Height = h; texdesc.MipLevels = 1; texdesc.ArraySize = 1; texdesc.Format = format; texdesc.SampleDesc.Count = 1; texdesc.SampleDesc.Quality = 0; texdesc.Usage = usage; texdesc.BindFlags = bindFlags; texdesc.CPUAccessFlags = 0; texdesc.MiscFlags = 0; hr = device->CreateTexture2D(&texdesc, NULL, &texture); KGLOG_COM_PROCESS_ERROR(hr); Exit0: return texture; }
HRESULT DxAssist::CreateRTDevice(ID3D11Texture2D* texture, DxRTDevice* RTDevice) { HRESULT hr = E_FAIL; HRESULT hresult = E_FAIL; ID3D11Device* device = m_device; ID3D11DeviceContext* deviceContext = m_deviceContext; D3D11_TEXTURE2D_DESC texdesc; ASSERT(device); ASSERT(deviceContext); hr = device->CreateRenderTargetView(texture, NULL, &RTDevice->RTView); KGLOG_COM_PROCESS_ERROR(hr); // Create the depth/stencil buffer that is used when rendering the cube. Most parameters remain the same, // except the format, and bind flags. texture->GetDesc(&texdesc); texdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; texdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; hr = device->CreateTexture2D(&texdesc, NULL, &RTDevice->RTDepthStencilBuf); KGLOG_COM_PROCESS_ERROR(hr); hr = device->CreateDepthStencilView( RTDevice->RTDepthStencilBuf, NULL, &RTDevice->RTDepthStencil); KGLOG_COM_PROCESS_ERROR(hr); hresult = S_OK; Exit0: if ( FAILED(hresult) ) { ReleaseRTDevice(RTDevice); } return hresult; }
gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource) { D3D11_TEXTURE2D_DESC textureDesc; source->GetDesc(&textureDesc); if (textureDesc.Format == mDXGIFormat) { // No conversion needed-- use copyback fastpath ID3D11Resource *stagingTexture = NULL; unsigned int stagingSubresourceIndex = 0; gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); if (error.isError()) { return error; } ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); UINT subresourceAfterResolve = sourceSubResource; ID3D11Texture2D* srcTex = NULL; if (textureDesc.SampleDesc.Count > 1) { D3D11_TEXTURE2D_DESC resolveDesc; resolveDesc.Width = textureDesc.Width; resolveDesc.Height = textureDesc.Height; resolveDesc.MipLevels = 1; resolveDesc.ArraySize = 1; resolveDesc.Format = textureDesc.Format; resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; resolveDesc.Usage = D3D11_USAGE_DEFAULT; resolveDesc.BindFlags = 0; resolveDesc.CPUAccessFlags = 0; resolveDesc.MiscFlags = 0; HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); } deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, textureDesc.Format); subresourceAfterResolve = 0; } else { srcTex = source; } D3D11_BOX srcBox; srcBox.left = sourceArea.x; srcBox.right = sourceArea.x + sourceArea.width; srcBox.top = sourceArea.y; srcBox.bottom = sourceArea.y + sourceArea.height; srcBox.front = 0; srcBox.back = 1; deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, xoffset, yoffset, zoffset, srcTex, subresourceAfterResolve, &srcBox); if (textureDesc.SampleDesc.Count > 1) { SafeRelease(srcTex); } } else { // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels D3D11_MAPPED_SUBRESOURCE mappedImage; gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); if (error.isError()) { return error; } // determine the offset coordinate into the destination buffer GLsizei rowOffset = gl::GetInternalFormatInfo(mActualFormat).pixelBytes * xoffset; uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch; const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); unmap(); if (error.isError()) { return error; } } mDirty = true; return gl::Error(GL_NO_ERROR); }
void MultiRenderTarget::Initialise( u32 count, u32 width, u32 height ) { // Store the width and height of the render texture. mWidth = width; mHeight = height; // Initialize the render target texture description. D3D11_TEXTURE2D_DESC textureDesc; ZeroMemory( &textureDesc, sizeof( textureDesc ) ); // Setup the render target texture description. textureDesc.Width = width; textureDesc.Height = height; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; textureDesc.SampleDesc.Count = 1; textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; textureDesc.CPUAccessFlags = 0; textureDesc.MiscFlags = 0; // Create the render target textures. ID3D11Device * device = GRAPHICS.GetPipeline()->GetDevice(); mRenderTargetTextures.resize( count, nullptr ); for( u32 i = 0; i < count; ++i ) { HRESULT result = device->CreateTexture2D( &textureDesc, nullptr, mRenderTargetTextures.data() + i ); if( FAILED( result ) ) { return; } } // Setup the description of the render target view. D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; renderTargetViewDesc.Format = textureDesc.Format; renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; renderTargetViewDesc.Texture2D.MipSlice = 0; // Create the render target views. mRenderTargetViews.resize( count, nullptr ); for( u32 i = 0; i < count; ++i ) { HRESULT result = device->CreateRenderTargetView( mRenderTargetTextures[i], &renderTargetViewDesc, mRenderTargetViews.data() + i ); if( FAILED( result ) ) { return; } } // Setup the description of the shader resource view. D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; shaderResourceViewDesc.Format = textureDesc.Format; shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shaderResourceViewDesc.Texture2D.MostDetailedMip = 0; shaderResourceViewDesc.Texture2D.MipLevels = 1; // Create the shader resource views. mShaderResourceViews.resize( count, nullptr ); for( u32 i = 0; i < count; ++i ) { HRESULT result = device->CreateShaderResourceView( mRenderTargetTextures[i], &shaderResourceViewDesc, mShaderResourceViews.data() + i ); if( FAILED( result ) ) { return; } } // Initialize the description of the depth buffer. D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory( &depthBufferDesc, sizeof( depthBufferDesc ) ); // Set up the description of the depth buffer. depthBufferDesc.Width = width; depthBufferDesc.Height = height; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. HRESULT result = device->CreateTexture2D( &depthBufferDesc, NULL, &mDepthStencilBuffer ); if( FAILED( result ) ) { return; } // Initailze the depth stencil view description. D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; ZeroMemory( &depthStencilViewDesc, sizeof( depthStencilViewDesc ) ); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = device->CreateDepthStencilView( mDepthStencilBuffer, &depthStencilViewDesc, &mDepthStencilView ); if( FAILED( result ) ) { return; } // Setup the viewport for rendering. mViewport.Width = static_cast<float>( width ); mViewport.Height = static_cast<float>( height ); mViewport.MinDepth = 0.0f; mViewport.MaxDepth = 1.0f; mViewport.TopLeftX = 0.0f; mViewport.TopLeftY = 0.0f; }
Coherent::UI::CoherentHandle CCoherentUISystem::CreateSharedTextureDX11( const CreateSurfaceTask& task, TexturePair* outTexturePair ) { // The shared texture's format for DX11 must be DXGI_FORMAT_B8G8R8A8_UNORM. // There is no corresponding ETEX_Format and after injecting the created // texture, COM errors occur. // TODO: Find a way to fool CryEngine into accepting a DXGI_FORMAT_B8G8R8A8_UNORM texture. // Create shared texture D3D11_TEXTURE2D_DESC desc; memset( &desc, 0, sizeof( desc ) ); desc.Width = task.Width; desc.Height = task.Height; desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; desc.SampleDesc.Count = 1; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); ID3D11Texture2D* pD3DTex = NULL; HRESULT hr = pDevice->CreateTexture2D( &desc, NULL, &pD3DTex ); if ( FAILED( hr ) ) { return Coherent::UI::CoherentHandle( 0 ); } IDXGIResource* pTempResource = NULL; hr = pD3DTex->QueryInterface( __uuidof( IDXGIResource ), ( void** )&pTempResource ); if ( FAILED( hr ) ) { SAFE_RELEASE( pD3DTex ); return Coherent::UI::CoherentHandle( 0 ); } HANDLE result; hr = pTempResource->GetSharedHandle( &result ); pTempResource->Release(); if ( FAILED( hr ) ) { SAFE_RELEASE( pD3DTex ); return Coherent::UI::CoherentHandle( 0 ); } ITexture* pCryTex = gD3DSystem->InjectTexture( pD3DTex, task.Width, task.Height, eTF_A8R8G8B8, 0 ); // The native texture has one more reference after InjectTexture if ( outTexturePair ) { outTexturePair->CryTextureID = pCryTex->GetTextureID(); outTexturePair->NativeTexture.pTexDX11 = pD3DTex; } SAFE_RELEASE( pD3DTex ); return Coherent::UI::CoherentHandle( result ); }
HRESULT STDMETHODCALLTYPE SwapPresentHook(UINT syncInterval, UINT flags) { IDXGISwapChain *swap = (IDXGISwapChain*)this; if(lpCurrentSwap == NULL && !bTargetAcquired) { lpCurrentSwap = swap; SetupD3D11(swap); bTargetAcquired = true; } if(lpCurrentSwap == swap) { ID3D11Device *device = NULL; HRESULT chi; if(SUCCEEDED(chi = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device))) { if(!lpCurrentDevice) { lpCurrentDevice = device; oldD3D11Release = GetVTable(device, (8/4)); newD3D11Release = ConvertClassProcToFarproc((CLASSPROC)&D3D11Override::DeviceReleaseHook); SetVTable(device, (8/4), newD3D11Release); } ID3D11DeviceContext *context; device->GetImmediateContext(&context); if(!bHasTextures && bCapturing) { if(dxgiFormat) { if(!hwndReceiver) hwndReceiver = FindWindow(RECEIVER_WINDOWCLASS, NULL); if(hwndReceiver) { D3D11_TEXTURE2D_DESC texDesc; ZeroMemory(&texDesc, sizeof(texDesc)); texDesc.Width = d3d11CaptureInfo.cx; texDesc.Height = d3d11CaptureInfo.cy; texDesc.MipLevels = 1; texDesc.ArraySize = 1; texDesc.Format = dxgiFormat; texDesc.SampleDesc.Count = 1; texDesc.Usage = D3D11_USAGE_STAGING; texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; bool bSuccess = true; UINT pitch; for(UINT i=0; i<2; i++) { HRESULT ching; if(FAILED(ching = device->CreateTexture2D(&texDesc, NULL, &d3d11Textures[i]))) { bSuccess = false; break; } if(i == 0) { ID3D11Resource *resource; if(FAILED(d3d11Textures[i]->QueryInterface(__uuidof(ID3D11Resource), (void**)&resource))) { bSuccess = false; break; } D3D11_MAPPED_SUBRESOURCE map; if(FAILED(context->Map(resource, 0, D3D11_MAP_READ, 0, &map))) { bSuccess = false; break; } pitch = map.RowPitch; context->Unmap(resource, 0); resource->Release(); } } if(bSuccess) { d3d11CaptureInfo.mapID = InitializeSharedMemory(pitch*d3d11CaptureInfo.cy, &d3d11CaptureInfo.mapSize, ©Data, textureBuffers); if(!d3d11CaptureInfo.mapID) bSuccess = false; } if(bSuccess) { bHasTextures = true; d3d11CaptureInfo.captureType = CAPTURETYPE_MEMORY; d3d11CaptureInfo.hwndSender = hwndSender; d3d11CaptureInfo.pitch = pitch; d3d11CaptureInfo.bFlip = FALSE; PostMessage(hwndReceiver, RECEIVER_NEWCAPTURE, 0, (LPARAM)&d3d11CaptureInfo); } else { for(UINT i=0; i<2; i++) { SafeRelease(d3d11Textures[i]); if(textureBuffers[i]) { free(textureBuffers[i]); textureBuffers[i] = NULL; } } } } } } if(bHasTextures) { if(bCapturing) { DWORD nextCapture = curCapture == 0 ? 1 : 0; ID3D11Texture2D *texture = d3d11Textures[curCapture]; ID3D11Resource *backBuffer = NULL; if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D11Resource, (void**)&backBuffer))) { if(bIsMultisampled) context->ResolveSubresource(texture, 0, backBuffer, 0, dxgiFormat); else context->CopyResource(texture, backBuffer); backBuffer->Release(); ID3D11Texture2D *lastTexture = d3d11Textures[nextCapture]; ID3D11Resource *resource; if(SUCCEEDED(lastTexture->QueryInterface(__uuidof(ID3D11Resource), (void**)&resource))) { D3D11_MAPPED_SUBRESOURCE map; if(SUCCEEDED(context->Map(resource, 0, D3D11_MAP_READ, 0, &map))) { LPBYTE *pTextureBuffer = NULL; int lastRendered = -1; //under no circumstances do we -ever- allow a stall if(WaitForSingleObject(textureMutexes[curCapture], 0) == WAIT_OBJECT_0) lastRendered = (int)curCapture; else if(WaitForSingleObject(textureMutexes[nextCapture], 0) == WAIT_OBJECT_0) lastRendered = (int)nextCapture; if(lastRendered != -1) { SSECopy(textureBuffers[lastRendered], map.pData, map.RowPitch*d3d11CaptureInfo.cy); ReleaseMutex(textureMutexes[lastRendered]); } context->Unmap(resource, 0); copyData->lastRendered = (UINT)lastRendered; } resource->Release(); } } curCapture = nextCapture; } else ClearD3D11Data(); } device->Release(); context->Release(); } } gi11swapPresent.Unhook(); HRESULT hRes = swap->Present(syncInterval, flags); gi11swapPresent.Rehook(); return hRes; }
gl::Error Image11::copyWithoutConversion(const gl::Offset &destOffset, const gl::Box &sourceArea, const TextureHelper11 &textureHelper, UINT sourceSubResource) { // No conversion needed-- use copyback fastpath ID3D11Resource *stagingTexture = nullptr; unsigned int stagingSubresourceIndex = 0; gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); if (error.isError()) { return error; } ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); UINT subresourceAfterResolve = sourceSubResource; ID3D11Resource *srcTex = nullptr; const gl::Extents &extents = textureHelper.getExtents(); bool needResolve = (textureHelper.getTextureType() == GL_TEXTURE_2D && textureHelper.getSampleCount() > 1); if (needResolve) { D3D11_TEXTURE2D_DESC resolveDesc; resolveDesc.Width = extents.width; resolveDesc.Height = extents.height; resolveDesc.MipLevels = 1; resolveDesc.ArraySize = 1; resolveDesc.Format = textureHelper.getFormat(); resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; resolveDesc.Usage = D3D11_USAGE_DEFAULT; resolveDesc.BindFlags = 0; resolveDesc.CPUAccessFlags = 0; resolveDesc.MiscFlags = 0; ID3D11Texture2D *srcTex2D = NULL; HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex2D); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); } srcTex = srcTex2D; deviceContext->ResolveSubresource(srcTex, 0, textureHelper.getTexture2D(), sourceSubResource, textureHelper.getFormat()); subresourceAfterResolve = 0; } else { srcTex = textureHelper.getResource(); } D3D11_BOX srcBox; srcBox.left = sourceArea.x; srcBox.right = sourceArea.x + sourceArea.width; srcBox.top = sourceArea.y; srcBox.bottom = sourceArea.y + sourceArea.height; srcBox.front = sourceArea.z; srcBox.back = sourceArea.z + sourceArea.depth; deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, destOffset.x, destOffset.y, destOffset.z, srcTex, subresourceAfterResolve, &srcBox); if (needResolve) { SafeRelease(srcTex); } mDirty = true; return gl::Error(GL_NO_ERROR); }
/** * Handle Stereo Drawing. ***/ void* StereoPresenter::Provoke(void* pThis, int eD3D, int eD3DInterface, int eD3DMethod, DWORD dwNumberConnected, int& nProvokerIndex) { #ifdef _DEBUG_STP { wchar_t buf[128]; wsprintf(buf, L"[STP] ifc %u mtd %u", eD3DInterface, eD3DMethod); OutputDebugString(buf); } #endif // update our global time static float fGlobalTime = 0.0f; static DWORD dwTimeStart = 0; DWORD dwTimeCur = GetTickCount(); if (dwTimeStart == 0) dwTimeStart = dwTimeCur; fGlobalTime = (dwTimeCur - dwTimeStart) / 1000.0f; // only present accepted bool bValid = false; if (((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) || ((eD3DInterface == INTERFACE_IDIRECT3DDEVICE9) && (eD3DMethod == METHOD_IDIRECT3DDEVICE9_PRESENT))) bValid = true; if (!bValid) return nullptr; // clear all previous menu events ZeroMemory(&m_abMenuEvents[0], sizeof(VireioMenuEvent)* (int)VireioMenuEvent::NumberOfEvents); // main menu update ? if ((m_sMainMenu.bOnChanged) && (!m_sMenuControl.eSelectionMovement)) { m_sMainMenu.bOnChanged = false; // loop through entries for (size_t nIx = 0; nIx < m_sMainMenu.asEntries.size(); nIx++) { // entry index changed ? if (m_sMainMenu.asEntries[nIx].bOnChanged) { m_sMainMenu.asEntries[nIx].bOnChanged = false; // set new menu index.. selection to zero m_sMenuControl.nMenuIx = (INT)nIx; m_sMenuControl.unSelectionFormer = m_sMenuControl.unSelection = 0; } } } // sub menu update ? if ((m_sSubMenu.bOnChanged) && (!m_sMenuControl.eSelectionMovement)) { m_sSubMenu.bOnChanged = false; // exit ? if (m_sSubMenu.bOnExit) m_sMenuControl.nMenuIx = -1; // loop through entries for (size_t nIx = 0; nIx < m_sSubMenu.asEntries.size(); nIx++) { // entry index changed ? if (m_sSubMenu.asEntries[nIx].bOnChanged) { m_sSubMenu.asEntries[nIx].bOnChanged = false; // font ? if (nIx == ENTRY_FONT) { // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; HRESULT nHr = S_OK; if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) nHr = GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext); else { if (m_ppcTexView11[0]) { if (*(m_ppcTexView11[0])) (*(m_ppcTexView11[0]))->GetDevice(&pcDevice); if (pcDevice) pcDevice->GetImmediateContext(&pcContext); else nHr = E_FAIL; if (!pcContext) nHr = E_FAIL; } else nHr = E_FAIL; } if (SUCCEEDED(nHr)) { HRESULT nHr; // get base directory std::string strVireioPath = GetBaseDir(); // add file path strVireioPath += "font//"; strVireioPath += m_sSubMenu.asEntries[nIx].astrValueEnumeration[m_sSubMenu.asEntries[nIx].unValue]; strVireioPath += ".spritefont"; OutputDebugStringA(strVireioPath.c_str()); // create font, make backup VireioFont* pcOldFont = m_pcFontSegeo128; m_pcFontSegeo128 = new VireioFont(pcDevice, pcContext, strVireioPath.c_str(), 128.0f, 1.0f, nHr, 1); if (FAILED(nHr)) { delete m_pcFontSegeo128; m_pcFontSegeo128 = pcOldFont; } else { // set new font name m_strFontName = m_sSubMenu.asEntries[nIx].astrValueEnumeration[m_sSubMenu.asEntries[nIx].unValue]; // write to ini file char szFilePathINI[1024]; GetCurrentDirectoryA(1024, szFilePathINI); strcat_s(szFilePathINI, "\\VireioPerception.ini"); WritePrivateProfileStringA("Stereo Presenter", "strFontName", m_strFontName.c_str(), szFilePathINI); } } SAFE_RELEASE(pcDevice); SAFE_RELEASE(pcContext); } } } } // get xbox controller input XINPUT_STATE sControllerState; bool bControllerAttached = false; ZeroMemory(&sControllerState, sizeof(XINPUT_STATE)); if (XInputGetState(0, &sControllerState) == ERROR_SUCCESS) { bControllerAttached = true; } if (true) { #pragma region menu hotkeys static bool bReleased = true; static bool s_bOnMenu = false; // keyboard menu on/off event + get hand poses UINT uIxHandPoses = 0, uIxPoseRequest = 0; s_bOnMenu = GetAsyncKeyState(VK_LCONTROL) && GetAsyncKeyState(0x51); for (UINT unIx = 0; unIx < 32; unIx++) { // set menu bool event if (m_apsSubMenues[unIx]) { if (m_apsSubMenues[unIx]->bOnBack) { // main menu ? exit if ((m_sMenuControl.nMenuIx == -1) && (!m_sMenuControl.eSelectionMovement)) s_bOnMenu = true; else m_abMenuEvents[VireioMenuEvent::OnExit] = TRUE; m_apsSubMenues[unIx]->bOnBack = false; } // hand poses ? if (m_apsSubMenues[unIx]->bHandPosesPresent) uIxHandPoses = unIx; if (m_apsSubMenues[unIx]->bHandPosesRequest) uIxPoseRequest = unIx; } } if ((m_apsSubMenues[uIxHandPoses]) && (m_apsSubMenues[uIxPoseRequest])) { // copy the hand pose data to the request node m_apsSubMenues[uIxPoseRequest]->sPoseMatrix[0] = m_apsSubMenues[uIxHandPoses]->sPoseMatrix[0]; m_apsSubMenues[uIxPoseRequest]->sPoseMatrix[1] = m_apsSubMenues[uIxHandPoses]->sPoseMatrix[1]; m_apsSubMenues[uIxPoseRequest]->sPosition[0] = m_apsSubMenues[uIxHandPoses]->sPosition[0]; m_apsSubMenues[uIxPoseRequest]->sPosition[1] = m_apsSubMenues[uIxHandPoses]->sPosition[1]; } // static hotkeys : LCTRL+Q - toggle vireio menu // F12 - toggle stereo output if (GetAsyncKeyState(VK_F12)) { m_bHotkeySwitch = true; } else if (s_bOnMenu) { m_bMenuHotkeySwitch = true; } else if (m_bMenuHotkeySwitch) { m_bMenuHotkeySwitch = false; m_bMenu = !m_bMenu; for (UINT unIx = 0; unIx < 32; unIx++) { // set sub menu active if menu is active if (m_apsSubMenues[unIx]) m_apsSubMenues[unIx]->bIsActive = m_bMenu; } } else if (m_bHotkeySwitch) { if (m_eStereoMode) m_eStereoMode = VireioMonitorStereoModes::Vireio_Mono; else m_eStereoMode = VireioMonitorStereoModes::Vireio_SideBySide; m_bHotkeySwitch = false; } else bReleased = true; #pragma endregion #pragma region menu events // menu is shown ? if (m_bMenu) { // handle controller if (bControllerAttached) { if (sControllerState.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) { m_abMenuEvents[VireioMenuEvent::OnExit] = TRUE; } if (sControllerState.Gamepad.wButtons & XINPUT_GAMEPAD_A) { m_abMenuEvents[VireioMenuEvent::OnAccept] = TRUE; } if (sControllerState.Gamepad.sThumbLY > 28000) m_abMenuEvents[VireioMenuEvent::OnUp] = TRUE; if (sControllerState.Gamepad.sThumbLY < -28000) m_abMenuEvents[VireioMenuEvent::OnDown] = TRUE; if (sControllerState.Gamepad.sThumbLX > 28000) m_abMenuEvents[VireioMenuEvent::OnRight] = TRUE; if (sControllerState.Gamepad.sThumbLX < -28000) m_abMenuEvents[VireioMenuEvent::OnLeft] = TRUE; } // loop through sub menues for (UINT unIx = 0; unIx < 32; unIx++) { // set bool events if (m_apsSubMenues[unIx]) { if (m_apsSubMenues[unIx]->bOnUp) m_abMenuEvents[VireioMenuEvent::OnUp] = TRUE; if (m_apsSubMenues[unIx]->bOnDown) m_abMenuEvents[VireioMenuEvent::OnDown] = TRUE; if (m_apsSubMenues[unIx]->bOnLeft) m_abMenuEvents[VireioMenuEvent::OnLeft] = TRUE; if (m_apsSubMenues[unIx]->bOnRight) m_abMenuEvents[VireioMenuEvent::OnRight] = TRUE; if (m_apsSubMenues[unIx]->bOnAccept) m_abMenuEvents[VireioMenuEvent::OnAccept] = TRUE; // clear events m_apsSubMenues[unIx]->bOnUp = false; m_apsSubMenues[unIx]->bOnDown = false; m_apsSubMenues[unIx]->bOnLeft = false; m_apsSubMenues[unIx]->bOnRight = false; m_apsSubMenues[unIx]->bOnAccept = false; m_apsSubMenues[unIx]->bOnBack = false; } } #pragma endregion #pragma region menu update/render // update UpdateMenu(fGlobalTime); // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; HRESULT nHr = S_OK; if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) nHr = GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext); else { if (m_ppcTexView11[0]) { if (*(m_ppcTexView11[0])) (*(m_ppcTexView11[0]))->GetDevice(&pcDevice); if (pcDevice) pcDevice->GetImmediateContext(&pcContext); else nHr = E_FAIL; if (!pcContext) nHr = E_FAIL; } else nHr = E_FAIL; } if (FAILED(nHr)) { // release frame texture+view if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } return nullptr; } // create the depth stencil... if D3D11 if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT) && (!m_pcDSGeometry11)) { ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); if (pcBackBuffer) { D3D11_TEXTURE2D_DESC sDesc; pcBackBuffer->GetDesc(&sDesc); pcBackBuffer->Release(); // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; ZeroMemory(&descDepth, sizeof(descDepth)); descDepth.Width = sDesc.Width; descDepth.Height = sDesc.Height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; if (FAILED(pcDevice->CreateTexture2D(&descDepth, NULL, &m_pcDSGeometry11))) OutputDebugString(L"[STP] Failed to create depth stencil."); // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory(&descDSV, sizeof(descDSV)); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; if (FAILED(pcDevice->CreateDepthStencilView(m_pcDSGeometry11, &descDSV, &m_pcDSVGeometry11))) OutputDebugString(L"[STP] Failed to create depth stencil view."); } } // get the viewport UINT dwNumViewports = 1; D3D11_VIEWPORT psViewport[16]; pcContext->RSGetViewports(&dwNumViewports, psViewport); // backup all states D3DX11_STATE_BLOCK sStateBlock; CreateStateblock(pcContext, &sStateBlock); // clear all states, set targets ClearContextState(pcContext); // set the menu texture (if present) if (m_ppcTexViewMenu) { if (*m_ppcTexViewMenu) { // set render target ID3D11RenderTargetView* pcRTView = *m_ppcTexViewMenu; pcContext->OMSetRenderTargets(1, &pcRTView, NULL); // set viewport D3D11_VIEWPORT sViewport = {}; sViewport.TopLeftX = 0; sViewport.TopLeftY = 0; sViewport.Width = 1024; sViewport.Height = 1024; sViewport.MinDepth = 0.0f; sViewport.MaxDepth = 1.0f; pcContext->RSSetViewports(1, &sViewport); // clear render target...zero alpha FLOAT afColorRgba[4] = { 0.5f, 0.4f, 0.2f, 0.4f }; pcContext->ClearRenderTargetView(*m_ppcTexViewMenu, afColorRgba); } } else if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) { // set first active render target - the stored back buffer - get the stored private data view ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); ID3D11RenderTargetView* pcView = nullptr; UINT dwSize = sizeof(pcView); pcBackBuffer->GetPrivateData(PDIID_ID3D11TextureXD_RenderTargetView, &dwSize, (void*)&pcView); if (dwSize) { pcContext->OMSetRenderTargets(1, (ID3D11RenderTargetView**)&pcView, m_pcDSVGeometry11); pcView->Release(); } else { // create render target view for the back buffer ID3D11RenderTargetView* pcRTV = nullptr; pcDevice->CreateRenderTargetView(pcBackBuffer, NULL, &pcRTV); if (pcRTV) { pcBackBuffer->SetPrivateDataInterface(PDIID_ID3D11TextureXD_RenderTargetView, pcRTV); pcRTV->Release(); } } pcContext->RSSetViewports(dwNumViewports, psViewport); pcBackBuffer->Release(); // clear the depth stencil pcContext->ClearDepthStencilView(m_pcDSVGeometry11, D3D11_CLEAR_DEPTH, 1.0f, 0); } // create the font class if not present nHr = S_OK; if (!m_pcFontSegeo128) { // get base directory std::string strVireioPath = GetBaseDir(); // add file path strVireioPath += "font//"; strVireioPath += m_strFontName; strVireioPath += ".spritefont"; OutputDebugStringA(strVireioPath.c_str()); // create font m_pcFontSegeo128 = new VireioFont(pcDevice, pcContext, strVireioPath.c_str(), 128.0f, 1.0f, nHr, 1); } if (FAILED(nHr)) { delete m_pcFontSegeo128; m_pcFontSegeo128 = nullptr; } // render text (if font present) if (m_pcFontSegeo128) { m_pcFontSegeo128->SetTextAttributes(0.0f, 0.2f, 0.0001f); // set additional tremble for "accepted" event float fDepthTremble = 0.0f; if (m_sMenuControl.eSelectionMovement == MenuControl::SelectionMovement::Accepted) { float fActionTimeElapsed = (fGlobalTime - m_sMenuControl.fActionStartTime) / m_sMenuControl.fActionTime; fDepthTremble = sin(fActionTimeElapsed*PI_F) * -3.0f; } m_pcFontSegeo128->ToRender(pcContext, fGlobalTime, m_sMenuControl.fYOrigin, 30.0f, fDepthTremble); RenderMenu(pcDevice, pcContext); } else OutputDebugString(L"Failed to create font!"); // set back device ApplyStateblock(pcContext, &sStateBlock); if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } } #pragma endregion #pragma region draw stereo (optionally) // draw stereo target to screen (optionally) if ((m_eStereoMode) && (eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) { // DX 11 if ((m_ppcTexView11[0]) && (m_ppcTexView11[1])) { // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; if (FAILED(GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext))) { // release frame texture+view if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } return nullptr; } // get the viewport UINT dwNumViewports = 1; D3D11_VIEWPORT psViewport[16]; pcContext->RSGetViewports(&dwNumViewports, psViewport); // backup all states D3DX11_STATE_BLOCK sStateBlock; CreateStateblock(pcContext, &sStateBlock); // clear all states, set targets ClearContextState(pcContext); // set first active render target - the stored back buffer - get the stored private data view ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); ID3D11RenderTargetView* pcView = nullptr; UINT dwSize = sizeof(pcView); pcBackBuffer->GetPrivateData(PDIID_ID3D11TextureXD_RenderTargetView, &dwSize, (void*)&pcView); if (dwSize) { pcContext->OMSetRenderTargets(1, (ID3D11RenderTargetView**)&pcView, m_pcDSVGeometry11); pcView->Release(); } else { // create render target view for the back buffer ID3D11RenderTargetView* pcRTV = nullptr; pcDevice->CreateRenderTargetView(pcBackBuffer, NULL, &pcRTV); if (pcRTV) { pcBackBuffer->SetPrivateDataInterface(PDIID_ID3D11TextureXD_RenderTargetView, pcRTV); pcRTV->Release(); } } pcContext->RSSetViewports(dwNumViewports, psViewport); pcBackBuffer->Release(); // clear the depth stencil pcContext->ClearDepthStencilView(m_pcDSVGeometry11, D3D11_CLEAR_DEPTH, 1.0f, 0); // create all bool bool bAllCreated = true; // create vertex shader if (!m_pcVertexShader11) { if (FAILED(CreateVertexShaderTechnique(pcDevice, &m_pcVertexShader11, &m_pcVertexLayout11, VertexShaderTechnique::PosUV2D))) bAllCreated = false; } // create pixel shader... TODO !! add option to switch output if (!m_pcPixelShader11) { if (FAILED(CreatePixelShaderEffect(pcDevice, &m_pcPixelShader11, PixelShaderTechnique::FullscreenSimple))) bAllCreated = false; } // Create vertex buffer if (!m_pcVertexBuffer11) { if (FAILED(CreateFullScreenVertexBuffer(pcDevice, &m_pcVertexBuffer11))) bAllCreated = false; } // create constant buffer if (!m_pcConstantBufferDirect11) { if (FAILED(CreateGeometryConstantBuffer(pcDevice, &m_pcConstantBufferDirect11, (UINT)sizeof(GeometryConstantBuffer)))) bAllCreated = false; } if (bAllCreated) { // left/right eye for (int nEye = 0; nEye < 2; nEye++) { // Set the input layout pcContext->IASetInputLayout(m_pcVertexLayout11); // Set vertex buffer UINT stride = sizeof(TexturedVertex); UINT offset = 0; pcContext->IASetVertexBuffers(0, 1, &m_pcVertexBuffer11, &stride, &offset); // Set constant buffer, first update it... scale and translate the left and right image D3DXMATRIX sScale; D3DXMatrixScaling(&sScale, 0.5f, 1.0f, 1.0f); D3DXMATRIX sTrans; if (nEye == 0) D3DXMatrixTranslation(&sTrans, -0.5f, 0.0f, 0.0f); else D3DXMatrixTranslation(&sTrans, 0.5f, 0.0f, 0.0f); D3DXMatrixTranspose(&sTrans, &sTrans); D3DXMATRIX sProj; D3DXMatrixMultiply(&sProj, &sTrans, &sScale); pcContext->UpdateSubresource((ID3D11Resource*)m_pcConstantBufferDirect11, 0, NULL, &sProj, 0, 0); pcContext->VSSetConstantBuffers(0, 1, &m_pcConstantBufferDirect11); // Set primitive topology pcContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // set texture pcContext->PSSetShaderResources(0, 1, m_ppcTexView11[nEye]); // set shaders pcContext->VSSetShader(m_pcVertexShader11, 0, 0); pcContext->PSSetShader(m_pcPixelShader11, 0, 0); // Render a triangle pcContext->Draw(6, 0); } } // set back device ApplyStateblock(pcContext, &sStateBlock); if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } } } #pragma endregion } return nullptr; }
// WinMain int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { HRESULT hr; // ウィンドウクラスを登録 WNDCLASSEX wcex = { sizeof( WNDCLASSEX ), // cbSize CS_HREDRAW | CS_VREDRAW, // style WndProc, // lpfnWndProc 0, // cbClsExtra 0, // cbWndExtra hInstance, // hInstance NULL, // hIcon NULL, // hCursor ( HBRUSH )( COLOR_WINDOW + 1 ), // hbrBackGround NULL, // lpszMenuName g_className, // lpszClassName NULL // hIconSm }; if ( ! RegisterClassEx( &wcex ) ) { MessageBox( NULL, _T( "失敗: RegisterClassEx()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "RegisterClassEx: ok\n" ) ); // ウィンドウサイズを計算 RECT r = { 0, 0, 800, 450 }; // 800x450 (16:9) if ( ! AdjustWindowRect( &r, WS_OVERLAPPEDWINDOW, FALSE ) ) { MessageBox( NULL, _T( "失敗: AdjustWindowRect()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "AdjustWindowRect: ok (%d, %d)-(%d, %d)\n" ), r.left, r.top, r.right, r.bottom ); // ウィンドウ生成 HWND hWnd; hWnd = CreateWindow( g_className, g_windowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, hInstance, NULL ); if ( hWnd == NULL ) { MessageBox( NULL, _T( "失敗: CreateWindow()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "CreateWindow: ok\n" ) ); // ウィンドウ表示 ShowWindow(hWnd, nCmdShow); dtprintf( _T( "ShowWindow: ok\n" ) ); // スワップチェイン設定 DXGI_SWAP_CHAIN_DESC scDesc = { { 1280, // BufferDesc.Width 720, // BufferDesc.Height { 60, // BufferDesc.RefreshRate.Numerator 1 // BufferDesc.RefreshRate.Denominator }, DXGI_FORMAT_R16G16B16A16_FLOAT, // BufferDesc.Format DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, // BufferDesc.ScanlineOrdering DXGI_MODE_SCALING_CENTERED // BufferDesc.Scaling }, { 1, // SampleDesc.Count 0 // SampleDesc.Quality }, DXGI_USAGE_RENDER_TARGET_OUTPUT, // BufferUsage 1, // BufferCount hWnd, // OutputWindow TRUE, // Windowed DXGI_SWAP_EFFECT_DISCARD, // SwapEffect DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH // Flags }; // Direct3D11 デバイス・デバイスコンテキスト・スワップチェーンを生成 ID3D11Device * pDevice = NULL; ID3D11DeviceContext * pDeviceContext = NULL; IDXGISwapChain * pSwapChain = NULL; D3D_FEATURE_LEVEL feature; hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scDesc, &pSwapChain, &pDevice, &feature, &pDeviceContext ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: D3D11CreateDeviceAndSwapChain()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "D3D11CreateDeviceAndSwapChain: ok (pDevice: 0x%p, pDeviceContext: 0x%p, pSwapChain: 0x%p, feature: 0x%4x)\n" ), pDevice, pDeviceContext, pSwapChain, ( int ) feature ); // バックバッファテクスチャを取得 ID3D11Texture2D * pBackBuffer = NULL; hr = pSwapChain->GetBuffer( 0, __uuidof( pBackBuffer ), reinterpret_cast< void ** >( &pBackBuffer ) ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: IDXGISwapChain::GetBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "IDXGISwapChain::GetBuffer: ok (pBackBuffer: 0x%p)\n" ), pBackBuffer ); // レンダーターゲットビューを生成 ID3D11RenderTargetView * pRenderTargetView = NULL; hr = pDevice->CreateRenderTargetView( pBackBuffer, NULL, &pRenderTargetView ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateRenderTargetView()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateRenderTargetView: ok (pRenderTargetView: 0x%p)\n" ), pRenderTargetView ); // デプス・ステンシルバッファとなるテクスチャを生成 D3D11_TEXTURE2D_DESC depthStencilBufferDesc = { 1280, // Width 720, // Height 1, // MipLevels 1, // ArraySize DXGI_FORMAT_D32_FLOAT, // Format { 1, // SampleDesc.Count 0 // SampleDesc.Quality }, D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_DEPTH_STENCIL, // BindFlags 0, // CPUAccessFlags 0 // MiscFlags }; ID3D11Texture2D * pDepthStencilBuffer = NULL; hr = pDevice->CreateTexture2D( &depthStencilBufferDesc, NULL, &pDepthStencilBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateTexture2D()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateTexture2D: ok (pDepthStencilBuffer: 0x%p)\n" ), pDepthStencilBuffer ); // デプス・ステンシルビューを生成 ID3D11DepthStencilView * pDepthStencilView = NULL; hr = pDevice->CreateDepthStencilView( pDepthStencilBuffer, NULL, &pDepthStencilView ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateDepthStencilView()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateDepthStencilView: ok (pDepthStencilView: 0x%p)\n" ), pDepthStencilView ); // レンダーターゲットビューとデプス・ステンシルビューをバインド ID3D11RenderTargetView * pRenderTargetViews[] = { pRenderTargetView }; pDeviceContext->OMSetRenderTargets( 1, pRenderTargetViews, pDepthStencilView ); dtprintf( _T( "ID3D11DeviceContext::OMSetRenderTargets: ok\n" ) ); // バックバッファはもうここでは使わない COM_SAFE_RELEASE( pBackBuffer ); // ビューポートをバインド D3D11_VIEWPORT viewport = { 0.0f, // TopLeftX 0.0f, // TopLeftY 1280.0f, // Width 720.0f, // Height 0.0f, // MinDepth 1.0f // MaxDepth }; pDeviceContext->RSSetViewports( 1, &viewport ); dtprintf( _T( "ID3D11DeviceContext::RSSetViewports: ok\n" ) ); // 頂点データ float vertices[ 8 ][ 7 ] = { // Xaxis Yaxis Zaxis 赤 緑 青 Alpha { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f }, // 手前左上 { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f }, // 手前右上 { 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f }, // 手前右下 { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f }, // 手前左下 { -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f }, // 奥左上 { 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f }, // 奥右上 { 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f }, // 奥右下 { -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f } // 奥左下 }; // 頂点バッファを生成 D3D11_BUFFER_DESC vertexBufferDesc = { sizeof( vertices ), // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_VERTEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA vertexResourceData = { vertices }; ID3D11Buffer * pVertexBuffer = NULL; hr = pDevice->CreateBuffer( &vertexBufferDesc, &vertexResourceData, &pVertexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pVertexBuffer: 0x%p)\n" ), pVertexBuffer ); // 頂点バッファをバインド UINT strides[] = { sizeof( float ) * 7 }; UINT offsets[] = { 0 }; pDeviceContext->IASetVertexBuffers( 0, 1, &pVertexBuffer, strides, offsets ); dtprintf( _T( "ID3D11DeviceContext::IASetVertexBuffers: ok\n" ) ); // インデックスデータ unsigned int indices[] = { 0, 1, 2, 0, 2, 3, // 手前 4, 0, 3, 4, 3, 7, // 左 1, 5, 6, 1, 6, 2, // 右 0, 4, 5, 0, 5, 1, // 上 2, 6, 7, 2, 7, 3, // 下 5, 4, 7, 5, 7, 6 }; // 裏 // インデックスバッファを生成 D3D11_BUFFER_DESC indexBufferDesc = { sizeof( indices ), // ByteWidth D3D11_USAGE_DEFAULT, // Usage D3D11_BIND_INDEX_BUFFER, // BindFlags 0, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; D3D11_SUBRESOURCE_DATA indexResourceData = { indices }; ID3D11Buffer * pIndexBuffer = NULL; hr = pDevice->CreateBuffer( &indexBufferDesc, &indexResourceData, &pIndexBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pIndexBuffer: 0x%p)\n" ), pIndexBuffer ); // インデックスバッファをバインド pDeviceContext->IASetIndexBuffer( pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); dtprintf( _T( "ID3D11DeviceContext::IASetIndexBuffer: ok\n" ) ); // プリミティブタイプを設定 pDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); dtprintf( _T( "ID3D11DeviceContext::IASetPrimitiveTopology: ok\n" ) ); // 頂点シェーダ用の定数バッファを作成 D3D11_BUFFER_DESC VSConstantBufferDesc = { sizeof( D3DXMATRIX ) * 3, // ByteWidth D3D11_USAGE_DYNAMIC, // Usage D3D11_BIND_CONSTANT_BUFFER, // BindFlags D3D11_CPU_ACCESS_WRITE, // CPUAccessFlags 0, // MiscFlags 0 // StructureByteStride }; ID3D11Buffer * pVSConstantBuffer = NULL; hr = pDevice->CreateBuffer( &VSConstantBufferDesc, NULL, &pVSConstantBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateBuffer()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateBuffer: ok (pVSConstantBuffer: 0x%p)\n" ), pVSConstantBuffer ); // 定数バッファをバインド pDeviceContext->VSSetConstantBuffers( 0, 1, &pVSConstantBuffer ); dtprintf( _T( "ID3D11DeviceContext::VSSetConstantBuffers: ok\n" ) ); // 頂点シェーダを作成 ID3D11VertexShader * pVertexShader = NULL; hr = pDevice->CreateVertexShader( g_vs_perspective, sizeof( g_vs_perspective ), NULL, &pVertexShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateVertexShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateVertexShader: ok (pVertexShader: 0x%p)\n" ), pVertexShader ); // ピクセルシェーダを作成 ID3D11PixelShader * pPixelShader = NULL; hr = pDevice->CreatePixelShader( g_ps_constant, sizeof( g_ps_constant ), NULL, &pPixelShader ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreatePixelShader()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreatePixelShader: ok (pPixelShader: 0x%p)\n" ), pPixelShader ); // シェーダをバインド pDeviceContext->VSSetShader( pVertexShader, NULL, 0 ); dtprintf( _T( "ID3D11DeviceContext::VSSetShader: ok\n" ) ); pDeviceContext->PSSetShader( pPixelShader, NULL, 0 ); dtprintf( _T( "ID3D11DeviceContext::PSSetShader: ok\n" ) ); pDeviceContext->GSSetShader( NULL, NULL, 0 ); pDeviceContext->HSSetShader( NULL, NULL, 0 ); pDeviceContext->DSSetShader( NULL, NULL, 0 ); // 入力エレメント記述子 D3D11_INPUT_ELEMENT_DESC verticesDesc[] = { { "IN_POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "IN_COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, sizeof(float)*3, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; // 入力レイアウトを生成 ID3D11InputLayout * pInputLayout = NULL; hr = pDevice->CreateInputLayout( verticesDesc, 2, g_vs_perspective, sizeof( g_vs_perspective ), &pInputLayout ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateInputLayout()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateInputLayout: ok (pInputLayout: 0x%p)\n" ), pInputLayout ); // 入力レイアウトをバインド pDeviceContext->IASetInputLayout( pInputLayout ); dtprintf( _T( "ID3D11DeviceContext::IASetInputLayout: ok\n" ) ); // ラスタライザステートを生成 D3D11_RASTERIZER_DESC rasterizerStateDesc = { D3D11_FILL_SOLID, // FillMode // D3D11_FILL_WIREFRAME, // FillMode (ワイヤーフレーム表示) D3D11_CULL_BACK, // CullMode // D3D11_CULL_NONE, // CullMode (カリングなし) FALSE, // FrontCounterClockwise 0, // DepthBias 0.0f, // DepthBiasClamp 0.0f, // SlopeScaledDepthBias TRUE, // DepthClipEnable FALSE, // ScissorEnable FALSE, // MultisampleEnable FALSE // AntialiasedLineEnable }; ID3D11RasterizerState * pRasterizerState = NULL; hr = pDevice->CreateRasterizerState( &rasterizerStateDesc, &pRasterizerState ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateRasterizerState()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateRasterizerState: ok (pRasterizerState: 0x%p)\n" ), pRasterizerState ); // ラスタライザステートをバインド pDeviceContext->RSSetState( pRasterizerState ); dtprintf( _T( "ID3D11DeviceContext::RSSetState: ok\n" ) ); // デプス・ステンシルステートを生成 D3D11_DEPTH_STENCIL_DESC depthStencilStateDesc = { TRUE, // DepthEnable D3D11_DEPTH_WRITE_MASK_ALL, // DepthWriteMask D3D11_COMPARISON_LESS, // DepthFunc FALSE, // StencilEnable D3D11_DEFAULT_STENCIL_READ_MASK, // StencilReadMask D3D11_DEFAULT_STENCIL_WRITE_MASK, // StencilWriteMask { D3D11_STENCIL_OP_KEEP, // FrontFace.StencilFailOp D3D11_STENCIL_OP_KEEP, // FrontFace.StencilDepthFailOp D3D11_STENCIL_OP_KEEP, // FrontFace.StencilPassOp D3D11_COMPARISON_ALWAYS // FrontFace.StencilFunc }, { D3D11_STENCIL_OP_KEEP, // BackFace.StencilFailOp D3D11_STENCIL_OP_KEEP, // BackFace.StencilDepthFailOp D3D11_STENCIL_OP_KEEP, // BackFace.StencilPassOp D3D11_COMPARISON_ALWAYS // BackFace.StencilFunc } }; ID3D11DepthStencilState * pDepthStencilState = NULL; hr = pDevice->CreateDepthStencilState( &depthStencilStateDesc, &pDepthStencilState ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "失敗: ID3D11Device::CreateDepthStencilState()" ), _T( "エラー" ), MB_OK | MB_ICONERROR ); return 0; } dtprintf( _T( "ID3D11Device::CreateDepthStencilState: ok (pDepthStencilState: 0x%p)\n" ), pDepthStencilState ); // デプス・ステンシルステートをバインド pDeviceContext->OMSetDepthStencilState( pDepthStencilState, 0 ); dtprintf( _T( "ID3D11DeviceContext::OMSetDepthStencilState: ok\n" ) ); MSG msg; while ( 1 ) { // メッセージを取得 if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if ( msg.message == WM_QUIT ) { dtprintf( _T( "PeekMessage: WM_QUIT\n" ) ); break; } // メッセージ処理 DispatchMessage( &msg ); } else { HRESULT hr; static unsigned int count = 0; float theta = ( count++ / 200.0f ) * ( 3.141593f / 2.0f ); // World-View-Projection 行列をそれぞれ生成 D3DXMATRIX world, view, projection; D3DXMatrixIdentity( &world ); const D3DXVECTOR3 eye( 1.8f * 1.414214f * -cosf( theta ), 1.8f, 1.8f * 1.414214f * sinf( theta ) ); const D3DXVECTOR3 at( 0.0f, 0.0f, 0.0f ); const D3DXVECTOR3 up( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtRH( &view, &eye, &at, &up ); D3DXMatrixPerspectiveFovRH( &projection, 3.141593f / 4.0f, 1280.0f / 720.0f, 1.0f, 10000.0f ); // 頂点シェーダ用定数バッファへアクセス D3D11_MAPPED_SUBRESOURCE mapped; hr = pDeviceContext->Map( pVSConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); if ( SUCCEEDED( hr ) ) { D3DXMATRIX * mapped_m = static_cast< D3DXMATRIX * >( mapped.pData ); mapped_m[0] = world; mapped_m[1] = view; mapped_m[2] = projection; // 後始末 pDeviceContext->Unmap( pVSConstantBuffer, 0 ); } // レンダーターゲットビューをクリア const float clear[ 4 ] = { 0.0f, 0.0f, 0.3f, 1.0f }; // RGBA pDeviceContext->ClearRenderTargetView( pRenderTargetView, clear ); // デプス・ステンシルビューをクリア pDeviceContext->ClearDepthStencilView( pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 ); // 描画 pDeviceContext->DrawIndexed( 36, 0, 0 ); pSwapChain->Present( 1, 0 ); // ちょっとだけ待つ Sleep( 5 ); } } // シェーダをアンバインド pDeviceContext->VSSetShader( NULL, NULL, 0 ); pDeviceContext->PSSetShader( NULL, NULL, 0 ); // デバイス・リソース解放 COM_SAFE_RELEASE( pDepthStencilState ); COM_SAFE_RELEASE( pRasterizerState ); COM_SAFE_RELEASE( pInputLayout ); COM_SAFE_RELEASE( pPixelShader ); COM_SAFE_RELEASE( pVertexShader ); COM_SAFE_RELEASE( pVSConstantBuffer ); COM_SAFE_RELEASE( pIndexBuffer ); COM_SAFE_RELEASE( pVertexBuffer ); COM_SAFE_RELEASE( pDepthStencilView ); COM_SAFE_RELEASE( pDepthStencilBuffer ); COM_SAFE_RELEASE( pRenderTargetView ); COM_SAFE_RELEASE( pSwapChain ); COM_SAFE_RELEASE( pDeviceContext ); COM_SAFE_RELEASE( pDevice ); return msg.wParam; }
bool CScreenshotSurface::capture() { #if defined(TARGET_RASPBERRY_PI) g_RBP.GetDisplaySize(m_width, m_height); m_buffer = g_RBP.CaptureDisplay(m_width, m_height, &m_stride, true, false); if (!m_buffer) return false; #elif defined(HAS_DX) g_graphicsContext.Lock(); if (g_application.m_pPlayer->IsPlayingVideo()) { #ifdef HAS_VIDEO_PLAYBACK g_renderManager.SetupScreenshot(); #endif } g_application.RenderNoPresent(); g_Windowing.FinishCommandList(); ID3D11DeviceContext* pImdContext = g_Windowing.GetImmediateContext(); ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); ID3D11Device* pDevice = g_Windowing.Get3D11Device(); ID3D11RenderTargetView* pRTView = nullptr; pContext->OMGetRenderTargets(1, &pRTView, nullptr); if (pRTView == nullptr) return false; ID3D11Resource *pRTResource = nullptr; pRTView->GetResource(&pRTResource); SAFE_RELEASE(pRTView); ID3D11Texture2D* pCopyTexture = nullptr; ID3D11Texture2D* pRTTexture = nullptr; HRESULT hr = pRTResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pRTTexture)); SAFE_RELEASE(pRTResource); if (FAILED(hr)) return false; D3D11_TEXTURE2D_DESC desc; pRTTexture->GetDesc(&desc); desc.Usage = D3D11_USAGE_STAGING; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.BindFlags = 0; if (SUCCEEDED(pDevice->CreateTexture2D(&desc, nullptr, &pCopyTexture))) { // take copy pImdContext->CopyResource(pCopyTexture, pRTTexture); D3D11_MAPPED_SUBRESOURCE res; if (SUCCEEDED(pImdContext->Map(pCopyTexture, 0, D3D11_MAP_READ, 0, &res))) { m_width = desc.Width; m_height = desc.Height; m_stride = res.RowPitch; m_buffer = new unsigned char[m_height * m_stride]; memcpy(m_buffer, res.pData, m_height * m_stride); pImdContext->Unmap(pCopyTexture, 0); } else CLog::Log(LOGERROR, "%s: MAP_READ failed.", __FUNCTION__); SAFE_RELEASE(pCopyTexture); } SAFE_RELEASE(pRTTexture); g_graphicsContext.Unlock(); #elif defined(HAS_GL) || defined(HAS_GLES) g_graphicsContext.BeginPaint(); if (g_application.m_pPlayer->IsPlayingVideo()) { #ifdef HAS_VIDEO_PLAYBACK g_renderManager.SetupScreenshot(); #endif } g_application.RenderNoPresent(); #ifndef HAS_GLES glReadBuffer(GL_BACK); #endif //get current viewport GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); m_width = viewport[2] - viewport[0]; m_height = viewport[3] - viewport[1]; m_stride = m_width * 4; unsigned char* surface = new unsigned char[m_stride * m_height]; //read pixels from the backbuffer #if HAS_GLES == 2 glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)surface); #else glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)surface); #endif g_graphicsContext.EndPaint(); //make a new buffer and copy the read image to it with the Y axis inverted m_buffer = new unsigned char[m_stride * m_height]; for (int y = 0; y < m_height; y++) { #ifdef HAS_GLES // we need to save in BGRA order so XOR Swap RGBA -> BGRA unsigned char* swap_pixels = surface + (m_height - y - 1) * m_stride; for (int x = 0; x < m_width; x++, swap_pixels+=4) { std::swap(swap_pixels[0], swap_pixels[2]); } #endif memcpy(m_buffer + y * m_stride, surface + (m_height - y - 1) *m_stride, m_stride); } delete [] surface; #if defined(HAS_LIBAMCODEC) // Captures the current visible videobuffer and blend it into m_buffer (captured overlay) CScreenshotAML::CaptureVideoFrame(m_buffer, m_width, m_height); #endif #ifdef HAS_IMXVPU // Captures the current visible framebuffer page and blends it into the // captured GL overlay g_IMXContext.CaptureDisplay(m_buffer, m_width, m_height); #endif #else //nothing to take a screenshot from return false; #endif return true; }
void init_for_dimensions(unsigned width, unsigned height) { if(zsv) zsv->Release(); ID3D11Texture2D* zsbuf; D3D11_TEXTURE2D_DESC zsbufd; memset(&zsbufd, 0, sizeof(zsbufd)); zsbufd.Width = width; zsbufd.Height = height; zsbufd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; zsbufd.ArraySize = 1; zsbufd.MipLevels = 1; zsbufd.SampleDesc.Count = 1; zsbufd.BindFlags = D3D11_BIND_DEPTH_STENCIL; ensure(dev->CreateTexture2D(&zsbufd, 0, &zsbuf)); ensure(dev->CreateDepthStencilView(zsbuf, 0, &zsv)); zsbuf->Release(); ID3D11Texture2D* offscreen; if(offscreen_rtv) { offscreen_rtv->Release(); offscreen_srv->Release(); offscreen_rtv = 0; offscreen_srv = 0; } if(impressions > 1) { DXGI_FORMAT formats[] = { DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R10G10B10A2_UNORM, }; DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; // this won't work well at all unsigned needed_support = D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_BLENDABLE | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE; for(unsigned i = 0; i < sizeof(formats); ++i) { unsigned support; dev->CheckFormatSupport(DXGI_FORMAT_R32G32B32A32_FLOAT, &support); if((support & needed_support) == needed_support) { format = formats[i]; break; } } D3D11_TEXTURE2D_DESC offscreend; memset(&offscreend, 0, sizeof(offscreend)); offscreend.Width = width; offscreend.Height = height; offscreend.Format = format; offscreend.MipLevels = 1; offscreend.ArraySize = 1; offscreend.SampleDesc.Count = 1; offscreend.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; ensure(dev->CreateTexture2D(&offscreend, 0, &offscreen)); ensure(dev->CreateRenderTargetView(offscreen, 0, &offscreen_rtv)); ensure(dev->CreateShaderResourceView(offscreen, 0, &offscreen_srv)); offscreen->Release(); } cur_width = width; cur_height = height; }
// Detour function that replaces the IDXGISwapChain::Present() API DllExport HRESULT __stdcall hook_DXGISwapChainPresent( IDXGISwapChain * This, UINT SyncInterval, UINT Flags ) { static int frame_interval; static LARGE_INTEGER initialTv, captureTv, freq; static int capture_initialized = 0; // int i; struct pooldata *data; struct vsource_frame *frame; // DXGI_SWAP_CHAIN_DESC pDESC; HRESULT hr = pDXGISwapChainPresent(This, SyncInterval, Flags); if(resolution_retrieved == 0) { if(DXGI_get_resolution(This) >= 0) { resolution_retrieved = 1; } return hr; } if(vsource_initialized == 0) { ga_error("video source not initialized.\n"); return hr; } This->GetDesc(&pDESC); pDXGI_FORMAT = pDESC.BufferDesc.Format; // extract screen format for sws_scale if(pDESC.BufferDesc.Width != game_width || pDESC.BufferDesc.Height != game_height) { ga_error("game width/height mismatched (%dx%d) != (%dx%d)\n", pDESC.BufferDesc.Width, pDESC.BufferDesc.Height, game_width, game_height); return hr; } // if (enable_server_rate_control && ga_hook_video_rate_control() < 0) return hr; if (dx_version == dx_none) { //bool check_result = FALSE; if (check_dx_device_version(This, IID_ID3D10Device)) { dx_version = dx_10; ga_error("[DXGISwapChain] DirectX 10\n"); } else if (check_dx_device_version(This, IID_ID3D10Device1)) { dx_version = dx_10_1; ga_error("[DXGISwapChain] DirectX 10.1\n"); } else if (check_dx_device_version(This, IID_ID3D11Device)) { dx_version = dx_11; ga_error("[DXGISwapChain] DirectX 11\n"); } } if (capture_initialized == 0) { frame_interval = 1000000/video_fps; // in the unif of us frame_interval++; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&initialTv); capture_initialized = 1; } else { QueryPerformanceCounter(&captureTv); } hr = 0; // d3d10 / d3d10.1 if (dx_version == dx_10 || dx_version == dx_10_1) { void *ppDevice; ID3D10Device *pDevice; //IUnknown *pDevice; if (dx_version == dx_10) { This->GetDevice(IID_ID3D10Device, &ppDevice); pDevice = (ID3D10Device *)ppDevice; } else if (dx_version == dx_10_1) { This->GetDevice(IID_ID3D10Device1, &ppDevice); pDevice = (ID3D10Device1 *)ppDevice; } else { OutputDebugString("Invalid DirectX version in IDXGISwapChain::Present"); return hr; } ID3D10RenderTargetView *pRTV = NULL; ID3D10Resource *pSrcResource = NULL; pDevice->OMGetRenderTargets(1, &pRTV, NULL); pRTV->GetResource(&pSrcResource); ID3D10Texture2D* pSrcBuffer = (ID3D10Texture2D *)pSrcResource; ID3D10Texture2D* pDstBuffer = NULL; D3D10_TEXTURE2D_DESC desc; pSrcBuffer->GetDesc(&desc); desc.BindFlags = 0; desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; desc.Usage = D3D10_USAGE_STAGING; hr = pDevice->CreateTexture2D(&desc, NULL, &pDstBuffer); if (FAILED(hr)) { OutputDebugString("Failed to create texture2D"); //assert(exp_state == exp_none); } pDevice->CopyResource(pDstBuffer, pSrcBuffer); D3D10_MAPPED_TEXTURE2D mapped_screen; hr = pDstBuffer->Map(0, D3D10_MAP_READ, 0, &mapped_screen); if (FAILED(hr)) { OutputDebugString("Failed to map from DstBuffer"); //assert(exp_state == exp_none); } // copy image do { unsigned char *src, *dst; data = g_pipe[0]->allocate_data(); frame = (struct vsource_frame*) data->ptr; frame->pixelformat = PIX_FMT_BGRA; frame->realwidth = desc.Width; frame->realheight = desc.Height; frame->realstride = desc.Width<<2; frame->realsize = frame->realwidth * frame->realstride; frame->linesize[0] = frame->realstride;//frame->stride; // src = (unsigned char*) mapped_screen.pData; dst = (unsigned char*) frame->imgbuf; for (i = 0; i < encoder_height; i++) { CopyMemory(dst, src, frame->realstride/*frame->stride*/); src += mapped_screen.RowPitch; dst += frame->realstride;//frame->stride; } frame->imgpts = pcdiff_us(captureTv, initialTv, freq)/frame_interval; } while(0); // duplicate from channel 0 to other channels for(i = 1; i < SOURCES; i++) { int j; struct pooldata *dupdata; struct vsource_frame *dupframe; dupdata = g_pipe[i]->allocate_data(); dupframe = (struct vsource_frame*) dupdata->ptr; // vsource_dup_frame(frame, dupframe); // g_pipe[i]->store_data(dupdata); g_pipe[i]->notify_all(); } g_pipe[0]->store_data(data); g_pipe[0]->notify_all(); pDstBuffer->Unmap(0); pDevice->Release(); pSrcResource->Release(); pSrcBuffer->Release(); pRTV->Release(); pDstBuffer->Release(); // d11 } else if (dx_version == dx_11) { void *ppDevice; This->GetDevice(IID_ID3D11Device, &ppDevice); ID3D11Device *pDevice = (ID3D11Device*) ppDevice; This->GetDevice(IID_ID3D11DeviceContext, &ppDevice); ID3D11DeviceContext *pDeviceContext = (ID3D11DeviceContext *) ppDevice; ID3D11RenderTargetView *pRTV = NULL; ID3D11Resource *pSrcResource = NULL; pDeviceContext->OMGetRenderTargets(1, &pRTV, NULL); pRTV->GetResource(&pSrcResource); ID3D11Texture2D *pSrcBuffer = (ID3D11Texture2D *)pSrcResource; ID3D11Texture2D *pDstBuffer = NULL; D3D11_TEXTURE2D_DESC desc; pSrcBuffer->GetDesc(&desc); desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; hr = pDevice->CreateTexture2D(&desc, NULL, &pDstBuffer); if (FAILED(hr)) { OutputDebugString("Failed to create buffer"); //assert(exp_state == exp_none); } pDeviceContext->CopyResource(pDstBuffer, pSrcBuffer); D3D11_MAPPED_SUBRESOURCE mapped_screen; hr = pDeviceContext->Map(pDstBuffer, 0, D3D11_MAP_READ, 0, &mapped_screen); if (FAILED(hr)) { OutputDebugString("Failed to map from DeviceContext"); //assert(exp_state == exp_none); } // copy image do { unsigned char *src, *dst; data = g_pipe[0]->allocate_data(); frame = (struct vsource_frame*) data->ptr; frame->pixelformat = PIX_FMT_BGRA; frame->realwidth = desc.Width; frame->realheight = desc.Height; frame->realstride = desc.Width<<2; frame->realsize = frame->realwidth * frame->realstride; frame->linesize[0] = frame->realstride;//frame->stride; // src = (unsigned char*) mapped_screen.pData; dst = (unsigned char*) frame->imgbuf; for (i = 0; i < encoder_height; i++) { CopyMemory(dst, src, frame->realstride/*frame->stride*/); src += mapped_screen.RowPitch; dst += frame->realstride;//frame->stride; } frame->imgpts = pcdiff_us(captureTv, initialTv, freq)/frame_interval; } while(0); // duplicate from channel 0 to other channels for(i = 1; i < SOURCES; i++) { int j; struct pooldata *dupdata; struct vsource_frame *dupframe; dupdata = g_pipe[i]->allocate_data(); dupframe = (struct vsource_frame*) dupdata->ptr; // vsource_dup_frame(frame, dupframe); // g_pipe[i]->store_data(dupdata); g_pipe[i]->notify_all(); } g_pipe[0]->store_data(data); g_pipe[0]->notify_all(); pDeviceContext->Unmap(pDstBuffer, 0); pDevice->Release(); pDeviceContext->Release(); pSrcResource->Release(); pSrcBuffer->Release(); pRTV->Release(); pDstBuffer->Release(); } return hr; }
void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) { gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer(); if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat) { // No conversion needed-- use copyback fastpath ID3D11Texture2D *colorBufferTexture = NULL; unsigned int subresourceIndex = 0; if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) { D3D11_TEXTURE2D_DESC textureDesc; colorBufferTexture->GetDesc(&textureDesc); ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11Texture2D* srcTex = NULL; if (textureDesc.SampleDesc.Count > 1) { D3D11_TEXTURE2D_DESC resolveDesc; resolveDesc.Width = textureDesc.Width; resolveDesc.Height = textureDesc.Height; resolveDesc.MipLevels = 1; resolveDesc.ArraySize = 1; resolveDesc.Format = textureDesc.Format; resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; resolveDesc.Usage = D3D11_USAGE_DEFAULT; resolveDesc.BindFlags = 0; resolveDesc.CPUAccessFlags = 0; resolveDesc.MiscFlags = 0; HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); if (FAILED(result)) { ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); return; } deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format); subresourceIndex = 0; } else { srcTex = colorBufferTexture; srcTex->AddRef(); } D3D11_BOX srcBox; srcBox.left = x; srcBox.right = x + width; srcBox.top = y; srcBox.bottom = y + height; srcBox.front = 0; srcBox.back = 1; deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox); SafeRelease(srcTex); SafeRelease(colorBufferTexture); } } else { // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels D3D11_MAPPED_SUBRESOURCE mappedImage; HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); if (FAILED(result)) { ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result); return; } // determine the offset coordinate into the destination buffer GLsizei rowOffset = gl::GetPixelBytes(mActualFormat) * xoffset; void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch; GLenum format = gl::GetFormat(mInternalFormat); GLenum type = gl::GetType(mInternalFormat); mRenderer->readPixels(source, x, y, width, height, format, type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); unmap(); } }
void BufferStorage11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) { flushQueuedPackCommand(); mQueuedPackCommand = new PackPixelsParams(params); D3D11_TEXTURE2D_DESC textureDesc; srcTexure->GetDesc(&textureDesc); if (mStagingTexture != NULL && (mTextureFormat != textureDesc.Format || mTextureSize.width != params.area.width || mTextureSize.height != params.area.height)) { SafeRelease(mStagingTexture); mTextureSize.width = 0; mTextureSize.height = 0; mTextureFormat = DXGI_FORMAT_UNKNOWN; } if (mStagingTexture == NULL) { ID3D11Device *device = mRenderer->getDevice(); HRESULT hr; mTextureSize.width = params.area.width; mTextureSize.height = params.area.height; mTextureFormat = textureDesc.Format; D3D11_TEXTURE2D_DESC stagingDesc; stagingDesc.Width = params.area.width; stagingDesc.Height = params.area.height; stagingDesc.MipLevels = 1; stagingDesc.ArraySize = 1; stagingDesc.Format = mTextureFormat; stagingDesc.SampleDesc.Count = 1; stagingDesc.SampleDesc.Quality = 0; stagingDesc.Usage = D3D11_USAGE_STAGING; stagingDesc.BindFlags = 0; stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; stagingDesc.MiscFlags = 0; hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture); ASSERT(SUCCEEDED(hr)); } if (textureDesc.SampleDesc.Count > 1) { UNIMPLEMENTED(); } ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); D3D11_BOX srcBox; srcBox.left = params.area.x; srcBox.right = params.area.x + params.area.width; srcBox.top = params.area.y; srcBox.bottom = params.area.y + params.area.height; srcBox.front = 0; srcBox.back = 1; // Asynchronous copy immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox); }
void CRenderCaptureDX::BeginRender() { ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); ID3D11Device* pDevice = g_Windowing.Get3D11Device(); CD3D11_QUERY_DESC queryDesc(D3D11_QUERY_EVENT); if (!m_asyncChecked) { m_asyncSupported = SUCCEEDED(pDevice->CreateQuery(&queryDesc, nullptr)); if (m_flags & CAPTUREFLAG_CONTINUOUS) { if (!m_asyncSupported) CLog::Log(LOGWARNING, "CRenderCaptureDX: D3D11_QUERY_OCCLUSION not supported, performance might suffer"); if (!UseOcclusionQuery()) CLog::Log(LOGWARNING, "CRenderCaptureDX: D3D11_QUERY_OCCLUSION disabled, performance might suffer"); } m_asyncChecked = true; } HRESULT result; if (m_surfaceWidth != m_width || m_surfaceHeight != m_height) { SAFE_RELEASE(m_renderSurface); SAFE_RELEASE(m_copySurface); CD3D11_TEXTURE2D_DESC texDesc(DXGI_FORMAT_B8G8R8A8_UNORM, m_width, m_height, 1, 1, D3D11_BIND_RENDER_TARGET); result = pDevice->CreateTexture2D(&texDesc, nullptr, &m_renderTexture); if (FAILED(result)) { CLog::Log(LOGERROR, "CRenderCaptureDX::BeginRender: CreateTexture2D (RENDER_TARGET) failed %s", g_Windowing.GetErrorDescription(result).c_str()); SetState(CAPTURESTATE_FAILED); return; } CD3D11_RENDER_TARGET_VIEW_DESC rtDesc(D3D11_RTV_DIMENSION_TEXTURE2D); result = pDevice->CreateRenderTargetView(m_renderTexture, &rtDesc, &m_renderSurface); if (FAILED(result)) { CLog::Log(LOGERROR, "CRenderCaptureDX::BeginRender: CreateRenderTargetView failed %s", g_Windowing.GetErrorDescription(result).c_str()); SetState(CAPTURESTATE_FAILED); return; } texDesc.BindFlags = 0; texDesc.Usage = D3D11_USAGE_STAGING; texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; result = pDevice->CreateTexture2D(&texDesc, nullptr, &m_copySurface); if (FAILED(result)) { CLog::Log(LOGERROR, "CRenderCaptureDX::BeginRender: CreateTexture2D (USAGE_STAGING) failed %s", g_Windowing.GetErrorDescription(result).c_str()); SetState(CAPTURESTATE_FAILED); return; } m_surfaceWidth = m_width; m_surfaceHeight = m_height; } if (m_bufferSize != m_width * m_height * 4) { m_bufferSize = m_width * m_height * 4; av_freep(&m_pixels); m_pixels = (uint8_t*)av_malloc(m_bufferSize); } pContext->OMSetRenderTargets(1, &m_renderSurface, nullptr); if (m_asyncSupported && UseOcclusionQuery()) { //generate an occlusion query if we don't have one if (!m_query) { result = pDevice->CreateQuery(&queryDesc, &m_query); if (FAILED(result)) { CLog::Log(LOGERROR, "CRenderCaptureDX::BeginRender: CreateQuery failed %s", g_Windowing.GetErrorDescription(result).c_str()); m_asyncSupported = false; SAFE_RELEASE(m_query); } } } else { //don't use an occlusion query, clean up any old one SAFE_RELEASE(m_query); } }
gl::Error Image11::createStagingTexture() { if (mStagingTexture) { return gl::Error(GL_NO_ERROR); } ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0); const DXGI_FORMAT dxgiFormat = getDXGIFormat(); ID3D11Device *device = mRenderer->getDevice(); HRESULT result; int lodOffset = 1; GLsizei width = mWidth; GLsizei height = mHeight; // adjust size if needed for compressed textures d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset); if (mTarget == GL_TEXTURE_3D) { ID3D11Texture3D *newTexture = NULL; D3D11_TEXTURE3D_DESC desc; desc.Width = width; desc.Height = height; desc.Depth = mDepth; desc.MipLevels = lodOffset + 1; desc.Format = dxgiFormat; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector< std::vector<BYTE> > textureData; d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth, lodOffset + 1, &initialData, &textureData); result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); } else { result = device->CreateTexture3D(&desc, NULL, &newTexture); } if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); } mStagingTexture = newTexture; mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); } else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) { ID3D11Texture2D *newTexture = NULL; D3D11_TEXTURE2D_DESC desc; desc.Width = width; desc.Height = height; desc.MipLevels = lodOffset + 1; desc.ArraySize = 1; desc.Format = dxgiFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector< std::vector<BYTE> > textureData; d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1, lodOffset + 1, &initialData, &textureData); result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); } else { result = device->CreateTexture2D(&desc, NULL, &newTexture); } if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); } mStagingTexture = newTexture; mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); } else { UNREACHABLE(); } mDirty = false; return gl::Error(GL_NO_ERROR); }
//=============================================================================================================================== bool TextureManager::loadTexture(BetterString filename, ID3D11Texture2D** texture, int& textureDataSize, byte*& srcTextureData, TextureType tt) { ID3D11Device* device = mD3DSystem->GetDevice11(); ID3D11DeviceContext* immediateContext = mD3DSystem->GetDeviceContext(); ID3D11Texture2D* tempTexture; //string file = "Textures\\"; //file += filename.toString(); HRESULT hr = E_FAIL; unique_ptr<wchar_t> name = filename.ToWideStr(); switch (tt) { case DDS: { hr = CreateDDSTextureFromFile(device, name.get(), (ID3D11Resource **)texture, NULL); } break; //case TGA: case PNG: { hr = CreateWICTextureFromFile(device, name.get(), (ID3D11Resource **)texture, NULL); } break; } //if(SUCCEEDED(D3DX11CreateTextureFromFile(device, file.c_str(), NULL, NULL, (ID3D11Resource **)texture, NULL))) if(SUCCEEDED(hr)) { // Load the texture and store it GetTexture(filename, tt); D3D11_TEXTURE2D_DESC desc; (*texture)->GetDesc(&desc); // To keep it simple, we limit the textures we load to RGBA 8bits per channel if(desc.Format != DXGI_FORMAT_R8G8B8A8_UNORM) { OutputDebugStringA( "We want to read a simple RGBA texture 8 bits per channel but the required texture has a different format." ); return false; } desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; if (device->CreateTexture2D(&desc, NULL, &tempTexture) != S_OK) return false; immediateContext->CopyResource(tempTexture, *texture); D3D11_MAPPED_SUBRESOURCE mappedResource; if (immediateContext->Map(tempTexture, 0, D3D11_MAP_READ, 0, &mappedResource) != S_OK) return false; textureDataSize = mappedResource.RowPitch * desc.Height; if(srcTextureData) delete [] srcTextureData; srcTextureData = new byte[textureDataSize]; memcpy(srcTextureData, mappedResource.pData, textureDataSize); immediateContext->Unmap(tempTexture, 0); return true; } else return false; }
TextureClient* IMFYCbCrImage::GetTextureClient(CompositableClient* aClient) { ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(); if (!device || aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) { IDirect3DDevice9* d3d9device = gfxWindowsPlatform::GetPlatform()->GetD3D9Device(); if (d3d9device && aClient->GetForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9) { return GetD3D9TextureClient(aClient); } return nullptr; } if (mTextureClient) { return mTextureClient; } RefPtr<ID3D11DeviceContext> ctx; device->GetImmediateContext(byRef(ctx)); CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_A8_UNORM, mData.mYSize.width, mData.mYSize.height, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; RefPtr<ID3D11Texture2D> textureY; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = mData.mCbCrSize.width; newDesc.Height = mData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); { AutoLockTexture lockY(textureY); AutoLockTexture lockCb(textureCb); AutoLockTexture lockCr(textureCr); ctx->UpdateSubresource(textureY, 0, nullptr, mData.mYChannel, mData.mYStride, mData.mYStride * mData.mYSize.height); ctx->UpdateSubresource(textureCb, 0, nullptr, mData.mCbChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); ctx->UpdateSubresource(textureCr, 0, nullptr, mData.mCrChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); } RefPtr<IDXGIResource> resource; HANDLE shareHandleY; textureY->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleY); HANDLE shareHandleCb; textureCb->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCb); HANDLE shareHandleCr; textureCr->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCr); mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(), TextureFlags::DEFAULT, textureY, textureCb, textureCr, shareHandleY, shareHandleCb, shareHandleCr, GetSize(), mData.mYSize, mData.mCbCrSize); return mTextureClient; }
Error Texture::platformInit(const Config& config) { ComPtr<ID3D11Resource> d3dResource; Renderer::PlatformDetails& plat = ((TextureDx11*)this)->_renderer.getPlatformDetails(); ID3D11Device* device = plat.device.Get(); if (config.depth > 0) { D3D11_TEXTURE3D_DESC desc; desc.Width = config.width; desc.Height = config.height; desc.Depth = config.depth; desc.MipLevels = config.lastMip+1; desc.Format = TranslateToDxgiFormat(config.format); desc.BindFlags = TranslateBindFlags(config.usage, config.format); desc.CPUAccessFlags = TranslateCpuAccessFlags(config.usage); desc.MiscFlags = TranslateMiscFlags(config.flags); desc.Usage = TranslateUsage(config.usage); HRESULT hr = device->CreateTexture3D(&desc, nullptr, (ID3D11Texture3D**) d3dResource.GetAddressOf()); if (FAILED(hr)) { EIGEN_RETURN_ERROR("Failed to create volume texture, HRESULT = %d", hr); } } else if (config.height > 0) { D3D11_TEXTURE2D_DESC desc; desc.Width = config.width; desc.Height = config.height; desc.MipLevels = config.lastMip+1; desc.ArraySize = config.arrayLength > 0 ? config.arrayLength : 1; desc.Format = TranslateToDxgiFormat(config.format); desc.SampleDesc.Count = (UINT)1 << (UINT)config.multisampling; desc.SampleDesc.Quality = 0; desc.BindFlags = TranslateBindFlags(config.usage, config.format); desc.CPUAccessFlags = TranslateCpuAccessFlags(config.usage); desc.MiscFlags = TranslateMiscFlags(config.flags); desc.Usage = TranslateUsage(config.usage); HRESULT hr = device->CreateTexture2D(&desc, nullptr, (ID3D11Texture2D**) d3dResource.GetAddressOf()); if (FAILED(hr)) { EIGEN_RETURN_ERROR("Failed to create texture, HRESULT = %d", hr); } } else { D3D11_TEXTURE1D_DESC desc; desc.Width = config.width; desc.MipLevels = config.lastMip+1; desc.ArraySize = config.arrayLength > 0 ? config.arrayLength : 1; desc.Format = TranslateToDxgiFormat(config.format); desc.BindFlags = TranslateBindFlags(config.usage, config.format); desc.CPUAccessFlags = TranslateCpuAccessFlags(config.usage); desc.MiscFlags = TranslateMiscFlags(config.flags); desc.Usage = TranslateUsage(config.usage); HRESULT hr = device->CreateTexture1D(&desc, nullptr, (ID3D11Texture1D**) d3dResource.GetAddressOf()); if (FAILED(hr)) { EIGEN_RETURN_ERROR("Failed to create 1D texture, HRESULT = %d", hr); } } ((TextureDx11*)this)->_d3dResource.Swap(d3dResource); EIGEN_RETURN_OK(); }