intel/genxml: Emit genxml enums as C enums
[mesa.git] / src / amd / vulkan / radv_meta_resolve.c
1 /*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26
27 #include "radv_meta.h"
28 #include "radv_private.h"
29 #include "nir/nir_builder.h"
30 #include "sid.h"
31 /**
32 * Vertex attributes used by all pipelines.
33 */
34 struct vertex_attrs {
35 float position[2]; /**< 3DPRIM_RECTLIST */
36 };
37
38 /* passthrough vertex shader */
39 static nir_shader *
40 build_nir_vs(void)
41 {
42 const struct glsl_type *vec4 = glsl_vec4_type();
43
44 nir_builder b;
45 nir_variable *a_position;
46 nir_variable *v_position;
47
48 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_VERTEX, NULL);
49 b.shader->info->name = ralloc_strdup(b.shader, "meta_resolve_vs");
50
51 a_position = nir_variable_create(b.shader, nir_var_shader_in, vec4,
52 "a_position");
53 a_position->data.location = VERT_ATTRIB_GENERIC0;
54
55 v_position = nir_variable_create(b.shader, nir_var_shader_out, vec4,
56 "gl_Position");
57 v_position->data.location = VARYING_SLOT_POS;
58
59 nir_copy_var(&b, v_position, a_position);
60
61 return b.shader;
62 }
63
64 /* simple passthrough shader */
65 static nir_shader *
66 build_nir_fs(void)
67 {
68 const struct glsl_type *vec4 = glsl_vec4_type();
69 nir_builder b;
70 nir_variable *f_color; /* vec4, fragment output color */
71
72 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL);
73 b.shader->info->name = ralloc_asprintf(b.shader,
74 "meta_resolve_fs");
75
76 f_color = nir_variable_create(b.shader, nir_var_shader_out, vec4,
77 "f_color");
78 f_color->data.location = FRAG_RESULT_DATA0;
79 nir_store_var(&b, f_color, nir_imm_vec4(&b, 0.0, 0.0, 0.0, 1.0), 0xf);
80
81 return b.shader;
82 }
83
84 static VkResult
85 create_pass(struct radv_device *device)
86 {
87 VkResult result;
88 VkDevice device_h = radv_device_to_handle(device);
89 const VkAllocationCallbacks *alloc = &device->meta_state.alloc;
90 VkAttachmentDescription attachments[2];
91 int i;
92
93 for (i = 0; i < 2; i++) {
94 attachments[i].format = VK_FORMAT_UNDEFINED;
95 attachments[i].samples = 1;
96 attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
97 attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
98 attachments[i].initialLayout = VK_IMAGE_LAYOUT_GENERAL;
99 attachments[i].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
100 }
101
102 result = radv_CreateRenderPass(device_h,
103 &(VkRenderPassCreateInfo) {
104 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
105 .attachmentCount = 2,
106 .pAttachments = attachments,
107 .subpassCount = 1,
108 .pSubpasses = &(VkSubpassDescription) {
109 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
110 .inputAttachmentCount = 0,
111 .colorAttachmentCount = 2,
112 .pColorAttachments = (VkAttachmentReference[]) {
113 {
114 .attachment = 0,
115 .layout = VK_IMAGE_LAYOUT_GENERAL,
116 },
117 {
118 .attachment = 1,
119 .layout = VK_IMAGE_LAYOUT_GENERAL,
120 },
121 },
122 .pResolveAttachments = NULL,
123 .pDepthStencilAttachment = &(VkAttachmentReference) {
124 .attachment = VK_ATTACHMENT_UNUSED,
125 },
126 .preserveAttachmentCount = 0,
127 .pPreserveAttachments = NULL,
128 },
129 .dependencyCount = 0,
130 },
131 alloc,
132 &device->meta_state.resolve.pass);
133
134 return result;
135 }
136
137 static VkResult
138 create_pipeline(struct radv_device *device,
139 VkShaderModule vs_module_h)
140 {
141 VkResult result;
142 VkDevice device_h = radv_device_to_handle(device);
143
144 struct radv_shader_module fs_module = {
145 .nir = build_nir_fs(),
146 };
147
148 if (!fs_module.nir) {
149 /* XXX: Need more accurate error */
150 result = VK_ERROR_OUT_OF_HOST_MEMORY;
151 goto cleanup;
152 }
153
154 result = radv_graphics_pipeline_create(device_h,
155 radv_pipeline_cache_to_handle(&device->meta_state.cache),
156 &(VkGraphicsPipelineCreateInfo) {
157 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
158 .stageCount = 2,
159 .pStages = (VkPipelineShaderStageCreateInfo[]) {
160 {
161 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
162 .stage = VK_SHADER_STAGE_VERTEX_BIT,
163 .module = vs_module_h,
164 .pName = "main",
165 },
166 {
167 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
168 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
169 .module = radv_shader_module_to_handle(&fs_module),
170 .pName = "main",
171 },
172 },
173 .pVertexInputState = &(VkPipelineVertexInputStateCreateInfo) {
174 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
175 .vertexBindingDescriptionCount = 1,
176 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
177 {
178 .binding = 0,
179 .stride = sizeof(struct vertex_attrs),
180 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
181 },
182 },
183 .vertexAttributeDescriptionCount = 1,
184 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
185 {
186 /* Position */
187 .location = 0,
188 .binding = 0,
189 .format = VK_FORMAT_R32G32_SFLOAT,
190 .offset = offsetof(struct vertex_attrs, position),
191 },
192 },
193 },
194 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
195 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
196 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
197 .primitiveRestartEnable = false,
198 },
199 .pViewportState = &(VkPipelineViewportStateCreateInfo) {
200 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
201 .viewportCount = 0,
202 .scissorCount = 0,
203 },
204 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) {
205 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
206 .depthClampEnable = false,
207 .rasterizerDiscardEnable = false,
208 .polygonMode = VK_POLYGON_MODE_FILL,
209 .cullMode = VK_CULL_MODE_NONE,
210 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
211 },
212 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
213 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
214 .rasterizationSamples = 1,
215 .sampleShadingEnable = false,
216 .pSampleMask = NULL,
217 .alphaToCoverageEnable = false,
218 .alphaToOneEnable = false,
219 },
220 .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
221 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
222 .logicOpEnable = false,
223 .attachmentCount = 2,
224 .pAttachments = (VkPipelineColorBlendAttachmentState []) {
225 {
226 .colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
227 VK_COLOR_COMPONENT_G_BIT |
228 VK_COLOR_COMPONENT_B_BIT |
229 VK_COLOR_COMPONENT_A_BIT,
230 },
231 {
232 .colorWriteMask = 0,
233
234 }
235 },
236 },
237 .pDynamicState = NULL,
238 .renderPass = device->meta_state.resolve.pass,
239 .subpass = 0,
240 },
241 &(struct radv_graphics_pipeline_create_info) {
242 .use_rectlist = true,
243 .custom_blend_mode = V_028808_CB_RESOLVE,
244 },
245 &device->meta_state.alloc,
246 &device->meta_state.resolve.pipeline);
247 if (result != VK_SUCCESS)
248 goto cleanup;
249
250 goto cleanup;
251
252 cleanup:
253 ralloc_free(fs_module.nir);
254 return result;
255 }
256
257 void
258 radv_device_finish_meta_resolve_state(struct radv_device *device)
259 {
260 struct radv_meta_state *state = &device->meta_state;
261 VkDevice device_h = radv_device_to_handle(device);
262 VkRenderPass pass_h = device->meta_state.resolve.pass;
263 const VkAllocationCallbacks *alloc = &device->meta_state.alloc;
264
265 if (pass_h)
266 radv_DestroyRenderPass(device_h, pass_h,
267 &device->meta_state.alloc);
268
269 VkPipeline pipeline_h = state->resolve.pipeline;
270 if (pipeline_h) {
271 radv_DestroyPipeline(device_h, pipeline_h, alloc);
272 }
273 }
274
275 VkResult
276 radv_device_init_meta_resolve_state(struct radv_device *device)
277 {
278 VkResult res = VK_SUCCESS;
279
280 zero(device->meta_state.resolve);
281
282 struct radv_shader_module vs_module = { .nir = build_nir_vs() };
283 if (!vs_module.nir) {
284 /* XXX: Need more accurate error */
285 res = VK_ERROR_OUT_OF_HOST_MEMORY;
286 goto fail;
287 }
288
289 res = create_pass(device);
290 if (res != VK_SUCCESS)
291 goto fail;
292
293 VkShaderModule vs_module_h = radv_shader_module_to_handle(&vs_module);
294 res = create_pipeline(device, vs_module_h);
295 if (res != VK_SUCCESS)
296 goto fail;
297
298 goto cleanup;
299
300 fail:
301 radv_device_finish_meta_resolve_state(device);
302
303 cleanup:
304 ralloc_free(vs_module.nir);
305
306 return res;
307 }
308
309 static void
310 emit_resolve(struct radv_cmd_buffer *cmd_buffer,
311 const VkOffset2D *dest_offset,
312 const VkExtent2D *resolve_extent)
313 {
314 struct radv_device *device = cmd_buffer->device;
315 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
316 uint32_t offset;
317 const struct vertex_attrs vertex_data[3] = {
318 {
319 .position = {
320 dest_offset->x,
321 dest_offset->y,
322 },
323 },
324 {
325 .position = {
326 dest_offset->x,
327 dest_offset->y + resolve_extent->height,
328 },
329 },
330 {
331 .position = {
332 dest_offset->x + resolve_extent->width,
333 dest_offset->y,
334 },
335 },
336 };
337
338 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB;
339 radv_cmd_buffer_upload_data(cmd_buffer, sizeof(vertex_data), 16, vertex_data, &offset);
340 struct radv_buffer vertex_buffer = {
341 .device = device,
342 .size = sizeof(vertex_data),
343 .bo = cmd_buffer->upload.upload_bo,
344 .offset = offset,
345 };
346
347 VkBuffer vertex_buffer_h = radv_buffer_to_handle(&vertex_buffer);
348
349 radv_CmdBindVertexBuffers(cmd_buffer_h,
350 /*firstBinding*/ 0,
351 /*bindingCount*/ 1,
352 (VkBuffer[]) { vertex_buffer_h },
353 (VkDeviceSize[]) { 0 });
354
355 VkPipeline pipeline_h = device->meta_state.resolve.pipeline;
356 RADV_FROM_HANDLE(radv_pipeline, pipeline, pipeline_h);
357
358 if (cmd_buffer->state.pipeline != pipeline) {
359 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
360 pipeline_h);
361 }
362
363 radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0);
364 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB;
365 si_emit_cache_flush(cmd_buffer);
366 }
367
368 void radv_CmdResolveImage(
369 VkCommandBuffer cmd_buffer_h,
370 VkImage src_image_h,
371 VkImageLayout src_image_layout,
372 VkImage dest_image_h,
373 VkImageLayout dest_image_layout,
374 uint32_t region_count,
375 const VkImageResolve* regions)
376 {
377 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, cmd_buffer_h);
378 RADV_FROM_HANDLE(radv_image, src_image, src_image_h);
379 RADV_FROM_HANDLE(radv_image, dest_image, dest_image_h);
380 struct radv_device *device = cmd_buffer->device;
381 struct radv_meta_saved_state saved_state;
382 VkDevice device_h = radv_device_to_handle(device);
383 bool use_compute_resolve = false;
384
385 /* we can use the hw resolve only for single full resolves */
386 if (region_count == 1) {
387 if (regions[0].srcOffset.x ||
388 regions[0].srcOffset.y ||
389 regions[0].srcOffset.z)
390 use_compute_resolve = true;
391 if (regions[0].dstOffset.x ||
392 regions[0].dstOffset.y ||
393 regions[0].dstOffset.z)
394 use_compute_resolve = true;
395
396 if (regions[0].extent.width != src_image->extent.width ||
397 regions[0].extent.height != src_image->extent.height ||
398 regions[0].extent.depth != src_image->extent.depth)
399 use_compute_resolve = true;
400 } else
401 use_compute_resolve = true;
402
403 if (use_compute_resolve) {
404
405 radv_fast_clear_flush_image_inplace(cmd_buffer, src_image);
406 radv_meta_resolve_compute_image(cmd_buffer,
407 src_image,
408 src_image_layout,
409 dest_image,
410 dest_image_layout,
411 region_count, regions);
412 return;
413 }
414
415 radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer);
416
417 assert(src_image->samples > 1);
418 assert(dest_image->samples == 1);
419
420 if (src_image->samples >= 16) {
421 /* See commit aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54 for the
422 * glBlitFramebuffer workaround for samples >= 16.
423 */
424 radv_finishme("vkCmdResolveImage: need interpolation workaround when "
425 "samples >= 16");
426 }
427
428 if (src_image->array_size > 1)
429 radv_finishme("vkCmdResolveImage: multisample array images");
430
431 for (uint32_t r = 0; r < region_count; ++r) {
432 const VkImageResolve *region = &regions[r];
433
434 /* From the Vulkan 1.0 spec:
435 *
436 * - The aspectMask member of srcSubresource and dstSubresource must
437 * only contain VK_IMAGE_ASPECT_COLOR_BIT
438 *
439 * - The layerCount member of srcSubresource and dstSubresource must
440 * match
441 */
442 assert(region->srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
443 assert(region->dstSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
444 assert(region->srcSubresource.layerCount ==
445 region->dstSubresource.layerCount);
446
447 const uint32_t src_base_layer =
448 radv_meta_get_iview_layer(src_image, &region->srcSubresource,
449 &region->srcOffset);
450
451 const uint32_t dest_base_layer =
452 radv_meta_get_iview_layer(dest_image, &region->dstSubresource,
453 &region->dstOffset);
454
455 /**
456 * From Vulkan 1.0.6 spec: 18.6 Resolving Multisample Images
457 *
458 * extent is the size in texels of the source image to resolve in width,
459 * height and depth. 1D images use only x and width. 2D images use x, y,
460 * width and height. 3D images use x, y, z, width, height and depth.
461 *
462 * srcOffset and dstOffset select the initial x, y, and z offsets in
463 * texels of the sub-regions of the source and destination image data.
464 * extent is the size in texels of the source image to resolve in width,
465 * height and depth. 1D images use only x and width. 2D images use x, y,
466 * width and height. 3D images use x, y, z, width, height and depth.
467 */
468 const struct VkExtent3D extent =
469 radv_sanitize_image_extent(src_image->type, region->extent);
470 const struct VkOffset3D dstOffset =
471 radv_sanitize_image_offset(dest_image->type, region->dstOffset);
472
473
474 for (uint32_t layer = 0; layer < region->srcSubresource.layerCount;
475 ++layer) {
476
477 struct radv_image_view src_iview;
478 radv_image_view_init(&src_iview, cmd_buffer->device,
479 &(VkImageViewCreateInfo) {
480 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
481 .image = src_image_h,
482 .viewType = radv_meta_get_view_type(src_image),
483 .format = src_image->vk_format,
484 .subresourceRange = {
485 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
486 .baseMipLevel = region->srcSubresource.mipLevel,
487 .levelCount = 1,
488 .baseArrayLayer = src_base_layer + layer,
489 .layerCount = 1,
490 },
491 },
492 cmd_buffer, VK_IMAGE_USAGE_SAMPLED_BIT);
493
494 struct radv_image_view dest_iview;
495 radv_image_view_init(&dest_iview, cmd_buffer->device,
496 &(VkImageViewCreateInfo) {
497 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
498 .image = dest_image_h,
499 .viewType = radv_meta_get_view_type(dest_image),
500 .format = dest_image->vk_format,
501 .subresourceRange = {
502 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
503 .baseMipLevel = region->dstSubresource.mipLevel,
504 .levelCount = 1,
505 .baseArrayLayer = dest_base_layer + layer,
506 .layerCount = 1,
507 },
508 },
509 cmd_buffer, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
510
511 VkFramebuffer fb_h;
512 radv_CreateFramebuffer(device_h,
513 &(VkFramebufferCreateInfo) {
514 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
515 .attachmentCount = 2,
516 .pAttachments = (VkImageView[]) {
517 radv_image_view_to_handle(&src_iview),
518 radv_image_view_to_handle(&dest_iview),
519 },
520 .width = radv_minify(dest_image->extent.width,
521 region->dstSubresource.mipLevel),
522 .height = radv_minify(dest_image->extent.height,
523 region->dstSubresource.mipLevel),
524 .layers = 1
525 },
526 &cmd_buffer->pool->alloc,
527 &fb_h);
528
529 radv_CmdBeginRenderPass(cmd_buffer_h,
530 &(VkRenderPassBeginInfo) {
531 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
532 .renderPass = device->meta_state.resolve.pass,
533 .framebuffer = fb_h,
534 .renderArea = {
535 .offset = {
536 dstOffset.x,
537 dstOffset.y,
538 },
539 .extent = {
540 extent.width,
541 extent.height,
542 }
543 },
544 .clearValueCount = 0,
545 .pClearValues = NULL,
546 },
547 VK_SUBPASS_CONTENTS_INLINE);
548
549 emit_resolve(cmd_buffer,
550 &(VkOffset2D) {
551 .x = dstOffset.x,
552 .y = dstOffset.y,
553 },
554 &(VkExtent2D) {
555 .width = extent.width,
556 .height = extent.height,
557 });
558
559 radv_CmdEndRenderPass(cmd_buffer_h);
560
561 radv_DestroyFramebuffer(device_h, fb_h,
562 &cmd_buffer->pool->alloc);
563 }
564 }
565
566 radv_meta_restore(&saved_state, cmd_buffer);
567 }
568
569 /**
570 * Emit any needed resolves for the current subpass.
571 */
572 void
573 radv_cmd_buffer_resolve_subpass(struct radv_cmd_buffer *cmd_buffer)
574 {
575 struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
576 const struct radv_subpass *subpass = cmd_buffer->state.subpass;
577 struct radv_meta_saved_state saved_state;
578
579 /* FINISHME(perf): Skip clears for resolve attachments.
580 *
581 * From the Vulkan 1.0 spec:
582 *
583 * If the first use of an attachment in a render pass is as a resolve
584 * attachment, then the loadOp is effectively ignored as the resolve is
585 * guaranteed to overwrite all pixels in the render area.
586 */
587
588 if (!subpass->has_resolve)
589 return;
590
591 radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer);
592
593 for (uint32_t i = 0; i < subpass->color_count; ++i) {
594 VkAttachmentReference src_att = subpass->color_attachments[i];
595 VkAttachmentReference dest_att = subpass->resolve_attachments[i];
596 struct radv_image *dst_img = cmd_buffer->state.framebuffer->attachments[dest_att.attachment].attachment->image;
597 if (dest_att.attachment == VK_ATTACHMENT_UNUSED)
598 continue;
599
600 if (dst_img->surface.dcc_size) {
601 radv_initialize_dcc(cmd_buffer, dst_img, 0xffffffff);
602 cmd_buffer->state.attachments[dest_att.attachment].current_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
603 }
604
605 struct radv_subpass resolve_subpass = {
606 .color_count = 2,
607 .color_attachments = (VkAttachmentReference[]) { src_att, dest_att },
608 .depth_stencil_attachment = { .attachment = VK_ATTACHMENT_UNUSED },
609 };
610
611 radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass, false);
612
613 /* Subpass resolves must respect the render area. We can ignore the
614 * render area here because vkCmdBeginRenderPass set the render area
615 * with 3DSTATE_DRAWING_RECTANGLE.
616 *
617 * XXX(chadv): Does the hardware really respect
618 * 3DSTATE_DRAWING_RECTANGLE when draing a 3DPRIM_RECTLIST?
619 */
620 emit_resolve(cmd_buffer,
621 &(VkOffset2D) { 0, 0 },
622 &(VkExtent2D) { fb->width, fb->height });
623 }
624
625 cmd_buffer->state.subpass = subpass;
626 radv_meta_restore(&saved_state, cmd_buffer);
627 }