Example #1
0
gl::Error Image11::copyWithoutConversion(const gl::Offset &destOffset,
                                         const gl::Box &sourceArea,
                                         const TextureHelper11 &textureHelper,
                                         UINT sourceSubResource)
{
    // No conversion needed-- use copyback fastpath
    const TextureHelper11 *stagingTexture = nullptr;
    unsigned int stagingSubresourceIndex = 0;
    ANGLE_TRY(getStagingTexture(&stagingTexture, &stagingSubresourceIndex));

    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();

    const gl::Extents &extents = textureHelper.getExtents();

    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;

    if (textureHelper.is2D() && textureHelper.getSampleCount() > 1)
    {
        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;

        d3d11::Texture2D resolveTex;
        ANGLE_TRY(mRenderer->allocateResource(resolveDesc, &resolveTex));

        deviceContext->ResolveSubresource(resolveTex.get(), 0, textureHelper.get(),
                                          sourceSubResource, textureHelper.getFormat());

        deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex,
                                             destOffset.x, destOffset.y, destOffset.z,
                                             resolveTex.get(), 0, &srcBox);
    }
    else
    {
        deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex,
                                             destOffset.x, destOffset.y, destOffset.z,
                                             textureHelper.get(), sourceSubResource, &srcBox);
    }

    mDirty = true;
    return gl::NoError();
}
Example #2
0
void MSAAFilter::RenderAA()
{
    PIXEvent pixEvent(L"MSAA Resolve + Temporal AA");
    ProfileBlock profileBlock(L"MSAA Resolve + Temporal AA");

    ID3D11DeviceContext* context = deviceManager.ImmediateContext();

    ID3D11RenderTargetView* rtvs[1] = { resolveTarget.RTView };

    context->OMSetRenderTargets(1, rtvs, nullptr);

    if(AppSettings::UseStandardResolve)
    {
        if(AppSettings::MSAAMode == 0)
            context->CopyResource(resolveTarget.Texture, colorTarget.Texture);
        else
            context->ResolveSubresource(resolveTarget.Texture, 0, colorTarget.Texture, 0, colorTarget.Format);
        return;
    }

    const uint32 SampleRadius = static_cast<uint32>((AppSettings::ResolveFilterDiameter / 2.0f) + 0.499f);
    ID3D11PixelShader* pixelShader = resolvePS[AppSettings::MSAAMode];
    context->PSSetShader(pixelShader, nullptr, 0);
    context->VSSetShader(resolveVS, nullptr, 0);

    resolveConstants.Data.TextureSize = Float2(static_cast<float>(colorTarget.Width), static_cast<float>(colorTarget.Height));
    resolveConstants.Data.SampleRadius = SampleRadius;;
    resolveConstants.ApplyChanges(context);
    resolveConstants.SetPS(context, 0);

    ID3D11ShaderResourceView* srvs[] = { colorTarget.SRView, velocityTarget.SRView, depthBuffer.SRView, prevFrameTarget.SRView};
    context->PSSetShaderResources(0, ArraySize_(srvs), srvs);

    ID3D11SamplerState* samplers[] = { samplerStates.LinearClamp(), samplerStates.Point() };
    context->PSSetSamplers(0, ArraySize_(samplers), samplers);

    ID3D11Buffer* vbs[1] = { nullptr };
    UINT strides[1] = { 0 };
    UINT offsets[1] = { 0 };
    context->IASetVertexBuffers(0, 1, vbs, strides, offsets);
    context->IASetInputLayout(nullptr);
    context->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
    context->Draw(3, 0);

    rtvs[0] = nullptr;
    context->OMSetRenderTargets(1, rtvs, nullptr);

    srvs[0] = srvs[1] = srvs[2] = nullptr;
    context->PSSetShaderResources(0, 3, srvs);

    context->CopyResource(prevFrameTarget.Texture, resolveTarget.Texture);
}
Example #3
0
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 CPUTRenderTargetColor::Resolve( CPUTRenderParameters &renderParams )
{
    ID3D11DeviceContext *pContext = CPUT_DX11::GetContext();
    pContext->ResolveSubresource( mpColorTextureDX,  0, mpColorTextureDXMSAA, 0, mColorFormat);
}
Example #5
0
    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, &copyData, 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;
    }
Example #6
0
HRESULT STDMETHODCALLTYPE D3D11SwapPresentHook(IDXGISwapChain *swap, UINT syncInterval, UINT flags)
{
    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;

                /*FARPROC curRelease = GetVTable(device, (8/4));
                if(curRelease != newD3D11Release)
                {
                    oldD3D11Release = curRelease;
                    newD3D11Release = (FARPROC)DeviceReleaseHook;
                    SetVTable(device, (8/4), newD3D11Release);
                }*/
            }

            ID3D11DeviceContext *context;
            device->GetImmediateContext(&context);

            if(bCapturing && bStopRequested)
            {
                ClearD3D11Data();
                bStopRequested = false;
            }

            if(!bHasTextures && bCapturing)
            {
                if(dxgiFormat)
                {
                    if(!hwndReceiver)
                        hwndReceiver = FindWindow(RECEIVER_WINDOWCLASS, NULL);

                    if(hwndReceiver)
                    {
                        BOOL bSuccess = DoD3D11Hook(device);

                        if(bSuccess)
                        {
                            d3d11CaptureInfo.mapID = InitializeSharedMemoryGPUCapture(&texData);
                            if(!d3d11CaptureInfo.mapID)
                            {
                                RUNONCE logOutput << "SwapPresentHook: creation of shared memory failed" << endl;
                                bSuccess = false;
                            }
                        }

                        if(bSuccess)
                            bSuccess = IsWindow(hwndReceiver);

                        if(bSuccess)
                        {
                            bHasTextures = true;
                            d3d11CaptureInfo.captureType = CAPTURETYPE_SHAREDTEX;
                            d3d11CaptureInfo.hwndSender = hwndSender;
                            d3d11CaptureInfo.bFlip = FALSE;
                            texData->texHandles[0] = sharedHandles[0];
                            texData->texHandles[1] = sharedHandles[1];
                            PostMessage(hwndReceiver, RECEIVER_NEWCAPTURE, 0, (LPARAM)&d3d11CaptureInfo);

                            logOutput << "DoD3D11Hook: success";
                        }
                        else
                        {
                            ClearD3D11Data();
                        }
                    }
                }
            }

            if(bHasTextures)
            {
                LONGLONG frameTime;
                if(bCapturing)
                {
                    if(texData)
                    {
                        if(frameTime = texData->frameTime)
                        {
                            LONGLONG timeVal = OSGetTimeMicroseconds();
                            LONGLONG timeElapsed = timeVal-lastTime;

                            if(timeElapsed >= frameTime)
                            {
                                lastTime += frameTime;
                                if(timeElapsed > frameTime*2)
                                    lastTime = timeVal;

                                DWORD nextCapture = curCapture == 0 ? 1 : 0;

                                ID3D11Resource *backBuffer = NULL;

                                if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D11Resource, (void**)&backBuffer)))
                                {
                                    if(bIsMultisampled)
                                        context->ResolveSubresource(copyTextureGame, 0, backBuffer, 0, dxgiFormat);
                                    else
                                        context->CopyResource(copyTextureGame, backBuffer);

                                    ID3D10Texture2D *outputTexture = NULL;
                                    int lastRendered = -1;

                                    if(keyedMutexes[curCapture]->AcquireSync(0, 0) == WAIT_OBJECT_0)
                                        lastRendered = (int)curCapture;
                                    else if(keyedMutexes[nextCapture]->AcquireSync(0, 0) == WAIT_OBJECT_0)
                                        lastRendered = (int)nextCapture;

                                    if(lastRendered != -1)
                                    {
                                        shareDevice->CopyResource(sharedTextures[lastRendered], copyTextureIntermediary);
                                        keyedMutexes[lastRendered]->ReleaseSync(0);
                                    }

                                    texData->lastRendered = lastRendered;
                                    backBuffer->Release();
                                }

                                curCapture = nextCapture;
                            }
                        }
                    }
                }
                else
                    ClearD3D11Data();
            }

            device->Release();
            context->Release();
        }
    }

    gi11swapPresent.Unhook();
    HRESULT hRes = swap->Present(syncInterval, flags);
    gi11swapPresent.Rehook();

    return hRes;
}
Example #7
0
void DoD3D11Capture(IDXGISwapChain *swap)
{
    ID3D11Device *device = NULL;
    HRESULT chi;
    if(SUCCEEDED(chi = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device)))
    {
        if(!lpCurrentDevice)
        {
            lpCurrentDevice = device;

            /*FARPROC curRelease = GetVTable(device, (8/4));
            if(curRelease != newD3D11Release)
            {
                oldD3D11Release = curRelease;
                newD3D11Release = (FARPROC)DeviceReleaseHook;
                SetVTable(device, (8/4), newD3D11Release);
            }*/
        }

        ID3D11DeviceContext *context;
        device->GetImmediateContext(&context);

        if(bCapturing && bStopRequested)
        {
            ClearD3D11Data();
            bCapturing = false;
            bStopRequested = false;
        }

        if(!bCapturing && WaitForSingleObject(hSignalRestart, 0) == WAIT_OBJECT_0)
        {
            hwndOBS = FindWindow(OBS_WINDOW_CLASS, NULL);
            if(hwndOBS)
                bCapturing = true;
        }

        if(!bHasTextures && bCapturing)
        {
            if(dxgiFormat && hwndOBS)
            {
                BOOL bSuccess = DoD3D11Hook(device);

                if(bSuccess)
                {
                    d3d11CaptureInfo.mapID = InitializeSharedMemoryGPUCapture(&texData);
                    if(!d3d11CaptureInfo.mapID)
                    {
                        RUNONCE logOutput << "SwapPresentHook: creation of shared memory failed" << endl;
                        bSuccess = false;
                    }
                }

                if(bSuccess)
                {
                    bHasTextures = true;
                    d3d11CaptureInfo.captureType = CAPTURETYPE_SHAREDTEX;
                    d3d11CaptureInfo.bFlip = FALSE;
                    texData->texHandle = (DWORD)sharedHandle;

                    memcpy(infoMem, &d3d11CaptureInfo, sizeof(CaptureInfo));
                    SetEvent(hSignalReady);

                    logOutput << "DoD3D11Hook: success" << endl;
                }
                else
                {
                    ClearD3D11Data();
                }
            }
        }

        if(bHasTextures)
        {
            LONGLONG timeVal = OSGetTimeMicroseconds();

            //check keep alive state, dumb but effective
            if(bCapturing)
            {
                if((timeVal-keepAliveTime) > 3000000)
                {
                    HANDLE hKeepAlive = OpenEvent(EVENT_ALL_ACCESS, FALSE, strKeepAlive.c_str());
                    if (hKeepAlive) {
                        CloseHandle(hKeepAlive);
                    } else {
                        ClearD3D11Data();
                        bCapturing = false;
                    }

                    keepAliveTime = timeVal;
                }
            }

            LONGLONG frameTime;
            if(bCapturing)
            {
                if(texData)
                {
                    if(frameTime = texData->frameTime)
                    {
                        LONGLONG timeElapsed = timeVal-lastTime;

                        if(timeElapsed >= frameTime)
                        {
                            if(!IsWindow(hwndOBS))
                            {
                                hwndOBS = NULL;
                                bStopRequested = true;
                            }

                            if(WaitForSingleObject(hSignalEnd, 0) == WAIT_OBJECT_0)
                                bStopRequested = true;

                            lastTime += frameTime;
                            if(timeElapsed > frameTime*2)
                                lastTime = timeVal;

                            DWORD nextCapture = curCapture == 0 ? 1 : 0;

                            ID3D11Resource *backBuffer = NULL;

                            if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D11Resource, (void**)&backBuffer)))
                            {
                                if(bIsMultisampled)
                                    context->ResolveSubresource(copyTextureGame, 0, backBuffer, 0, dxgiFormat);
                                else
                                    context->CopyResource(copyTextureGame, backBuffer);

                                backBuffer->Release();
                            }

                            curCapture = nextCapture;
                        }
                    }
                }
            }
            else
                ClearD3D11Data();
        }

        device->Release();
        context->Release();
    }
}
Example #8
0
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();
    }
}
Example #9
0
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);
}
Example #10
0
gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Box &sourceArea, ID3D11Resource *source, UINT sourceSubResource)
{
    D3D11_RESOURCE_DIMENSION dim;
    source->GetType(&dim);

    DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
    gl::Extents extents;
    UINT sampleCount = 0;

    ID3D11Texture2D *source2D = NULL;

    if (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D)
    {
        D3D11_TEXTURE2D_DESC textureDesc2D;
        source2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(source);
        ASSERT(source2D);
        source2D->GetDesc(&textureDesc2D);

        format = textureDesc2D.Format;
        extents = gl::Extents(textureDesc2D.Width, textureDesc2D.Height, 1);
        sampleCount = textureDesc2D.SampleDesc.Count;
    }
    else if (dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
    {
        D3D11_TEXTURE3D_DESC textureDesc3D;
        ID3D11Texture3D *source3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(source);
        ASSERT(source3D);
        source3D->GetDesc(&textureDesc3D);

        format = textureDesc3D.Format;
        extents = gl::Extents(textureDesc3D.Width, textureDesc3D.Height, textureDesc3D.Depth);
        sampleCount = 1;
    }
    else
    {
        UNREACHABLE();
    }

    if (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;

        ID3D11Resource *srcTex = NULL;

        bool needResolve = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D && sampleCount > 1);

        if (needResolve)
        {
            D3D11_TEXTURE2D_DESC resolveDesc;
            resolveDesc.Width = extents.width;
            resolveDesc.Height = extents.height;
            resolveDesc.MipLevels = 1;
            resolveDesc.ArraySize = 1;
            resolveDesc.Format = format;
            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, source, sourceSubResource, 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 = 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);
        }
    }
    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
        const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
        GLsizei rowOffset = dxgiFormatInfo.pixelBytes * destOffset.x;
        uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * destOffset.y + rowOffset + destOffset.z * mappedImage.DepthPitch;

        const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);

        // Currently in ANGLE, the source data may only need to be converted if the source is the current framebuffer
        // and OpenGL ES framebuffers must be 2D textures therefore we should not need to convert 3D textures between different formats.
        ASSERT(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D);
        ASSERT(sourceArea.z == 0 && sourceArea.depth == 1);
        gl::Rectangle sourceRect(sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height);
        error = mRenderer->readTextureData(source2D, sourceSubResource, sourceRect, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);

        unmap();

        if (error.isError())
        {
            return error;
        }
    }

    mDirty = true;

    return gl::Error(GL_NO_ERROR);
}