0

I am trying to draw something 10-bit pixel arrays on to the HDR canvas but failed.

  1. I add my codes base on https://github.com/vesa-org/DisplayHDRTest
  2. The code is inserted into Game::GenerateTestPattern_CalibrateMaxFullFrameValue
  3. I could judge from the rendering result that it's not so bright as it uses the "brush" to draw, very likely just drawing an SDR content. Even I use the DXGI_FORMAT_R10G10B10A2_UNORM as the pixel format. And I think it also draws the red as scanlines.

enter image description here

  1. Here the entire code of Game::GenerateTestPattern_CalibrateMaxFullFrameValue:
void Game::GenerateTestPattern_CalibrateMaxFullFrameValue(ID2D1DeviceContext2 * ctx) // Verify MaxFALL (MaxFF TML)
{
    // set up background (clear full screen)
    float backNits = m_outputDesc.MaxFullFrameLuminance;
    float avg = backNits;
    if (m_newTestSelected) SetMetadata(backNits, avg, GAMUT_Native);
    float c = nitstoCCCS(backNits);
    ComPtr<ID2D1SolidColorBrush> backBrush;
    DX::ThrowIfFailed(ctx->CreateSolidColorBrush(D2D1::ColorF(c * m_rgbMask.r, c * m_rgbMask.g, c * m_rgbMask.b), &backBrush));
    auto logSize = m_deviceResources->GetLogicalSize();
    ctx->FillRectangle(&logSize, backBrush.Get());
    float2 center;
    center.x = (logSize.right - logSize.left)*0.50f;
    center.y = (logSize.bottom - logSize.top)*0.50f;
    float size = sqrt((logSize.right - logSize.left) * (logSize.bottom - logSize.top));

    // inner boxes
    float nits = 0;
    if (CheckHDR_On())
    {
        nits = Remove2084(m_maxFullFramePQValue / 1023.0f)*10000.0f;
        c = nitstoCCCS(nits);
    }
    else
    {
        c = m_maxFullFramesRGBValue / 255.0f;
        nits = RemoveSRGBCurve(c)*80.0f;
    }
    ComPtr<ID2D1SolidColorBrush> centerBrush;
    DX::ThrowIfFailed(ctx->CreateSolidColorBrush(D2D1::ColorF(c * m_rgbMask.r, c * m_rgbMask.g, c * m_rgbMask.b), &centerBrush));

    size = size * 0.333333333f;
    size = size * 0.333333333f;
    D2D1_RECT_F centerSquare1 =
    {
        center.x - size * 1.03f,
        center.y - size * 1.03f,
        center.x - size * 0.03f,
        center.y - size * 0.03f
    };
    ctx->FillRectangle(&centerSquare1, centerBrush.Get());

    D2D1_RECT_F centerSquare2 =
    {
        center.x + size * 0.03f,
        center.y - size * 1.03f,
        center.x + size * 1.03f,
        center.y - size * 0.03f
    };
    ctx->FillRectangle(&centerSquare2, centerBrush.Get());

    D2D1_RECT_F centerSquare3 =
    {
        center.x - size * 1.03f,
        center.y + size * 0.03f,
        center.x - size * 0.03f,
        center.y + size * 1.03f
    };
    ctx->FillRectangle(&centerSquare3, centerBrush.Get());

    D2D1_RECT_F centerSquare4 =
    {
        center.x + size * 0.03f,
        center.y + size * 0.03f,
        center.x + size * 1.03f,
        center.y + size * 1.03f
    };
    ctx->FillRectangle(&centerSquare4, centerBrush.Get());

    if (m_showExplanatoryText)
    {
        std::wstringstream title;
        title << L"Calibrate Max Full Frame Luminance Value: ";
        if (CheckHDR_On())
        {
            title << L"\nHDR10: ";
            title << static_cast<unsigned int>(m_maxFullFramePQValue);
            title << L"  Nits: ";
            title << nits;
        }
        else
        {
            title << L"\nsRGB: ";
            title << static_cast<unsigned int>(m_maxEffectivesRGBValue);
            title << L"  Nits: ";
            title << nits;
        }

        title << L"\nToggle Overlay using O";
        title << L"\nToggle RGB using RGB";

        title << L"\nAdjust brightness using Up/Down arrows";
        title << L"\n  until inner boxes just barely disappear";
        RenderText(ctx, m_largeFormat.Get(), title.str(), m_testTitleRect, true);

        PrintMetadata(ctx, true);

        DrawCenterText(ctx);
    }

    if (1)  // My Code to try to draw a 1500 nits red
    {
        auto out = m_deviceResources->GetOutputSize();

        D2D1_SIZE_U  size = { out.right, out.bottom };

        int pitch = size.width*4 ;
        int total = pitch * size.height;
        int allocated = total * 4;
        void* pixels = malloc(allocated); // large enough
        memset(pixels, 0xff, total);
        
        int alpha = 3 << 30; // Though it should be ignored
        for (int y = 0; y < size.height  ; y++)
        {
            unsigned long* line = pitch * y + (unsigned long*)pixels;
            for (int x = 0; x < size.width; x++)
            {
                unsigned long* p = line + x;

                //int c = 1023 & (t);
                int C = 800;

                *p = C | (0 << 10) | (0 << 10 << 10) | (0 << 10 << 10 << 10) | alpha;
            }

        }

        D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
            DXGI_FORMAT_R10G10B10A2_UNORM,
            D2D1_ALPHA_MODE_IGNORE
        );

        D2D1_BITMAP_PROPERTIES1 props;// = D2D1::RenderTargetProperties();
        memset(&props, 0, sizeof(props));
        props.pixelFormat = pixelFormat;
        ctx->GetDpi(&props.dpiX, &props.dpiY);
        props.bitmapOptions = D2D1_BITMAP_OPTIONS_NONE;

        props.colorContext = NULL;

        ID2D1Bitmap1* bm = NULL;
        HRESULT ret = ctx->CreateBitmap(
            size, pixels, pitch, &props, &bm);      

//      ctx->DrawBitmap(bm, D2D1::RectF(0, 0, size.width, size.height));
        ctx->DrawImage(bm, D2D1::Point2F(0, 0));

        bm->Release();
        //  delete bm;
        free(pixels);
    }

    m_newTestSelected = false;

}

  1. If you follow this steps and run in you PC, this test is after "Calibrate Max Tone Mapped Luminance Value".

I wish I can draw some 10-bit colors in the memory, and it can be drawn onto a HDR surface just like the brush and text the context creates.

Thanks in advance.

0 Answers0