}
static VkResult
-create_pass(struct radv_device *device)
+create_pass(struct radv_device *device, VkFormat vk_format, VkRenderPass *pass)
{
VkResult result;
VkDevice device_h = radv_device_to_handle(device);
int i;
for (i = 0; i < 2; i++) {
- attachments[i].format = VK_FORMAT_UNDEFINED;
+ attachments[i].format = vk_format;
attachments[i].samples = 1;
attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
.dependencyCount = 0,
},
alloc,
- &device->meta_state.resolve.pass);
+ pass);
return result;
}
static VkResult
create_pipeline(struct radv_device *device,
- VkShaderModule vs_module_h)
+ VkShaderModule vs_module_h,
+ VkPipeline *pipeline,
+ VkRenderPass pass)
{
VkResult result;
VkDevice device_h = radv_device_to_handle(device);
.pPushConstantRanges = NULL,
};
- result = radv_CreatePipelineLayout(radv_device_to_handle(device),
- &pl_create_info,
- &device->meta_state.alloc,
- &device->meta_state.resolve.p_layout);
- if (result != VK_SUCCESS)
- goto cleanup;
+ if (!device->meta_state.resolve.p_layout) {
+ result = radv_CreatePipelineLayout(radv_device_to_handle(device),
+ &pl_create_info,
+ &device->meta_state.alloc,
+ &device->meta_state.resolve.p_layout);
+ if (result != VK_SUCCESS)
+ goto cleanup;
+ }
result = radv_graphics_pipeline_create(device_h,
radv_pipeline_cache_to_handle(&device->meta_state.cache),
},
},
.layout = device->meta_state.resolve.p_layout,
- .renderPass = device->meta_state.resolve.pass,
+ .renderPass = pass,
.subpass = 0,
},
&(struct radv_graphics_pipeline_create_info) {
.use_rectlist = true,
.custom_blend_mode = V_028808_CB_RESOLVE,
},
- &device->meta_state.alloc,
- &device->meta_state.resolve.pipeline);
+ &device->meta_state.alloc, pipeline);
if (result != VK_SUCCESS)
goto cleanup;
{
struct radv_meta_state *state = &device->meta_state;
- radv_DestroyRenderPass(radv_device_to_handle(device),
- state->resolve.pass, &state->alloc);
+ for (uint32_t j = 0; j < NUM_META_FS_KEYS; j++) {
+ radv_DestroyRenderPass(radv_device_to_handle(device),
+ state->resolve.pass[j], &state->alloc);
+ radv_DestroyPipeline(radv_device_to_handle(device),
+ state->resolve.pipeline[j], &state->alloc);
+ }
radv_DestroyPipelineLayout(radv_device_to_handle(device),
state->resolve.p_layout, &state->alloc);
- radv_DestroyPipeline(radv_device_to_handle(device),
- state->resolve.pipeline, &state->alloc);
+
}
+static VkFormat pipeline_formats[] = {
+ VK_FORMAT_R8G8B8A8_UNORM,
+ VK_FORMAT_R8G8B8A8_UINT,
+ VK_FORMAT_R8G8B8A8_SINT,
+ VK_FORMAT_A2R10G10B10_UINT_PACK32,
+ VK_FORMAT_A2R10G10B10_SINT_PACK32,
+ VK_FORMAT_R16G16B16A16_UNORM,
+ VK_FORMAT_R16G16B16A16_SNORM,
+ VK_FORMAT_R16G16B16A16_UINT,
+ VK_FORMAT_R16G16B16A16_SINT,
+ VK_FORMAT_R32_SFLOAT,
+ VK_FORMAT_R32G32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT
+};
+
VkResult
radv_device_init_meta_resolve_state(struct radv_device *device)
{
VkResult res = VK_SUCCESS;
-
+ struct radv_meta_state *state = &device->meta_state;
struct radv_shader_module vs_module = { .nir = radv_meta_build_nir_vs_generate_vertices() };
if (!vs_module.nir) {
/* XXX: Need more accurate error */
goto fail;
}
- res = create_pass(device);
- if (res != VK_SUCCESS)
- goto fail;
-
- VkShaderModule vs_module_h = radv_shader_module_to_handle(&vs_module);
- res = create_pipeline(device, vs_module_h);
- if (res != VK_SUCCESS)
- goto fail;
+ for (uint32_t i = 0; i < ARRAY_SIZE(pipeline_formats); ++i) {
+ VkFormat format = pipeline_formats[i];
+ unsigned fs_key = radv_format_meta_fs_key(format);
+ res = create_pass(device, format, &state->resolve.pass[fs_key]);
+ if (res != VK_SUCCESS)
+ goto fail;
+
+ VkShaderModule vs_module_h = radv_shader_module_to_handle(&vs_module);
+ res = create_pipeline(device, vs_module_h,
+ &state->resolve.pipeline[fs_key], state->resolve.pass[fs_key]);
+ if (res != VK_SUCCESS)
+ goto fail;
+ }
goto cleanup;
static void
emit_resolve(struct radv_cmd_buffer *cmd_buffer,
+ VkFormat vk_format,
const VkOffset2D *dest_offset,
const VkExtent2D *resolve_extent)
{
struct radv_device *device = cmd_buffer->device;
VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
+ unsigned fs_key = radv_format_meta_fs_key(vk_format);
cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB;
radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
- device->meta_state.resolve.pipeline);
+ device->meta_state.resolve.pipeline[fs_key]);
radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
.x = dest_offset->x,
if (dest_image->surface.dcc_size) {
radv_initialize_dcc(cmd_buffer, dest_image, 0xffffffff);
}
+ unsigned fs_key = radv_format_meta_fs_key(dest_image->vk_format);
for (uint32_t r = 0; r < region_count; ++r) {
const VkImageResolve *region = ®ions[r];
radv_CmdBeginRenderPass(cmd_buffer_h,
&(VkRenderPassBeginInfo) {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .renderPass = device->meta_state.resolve.pass,
+ .renderPass = device->meta_state.resolve.pass[fs_key],
.framebuffer = fb_h,
.renderArea = {
.offset = {
VK_SUBPASS_CONTENTS_INLINE);
emit_resolve(cmd_buffer,
+ dest_iview.vk_format,
&(VkOffset2D) {
.x = dstOffset.x,
.y = dstOffset.y,
radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass, false);
emit_resolve(cmd_buffer,
+ dst_img->vk_format,
&(VkOffset2D) { 0, 0 },
&(VkExtent2D) { fb->width, fb->height });
}