BLIT2D_NUM_SRC_TYPES,
};
+static VkResult
+blit2d_init_color_pipeline(struct radv_device *device,
+ enum blit2d_src_type src_type,
+ VkFormat format,
+ uint32_t log2_samples);
+
+static VkResult
+blit2d_init_depth_only_pipeline(struct radv_device *device,
+ enum blit2d_src_type src_type,
+ uint32_t log2_samples);
+
+static VkResult
+blit2d_init_stencil_only_pipeline(struct radv_device *device,
+ enum blit2d_src_type src_type,
+ uint32_t log2_samples);
+
static void
create_iview(struct radv_cmd_buffer *cmd_buffer,
struct radv_meta_blit2d_surf *surf,
.baseArrayLayer = surf->layer,
.layerCount = 1
},
- });
+ }, NULL);
}
static void
unsigned i;
for_each_bit(i, dst->aspect_mask) {
unsigned aspect_mask = 1u << i;
+ unsigned src_aspect_mask = aspect_mask;
VkFormat depth_format = 0;
if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
depth_format = vk_format_stencil_only(dst->image->vk_format);
else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
depth_format = vk_format_depth_only(dst->image->vk_format);
+ else if (src_img)
+ src_aspect_mask = src_img->aspect_mask;
+
struct blit2d_src_temps src_temps;
- blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format, aspect_mask, log2_samples);
+ blit2d_bind_src(cmd_buffer, src_img, src_buf, &src_temps, src_type, depth_format, src_aspect_mask, log2_samples);
struct blit2d_dst_temps dst_temps;
blit2d_bind_dst(cmd_buffer, dst, rects[r].dst_x + rects[r].width,
VK_SHADER_STAGE_VERTEX_BIT, 0, 16,
vertex_push_constants);
- if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
+ if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT ||
+ aspect_mask == VK_IMAGE_ASPECT_PLANE_0_BIT ||
+ aspect_mask == VK_IMAGE_ASPECT_PLANE_1_BIT ||
+ aspect_mask == VK_IMAGE_ASPECT_PLANE_2_BIT) {
unsigned fs_key = radv_format_meta_fs_key(dst_temps.iview.vk_format);
unsigned dst_layout = radv_meta_dst_layout_from_layout(dst->current_layout);
- radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer),
- &(VkRenderPassBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+ if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key] == VK_NULL_HANDLE) {
+ VkResult ret = blit2d_init_color_pipeline(device, src_type, radv_fs_key_format_exemplars[fs_key], log2_samples);
+ if (ret != VK_SUCCESS) {
+ cmd_buffer->record_result = ret;
+ goto fail_pipeline;
+ }
+ }
+
+ radv_cmd_buffer_begin_render_pass(cmd_buffer,
+ &(VkRenderPassBeginInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = device->meta_state.blit2d_render_passes[fs_key][dst_layout],
.framebuffer = dst_temps.fb,
.renderArea = {
- .offset = { rects[r].dst_x, rects[r].dst_y, },
- .extent = { rects[r].width, rects[r].height },
- },
+ .offset = { rects[r].dst_x, rects[r].dst_y, },
+ .extent = { rects[r].width, rects[r].height },
+ },
.clearValueCount = 0,
- .pClearValues = NULL,
- }, VK_SUBPASS_CONTENTS_INLINE);
+ .pClearValues = NULL,
+ });
+ radv_cmd_buffer_set_subpass(cmd_buffer,
+ &cmd_buffer->state.pass->subpasses[0]);
bind_pipeline(cmd_buffer, src_type, fs_key, log2_samples);
} else if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dst->current_layout);
- radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer),
- &(VkRenderPassBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+
+ if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type] == VK_NULL_HANDLE) {
+ VkResult ret = blit2d_init_depth_only_pipeline(device, src_type, log2_samples);
+ if (ret != VK_SUCCESS) {
+ cmd_buffer->record_result = ret;
+ goto fail_pipeline;
+ }
+ }
+
+ radv_cmd_buffer_begin_render_pass(cmd_buffer,
+ &(VkRenderPassBeginInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = device->meta_state.blit2d_depth_only_rp[ds_layout],
.framebuffer = dst_temps.fb,
.renderArea = {
- .offset = { rects[r].dst_x, rects[r].dst_y, },
- .extent = { rects[r].width, rects[r].height },
- },
+ .offset = { rects[r].dst_x, rects[r].dst_y, },
+ .extent = { rects[r].width, rects[r].height },
+ },
.clearValueCount = 0,
- .pClearValues = NULL,
- }, VK_SUBPASS_CONTENTS_INLINE);
+ .pClearValues = NULL,
+ });
+ radv_cmd_buffer_set_subpass(cmd_buffer,
+ &cmd_buffer->state.pass->subpasses[0]);
bind_depth_pipeline(cmd_buffer, src_type, log2_samples);
} else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
enum radv_blit_ds_layout ds_layout = radv_meta_blit_ds_to_type(dst->current_layout);
- radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer),
- &(VkRenderPassBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+
+ if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type] == VK_NULL_HANDLE) {
+ VkResult ret = blit2d_init_stencil_only_pipeline(device, src_type, log2_samples);
+ if (ret != VK_SUCCESS) {
+ cmd_buffer->record_result = ret;
+ goto fail_pipeline;
+ }
+ }
+
+ radv_cmd_buffer_begin_render_pass(cmd_buffer,
+ &(VkRenderPassBeginInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = device->meta_state.blit2d_stencil_only_rp[ds_layout],
.framebuffer = dst_temps.fb,
.renderArea = {
- .offset = { rects[r].dst_x, rects[r].dst_y, },
- .extent = { rects[r].width, rects[r].height },
- },
+ .offset = { rects[r].dst_x, rects[r].dst_y, },
+ .extent = { rects[r].width, rects[r].height },
+ },
.clearValueCount = 0,
- .pClearValues = NULL,
- }, VK_SUBPASS_CONTENTS_INLINE);
+ .pClearValues = NULL,
+ });
+ radv_cmd_buffer_set_subpass(cmd_buffer,
+ &cmd_buffer->state.pass->subpasses[0]);
bind_stencil_pipeline(cmd_buffer, src_type, log2_samples);
} else
- if (log2_samples > 0) {
- for (uint32_t sample = 0; sample < src_img->image->info.samples; sample++) {
- uint32_t sample_mask = 1 << sample;
- radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
- device->meta_state.blit2d[log2_samples].p_layouts[src_type],
- VK_SHADER_STAGE_FRAGMENT_BIT, 20, 4,
- &sample);
-
- radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer),
- device->meta_state.blit2d[log2_samples].p_layouts[src_type],
- VK_SHADER_STAGE_FRAGMENT_BIT, 24, 4,
- &sample_mask);
-
- radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
- }
- }
- else
- radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
- radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer));
+ radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
+ radv_cmd_buffer_end_render_pass(cmd_buffer);
+fail_pipeline:
/* At the point where we emit the draw call, all data from the
* descriptor sets, etc. has been used. We are free to delete it.
*/
tex_pos_3d = nir_vec(b, chans, 3);
}
if (is_multisampled) {
- sample_idx = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_push_constant);
- nir_intrinsic_set_base(sample_idx, 20);
- nir_intrinsic_set_range(sample_idx, 4);
- sample_idx->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
+ sample_idx = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_sample_id);
sample_idx->num_components = 1;
nir_ssa_dest_init(&sample_idx->instr, &sample_idx->dest, 1, 32, "sample_idx");
nir_builder_instr_insert(b, &sample_idx->instr);
nir_ssa_def *pos_y = nir_channel(b, tex_pos, 1);
pos_y = nir_imul(b, pos_y, &width->dest.ssa);
pos_x = nir_iadd(b, pos_x, pos_y);
- //pos_x = nir_iadd(b, pos_x, nir_imm_int(b, 100000));
nir_ssa_def *tex_deref = &nir_build_deref_var(b, sampler)->dest.ssa;
.vertexAttributeDescriptionCount = 0,
};
-static void
-build_nir_store_sample_mask(struct nir_builder *b)
-{
- nir_intrinsic_instr *sample_mask = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_push_constant);
- nir_intrinsic_set_base(sample_mask, 24);
- nir_intrinsic_set_range(sample_mask, 4);
- sample_mask->src[0] = nir_src_for_ssa(nir_imm_int(b, 0));
- sample_mask->num_components = 1;
- nir_ssa_dest_init(&sample_mask->instr, &sample_mask->dest, 1, 32, "sample_mask");
- nir_builder_instr_insert(b, &sample_mask->instr);
-
- const struct glsl_type *sample_mask_out_type = glsl_uint_type();
-
- nir_variable *sample_mask_out =
- nir_variable_create(b->shader, nir_var_shader_out,
- sample_mask_out_type, "sample_mask_out");
- sample_mask_out->data.location = FRAG_RESULT_SAMPLE_MASK;
-
- nir_store_var(b, sample_mask_out, &sample_mask->dest.ssa, 0x1);
-}
-
static nir_shader *
build_nir_copy_fragment_shader(struct radv_device *device,
texel_fetch_build_func txf_func, const char* name, bool is_3d,
vec4, "f_color");
color_out->data.location = FRAG_RESULT_DATA0;
- if (is_multisampled) {
- build_nir_store_sample_mask(&b);
- }
-
nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
vec4, "f_color");
color_out->data.location = FRAG_RESULT_DEPTH;
- if (is_multisampled) {
- build_nir_store_sample_mask(&b);
- }
-
nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
vec4, "f_color");
color_out->data.location = FRAG_RESULT_STENCIL;
- if (is_multisampled) {
- build_nir_store_sample_mask(&b);
- }
-
nir_ssa_def *pos_int = nir_f2i32(&b, nir_load_var(&b, tex_pos_in));
nir_ssa_def *tex_pos = nir_channels(&b, pos_int, 0x3);
state->blit2d_stencil_only_rp[j], &state->alloc);
}
- for (unsigned log2_samples = 0; log2_samples < 1 + MAX_SAMPLES_LOG2; ++log2_samples) {
+ for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; ++log2_samples) {
for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
radv_DestroyPipelineLayout(radv_device_to_handle(device),
state->blit2d[log2_samples].p_layouts[src],
unsigned fs_key = radv_format_meta_fs_key(format);
const char *name;
+ mtx_lock(&device->meta_state.mtx);
+ if (device->meta_state.blit2d[log2_samples].pipelines[src_type][fs_key]) {
+ mtx_unlock(&device->meta_state.mtx);
+ return VK_SUCCESS;
+ }
+
texel_fetch_build_func src_func;
switch(src_type) {
case BLIT2D_SRC_TYPE_IMAGE:
.attachment = VK_ATTACHMENT_UNUSED,
.layout = layout,
},
- .preserveAttachmentCount = 1,
- .pPreserveAttachments = (uint32_t[]) { 0 },
+ .preserveAttachmentCount = 0,
+ .pPreserveAttachments = NULL,
+ },
+ .dependencyCount = 2,
+ .pDependencies = (VkSubpassDependency[]) {
+ {
+ .srcSubpass = VK_SUBPASS_EXTERNAL,
+ .dstSubpass = 0,
+ .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ .srcAccessMask = 0,
+ .dstAccessMask = 0,
+ .dependencyFlags = 0
+ },
+ {
+ .srcSubpass = 0,
+ .dstSubpass = VK_SUBPASS_EXTERNAL,
+ .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ .srcAccessMask = 0,
+ .dstAccessMask = 0,
+ .dependencyFlags = 0
+ }
},
- .dependencyCount = 0,
}, &device->meta_state.alloc, &device->meta_state.blit2d_render_passes[fs_key][dst_layout]);
}
}
.pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.rasterizationSamples = 1 << log2_samples,
- .sampleShadingEnable = false,
+ .sampleShadingEnable = log2_samples > 1,
+ .minSampleShading = 1.0,
.pSampleMask = (VkSampleMask[]) { UINT32_MAX },
},
.pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
ralloc_free(vs.nir);
ralloc_free(fs.nir);
+ mtx_unlock(&device->meta_state.mtx);
return result;
}
VkResult result;
const char *name;
+ mtx_lock(&device->meta_state.mtx);
+ if (device->meta_state.blit2d[log2_samples].depth_only_pipeline[src_type]) {
+ mtx_unlock(&device->meta_state.mtx);
+ return VK_SUCCESS;
+ }
+
texel_fetch_build_func src_func;
switch(src_type) {
case BLIT2D_SRC_TYPE_IMAGE:
.attachment = 0,
.layout = layout,
},
- .preserveAttachmentCount = 1,
- .pPreserveAttachments = (uint32_t[]) { 0 },
+ .preserveAttachmentCount = 0,
+ .pPreserveAttachments = NULL,
},
- .dependencyCount = 0,
+ .dependencyCount = 2,
+ .pDependencies = (VkSubpassDependency[]) {
+ {
+ .srcSubpass = VK_SUBPASS_EXTERNAL,
+ .dstSubpass = 0,
+ .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ .srcAccessMask = 0,
+ .dstAccessMask = 0,
+ .dependencyFlags = 0
+ },
+ {
+ .srcSubpass = 0,
+ .dstSubpass = VK_SUBPASS_EXTERNAL,
+ .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ .srcAccessMask = 0,
+ .dstAccessMask = 0,
+ .dependencyFlags = 0
+ }
+ },
}, &device->meta_state.alloc, &device->meta_state.blit2d_depth_only_rp[ds_layout]);
}
}
ralloc_free(vs.nir);
ralloc_free(fs.nir);
+ mtx_unlock(&device->meta_state.mtx);
return result;
}
VkResult result;
const char *name;
+ mtx_lock(&device->meta_state.mtx);
+ if (device->meta_state.blit2d[log2_samples].stencil_only_pipeline[src_type]) {
+ mtx_unlock(&device->meta_state.mtx);
+ return VK_SUCCESS;
+ }
+
texel_fetch_build_func src_func;
switch(src_type) {
case BLIT2D_SRC_TYPE_IMAGE:
.attachment = 0,
.layout = layout,
},
- .preserveAttachmentCount = 1,
- .pPreserveAttachments = (uint32_t[]) { 0 },
+ .preserveAttachmentCount = 0,
+ .pPreserveAttachments = NULL,
},
- .dependencyCount = 0,
+ .dependencyCount = 2,
+ .pDependencies = (VkSubpassDependency[]) {
+ {
+ .srcSubpass = VK_SUBPASS_EXTERNAL,
+ .dstSubpass = 0,
+ .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ .srcAccessMask = 0,
+ .dstAccessMask = 0,
+ .dependencyFlags = 0
+ },
+ {
+ .srcSubpass = 0,
+ .dstSubpass = VK_SUBPASS_EXTERNAL,
+ .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ .srcAccessMask = 0,
+ .dstAccessMask = 0,
+ .dependencyFlags = 0
+ }
+ },
}, &device->meta_state.alloc, &device->meta_state.blit2d_stencil_only_rp[ds_layout]);
}
}
ralloc_free(vs.nir);
ralloc_free(fs.nir);
+ mtx_unlock(&device->meta_state.mtx);
return result;
}
VkDescriptorType desc_type = (idx == BLIT2D_SRC_TYPE_BUFFER) ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
const VkPushConstantRange push_constant_ranges[] = {
{VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
- {VK_SHADER_STAGE_FRAGMENT_BIT, 16, 12},
+ {VK_SHADER_STAGE_FRAGMENT_BIT, 16, 4},
};
int num_push_constant_range = (idx != BLIT2D_SRC_TYPE_IMAGE || log2_samples > 0) ? 2 : 1;
}
VkResult
-radv_device_init_meta_blit2d_state(struct radv_device *device)
+radv_device_init_meta_blit2d_state(struct radv_device *device, bool on_demand)
{
VkResult result;
bool create_3d = device->physical_device->rad_info.chip_class >= GFX9;
- for (unsigned log2_samples = 0; log2_samples < 1 + MAX_SAMPLES_LOG2; log2_samples++) {
+ for (unsigned log2_samples = 0; log2_samples < MAX_SAMPLES_LOG2; log2_samples++) {
for (unsigned src = 0; src < BLIT2D_NUM_SRC_TYPES; src++) {
if (src == BLIT2D_SRC_TYPE_IMAGE_3D && !create_3d)
continue;
if (result != VK_SUCCESS)
goto fail;
+ if (on_demand)
+ continue;
+
for (unsigned j = 0; j < NUM_META_FS_KEYS; ++j) {
result = blit2d_init_color_pipeline(device, src, radv_fs_key_format_exemplars[j], log2_samples);
if (result != VK_SUCCESS)