summaryrefslogtreecommitdiffstats
path: root/src/amd/vulkan/radv_meta_clear.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/amd/vulkan/radv_meta_clear.c')
-rw-r--r--src/amd/vulkan/radv_meta_clear.c96
1 files changed, 89 insertions, 7 deletions
diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c
index 4f77e32b83f..0ae7191f17d 100644
--- a/src/amd/vulkan/radv_meta_clear.c
+++ b/src/amd/vulkan/radv_meta_clear.c
@@ -200,7 +200,13 @@ create_color_renderpass(struct radv_device *device,
uint32_t samples,
VkRenderPass *pass)
{
- return radv_CreateRenderPass(radv_device_to_handle(device),
+ mtx_lock(&device->meta_state.mtx);
+ if (*pass) {
+ mtx_unlock (&device->meta_state.mtx);
+ return VK_SUCCESS;
+ }
+
+ VkResult result = radv_CreateRenderPass(radv_device_to_handle(device),
&(VkRenderPassCreateInfo) {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.attachmentCount = 1,
@@ -231,6 +237,8 @@ create_color_renderpass(struct radv_device *device,
},
.dependencyCount = 0,
}, &device->meta_state.alloc, pass);
+ mtx_unlock(&device->meta_state.mtx);
+ return result;
}
static VkResult
@@ -243,6 +251,13 @@ create_color_pipeline(struct radv_device *device,
struct nir_shader *vs_nir;
struct nir_shader *fs_nir;
VkResult result;
+
+ mtx_lock(&device->meta_state.mtx);
+ if (*pipeline) {
+ mtx_unlock(&device->meta_state.mtx);
+ return VK_SUCCESS;
+ }
+
build_color_shaders(&vs_nir, &fs_nir, frag_output);
const VkPipelineVertexInputStateCreateInfo vi_state = {
@@ -284,6 +299,7 @@ create_color_pipeline(struct radv_device *device,
device->meta_state.clear_color_p_layout,
&extra, &device->meta_state.alloc, pipeline);
+ mtx_unlock(&device->meta_state.mtx);
return result;
}
@@ -349,6 +365,26 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
return;
}
+ if (device->meta_state.clear[samples_log2].render_pass[fs_key] == VK_NULL_HANDLE) {
+ VkResult ret = create_color_renderpass(device, radv_fs_key_format_exemplars[fs_key],
+ samples,
+ &device->meta_state.clear[samples_log2].render_pass[fs_key]);
+ if (ret != VK_SUCCESS) {
+ cmd_buffer->record_result = ret;
+ return;
+ }
+ }
+
+ if (device->meta_state.clear[samples_log2].color_pipelines[fs_key] == VK_NULL_HANDLE) {
+ VkResult ret = create_color_pipeline(device, samples, 0,
+ &device->meta_state.clear[samples_log2].color_pipelines[fs_key],
+ device->meta_state.clear[samples_log2].render_pass[fs_key]);
+ if (ret != VK_SUCCESS) {
+ cmd_buffer->record_result = ret;
+ return;
+ }
+ }
+
pipeline = device->meta_state.clear[samples_log2].color_pipelines[fs_key];
if (!pipeline) {
radv_finishme("color clears incomplete");
@@ -449,7 +485,13 @@ create_depthstencil_renderpass(struct radv_device *device,
uint32_t samples,
VkRenderPass *render_pass)
{
- return radv_CreateRenderPass(radv_device_to_handle(device),
+ mtx_lock(&device->meta_state.mtx);
+ if (*render_pass) {
+ mtx_unlock(&device->meta_state.mtx);
+ return VK_SUCCESS;
+ }
+
+ VkResult result = radv_CreateRenderPass(radv_device_to_handle(device),
&(VkRenderPassCreateInfo) {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.attachmentCount = 1,
@@ -477,6 +519,8 @@ create_depthstencil_renderpass(struct radv_device *device,
},
.dependencyCount = 0,
}, &device->meta_state.alloc, render_pass);
+ mtx_unlock(&device->meta_state.mtx);
+ return result;
}
static VkResult
@@ -489,6 +533,13 @@ create_depthstencil_pipeline(struct radv_device *device,
{
struct nir_shader *vs_nir, *fs_nir;
VkResult result;
+
+ mtx_lock(&device->meta_state.mtx);
+ if (*pipeline) {
+ mtx_unlock(&device->meta_state.mtx);
+ return VK_SUCCESS;
+ }
+
build_depthstencil_shader(&vs_nir, &fs_nir);
const VkPipelineVertexInputStateCreateInfo vi_state = {
@@ -536,6 +587,8 @@ create_depthstencil_pipeline(struct radv_device *device,
samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state,
device->meta_state.clear_depth_p_layout,
&extra, &device->meta_state.alloc, pipeline);
+
+ mtx_unlock(&device->meta_state.mtx);
return result;
}
@@ -579,6 +632,7 @@ pick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer,
{
bool fast = depth_view_can_fast_clear(cmd_buffer, iview, aspects, layout, clear_rect, clear_value);
int index = DEPTH_CLEAR_SLOW;
+ VkPipeline *pipeline;
if (fast) {
/* we don't know the previous clear values, so we always have
@@ -588,13 +642,36 @@ pick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer,
switch (aspects) {
case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
- return meta_state->clear[samples_log2].depthstencil_pipeline[index];
+ pipeline = &meta_state->clear[samples_log2].depthstencil_pipeline[index];
+ break;
case VK_IMAGE_ASPECT_DEPTH_BIT:
- return meta_state->clear[samples_log2].depth_only_pipeline[index];
+ pipeline = &meta_state->clear[samples_log2].depth_only_pipeline[index];
+ break;
case VK_IMAGE_ASPECT_STENCIL_BIT:
- return meta_state->clear[samples_log2].stencil_only_pipeline[index];
+ pipeline = &meta_state->clear[samples_log2].stencil_only_pipeline[index];
+ break;
+ default:
+ unreachable("expected depth or stencil aspect");
+ }
+
+ if (cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp == VK_NULL_HANDLE) {
+ VkResult ret = create_depthstencil_renderpass(cmd_buffer->device, 1u << samples_log2,
+ &cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp);
+ if (ret != VK_SUCCESS) {
+ cmd_buffer->record_result = ret;
+ return VK_NULL_HANDLE;
+ }
}
- unreachable("expected depth or stencil aspect");
+
+ if (*pipeline == VK_NULL_HANDLE) {
+ VkResult ret = create_depthstencil_pipeline(cmd_buffer->device, aspects, 1u << samples_log2, index,
+ pipeline, cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp);
+ if (ret != VK_SUCCESS) {
+ cmd_buffer->record_result = ret;
+ return VK_NULL_HANDLE;
+ }
+ }
+ return *pipeline;
}
static void
@@ -638,6 +715,8 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
subpass->depth_stencil_attachment.layout,
clear_rect,
clear_value);
+ if (!pipeline)
+ return;
radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline);
@@ -758,7 +837,7 @@ fail:
}
VkResult
-radv_device_init_meta_clear_state(struct radv_device *device)
+radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand)
{
VkResult res;
struct radv_meta_state *state = &device->meta_state;
@@ -791,6 +870,9 @@ radv_device_init_meta_clear_state(struct radv_device *device)
if (res != VK_SUCCESS)
goto fail;
+ if (on_demand)
+ return VK_SUCCESS;
+
for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) {
uint32_t samples = 1 << i;
for (uint32_t j = 0; j < NUM_META_FS_KEYS; ++j) {