mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 05:10:11 +01:00
pvr: factor out framebuffer-specific code
Acked-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38922>
This commit is contained in:
parent
5c70230c49
commit
b5400c8ddf
6 changed files with 315 additions and 280 deletions
|
|
@ -35,6 +35,7 @@ pvr_files = files(
|
|||
'pvr_device.c',
|
||||
'pvr_dump_bo.c',
|
||||
'pvr_dump_csb.c',
|
||||
'pvr_framebuffer.c',
|
||||
'pvr_free_list.c',
|
||||
'pvr_formats.c',
|
||||
'pvr_hw_pass.c',
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "pvr_device_info.h"
|
||||
#include "pvr_entrypoints.h"
|
||||
#include "pvr_formats.h"
|
||||
#include "pvr_framebuffer.h"
|
||||
#include "pvr_hw_pass.h"
|
||||
#include "pvr_image.h"
|
||||
#include "pvr_job_common.h"
|
||||
|
|
|
|||
|
|
@ -1868,73 +1868,8 @@ VkResult pvr_gpu_upload_pds(struct pvr_device *device,
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
pvr_render_state_create_ppp_state(struct pvr_device *device,
|
||||
struct pvr_render_state *rstate)
|
||||
{
|
||||
const uint32_t cache_line_size =
|
||||
pvr_get_slc_cache_line_size(&device->pdevice->dev_info);
|
||||
uint32_t ppp_state[3];
|
||||
VkResult result;
|
||||
|
||||
pvr_csb_pack (&ppp_state[0], TA_STATE_HEADER, header) {
|
||||
header.pres_terminate = true;
|
||||
}
|
||||
|
||||
pvr_csb_pack (&ppp_state[1], TA_STATE_TERMINATE0, term0) {
|
||||
term0.clip_right =
|
||||
DIV_ROUND_UP(
|
||||
rstate->width,
|
||||
ROGUE_TA_STATE_TERMINATE0_CLIP_RIGHT_BLOCK_SIZE_IN_PIXELS) -
|
||||
1;
|
||||
term0.clip_bottom =
|
||||
DIV_ROUND_UP(
|
||||
rstate->height,
|
||||
ROGUE_TA_STATE_TERMINATE0_CLIP_BOTTOM_BLOCK_SIZE_IN_PIXELS) -
|
||||
1;
|
||||
}
|
||||
|
||||
pvr_csb_pack (&ppp_state[2], TA_STATE_TERMINATE1, term1) {
|
||||
term1.render_target = 0;
|
||||
term1.clip_left = 0;
|
||||
}
|
||||
|
||||
result = pvr_gpu_upload(device,
|
||||
device->heaps.general_heap,
|
||||
ppp_state,
|
||||
sizeof(ppp_state),
|
||||
cache_line_size,
|
||||
&rstate->ppp_state_bo);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
/* Calculate the size of PPP state in dwords. */
|
||||
rstate->ppp_state_size = sizeof(ppp_state) / sizeof(uint32_t);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static bool pvr_render_targets_init(struct pvr_render_target *render_targets,
|
||||
uint32_t render_targets_count)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < render_targets_count; i++) {
|
||||
if (pthread_mutex_init(&render_targets[i].mutex, NULL))
|
||||
goto err_mutex_destroy;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
err_mutex_destroy:
|
||||
while (i--)
|
||||
pthread_mutex_destroy(&render_targets[i].mutex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void pvr_render_targets_fini(struct pvr_render_target *render_targets,
|
||||
uint32_t render_targets_count)
|
||||
void pvr_render_targets_fini(struct pvr_render_target *render_targets,
|
||||
uint32_t render_targets_count)
|
||||
{
|
||||
for (uint32_t i = 0; i < render_targets_count; i++) {
|
||||
pvr_render_targets_datasets_destroy(&render_targets[i]);
|
||||
|
|
@ -1942,19 +1877,6 @@ static void pvr_render_targets_fini(struct pvr_render_target *render_targets,
|
|||
}
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
pvr_render_pass_get_scratch_buffer_size(struct pvr_device *device,
|
||||
const struct pvr_render_pass *pass,
|
||||
const struct pvr_render_state *rstate)
|
||||
{
|
||||
return pvr_spm_scratch_buffer_calc_required_size(
|
||||
pass->hw_setup->renders,
|
||||
pass->hw_setup->render_count,
|
||||
pass->max_sample_count,
|
||||
rstate->width,
|
||||
rstate->height);
|
||||
}
|
||||
|
||||
void pvr_render_state_cleanup(struct pvr_device *device,
|
||||
const struct pvr_render_state *rstate)
|
||||
{
|
||||
|
|
@ -1975,206 +1897,6 @@ void pvr_render_state_cleanup(struct pvr_device *device,
|
|||
vk_free(&device->vk.alloc, rstate->render_targets);
|
||||
}
|
||||
|
||||
VkResult
|
||||
pvr_render_state_setup(struct pvr_device *device,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
struct pvr_render_state *rstate,
|
||||
uint32_t render_count,
|
||||
const struct pvr_renderpass_hwsetup_render *renders)
|
||||
{
|
||||
struct pvr_spm_bgobj_state *spm_bgobj_state_per_render;
|
||||
struct pvr_spm_eot_state *spm_eot_state_per_render;
|
||||
struct pvr_render_target *render_targets;
|
||||
uint32_t render_targets_count;
|
||||
VkResult result;
|
||||
|
||||
render_targets_count =
|
||||
PVR_RENDER_TARGETS_PER_FRAMEBUFFER(&device->pdevice->dev_info);
|
||||
|
||||
VK_MULTIALLOC(ma);
|
||||
vk_multialloc_add(&ma,
|
||||
&render_targets,
|
||||
__typeof__(*render_targets),
|
||||
render_targets_count);
|
||||
vk_multialloc_add(&ma,
|
||||
&spm_eot_state_per_render,
|
||||
__typeof__(*spm_eot_state_per_render),
|
||||
render_count);
|
||||
vk_multialloc_add(&ma,
|
||||
&spm_bgobj_state_per_render,
|
||||
__typeof__(*spm_bgobj_state_per_render),
|
||||
render_count);
|
||||
|
||||
if (!vk_multialloc_zalloc2(&ma,
|
||||
&device->vk.alloc,
|
||||
pAllocator,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) {
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
rstate->render_targets = render_targets;
|
||||
rstate->render_targets_count = render_targets_count;
|
||||
if (!pvr_render_targets_init(rstate->render_targets, render_targets_count)) {
|
||||
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
goto err_free_render_targets;
|
||||
}
|
||||
|
||||
assert(rstate->scratch_buffer_size);
|
||||
result = pvr_spm_scratch_buffer_get_buffer(device,
|
||||
rstate->scratch_buffer_size,
|
||||
&rstate->scratch_buffer);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_finish_render_targets;
|
||||
|
||||
result = pvr_render_state_create_ppp_state(device, rstate);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_release_scratch_buffer;
|
||||
|
||||
for (uint32_t i = 0; i < render_count; i++) {
|
||||
result = pvr_spm_init_eot_state(device,
|
||||
&spm_eot_state_per_render[i],
|
||||
rstate,
|
||||
&renders[i]);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_finish_eot_state;
|
||||
|
||||
result = pvr_spm_init_bgobj_state(device,
|
||||
&spm_bgobj_state_per_render[i],
|
||||
rstate,
|
||||
&renders[i]);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_finish_bgobj_state;
|
||||
|
||||
continue;
|
||||
|
||||
err_finish_bgobj_state:
|
||||
pvr_spm_finish_eot_state(device, &spm_eot_state_per_render[i]);
|
||||
|
||||
for (uint32_t j = 0; j < i; j++)
|
||||
pvr_spm_finish_bgobj_state(device, &spm_bgobj_state_per_render[j]);
|
||||
|
||||
err_finish_eot_state:
|
||||
for (uint32_t j = 0; j < i; j++)
|
||||
pvr_spm_finish_eot_state(device, &spm_eot_state_per_render[j]);
|
||||
|
||||
goto err_free_ppp_state_bo;
|
||||
}
|
||||
|
||||
rstate->render_count = render_count;
|
||||
rstate->spm_eot_state_per_render = spm_eot_state_per_render;
|
||||
rstate->spm_bgobj_state_per_render = spm_bgobj_state_per_render;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_free_ppp_state_bo:
|
||||
pvr_bo_suballoc_free(rstate->ppp_state_bo);
|
||||
|
||||
err_release_scratch_buffer:
|
||||
pvr_spm_scratch_buffer_release(device, rstate->scratch_buffer);
|
||||
|
||||
err_finish_render_targets:
|
||||
pvr_render_targets_fini(rstate->render_targets, render_targets_count);
|
||||
|
||||
err_free_render_targets:
|
||||
vk_free2(&device->vk.alloc, pAllocator, rstate->render_targets);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VkResult pvr_CreateFramebuffer(VkDevice _device,
|
||||
const VkFramebufferCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkFramebuffer *pFramebuffer)
|
||||
{
|
||||
VK_FROM_HANDLE(pvr_render_pass, pass, pCreateInfo->renderPass);
|
||||
VK_FROM_HANDLE(pvr_device, device, _device);
|
||||
const VkFramebufferAttachmentsCreateInfoKHR *pImageless;
|
||||
struct pvr_framebuffer *framebuffer;
|
||||
struct pvr_image_view **attachments;
|
||||
struct pvr_render_state *rstate;
|
||||
VkResult result;
|
||||
|
||||
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
|
||||
|
||||
pImageless = vk_find_struct_const(pCreateInfo->pNext,
|
||||
FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
|
||||
|
||||
VK_MULTIALLOC(ma);
|
||||
vk_multialloc_add(&ma, &framebuffer, __typeof__(*framebuffer), 1);
|
||||
vk_multialloc_add(&ma, &rstate, __typeof__(*rstate), 1);
|
||||
vk_multialloc_add(&ma,
|
||||
&attachments,
|
||||
__typeof__(*attachments),
|
||||
pCreateInfo->attachmentCount);
|
||||
|
||||
if (!vk_multialloc_zalloc2(&ma,
|
||||
&device->vk.alloc,
|
||||
pAllocator,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vk_object_base_init(&device->vk,
|
||||
&framebuffer->base,
|
||||
VK_OBJECT_TYPE_FRAMEBUFFER);
|
||||
|
||||
framebuffer->attachments = attachments;
|
||||
if (!pImageless)
|
||||
framebuffer->attachment_count = pCreateInfo->attachmentCount;
|
||||
else
|
||||
framebuffer->attachment_count = pImageless->attachmentImageInfoCount;
|
||||
for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
|
||||
if (!pImageless) {
|
||||
framebuffer->attachments[i] =
|
||||
pvr_image_view_from_handle(pCreateInfo->pAttachments[i]);
|
||||
} else {
|
||||
assert(i < pImageless->attachmentImageInfoCount);
|
||||
}
|
||||
}
|
||||
|
||||
rstate->width = pCreateInfo->width;
|
||||
rstate->height = pCreateInfo->height;
|
||||
rstate->layers = pCreateInfo->layers;
|
||||
rstate->scratch_buffer_size =
|
||||
pvr_render_pass_get_scratch_buffer_size(device, pass, rstate);
|
||||
|
||||
result = pvr_render_state_setup(device,
|
||||
pAllocator,
|
||||
rstate,
|
||||
pass->hw_setup->render_count,
|
||||
pass->hw_setup->renders);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_free_framebuffer;
|
||||
|
||||
framebuffer->rstate = rstate;
|
||||
|
||||
*pFramebuffer = pvr_framebuffer_to_handle(framebuffer);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_free_framebuffer:
|
||||
vk_object_base_finish(&framebuffer->base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, framebuffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void pvr_DestroyFramebuffer(VkDevice _device,
|
||||
VkFramebuffer _fb,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
VK_FROM_HANDLE(pvr_framebuffer, framebuffer, _fb);
|
||||
VK_FROM_HANDLE(pvr_device, device, _device);
|
||||
|
||||
if (!framebuffer)
|
||||
return;
|
||||
|
||||
pvr_render_state_cleanup(device, framebuffer->rstate);
|
||||
/* the render state is freed with the framebuffer */
|
||||
|
||||
vk_object_base_finish(&framebuffer->base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, framebuffer);
|
||||
}
|
||||
|
||||
void pvr_GetBufferMemoryRequirements2(
|
||||
VkDevice _device,
|
||||
const VkBufferMemoryRequirementsInfo2 *pInfo,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ struct pvr_border_color_table;
|
|||
struct pvr_device_static_clear_state;
|
||||
struct pvr_instance;
|
||||
struct pvr_queue;
|
||||
struct pvr_render_target;
|
||||
|
||||
struct pvr_compute_query_shader {
|
||||
struct pvr_suballoc_bo *usc_bo;
|
||||
|
|
@ -228,4 +229,7 @@ void pvr_rstate_entry_add(struct pvr_device *device,
|
|||
void pvr_rstate_entry_remove(struct pvr_device *device,
|
||||
const struct pvr_render_state *rstate);
|
||||
|
||||
void pvr_render_targets_fini(struct pvr_render_target *render_targets,
|
||||
uint32_t render_targets_count);
|
||||
|
||||
#endif /* PVR_DEVICE_H */
|
||||
|
|
|
|||
306
src/imagination/vulkan/pvr_framebuffer.c
Normal file
306
src/imagination/vulkan/pvr_framebuffer.c
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* Copyright © 2022 Imagination Technologies Ltd.
|
||||
*
|
||||
* based in part on anv driver which is:
|
||||
* Copyright © 2015 Intel Corporation
|
||||
*
|
||||
* based in part on v3dv driver which is:
|
||||
* Copyright © 2019 Raspberry Pi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "pvr_framebuffer.h"
|
||||
|
||||
#include "vk_util.h"
|
||||
|
||||
#include "hwdef/pvr_hw_utils.h"
|
||||
|
||||
#include "pvr_cmd_buffer.h"
|
||||
#include "pvr_csb.h"
|
||||
#include "pvr_device.h"
|
||||
#include "pvr_entrypoints.h"
|
||||
#include "pvr_hw_pass.h"
|
||||
#include "pvr_image.h"
|
||||
#include "pvr_pass.h"
|
||||
#include "pvr_physical_device.h"
|
||||
#include "pvr_rt_dataset.h"
|
||||
#include "pvr_spm.h"
|
||||
|
||||
static VkResult
|
||||
pvr_render_state_create_ppp_state(struct pvr_device *device,
|
||||
struct pvr_render_state *rstate)
|
||||
{
|
||||
const uint32_t cache_line_size =
|
||||
pvr_get_slc_cache_line_size(&device->pdevice->dev_info);
|
||||
uint32_t ppp_state[3];
|
||||
VkResult result;
|
||||
|
||||
pvr_csb_pack (&ppp_state[0], TA_STATE_HEADER, header) {
|
||||
header.pres_terminate = true;
|
||||
}
|
||||
|
||||
pvr_csb_pack (&ppp_state[1], TA_STATE_TERMINATE0, term0) {
|
||||
term0.clip_right =
|
||||
DIV_ROUND_UP(
|
||||
rstate->width,
|
||||
ROGUE_TA_STATE_TERMINATE0_CLIP_RIGHT_BLOCK_SIZE_IN_PIXELS) -
|
||||
1;
|
||||
term0.clip_bottom =
|
||||
DIV_ROUND_UP(
|
||||
rstate->height,
|
||||
ROGUE_TA_STATE_TERMINATE0_CLIP_BOTTOM_BLOCK_SIZE_IN_PIXELS) -
|
||||
1;
|
||||
}
|
||||
|
||||
pvr_csb_pack (&ppp_state[2], TA_STATE_TERMINATE1, term1) {
|
||||
term1.render_target = 0;
|
||||
term1.clip_left = 0;
|
||||
}
|
||||
|
||||
result = pvr_gpu_upload(device,
|
||||
device->heaps.general_heap,
|
||||
ppp_state,
|
||||
sizeof(ppp_state),
|
||||
cache_line_size,
|
||||
&rstate->ppp_state_bo);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
/* Calculate the size of PPP state in dwords. */
|
||||
rstate->ppp_state_size = sizeof(ppp_state) / sizeof(uint32_t);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static bool pvr_render_targets_init(struct pvr_render_target *render_targets,
|
||||
uint32_t render_targets_count)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < render_targets_count; i++) {
|
||||
if (pthread_mutex_init(&render_targets[i].mutex, NULL))
|
||||
goto err_mutex_destroy;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
err_mutex_destroy:
|
||||
while (i--)
|
||||
pthread_mutex_destroy(&render_targets[i].mutex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
VkResult
|
||||
pvr_render_state_setup(struct pvr_device *device,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
struct pvr_render_state *rstate,
|
||||
uint32_t render_count,
|
||||
const struct pvr_renderpass_hwsetup_render *renders)
|
||||
{
|
||||
struct pvr_spm_bgobj_state *spm_bgobj_state_per_render;
|
||||
struct pvr_spm_eot_state *spm_eot_state_per_render;
|
||||
struct pvr_render_target *render_targets;
|
||||
uint32_t render_targets_count;
|
||||
VkResult result;
|
||||
|
||||
render_targets_count =
|
||||
PVR_RENDER_TARGETS_PER_FRAMEBUFFER(&device->pdevice->dev_info);
|
||||
|
||||
VK_MULTIALLOC(ma);
|
||||
vk_multialloc_add(&ma,
|
||||
&render_targets,
|
||||
__typeof__(*render_targets),
|
||||
render_targets_count);
|
||||
vk_multialloc_add(&ma,
|
||||
&spm_eot_state_per_render,
|
||||
__typeof__(*spm_eot_state_per_render),
|
||||
render_count);
|
||||
vk_multialloc_add(&ma,
|
||||
&spm_bgobj_state_per_render,
|
||||
__typeof__(*spm_bgobj_state_per_render),
|
||||
render_count);
|
||||
|
||||
if (!vk_multialloc_zalloc2(&ma,
|
||||
&device->vk.alloc,
|
||||
pAllocator,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) {
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
rstate->render_targets = render_targets;
|
||||
rstate->render_targets_count = render_targets_count;
|
||||
if (!pvr_render_targets_init(rstate->render_targets, render_targets_count)) {
|
||||
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
goto err_free_render_targets;
|
||||
}
|
||||
|
||||
assert(rstate->scratch_buffer_size);
|
||||
result = pvr_spm_scratch_buffer_get_buffer(device,
|
||||
rstate->scratch_buffer_size,
|
||||
&rstate->scratch_buffer);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_finish_render_targets;
|
||||
|
||||
result = pvr_render_state_create_ppp_state(device, rstate);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_release_scratch_buffer;
|
||||
|
||||
for (uint32_t i = 0; i < render_count; i++) {
|
||||
result = pvr_spm_init_eot_state(device,
|
||||
&spm_eot_state_per_render[i],
|
||||
rstate,
|
||||
&renders[i]);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_finish_eot_state;
|
||||
|
||||
result = pvr_spm_init_bgobj_state(device,
|
||||
&spm_bgobj_state_per_render[i],
|
||||
rstate,
|
||||
&renders[i]);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_finish_bgobj_state;
|
||||
|
||||
continue;
|
||||
|
||||
err_finish_bgobj_state:
|
||||
pvr_spm_finish_eot_state(device, &spm_eot_state_per_render[i]);
|
||||
|
||||
for (uint32_t j = 0; j < i; j++)
|
||||
pvr_spm_finish_bgobj_state(device, &spm_bgobj_state_per_render[j]);
|
||||
|
||||
err_finish_eot_state:
|
||||
for (uint32_t j = 0; j < i; j++)
|
||||
pvr_spm_finish_eot_state(device, &spm_eot_state_per_render[j]);
|
||||
|
||||
goto err_free_ppp_state_bo;
|
||||
}
|
||||
|
||||
rstate->render_count = render_count;
|
||||
rstate->spm_eot_state_per_render = spm_eot_state_per_render;
|
||||
rstate->spm_bgobj_state_per_render = spm_bgobj_state_per_render;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_free_ppp_state_bo:
|
||||
pvr_bo_suballoc_free(rstate->ppp_state_bo);
|
||||
|
||||
err_release_scratch_buffer:
|
||||
pvr_spm_scratch_buffer_release(device, rstate->scratch_buffer);
|
||||
|
||||
err_finish_render_targets:
|
||||
pvr_render_targets_fini(rstate->render_targets, render_targets_count);
|
||||
|
||||
err_free_render_targets:
|
||||
vk_free2(&device->vk.alloc, pAllocator, rstate->render_targets);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
pvr_render_pass_get_scratch_buffer_size(struct pvr_device *device,
|
||||
const struct pvr_render_pass *pass,
|
||||
const struct pvr_render_state *rstate)
|
||||
{
|
||||
return pvr_spm_scratch_buffer_calc_required_size(
|
||||
pass->hw_setup->renders,
|
||||
pass->hw_setup->render_count,
|
||||
pass->max_sample_count,
|
||||
rstate->width,
|
||||
rstate->height);
|
||||
}
|
||||
|
||||
VkResult pvr_CreateFramebuffer(VkDevice _device,
|
||||
const VkFramebufferCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkFramebuffer *pFramebuffer)
|
||||
{
|
||||
VK_FROM_HANDLE(pvr_render_pass, pass, pCreateInfo->renderPass);
|
||||
VK_FROM_HANDLE(pvr_device, device, _device);
|
||||
const VkFramebufferAttachmentsCreateInfoKHR *pImageless;
|
||||
struct pvr_framebuffer *framebuffer;
|
||||
struct pvr_image_view **attachments;
|
||||
struct pvr_render_state *rstate;
|
||||
VkResult result;
|
||||
|
||||
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
|
||||
|
||||
pImageless = vk_find_struct_const(pCreateInfo->pNext,
|
||||
FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
|
||||
|
||||
VK_MULTIALLOC(ma);
|
||||
vk_multialloc_add(&ma, &framebuffer, __typeof__(*framebuffer), 1);
|
||||
vk_multialloc_add(&ma, &rstate, __typeof__(*rstate), 1);
|
||||
vk_multialloc_add(&ma,
|
||||
&attachments,
|
||||
__typeof__(*attachments),
|
||||
pCreateInfo->attachmentCount);
|
||||
|
||||
if (!vk_multialloc_zalloc2(&ma,
|
||||
&device->vk.alloc,
|
||||
pAllocator,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vk_object_base_init(&device->vk,
|
||||
&framebuffer->base,
|
||||
VK_OBJECT_TYPE_FRAMEBUFFER);
|
||||
|
||||
framebuffer->attachments = attachments;
|
||||
if (!pImageless)
|
||||
framebuffer->attachment_count = pCreateInfo->attachmentCount;
|
||||
else
|
||||
framebuffer->attachment_count = pImageless->attachmentImageInfoCount;
|
||||
for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
|
||||
if (!pImageless) {
|
||||
framebuffer->attachments[i] =
|
||||
pvr_image_view_from_handle(pCreateInfo->pAttachments[i]);
|
||||
} else {
|
||||
assert(i < pImageless->attachmentImageInfoCount);
|
||||
}
|
||||
}
|
||||
|
||||
rstate->width = pCreateInfo->width;
|
||||
rstate->height = pCreateInfo->height;
|
||||
rstate->layers = pCreateInfo->layers;
|
||||
rstate->scratch_buffer_size =
|
||||
pvr_render_pass_get_scratch_buffer_size(device, pass, rstate);
|
||||
|
||||
result = pvr_render_state_setup(device,
|
||||
pAllocator,
|
||||
rstate,
|
||||
pass->hw_setup->render_count,
|
||||
pass->hw_setup->renders);
|
||||
if (result != VK_SUCCESS)
|
||||
goto err_free_framebuffer;
|
||||
|
||||
framebuffer->rstate = rstate;
|
||||
|
||||
*pFramebuffer = pvr_framebuffer_to_handle(framebuffer);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_free_framebuffer:
|
||||
vk_object_base_finish(&framebuffer->base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, framebuffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void pvr_DestroyFramebuffer(VkDevice _device,
|
||||
VkFramebuffer _fb,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
VK_FROM_HANDLE(pvr_framebuffer, framebuffer, _fb);
|
||||
VK_FROM_HANDLE(pvr_device, device, _device);
|
||||
|
||||
if (!framebuffer)
|
||||
return;
|
||||
|
||||
pvr_render_state_cleanup(device, framebuffer->rstate);
|
||||
/* the render state is freed with the framebuffer */
|
||||
|
||||
vk_object_base_finish(&framebuffer->base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, framebuffer);
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include "vk_object.h"
|
||||
|
||||
#include "pvr_limits.h"
|
||||
#include "pvr_macros.h"
|
||||
|
||||
struct pvr_render_target {
|
||||
struct pvr_rt_dataset *rt_dataset[PVR_MAX_MULTIVIEW];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue