mirror of
				https://github.com/gnif/LookingGlass.git
				synced 2025-11-04 06:31:54 +00:00 
			
		
		
		
	[host] dxgi: seperate out and implement a post processor chain
This commit is contained in:
		@@ -8,6 +8,8 @@ add_library(capture_DXGI STATIC
 | 
			
		||||
  src/ods_capture.c
 | 
			
		||||
  src/util.c
 | 
			
		||||
  src/com_ref.c
 | 
			
		||||
 | 
			
		||||
  src/pp/sdrwhitelevel.c
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_definitions("-DCOBJMACROS -DINITGUID")
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,16 @@
 | 
			
		||||
 | 
			
		||||
#define LOCKED(...) INTERLOCKED_SECTION(this->deviceContextLock, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
//post processers
 | 
			
		||||
extern const DXGIPostProcess DXGIPP_SDRWhiteLevel;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  const DXGIPostProcess * pp;
 | 
			
		||||
  void                  * opaque;
 | 
			
		||||
}
 | 
			
		||||
PostProcessInstance;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  unsigned int id;
 | 
			
		||||
@@ -61,12 +71,6 @@ DownsampleRule;
 | 
			
		||||
 | 
			
		||||
static Vector downsampleRules = {0};
 | 
			
		||||
 | 
			
		||||
struct ShaderConsts
 | 
			
		||||
{
 | 
			
		||||
  float sdrWhiteLevel;
 | 
			
		||||
}
 | 
			
		||||
__attribute__((aligned(16)));
 | 
			
		||||
 | 
			
		||||
// locals
 | 
			
		||||
static struct DXGIInterface * this = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -82,6 +86,10 @@ static struct DXGICopyBackend * backends[] = {
 | 
			
		||||
static bool          dxgi_deinit(void);
 | 
			
		||||
static CaptureResult dxgi_releaseFrame(void);
 | 
			
		||||
 | 
			
		||||
static bool ppInit(const DXGIPostProcess * pp, bool shareable);
 | 
			
		||||
static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src);
 | 
			
		||||
static void ppFreeAll(void);
 | 
			
		||||
 | 
			
		||||
// implementation
 | 
			
		||||
 | 
			
		||||
static const char * dxgi_getName(void)
 | 
			
		||||
@@ -626,18 +634,10 @@ static bool dxgi_init(void)
 | 
			
		||||
      IDXGIOutput6_GetDesc1(*output6, &desc1);
 | 
			
		||||
      this->dxgiColorSpace = desc1.ColorSpace;
 | 
			
		||||
 | 
			
		||||
      if (!getDisplayPathInfo(desc1.Monitor, &this->displayPathInfo))
 | 
			
		||||
      {
 | 
			
		||||
        DEBUG_ERROR("Failed to get the display path info");
 | 
			
		||||
        goto fail;
 | 
			
		||||
      }
 | 
			
		||||
      this->sdrWhiteLevel = getSDRWhiteLevel(&this->displayPathInfo);
 | 
			
		||||
 | 
			
		||||
      DEBUG_INFO("Bits Per Color    : %u"   , desc1.BitsPerColor);
 | 
			
		||||
      DEBUG_INFO("Color Space       : %s"   , getDXGIColorSpaceTypeStr(this->dxgiColorSpace));
 | 
			
		||||
      DEBUG_INFO("Min/Max Luminance : %f/%f", desc1.MinLuminance, desc1.MaxLuminance);
 | 
			
		||||
      DEBUG_INFO("Frame Luminance   : %f"   , desc1.MaxFullFrameLuminance);
 | 
			
		||||
      DEBUG_INFO("SDR White Level   : %f"   , this->sdrWhiteLevel);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -753,185 +753,26 @@ static bool dxgi_init(void)
 | 
			
		||||
  for (int i = 0; i < this->maxTextures; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    this->texture[i].texDamageCount = -1;
 | 
			
		||||
    if (!this->hdr)
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    D3D11_TEXTURE2D_DESC hdrTexDesc =
 | 
			
		||||
    {
 | 
			
		||||
      .Width              = this->width,
 | 
			
		||||
      .Height             = this->height,
 | 
			
		||||
      .MipLevels          = 1,
 | 
			
		||||
      .ArraySize          = 1,
 | 
			
		||||
      .SampleDesc.Count   = 1,
 | 
			
		||||
      .SampleDesc.Quality = 0,
 | 
			
		||||
      .Usage              = D3D11_USAGE_DEFAULT,
 | 
			
		||||
      .Format             = DXGI_FORMAT_R10G10B10A2_UNORM,
 | 
			
		||||
      .BindFlags          = D3D11_BIND_RENDER_TARGET |
 | 
			
		||||
                            D3D11_BIND_SHADER_RESOURCE,
 | 
			
		||||
      .CPUAccessFlags     = 0,
 | 
			
		||||
      .MiscFlags          = 0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // allow texture sharing with other backends
 | 
			
		||||
    if (this->backend != ©BackendD3D11)
 | 
			
		||||
      hdrTexDesc.MiscFlags |=
 | 
			
		||||
        D3D11_RESOURCE_MISC_SHARED |
 | 
			
		||||
        D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
 | 
			
		||||
 | 
			
		||||
    status = ID3D11Device_CreateTexture2D(*this->device, &hdrTexDesc, NULL,
 | 
			
		||||
      (ID3D11Texture2D **)comRef_newGlobal(&this->texture[i].hdrTex));
 | 
			
		||||
 | 
			
		||||
    if (FAILED(status))
 | 
			
		||||
    {
 | 
			
		||||
      DEBUG_WINERROR("Failed to create HDR texture", status);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    status = ID3D11Device_CreateRenderTargetView(*this->device,
 | 
			
		||||
      (ID3D11Resource *)*this->texture[i].hdrTex, NULL,
 | 
			
		||||
      (ID3D11RenderTargetView **)comRef_newGlobal(
 | 
			
		||||
        &this->texture[i].renderTarget));
 | 
			
		||||
 | 
			
		||||
    if (FAILED(status))
 | 
			
		||||
    {
 | 
			
		||||
      DEBUG_WINERROR("Failed to create HDR target view", status);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
    vector_create(&this->texture[i].pp, sizeof(PostProcessInstance), 0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (this->hdr)
 | 
			
		||||
  const D3D11_VIEWPORT vp =
 | 
			
		||||
  {
 | 
			
		||||
    const D3D11_VIEWPORT vp =
 | 
			
		||||
    {
 | 
			
		||||
      .TopLeftX = 0.0f,
 | 
			
		||||
      .TopLeftY = 0.0f,
 | 
			
		||||
      .Width    = this->width,
 | 
			
		||||
      .Height   = this->height,
 | 
			
		||||
      .MinDepth = 0.0f,
 | 
			
		||||
      .MaxDepth = 1.0f,
 | 
			
		||||
    };
 | 
			
		||||
    ID3D11DeviceContext_RSSetViewports(*this->deviceContext, 1, &vp);
 | 
			
		||||
    .TopLeftX = 0.0f,
 | 
			
		||||
    .TopLeftY = 0.0f,
 | 
			
		||||
    .Width    = this->width,
 | 
			
		||||
    .Height   = this->height,
 | 
			
		||||
    .MinDepth = 0.0f,
 | 
			
		||||
    .MaxDepth = 1.0f,
 | 
			
		||||
  };
 | 
			
		||||
  ID3D11DeviceContext_RSSetViewports(*this->deviceContext, 1, &vp);
 | 
			
		||||
 | 
			
		||||
    static const char * vshader =
 | 
			
		||||
      "void main(\n"
 | 
			
		||||
      "  in  uint   vertexID : SV_VERTEXID,\n"
 | 
			
		||||
      "  out float4 position : SV_POSITION,\n"
 | 
			
		||||
      "  out float2 texCoord : TEXCOORD0)\n"
 | 
			
		||||
      "{\n"
 | 
			
		||||
      "  float2 positions[4] =\n"
 | 
			
		||||
      "  {\n"
 | 
			
		||||
      "    float2(-1.0,  1.0),\n"
 | 
			
		||||
      "    float2( 1.0,  1.0),\n"
 | 
			
		||||
      "    float2(-1.0, -1.0),\n"
 | 
			
		||||
      "    float2( 1.0, -1.0)\n"
 | 
			
		||||
      "  };\n"
 | 
			
		||||
      "\n"
 | 
			
		||||
      "  float2 texCoords[4] =\n"
 | 
			
		||||
      "  {\n"
 | 
			
		||||
      "    float2(0.0, 0.0),\n"
 | 
			
		||||
      "    float2(1.0, 0.0),\n"
 | 
			
		||||
      "    float2(0.0, 1.0),\n"
 | 
			
		||||
      "    float2(1.0, 1.0)\n"
 | 
			
		||||
      "  };\n"
 | 
			
		||||
      "\n"
 | 
			
		||||
      "  position = float4(positions[vertexID], 0.0, 1.0);\n"
 | 
			
		||||
      "  texCoord = texCoords[vertexID];\n"
 | 
			
		||||
      "}";
 | 
			
		||||
 | 
			
		||||
    static const char * pshader =
 | 
			
		||||
      "Texture2D    gInputTexture : register(t0);\n"
 | 
			
		||||
      "SamplerState gSamplerState : register(s0);\n"
 | 
			
		||||
      "cbuffer      gConsts       : register(b0)\n"
 | 
			
		||||
      "{\n"
 | 
			
		||||
      "  float SDRWhiteLevel;"
 | 
			
		||||
      "};\n"
 | 
			
		||||
      "\n"
 | 
			
		||||
      "float4 main(\n"
 | 
			
		||||
      "  float4 position : SV_POSITION,\n"
 | 
			
		||||
      "  float2 texCoord : TEXCOORD0) : SV_TARGET"
 | 
			
		||||
      "{\n"
 | 
			
		||||
      "  float4 color = gInputTexture.Sample(gSamplerState, texCoord);\n"
 | 
			
		||||
      "  color.rgb   *= SDRWhiteLevel;\n"
 | 
			
		||||
      "  return color;\n"
 | 
			
		||||
      "}\n";
 | 
			
		||||
 | 
			
		||||
    comRef_defineLocal(ID3DBlob, byteCode);
 | 
			
		||||
    if (!compileShader(byteCode, "main", "vs_5_0", vshader))
 | 
			
		||||
      goto fail;
 | 
			
		||||
 | 
			
		||||
    status = ID3D11Device_CreateVertexShader(
 | 
			
		||||
      *this->device,
 | 
			
		||||
      ID3D10Blob_GetBufferPointer(*byteCode),
 | 
			
		||||
      ID3D10Blob_GetBufferSize   (*byteCode),
 | 
			
		||||
      NULL,
 | 
			
		||||
      (ID3D11VertexShader **)comRef_newGlobal(&this->vertexShader));
 | 
			
		||||
 | 
			
		||||
    if (FAILED(status))
 | 
			
		||||
    {
 | 
			
		||||
      DEBUG_WINERROR("Failed to create the vertex shader", status);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    comRef_release(byteCode);
 | 
			
		||||
    if (!compileShader(byteCode, "main", "ps_5_0", pshader))
 | 
			
		||||
      goto fail;
 | 
			
		||||
 | 
			
		||||
    status = ID3D11Device_CreatePixelShader(
 | 
			
		||||
      *this->device,
 | 
			
		||||
      ID3D10Blob_GetBufferPointer(*byteCode),
 | 
			
		||||
      ID3D10Blob_GetBufferSize   (*byteCode),
 | 
			
		||||
      NULL,
 | 
			
		||||
      (ID3D11PixelShader **)comRef_newGlobal(&this->pixelShader));
 | 
			
		||||
 | 
			
		||||
    if (FAILED(status))
 | 
			
		||||
    {
 | 
			
		||||
      DEBUG_WINERROR("Failed to create the pixel shader", status);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const D3D11_SAMPLER_DESC samplerDesc =
 | 
			
		||||
    {
 | 
			
		||||
      .Filter         = D3D11_FILTER_MIN_MAG_MIP_LINEAR,
 | 
			
		||||
      .AddressU       = D3D11_TEXTURE_ADDRESS_WRAP,
 | 
			
		||||
      .AddressV       = D3D11_TEXTURE_ADDRESS_WRAP,
 | 
			
		||||
      .AddressW       = D3D11_TEXTURE_ADDRESS_WRAP,
 | 
			
		||||
      .ComparisonFunc = D3D11_COMPARISON_NEVER,
 | 
			
		||||
      .MinLOD         = 0,
 | 
			
		||||
      .MaxLOD         = D3D11_FLOAT32_MAX
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    status = ID3D11Device_CreateSamplerState(
 | 
			
		||||
      *this->device, &samplerDesc,
 | 
			
		||||
      (ID3D11SamplerState  **)comRef_newGlobal(&this->samplerState));
 | 
			
		||||
 | 
			
		||||
    if (FAILED(status))
 | 
			
		||||
    {
 | 
			
		||||
      DEBUG_WINERROR("Failed to create the sampler state", status);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct ShaderConsts consts =
 | 
			
		||||
    {
 | 
			
		||||
      .sdrWhiteLevel = 80.0f / this->sdrWhiteLevel
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    D3D11_BUFFER_DESC bufferDesc =
 | 
			
		||||
    {
 | 
			
		||||
      .ByteWidth      = sizeof(consts),
 | 
			
		||||
      .Usage          = D3D11_USAGE_DEFAULT,
 | 
			
		||||
      .BindFlags      = D3D11_BIND_CONSTANT_BUFFER,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    D3D11_SUBRESOURCE_DATA initData = { .pSysMem = &consts };
 | 
			
		||||
    status = ID3D11Device_CreateBuffer(
 | 
			
		||||
      *this->device, &bufferDesc, &initData,
 | 
			
		||||
      (ID3D11Buffer **)comRef_newGlobal(&this->constBuffer));
 | 
			
		||||
 | 
			
		||||
    if (FAILED(status))
 | 
			
		||||
    {
 | 
			
		||||
      DEBUG_WINERROR("Failed to create the constant buffer", status);
 | 
			
		||||
      goto fail;
 | 
			
		||||
    }
 | 
			
		||||
  // if HDR add the SDRWhiteLevel post processor to correct the output
 | 
			
		||||
  if (this->hdr && !ppInit(&DXGIPP_SDRWhiteLevel,
 | 
			
		||||
    this->backend != ©BackendD3D11))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_ERROR("Failed to initialize the SDRWhiteLevel post processor");
 | 
			
		||||
    goto fail;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
 | 
			
		||||
@@ -961,19 +802,20 @@ static bool dxgi_deinit(void)
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < this->maxTextures; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    if (this->texture[i].map)
 | 
			
		||||
    {
 | 
			
		||||
      this->backend->unmapTexture(this->texture + i);
 | 
			
		||||
      this->texture[i].map = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    Texture * tex = &this->texture[i];
 | 
			
		||||
    if (!tex->map)
 | 
			
		||||
      continue;
 | 
			
		||||
    this->backend->unmapTexture(tex);
 | 
			
		||||
    tex->map = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (this->dup && *this->dup)
 | 
			
		||||
    dxgi_releaseFrame();
 | 
			
		||||
 | 
			
		||||
  // this MUST run before backend->free().
 | 
			
		||||
  // this MUST run before backend->free() & ppFreeAll.
 | 
			
		||||
  comRef_free();
 | 
			
		||||
 | 
			
		||||
  ppFreeAll();
 | 
			
		||||
  if (this->backend)
 | 
			
		||||
  {
 | 
			
		||||
    this->backend->free();
 | 
			
		||||
@@ -1223,76 +1065,14 @@ static CaptureResult dxgi_capture(void)
 | 
			
		||||
        computeFrameDamage(tex);
 | 
			
		||||
      computeTexDamage(tex);
 | 
			
		||||
 | 
			
		||||
      if (this->hdr)
 | 
			
		||||
      {
 | 
			
		||||
        // setup the pixel shader input resource view
 | 
			
		||||
        comRef_defineLocal(ID3D11ShaderResourceView, inputSRV);
 | 
			
		||||
        {
 | 
			
		||||
          const D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc =
 | 
			
		||||
          {
 | 
			
		||||
            .Format              = this->dxgiSrcFormat,
 | 
			
		||||
            .ViewDimension       = D3D11_SRV_DIMENSION_TEXTURE2D,
 | 
			
		||||
            .Texture2D.MipLevels = 1
 | 
			
		||||
          };
 | 
			
		||||
          status = ID3D11Device_CreateShaderResourceView(
 | 
			
		||||
            *this->device, (ID3D11Resource *)*src, &srvDesc, inputSRV);
 | 
			
		||||
          if (FAILED(status))
 | 
			
		||||
          {
 | 
			
		||||
            DEBUG_WINERROR("Failed to create the source resource view", status);
 | 
			
		||||
            result = CAPTURE_RESULT_ERROR;
 | 
			
		||||
            goto exit;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        float nits = getSDRWhiteLevel(&this->displayPathInfo);
 | 
			
		||||
        if (nits != this->sdrWhiteLevel)
 | 
			
		||||
        {
 | 
			
		||||
          this->sdrWhiteLevel = nits;
 | 
			
		||||
 | 
			
		||||
          struct ShaderConsts consts =
 | 
			
		||||
          {
 | 
			
		||||
            .sdrWhiteLevel = 80.0f / nits
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          ID3D11DeviceContext_UpdateSubresource(
 | 
			
		||||
            *this->deviceContext, (ID3D11Resource*)*this->constBuffer,
 | 
			
		||||
            0, NULL, &consts, 0, 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ID3D11DeviceContext_VSSetShader(
 | 
			
		||||
          *this->deviceContext, *this->vertexShader, NULL, 0);
 | 
			
		||||
 | 
			
		||||
        ID3D11DeviceContext_PSSetShader(
 | 
			
		||||
          *this->deviceContext, *this->pixelShader, NULL, 0);
 | 
			
		||||
        ID3D11DeviceContext_PSSetShaderResources(
 | 
			
		||||
          *this->deviceContext, 0, 1, inputSRV);
 | 
			
		||||
        ID3D11DeviceContext_PSSetSamplers(
 | 
			
		||||
          *this->deviceContext, 0, 1, this->samplerState);
 | 
			
		||||
        ID3D11DeviceContext_PSSetConstantBuffers(
 | 
			
		||||
          *this->deviceContext, 0, 1, this->constBuffer);
 | 
			
		||||
 | 
			
		||||
        ID3D11DeviceContext_OMSetRenderTargets(
 | 
			
		||||
          *this->deviceContext, 1, tex->renderTarget, NULL);
 | 
			
		||||
 | 
			
		||||
        ID3D11DeviceContext_IASetPrimitiveTopology(
 | 
			
		||||
          *this->deviceContext, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
 | 
			
		||||
 | 
			
		||||
        ID3D11DeviceContext_Draw(*this->deviceContext, 4, 0);
 | 
			
		||||
      ID3D11Texture2D * dst = ppRun(tex, *src);
 | 
			
		||||
      if (dst != *src)
 | 
			
		||||
        ID3D11DeviceContext_Flush(*this->deviceContext);
 | 
			
		||||
 | 
			
		||||
        if (!this->backend->copyFrame(tex, *tex->hdrTex))
 | 
			
		||||
        {
 | 
			
		||||
          result = CAPTURE_RESULT_ERROR;
 | 
			
		||||
          goto exit;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      if (!this->backend->copyFrame(tex, dst))
 | 
			
		||||
      {
 | 
			
		||||
        if (!this->backend->copyFrame(tex, *src))
 | 
			
		||||
        {
 | 
			
		||||
          result = CAPTURE_RESULT_ERROR;
 | 
			
		||||
          goto exit;
 | 
			
		||||
        }
 | 
			
		||||
        result = CAPTURE_RESULT_ERROR;
 | 
			
		||||
        goto exit;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      for (int i = 0; i < this->maxTextures; ++i)
 | 
			
		||||
@@ -1535,6 +1315,51 @@ static CaptureResult dxgi_releaseFrame(void)
 | 
			
		||||
  return CAPTURE_RESULT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool ppInit(const DXGIPostProcess * pp, bool shareable)
 | 
			
		||||
{
 | 
			
		||||
  if (!pp->setup(this->device, this->deviceContext, this->output))
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  for(int i = 0; i < this->maxTextures; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    PostProcessInstance inst = { .pp = pp };
 | 
			
		||||
    if (!pp->init(&inst.opaque, this->width, this->height, shareable))
 | 
			
		||||
      return false;
 | 
			
		||||
 | 
			
		||||
    vector_push(&this->texture[i].pp, &inst);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src)
 | 
			
		||||
{
 | 
			
		||||
  PostProcessInstance * inst;
 | 
			
		||||
  vector_forEachRef(inst, &tex->pp)
 | 
			
		||||
    src = inst->pp->run(inst->opaque, src);
 | 
			
		||||
 | 
			
		||||
  return src;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ppFreeAll(void)
 | 
			
		||||
{
 | 
			
		||||
  for(int i = 0; i < this->maxTextures; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    Texture * tex = &this->texture[i];
 | 
			
		||||
    if (!tex->pp.data)
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    PostProcessInstance * inst;
 | 
			
		||||
    vector_forEachRef(inst, &tex->pp)
 | 
			
		||||
    {
 | 
			
		||||
      inst->pp->free(inst->opaque);
 | 
			
		||||
      if (i == this->maxTextures - 1)
 | 
			
		||||
        inst->pp->finish();
 | 
			
		||||
    }
 | 
			
		||||
    vector_destroy(&tex->pp);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct CaptureInterface Capture_DXGI =
 | 
			
		||||
{
 | 
			
		||||
  .shortName       = "DXGI",
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@
 | 
			
		||||
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "pp.h"
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <dxgi.h>
 | 
			
		||||
#include <dxgi1_2.h>
 | 
			
		||||
@@ -28,6 +30,7 @@
 | 
			
		||||
#include "common/event.h"
 | 
			
		||||
#include "common/locking.h"
 | 
			
		||||
#include "common/types.h"
 | 
			
		||||
#include "common/vector.h"
 | 
			
		||||
#include "interface/capture.h"
 | 
			
		||||
 | 
			
		||||
enum TextureState
 | 
			
		||||
@@ -47,8 +50,9 @@ typedef struct Texture
 | 
			
		||||
  FrameDamageRect            damageRects[KVMFR_MAX_DAMAGE_RECTS];
 | 
			
		||||
  int32_t                    texDamageCount;
 | 
			
		||||
  FrameDamageRect            texDamageRects[KVMFR_MAX_DAMAGE_RECTS];
 | 
			
		||||
  ID3D11RenderTargetView  ** renderTarget;
 | 
			
		||||
  ID3D11Texture2D         ** hdrTex;
 | 
			
		||||
 | 
			
		||||
  // post processing
 | 
			
		||||
  Vector                     pp;
 | 
			
		||||
 | 
			
		||||
  void                     * impl;
 | 
			
		||||
}
 | 
			
		||||
@@ -89,13 +93,7 @@ struct DXGIInterface
 | 
			
		||||
  bool                       needsRelease;
 | 
			
		||||
  DXGI_FORMAT                dxgiSrcFormat, dxgiFormat;
 | 
			
		||||
  bool                       hdr;
 | 
			
		||||
  DISPLAYCONFIG_PATH_INFO    displayPathInfo;
 | 
			
		||||
  DXGI_COLOR_SPACE_TYPE      dxgiColorSpace;
 | 
			
		||||
  float                      sdrWhiteLevel;
 | 
			
		||||
  ID3D11Buffer            ** constBuffer;
 | 
			
		||||
  ID3D11PixelShader       ** pixelShader;
 | 
			
		||||
  ID3D11VertexShader      ** vertexShader;
 | 
			
		||||
  ID3D11SamplerState      ** samplerState;
 | 
			
		||||
  struct DXGICopyBackend   * backend;
 | 
			
		||||
 | 
			
		||||
  CaptureGetPointerBuffer    getPointerBufferFn;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								host/platform/Windows/capture/DXGI/src/pp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								host/platform/Windows/capture/DXGI/src/pp.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Looking Glass
 | 
			
		||||
 * Copyright © 2017-2023 The Looking Glass Authors
 | 
			
		||||
 * https://looking-glass.io
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the Free
 | 
			
		||||
 * Software Foundation; either version 2 of the License, or (at your option)
 | 
			
		||||
 * any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
			
		||||
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc., 59
 | 
			
		||||
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <d3d11.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  /* the friendly name of the processor for debugging */
 | 
			
		||||
  const char * name;
 | 
			
		||||
 | 
			
		||||
  /* early initialization for registering options */
 | 
			
		||||
  void (*earlyInit)(void);
 | 
			
		||||
 | 
			
		||||
  /* common setup */
 | 
			
		||||
  bool (*setup)(
 | 
			
		||||
    ID3D11Device        ** device,
 | 
			
		||||
    ID3D11DeviceContext ** context,
 | 
			
		||||
    IDXGIOutput         ** output);
 | 
			
		||||
 | 
			
		||||
  /* instance initialization */
 | 
			
		||||
  bool (*init)(
 | 
			
		||||
    void ** opaque,
 | 
			
		||||
    int     width,
 | 
			
		||||
    int     height,
 | 
			
		||||
    bool    shareable);
 | 
			
		||||
 | 
			
		||||
  /* perform the processing */
 | 
			
		||||
  ID3D11Texture2D * (*run)(void * opaque, ID3D11Texture2D * src);
 | 
			
		||||
 | 
			
		||||
  /* instance destruction */
 | 
			
		||||
  void (*free)(void * opaque);
 | 
			
		||||
 | 
			
		||||
  /* cleanup */
 | 
			
		||||
  void (*finish)(void);
 | 
			
		||||
}
 | 
			
		||||
DXGIPostProcess;
 | 
			
		||||
							
								
								
									
										377
									
								
								host/platform/Windows/capture/DXGI/src/pp/sdrwhitelevel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										377
									
								
								host/platform/Windows/capture/DXGI/src/pp/sdrwhitelevel.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,377 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Looking Glass
 | 
			
		||||
 * Copyright © 2017-2023 The Looking Glass Authors
 | 
			
		||||
 * https://looking-glass.io
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the Free
 | 
			
		||||
 * Software Foundation; either version 2 of the License, or (at your option)
 | 
			
		||||
 * any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
			
		||||
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along
 | 
			
		||||
 * with this program; if not, write to the Free Software Foundation, Inc., 59
 | 
			
		||||
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "pp.h"
 | 
			
		||||
#include "com_ref.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
#include "common/debug.h"
 | 
			
		||||
#include "common/windebug.h"
 | 
			
		||||
 | 
			
		||||
#include <dxgi1_6.h>
 | 
			
		||||
 | 
			
		||||
typedef struct SDRWhiteLevel
 | 
			
		||||
{
 | 
			
		||||
  ID3D11Device        ** device;
 | 
			
		||||
  ID3D11DeviceContext ** context;
 | 
			
		||||
 | 
			
		||||
  ID3D11VertexShader  ** vshader;
 | 
			
		||||
  ID3D11PixelShader   ** pshader;
 | 
			
		||||
  ID3D11SamplerState  ** sampler;
 | 
			
		||||
  ID3D11Buffer        ** buffer;
 | 
			
		||||
 | 
			
		||||
  DISPLAYCONFIG_PATH_INFO displayPathInfo;
 | 
			
		||||
  float sdrWhiteLevel;
 | 
			
		||||
}
 | 
			
		||||
SDRWhiteLevel;
 | 
			
		||||
SDRWhiteLevel this = {0};
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  ID3D11Texture2D        ** tex;
 | 
			
		||||
  ID3D11RenderTargetView ** target;
 | 
			
		||||
}
 | 
			
		||||
SDRWhiteLevelInst;
 | 
			
		||||
 | 
			
		||||
struct ShaderConsts
 | 
			
		||||
{
 | 
			
		||||
  float sdrWhiteLevel;
 | 
			
		||||
}
 | 
			
		||||
__attribute__((aligned(16)));
 | 
			
		||||
 | 
			
		||||
static const char * vshader =
 | 
			
		||||
  "void main(\n"
 | 
			
		||||
  "  in  uint   vertexID : SV_VERTEXID,\n"
 | 
			
		||||
  "  out float4 position : SV_POSITION,\n"
 | 
			
		||||
  "  out float2 texCoord : TEXCOORD0)\n"
 | 
			
		||||
  "{\n"
 | 
			
		||||
  "  float2 positions[4] =\n"
 | 
			
		||||
  "  {\n"
 | 
			
		||||
  "    float2(-1.0,  1.0),\n"
 | 
			
		||||
  "    float2( 1.0,  1.0),\n"
 | 
			
		||||
  "    float2(-1.0, -1.0),\n"
 | 
			
		||||
  "    float2( 1.0, -1.0)\n"
 | 
			
		||||
  "  };\n"
 | 
			
		||||
  "\n"
 | 
			
		||||
  "  float2 texCoords[4] =\n"
 | 
			
		||||
  "  {\n"
 | 
			
		||||
  "    float2(0.0, 0.0),\n"
 | 
			
		||||
  "    float2(1.0, 0.0),\n"
 | 
			
		||||
  "    float2(0.0, 1.0),\n"
 | 
			
		||||
  "    float2(1.0, 1.0)\n"
 | 
			
		||||
  "  };\n"
 | 
			
		||||
  "\n"
 | 
			
		||||
  "  position = float4(positions[vertexID], 0.0, 1.0);\n"
 | 
			
		||||
  "  texCoord = texCoords[vertexID];\n"
 | 
			
		||||
  "}";
 | 
			
		||||
 | 
			
		||||
static const char * pshader =
 | 
			
		||||
  "Texture2D    gInputTexture : register(t0);\n"
 | 
			
		||||
  "SamplerState gSamplerState : register(s0);\n"
 | 
			
		||||
  "cbuffer      gConsts       : register(b0)\n"
 | 
			
		||||
  "{\n"
 | 
			
		||||
  "  float SDRWhiteLevel;"
 | 
			
		||||
  "};\n"
 | 
			
		||||
  "\n"
 | 
			
		||||
  "float4 main(\n"
 | 
			
		||||
  "  float4 position : SV_POSITION,\n"
 | 
			
		||||
  "  float2 texCoord : TEXCOORD0) : SV_TARGET"
 | 
			
		||||
  "{\n"
 | 
			
		||||
  "  float4 color = gInputTexture.Sample(gSamplerState, texCoord);\n"
 | 
			
		||||
  "  color.rgb   *= SDRWhiteLevel;\n"
 | 
			
		||||
  "  return color;\n"
 | 
			
		||||
  "}\n";
 | 
			
		||||
 | 
			
		||||
static void updateConsts(void);
 | 
			
		||||
 | 
			
		||||
static bool sdrWhiteLevel_setup(
 | 
			
		||||
  ID3D11Device        ** device,
 | 
			
		||||
  ID3D11DeviceContext ** context,
 | 
			
		||||
  IDXGIOutput         ** output
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
  bool result = false;
 | 
			
		||||
  comRef_scopePush();
 | 
			
		||||
  HRESULT status;
 | 
			
		||||
 | 
			
		||||
  this.device  = device;
 | 
			
		||||
  this.context = context;
 | 
			
		||||
 | 
			
		||||
  comRef_defineLocal(IDXGIOutput6, output6);
 | 
			
		||||
  status = IDXGIOutput_QueryInterface(
 | 
			
		||||
    *output, &IID_IDXGIOutput6, (void **)output6);
 | 
			
		||||
 | 
			
		||||
  if (!SUCCEEDED(status))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_ERROR("Failed to get the IDXGIOutput6 interface");
 | 
			
		||||
    goto exit;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DXGI_OUTPUT_DESC1 desc1;
 | 
			
		||||
  IDXGIOutput6_GetDesc1(*output6, &desc1);
 | 
			
		||||
  if (!getDisplayPathInfo(desc1.Monitor, &this.displayPathInfo))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_ERROR("Failed to get the display path info");
 | 
			
		||||
    goto exit;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // compile and create the vertex shader
 | 
			
		||||
  comRef_defineLocal(ID3DBlob, byteCode);
 | 
			
		||||
  if (!compileShader(byteCode, "main", "vs_5_0", vshader))
 | 
			
		||||
    goto exit;
 | 
			
		||||
 | 
			
		||||
  status = ID3D11Device_CreateVertexShader(
 | 
			
		||||
    *this.device,
 | 
			
		||||
    ID3D10Blob_GetBufferPointer(*byteCode),
 | 
			
		||||
    ID3D10Blob_GetBufferSize   (*byteCode),
 | 
			
		||||
    NULL,
 | 
			
		||||
    (ID3D11VertexShader **)comRef_newGlobal(&this.vshader));
 | 
			
		||||
 | 
			
		||||
  if (FAILED(status))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_WINERROR("Failed to create the vertex shader", status);
 | 
			
		||||
    goto exit;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  comRef_release(byteCode);
 | 
			
		||||
  if (!compileShader(byteCode, "main", "ps_5_0", pshader))
 | 
			
		||||
    goto exit;
 | 
			
		||||
 | 
			
		||||
  status = ID3D11Device_CreatePixelShader(
 | 
			
		||||
    *this.device,
 | 
			
		||||
    ID3D10Blob_GetBufferPointer(*byteCode),
 | 
			
		||||
    ID3D10Blob_GetBufferSize   (*byteCode),
 | 
			
		||||
    NULL,
 | 
			
		||||
    (ID3D11PixelShader **)comRef_newGlobal(&this.pshader));
 | 
			
		||||
 | 
			
		||||
  if (FAILED(status))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_WINERROR("Failed to create the pixel shader", status);
 | 
			
		||||
    goto exit;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const D3D11_SAMPLER_DESC samplerDesc =
 | 
			
		||||
  {
 | 
			
		||||
    .Filter         = D3D11_FILTER_MIN_MAG_MIP_LINEAR,
 | 
			
		||||
    .AddressU       = D3D11_TEXTURE_ADDRESS_WRAP,
 | 
			
		||||
    .AddressV       = D3D11_TEXTURE_ADDRESS_WRAP,
 | 
			
		||||
    .AddressW       = D3D11_TEXTURE_ADDRESS_WRAP,
 | 
			
		||||
    .ComparisonFunc = D3D11_COMPARISON_NEVER,
 | 
			
		||||
    .MinLOD         = 0,
 | 
			
		||||
    .MaxLOD         = D3D11_FLOAT32_MAX
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  status = ID3D11Device_CreateSamplerState(
 | 
			
		||||
    *this.device, &samplerDesc,
 | 
			
		||||
    (ID3D11SamplerState  **)comRef_newGlobal(&this.sampler));
 | 
			
		||||
 | 
			
		||||
  if (FAILED(status))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_WINERROR("Failed to create the sampler state", status);
 | 
			
		||||
    goto exit;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  D3D11_BUFFER_DESC bufferDesc =
 | 
			
		||||
  {
 | 
			
		||||
    .ByteWidth      = sizeof(struct ShaderConsts),
 | 
			
		||||
    .Usage          = D3D11_USAGE_DEFAULT,
 | 
			
		||||
    .BindFlags      = D3D11_BIND_CONSTANT_BUFFER,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  status = ID3D11Device_CreateBuffer(
 | 
			
		||||
    *this.device, &bufferDesc, NULL,
 | 
			
		||||
    (ID3D11Buffer **)comRef_newGlobal(&this.buffer));
 | 
			
		||||
 | 
			
		||||
  if (FAILED(status))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_WINERROR("Failed to create the constant buffer", status);
 | 
			
		||||
    goto exit;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  updateConsts();
 | 
			
		||||
  DEBUG_INFO("SDR White Level   : %f"   , this.sdrWhiteLevel);
 | 
			
		||||
 | 
			
		||||
  result = true;
 | 
			
		||||
 | 
			
		||||
exit:
 | 
			
		||||
  comRef_scopePop();
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sdrWhiteLevel_finish(void)
 | 
			
		||||
{
 | 
			
		||||
  memset(&this, 0, sizeof(this));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool sdrWhiteLevel_init(
 | 
			
		||||
  void ** opaque,
 | 
			
		||||
  int  width,
 | 
			
		||||
  int  height,
 | 
			
		||||
  bool shareable)
 | 
			
		||||
{
 | 
			
		||||
  SDRWhiteLevelInst * inst = (SDRWhiteLevelInst *)calloc(1, sizeof(*inst));
 | 
			
		||||
  if (!inst)
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_ERROR("Failed to allocate memory");
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  comRef_scopePush();
 | 
			
		||||
 | 
			
		||||
  // create the output texture
 | 
			
		||||
  D3D11_TEXTURE2D_DESC texDesc =
 | 
			
		||||
  {
 | 
			
		||||
    .Width              = width,
 | 
			
		||||
    .Height             = height,
 | 
			
		||||
    .MipLevels          = 1,
 | 
			
		||||
    .ArraySize          = 1,
 | 
			
		||||
    .SampleDesc.Count   = 1,
 | 
			
		||||
    .SampleDesc.Quality = 0,
 | 
			
		||||
    .Usage              = D3D11_USAGE_DEFAULT,
 | 
			
		||||
    .Format             = DXGI_FORMAT_R10G10B10A2_UNORM,
 | 
			
		||||
    .BindFlags          = D3D11_BIND_RENDER_TARGET |
 | 
			
		||||
                          D3D11_BIND_SHADER_RESOURCE,
 | 
			
		||||
    .CPUAccessFlags     = 0,
 | 
			
		||||
    .MiscFlags          = 0
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // allow texture sharing with other backends
 | 
			
		||||
  if (shareable)
 | 
			
		||||
    texDesc.MiscFlags |=
 | 
			
		||||
      D3D11_RESOURCE_MISC_SHARED |
 | 
			
		||||
      D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
 | 
			
		||||
 | 
			
		||||
  comRef_defineLocal(ID3D11Texture2D, tex);
 | 
			
		||||
  HRESULT status = ID3D11Device_CreateTexture2D(
 | 
			
		||||
    *this.device, &texDesc, NULL, tex);
 | 
			
		||||
 | 
			
		||||
  if (FAILED(status))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_WINERROR("Failed to create the output texture", status);
 | 
			
		||||
    goto fail;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  comRef_defineLocal(ID3D11RenderTargetView, target);
 | 
			
		||||
  status = ID3D11Device_CreateRenderTargetView(
 | 
			
		||||
    *this.device, *(ID3D11Resource **)tex, NULL, target);
 | 
			
		||||
 | 
			
		||||
  if (FAILED(status))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_WINERROR("Failed to create the render target view", status);
 | 
			
		||||
    goto fail;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  *opaque = inst;
 | 
			
		||||
  comRef_toGlobal(inst->tex   , tex   );
 | 
			
		||||
  comRef_toGlobal(inst->target, target);
 | 
			
		||||
 | 
			
		||||
  comRef_scopePop();
 | 
			
		||||
  return true;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
  comRef_scopePop();
 | 
			
		||||
  free(inst);
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sdrWhiteLevel_free(void * opaque)
 | 
			
		||||
{
 | 
			
		||||
  SDRWhiteLevelInst * inst = (SDRWhiteLevelInst *)opaque;
 | 
			
		||||
  comRef_release(inst->target);
 | 
			
		||||
  comRef_release(inst->tex   );
 | 
			
		||||
  free(inst);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void updateConsts(void)
 | 
			
		||||
{
 | 
			
		||||
  float nits = getSDRWhiteLevel(&this.displayPathInfo);
 | 
			
		||||
  if (nits == this.sdrWhiteLevel)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  this.sdrWhiteLevel = nits;
 | 
			
		||||
 | 
			
		||||
  struct ShaderConsts consts = { .sdrWhiteLevel = 80.0f / nits };
 | 
			
		||||
  ID3D11DeviceContext_UpdateSubresource(
 | 
			
		||||
    *this.context, *(ID3D11Resource**)this.buffer,
 | 
			
		||||
    0, NULL, &consts, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ID3D11Texture2D * sdrWhiteLevel_run(void * opaque, ID3D11Texture2D * src)
 | 
			
		||||
{
 | 
			
		||||
  comRef_scopePush();
 | 
			
		||||
  ID3D11Texture2D * result = NULL;
 | 
			
		||||
  SDRWhiteLevelInst * inst = (SDRWhiteLevelInst *)opaque;
 | 
			
		||||
  HRESULT status;
 | 
			
		||||
 | 
			
		||||
  updateConsts();
 | 
			
		||||
 | 
			
		||||
  // setup the pixel shader input resource view
 | 
			
		||||
  comRef_defineLocal(ID3D11ShaderResourceView, inputSRV);
 | 
			
		||||
  D3D11_TEXTURE2D_DESC desc;
 | 
			
		||||
  ID3D11Texture2D_GetDesc(src, &desc);
 | 
			
		||||
 | 
			
		||||
  const D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc =
 | 
			
		||||
  {
 | 
			
		||||
    .Format              = desc.Format,
 | 
			
		||||
    .ViewDimension       = D3D11_SRV_DIMENSION_TEXTURE2D,
 | 
			
		||||
    .Texture2D.MipLevels = 1
 | 
			
		||||
  };
 | 
			
		||||
  status = ID3D11Device_CreateShaderResourceView(
 | 
			
		||||
    *this.device, (ID3D11Resource *)src, &srvDesc, inputSRV);
 | 
			
		||||
  if (FAILED(status))
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_WINERROR("Failed to create the source resource view", status);
 | 
			
		||||
    goto exit;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // set the vertex and pixel shader
 | 
			
		||||
  ID3D11DeviceContext_VSSetShader(*this.context, *this.vshader, NULL, 0);
 | 
			
		||||
  ID3D11DeviceContext_PSSetShader(*this.context, *this.pshader, NULL, 0);
 | 
			
		||||
 | 
			
		||||
  // set the pixel shader resources
 | 
			
		||||
  ID3D11DeviceContext_PSSetShaderResources(*this.context, 0, 1, inputSRV    );
 | 
			
		||||
  ID3D11DeviceContext_PSSetSamplers       (*this.context, 0, 1, this.sampler);
 | 
			
		||||
  ID3D11DeviceContext_PSSetConstantBuffers(*this.context, 0, 1, this.buffer );
 | 
			
		||||
 | 
			
		||||
  // set the render target
 | 
			
		||||
  ID3D11DeviceContext_OMSetRenderTargets(*this.context, 1, inst->target, NULL);
 | 
			
		||||
 | 
			
		||||
  ID3D11DeviceContext_IASetPrimitiveTopology(
 | 
			
		||||
    *this.context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
 | 
			
		||||
 | 
			
		||||
  ID3D11DeviceContext_Draw(*this.context, 4, 0);
 | 
			
		||||
 | 
			
		||||
  result = *inst->tex;
 | 
			
		||||
 | 
			
		||||
exit:
 | 
			
		||||
  comRef_scopePop();
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DXGIPostProcess DXGIPP_SDRWhiteLevel =
 | 
			
		||||
{
 | 
			
		||||
  .name      = "SDRWhiteLevel",
 | 
			
		||||
  .earlyInit = NULL,
 | 
			
		||||
  .setup     = sdrWhiteLevel_setup,
 | 
			
		||||
  .init      = sdrWhiteLevel_init,
 | 
			
		||||
  .free      = sdrWhiteLevel_free,
 | 
			
		||||
  .run       = sdrWhiteLevel_run,
 | 
			
		||||
  .finish    = sdrWhiteLevel_finish
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user