#include "wsi.h"
#include <string.h>
+static void
+add_tdm_layer(vk_physical_device_t *pdev, tdm_layer *layer,
+ vk_display_t *display, tdm_output *output)
+{
+ int zpos;
+
+ vk_display_plane_t *plane = &pdev->planes[pdev->plane_count];
+
+ plane->pdev = pdev;
+ plane->tdm_layer = layer;
+
+ plane->supported_display_count = 1;
+ plane->supported_displays[0] = display;
+
+ /* TODO: Map layer zpos into positive integer range between [0, NUM_LAYERS].*/
+ plane->current_display = display;
+
+ tdm_layer_get_zpos(layer, &zpos);
+ plane->current_stack_index = zpos;
+
+ plane->prop.currentDisplay = VK_TO_HANDLE(VkDisplayKHR, plane->current_display);
+ plane->prop.currentStackIndex = plane->current_stack_index;
+
+ pdev->plane_count++;
+}
+
+static void
+plane_fini(vk_display_plane_t *plane)
+{
+ /* Do Nothing */
+}
+
+static void
+add_tdm_output(vk_physical_device_t *pdev, tdm_output *output)
+{
+ vk_display_t *display = &pdev->displays[pdev->display_count];
+ const char *str;
+ unsigned int w, h;
+ int count, i;
+ const tdm_output_mode *modes;
+ tdm_error error;
+
+ display->pdev = pdev;
+ display->tdm_output = output;
+
+ /* Initialize modes. */
+ tdm_output_get_available_modes(output, &modes, &count);
+ VK_ASSERT(count > 0);
+
+ display->built_in_modes = calloc(count, sizeof(vk_display_mode_t));
+ VK_CHECK(display->built_in_modes, return, "calloc() failed.\n");
+
+ for (i = 0; i < count; i++) {
+ display->built_in_modes[i].display = display;
+ display->built_in_modes[i].prop.displayMode =
+ VK_TO_HANDLE(VkDisplayModeKHR, &display->built_in_modes[i]);
+ display->built_in_modes[i].prop.parameters.visibleRegion.width = modes[i].hdisplay;
+ display->built_in_modes[i].prop.parameters.visibleRegion.height = modes[i].vdisplay;
+ display->built_in_modes[i].prop.parameters.refreshRate = modes[i].vrefresh;
+ }
+
+ display->custom_mode_count = 0;
+ display->custom_modes = NULL;
+
+ /* Initialize prop. */
+ display->prop.display = VK_TO_HANDLE(VkDisplayKHR, display);
+
+ tdm_output_get_model_info(output, NULL, NULL, &str);
+ display->prop.displayName = strdup(str);
+
+ tdm_output_get_physical_size(output, &w, &h);
+ display->prop.physicalDimensions.width = w;
+ display->prop.physicalDimensions.height = h;
+
+ /* TODO: Physical Resolution */
+
+ /* TODO: Transform */
+ display->prop.supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+
+ /* TODO: Changing Z pos is only allowed for video layers. */
+ display->prop.planeReorderPossible = VK_FALSE;
+
+ display->prop.persistentContent = VK_FALSE;
+
+ /* Add layers */
+ error = tdm_output_get_layer_count(output, &count);
+
+ for (i = 0; i < count; i++) {
+ tdm_layer *layer = tdm_output_get_layer(output, i, &error);
+ add_tdm_layer(pdev, layer, display, output);
+ }
+
+ /* Finally increase display count. */
+ pdev->display_count++;
+}
+
+static void
+display_fini(vk_display_t *display)
+{
+ if (display->built_in_modes)
+ free(display->built_in_modes);
+
+ if (display->custom_modes)
+ free(display->custom_modes);
+}
+
void
-vk_display_init(vk_physical_device_t *pdev)
+vk_physical_device_fini_display(vk_physical_device_t *pdev)
{
- /* TODO: */
+ uint32_t i;
+
+ for (i = 0; i < pdev->display_count; i++)
+ display_fini(&pdev->displays[i]);
+
+ for (i = 0; i < pdev->plane_count; i++)
+ plane_fini(&pdev->planes[i]);
+ if (pdev->tdm_display)
+ tdm_display_deinit(pdev->tdm_display);
+
+ pdev->tdm_display = NULL;
pdev->display_count = 0;
- pdev->displays = NULL;
+ pdev->plane_count = 0;
+}
+VkBool32
+vk_physical_device_init_display(vk_physical_device_t *pdev)
+{
+ tdm_error err;
+ int output_count, i;
+
+ pdev->tdm_display = NULL;
+ pdev->display_count = 0;
pdev->plane_count = 0;
- pdev->planes = NULL;
+
+ /* Initialize TDM display. */
+ pdev->tdm_display = tdm_display_init(&err);
+ VK_CHECK(err == TDM_ERROR_NONE, goto error, "tdm_display_init() failed.\n");
+
+ /* Get total output count. */
+ err = tdm_display_get_output_count(pdev->tdm_display, &output_count);
+ VK_CHECK(err == TDM_ERROR_NONE, goto error, "tdm_display_get_output_count() failed.\n");
+
+ /* Add TDM outputs. */
+ for (i = 0; i < output_count; i++) {
+ tdm_output *output = tdm_display_get_output(pdev->tdm_display, i, &err);
+ VK_CHECK(err == TDM_ERROR_NONE, goto error, "tdm_display_get_output() failed.\n");
+ add_tdm_output(pdev, output);
+ }
+
+ return VK_TRUE;
+
+error:
+ vk_physical_device_fini_display(pdev);
+ return VK_FALSE;
}
VKAPI_ATTR VkResult VKAPI_CALL
#include <vulkan/vk_icd.h>
#include <utils.h>
#include <tpl.h>
+#include <tdm.h>
#define VK_TO_HANDLE(type, x) ((type)((uintptr_t)(x)))
#define VK_TO_POINTER(type, x) ((type *)((uintptr_t)(x)))
+#define VK_MAX_DISPLAY_COUNT 16
+#define VK_MAX_PLANE_COUNT 64
+
typedef struct vk_surface vk_surface_t;
typedef struct vk_swapchain vk_swapchain_t;
typedef struct vk_buffer vk_buffer_t;
vk_icd_t *
vk_get_icd(void);
-struct vk_physical_device {
- VkPhysicalDevice pdev;
-
- uint32_t display_count;
- vk_display_t *displays;
-
- uint32_t plane_count;
- vk_display_plane_t *planes;
-};
-
vk_physical_device_t *
vk_get_physical_device(VkPhysicalDevice pdev);
struct vk_display {
+ vk_physical_device_t *pdev;
+
+ tdm_output *tdm_output;
+
VkDisplayPropertiesKHR prop;
uint32_t built_in_mode_count;
uint32_t custom_mode_count;
vk_display_mode_t *custom_modes;
-
- vk_display_plane_t *current_plane;
};
struct vk_display_plane {
- VkDisplayPlanePropertiesKHR prop;
+ vk_physical_device_t *pdev;
+
+ tdm_layer *tdm_layer;
- uint32_t supported_display_count;
- vk_display_t **supported_displays;
+ VkDisplayPlanePropertiesKHR prop;
- vk_display_t *current_display;
- uint32_t current_stack_index;
+ uint32_t supported_display_count;
+ vk_display_t *supported_displays[VK_MAX_DISPLAY_COUNT];
+
+ vk_display_t *current_display;
+ uint32_t current_stack_index;
};
struct vk_display_mode {
- VkDisplayModePropertiesKHR prop;
vk_display_t *display;
+ VkDisplayModePropertiesKHR prop;
+};
+
+struct vk_physical_device {
+ VkPhysicalDevice pdev;
+
+ tdm_display *tdm_display;
+
+ uint32_t display_count;
+ vk_display_t displays[VK_MAX_DISPLAY_COUNT];
+
+ uint32_t plane_count;
+ vk_display_plane_t planes[VK_MAX_PLANE_COUNT];
};
struct vk_buffer {
vk_buffer_t *buffers;
};
+VkBool32
+vk_physical_device_init_display(vk_physical_device_t *pdev);
+
void
-vk_display_init(vk_physical_device_t *pdev);
+vk_physical_device_fini_display(vk_physical_device_t *pdev);
const VkAllocationCallbacks *
vk_get_allocator(void *parent, const VkAllocationCallbacks *allocator);