This is a map of miptree slices to needed resolves, implemented as a linked list. A future commit will embed such a list in intel_mipmap_tree. If you think I'm crazy to put a list in a miptree, read the Doxygen in this patch for intel_resolve_map. v2: [anholt] Move Doxygen from functin prototypes to definitions. Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Chad Versace <chad.versace@linux.intel.com>tags/mesa-8.0-rc1
| @@ -15,6 +15,7 @@ i965_C_SOURCES := \ | |||
| intel_fbo.c \ | |||
| intel_mipmap_tree.c \ | |||
| intel_regions.c \ | |||
| intel_resolve_map.c \ | |||
| intel_screen.c \ | |||
| intel_span.c \ | |||
| intel_pixel.c \ | |||
| @@ -0,0 +1 @@ | |||
| ../intel/intel_resolve_map.c | |||
| @@ -0,0 +1,111 @@ | |||
| /* | |||
| * Copyright © 2011 Intel Corporation | |||
| * | |||
| * Permission is hereby granted, free of charge, to any person obtaining a | |||
| * copy of this software and associated documentation files (the "Software"), | |||
| * to deal in the Software without restriction, including without limitation | |||
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| * and/or sell copies of the Software, and to permit persons to whom the | |||
| * Software is furnished to do so, subject to the following conditions: | |||
| * | |||
| * The above copyright notice and this permission notice (including the next | |||
| * paragraph) shall be included in all copies or substantial portions of the | |||
| * Software. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |||
| * IN THE SOFTWARE. | |||
| */ | |||
| #include "intel_resolve_map.h" | |||
| #include <assert.h> | |||
| #include <stdlib.h> | |||
| /** | |||
| * \brief Set that the miptree slice at (level, layer) needs a resolve. | |||
| * | |||
| * \pre If a map element already exists with the given key, then | |||
| * the new and existing element value must be identical. | |||
| */ | |||
| void | |||
| intel_resolve_map_set(struct intel_resolve_map *head, | |||
| uint32_t level, | |||
| uint32_t layer, | |||
| enum intel_need_resolve need) | |||
| { | |||
| struct intel_resolve_map **tail = &head->next; | |||
| struct intel_resolve_map *prev = head; | |||
| while (*tail) { | |||
| if ((*tail)->level == level && (*tail)->layer == layer) { | |||
| assert((*tail)->need == need); | |||
| return; | |||
| } | |||
| prev = *tail; | |||
| tail = &(*tail)->next; | |||
| } | |||
| *tail = malloc(sizeof(**tail)); | |||
| (*tail)->prev = prev; | |||
| (*tail)->next = NULL; | |||
| (*tail)->level = level; | |||
| (*tail)->layer = layer; | |||
| (*tail)->need = need; | |||
| } | |||
| /** | |||
| * \brief Get an element from the map. | |||
| * \return null if element is not contained in map. | |||
| */ | |||
| struct intel_resolve_map* | |||
| intel_resolve_map_get(struct intel_resolve_map *head, | |||
| uint32_t level, | |||
| uint32_t layer) | |||
| { | |||
| struct intel_resolve_map *item = head->next; | |||
| while (item) { | |||
| if (item->level == level && item->layer == layer) | |||
| break; | |||
| else | |||
| item = item->next; | |||
| } | |||
| return item; | |||
| } | |||
| /** | |||
| * \brief Remove and free an element from the map. | |||
| */ | |||
| void | |||
| intel_resolve_map_remove(struct intel_resolve_map *elem) | |||
| { | |||
| if (elem->prev) | |||
| elem->prev->next = elem->next; | |||
| if (elem->next) | |||
| elem->next->prev = elem->prev; | |||
| free(elem); | |||
| } | |||
| /** | |||
| * \brief Remove and free all elements of the map. | |||
| */ | |||
| void | |||
| intel_resolve_map_clear(struct intel_resolve_map *head) | |||
| { | |||
| struct intel_resolve_map *next = head->next; | |||
| struct intel_resolve_map *trash; | |||
| while (next) { | |||
| trash = next; | |||
| next = next->next; | |||
| free(trash); | |||
| } | |||
| head->next = NULL; | |||
| } | |||
| @@ -0,0 +1,83 @@ | |||
| /* | |||
| * Copyright © 2011 Intel Corporation | |||
| * | |||
| * Permission is hereby granted, free of charge, to any person obtaining a | |||
| * copy of this software and associated documentation files (the "Software"), | |||
| * to deal in the Software without restriction, including without limitation | |||
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| * and/or sell copies of the Software, and to permit persons to whom the | |||
| * Software is furnished to do so, subject to the following conditions: | |||
| * | |||
| * The above copyright notice and this permission notice (including the next | |||
| * paragraph) shall be included in all copies or substantial portions of the | |||
| * Software. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |||
| * IN THE SOFTWARE. | |||
| */ | |||
| #pragma once | |||
| #include <stdint.h> | |||
| enum intel_need_resolve { | |||
| INTEL_NEED_HIZ_RESOLVE, | |||
| INTEL_NEED_DEPTH_RESOLVE, | |||
| }; | |||
| /** | |||
| * \brief Map of miptree slices to needed resolves. | |||
| * | |||
| * The map is implemented as a linear doubly-linked list. | |||
| * | |||
| * In the intel_resolve_map*() functions, the \c head argument is not | |||
| * inspected for its data. It only serves as an anchor for the list. | |||
| * | |||
| * \par Design Discussion | |||
| * | |||
| * There are two possible ways to record which miptree slices need | |||
| * resolves. 1) Maintain a flag for every miptree slice in the texture, | |||
| * likely in intel_mipmap_level::slice, or 2) maintain a list of only | |||
| * those slices that need a resolve. | |||
| * | |||
| * Immediately before drawing, a full depth resolve performed on each | |||
| * enabled depth texture. If design 1 were chosen, then at each draw call | |||
| * it would be necessary to iterate over each miptree slice of each | |||
| * enabled depth texture in order to query if each slice needed a resolve. | |||
| * In the worst case, this would require 2^16 iterations: 16 texture | |||
| * units, 16 miplevels, and 256 depth layers (assuming maximums for OpenGL | |||
| * 2.1). | |||
| * | |||
| * By choosing design 2, the number of iterations is exactly the minimum | |||
| * necessary. | |||
| */ | |||
| struct intel_resolve_map { | |||
| uint32_t level; | |||
| uint32_t layer; | |||
| enum intel_need_resolve need; | |||
| struct intel_resolve_map *next; | |||
| struct intel_resolve_map *prev; | |||
| }; | |||
| void | |||
| intel_resolve_map_set(struct intel_resolve_map *head, | |||
| uint32_t level, | |||
| uint32_t layer, | |||
| enum intel_need_resolve need); | |||
| struct intel_resolve_map* | |||
| intel_resolve_map_get(struct intel_resolve_map *head, | |||
| uint32_t level, | |||
| uint32_t layer); | |||
| void | |||
| intel_resolve_map_remove(struct intel_resolve_map *elem); | |||
| void | |||
| intel_resolve_map_clear(struct intel_resolve_map *head); | |||