Rework dummy image handling to avoid RTX HDR driver bug

As a side effect, it avoids useless allocations and uploads of
a zeroed memory buffer to clear the dummy image textures.
This commit is contained in:
Cameron Gutman
2024-02-24 14:18:15 -06:00
parent e430f51e2f
commit 75a97883e7
+13 -18
View File
@@ -125,6 +125,9 @@ namespace platf::dxgi {
// the first successful capture of a desktop frame // the first successful capture of a desktop frame
bool dummy = false; bool dummy = false;
// Set to true if the image is blank (contains no content at all, including a cursor)
bool blank = true;
// Unique identifier for this image // Unique identifier for this image
uint32_t id = 0; uint32_t id = 0;
@@ -382,6 +385,7 @@ namespace platf::dxgi {
} }
auto &img = (img_d3d_t &) img_base; auto &img = (img_d3d_t &) img_base;
if (!img.blank) {
auto &img_ctx = img_ctx_map[img.id]; auto &img_ctx = img_ctx_map[img.id];
// Open the shared capture texture with our ID3D11Device // Open the shared capture texture with our ID3D11Device
@@ -414,6 +418,7 @@ namespace platf::dxgi {
ID3D11ShaderResourceView *emptyShaderResourceView = nullptr; ID3D11ShaderResourceView *emptyShaderResourceView = nullptr;
device_ctx->PSSetShaderResources(0, 1, &emptyShaderResourceView); device_ctx->PSSetShaderResources(0, 1, &emptyShaderResourceView);
}
return 0; return 0;
} }
@@ -1144,6 +1149,9 @@ namespace platf::dxgi {
return { nullptr, nullptr }; return { nullptr, nullptr };
} }
// Clear the blank flag now that we're ready to capture into the image
d3d_img->blank = false;
return { std::move(d3d_img), std::move(lock_helper) }; return { std::move(d3d_img), std::move(lock_helper) };
}; };
@@ -1289,15 +1297,14 @@ namespace platf::dxgi {
// Clear the image if it has been used as a dummy. // Clear the image if it has been used as a dummy.
// It can have the mouse cursor blended onto it. // It can have the mouse cursor blended onto it.
auto old_d3d_img = (img_d3d_t *) img_out.get(); auto old_d3d_img = (img_d3d_t *) img_out.get();
bool reclear_dummy = old_d3d_img->dummy && old_d3d_img->capture_texture; bool reclear_dummy = !old_d3d_img->blank && old_d3d_img->capture_texture;
auto [d3d_img, lock] = get_locked_d3d_img(img_out, true); auto [d3d_img, lock] = get_locked_d3d_img(img_out, true);
if (!d3d_img) return capture_e::error; if (!d3d_img) return capture_e::error;
if (reclear_dummy) { if (reclear_dummy) {
auto dummy_data = std::make_unique<std::uint8_t[]>(d3d_img->row_pitch * d3d_img->height); const float rgb_black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
std::fill_n(dummy_data.get(), d3d_img->row_pitch * d3d_img->height, 0); device_ctx->ClearRenderTargetView(d3d_img->capture_rt.get(), rgb_black);
device_ctx->UpdateSubresource(d3d_img->capture_texture.get(), 0, nullptr, dummy_data.get(), d3d_img->row_pitch, 0);
} }
if (blend_mouse_cursor_flag) { if (blend_mouse_cursor_flag) {
@@ -1409,6 +1416,7 @@ namespace platf::dxgi {
img->width = width_before_rotation; img->width = width_before_rotation;
img->height = height_before_rotation; img->height = height_before_rotation;
img->id = next_image_id++; img->id = next_image_id++;
img->blank = true;
return img; return img;
} }
@@ -1456,20 +1464,7 @@ namespace platf::dxgi {
t.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; t.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
t.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; t.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
HRESULT status; auto status = device->CreateTexture2D(&t, nullptr, &img->capture_texture);
if (dummy) {
auto dummy_data = std::make_unique<std::uint8_t[]>(img->row_pitch * img->height);
std::fill_n(dummy_data.get(), img->row_pitch * img->height, 0);
D3D11_SUBRESOURCE_DATA initial_data {
dummy_data.get(),
(UINT) img->row_pitch,
0
};
status = device->CreateTexture2D(&t, &initial_data, &img->capture_texture);
}
else {
status = device->CreateTexture2D(&t, nullptr, &img->capture_texture);
}
if (FAILED(status)) { if (FAILED(status)) {
BOOST_LOG(error) << "Failed to create img buf texture [0x"sv << util::hex(status).to_string_view() << ']'; BOOST_LOG(error) << "Failed to create img buf texture [0x"sv << util::hex(status).to_string_view() << ']';
return -1; return -1;