2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **********************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "brw_state.h"
34 #include "intel_batchbuffer.h"
37 /* XXX: Fixme - have to include these to get the sizes of the prog_key
47 /***********************************************************************
48 * Check cache for uploaded version of struct, else upload new one.
49 * Fail when memory is exhausted.
51 * XXX: FIXME: Currently search is so slow it would be quicker to
52 * regenerate the data every time...
55 static GLuint
hash_key( const void *key
, GLuint key_size
)
57 GLuint
*ikey
= (GLuint
*)key
;
60 assert(key_size
% 4 == 0);
62 /* I'm sure this can be improved on:
64 for (i
= 0; i
< key_size
/4; i
++)
70 static struct brw_cache_item
*search_cache( struct brw_cache
*cache
,
75 struct brw_cache_item
*c
;
77 for (c
= cache
->items
[hash
% cache
->size
]; c
; c
= c
->next
) {
78 if (c
->hash
== hash
&&
79 c
->key_size
== key_size
&&
80 memcmp(c
->key
, key
, key_size
) == 0)
88 static void rehash( struct brw_cache
*cache
)
90 struct brw_cache_item
**items
;
91 struct brw_cache_item
*c
, *next
;
94 size
= cache
->size
* 3;
95 items
= (struct brw_cache_item
**) _mesa_malloc(size
* sizeof(*items
));
96 _mesa_memset(items
, 0, size
* sizeof(*items
));
98 for (i
= 0; i
< cache
->size
; i
++)
99 for (c
= cache
->items
[i
]; c
; c
= next
) {
101 c
->next
= items
[c
->hash
% size
];
102 items
[c
->hash
% size
] = c
;
106 cache
->items
= items
;
111 GLboolean
brw_search_cache( struct brw_cache
*cache
,
115 GLuint
*offset_return
)
117 struct brw_cache_item
*item
;
119 GLuint hash
= hash_key(key
, key_size
);
121 item
= search_cache(cache
, hash
, key
, key_size
);
125 *(void **)aux_return
= (void *)((char *)item
->key
+ item
->key_size
);
127 *offset_return
= addr
= item
->offset
;
130 if (item
== NULL
|| addr
!= cache
->last_addr
) {
131 cache
->brw
->state
.dirty
.cache
|= 1<<cache
->id
;
132 cache
->last_addr
= addr
;
138 GLuint
brw_upload_cache( struct brw_cache
*cache
,
147 struct brw_cache_item
*item
= CALLOC_STRUCT(brw_cache_item
);
148 GLuint hash
= hash_key(key
, key_size
);
149 void *tmp
= _mesa_malloc(key_size
+ cache
->aux_size
);
151 if (!brw_pool_alloc(cache
->pool
, data_size
, 6, &offset
)) {
152 /* Should not be possible:
154 _mesa_printf("brw_pool_alloc failed\n");
158 memcpy(tmp
, key
, key_size
);
161 memcpy(tmp
+key_size
, aux
, cache
->aux_size
);
165 item
->key_size
= key_size
;
166 item
->offset
= offset
;
167 item
->data_size
= data_size
;
169 if (++cache
->n_items
> cache
->size
* 1.5)
173 item
->next
= cache
->items
[hash
];
174 cache
->items
[hash
] = item
;
177 assert(cache
->aux_size
);
178 *(void **)aux_return
= (void *)((char *)item
->key
+ item
->key_size
);
181 if (INTEL_DEBUG
& DEBUG_STATE
)
182 _mesa_printf("upload %s: %d bytes to pool buffer %d offset %x\n",
188 /* Copy data to the buffer:
190 bmBufferSubData(&cache
->brw
->intel
,
197 cache
->brw
->state
.dirty
.cache
|= 1<<cache
->id
;
198 cache
->last_addr
= offset
;
203 /* This doesn't really work with aux data. Use search/upload instead
205 GLuint
brw_cache_data_sz(struct brw_cache
*cache
,
211 if (!brw_search_cache(cache
, data
, data_size
, NULL
, &addr
)) {
212 addr
= brw_upload_cache(cache
,
221 GLuint
brw_cache_data(struct brw_cache
*cache
,
224 return brw_cache_data_sz(cache
, data
, cache
->key_size
);
232 static void brw_init_cache( struct brw_context
*brw
,
237 enum pool_type pool_type
)
239 struct brw_cache
*cache
= &brw
->cache
[id
];
247 cache
->items
= (struct brw_cache_item
**)
248 _mesa_calloc(cache
->size
*
249 sizeof(struct brw_cache_item
));
252 cache
->key_size
= key_size
;
253 cache
->aux_size
= aux_size
;
255 case DW_GENERAL_STATE
: cache
->pool
= &brw
->pool
[BRW_GS_POOL
]; break;
256 case DW_SURFACE_STATE
: cache
->pool
= &brw
->pool
[BRW_SS_POOL
]; break;
257 default: assert(0); break;
261 void brw_init_caches( struct brw_context
*brw
)
267 sizeof(struct brw_cc_viewport
),
274 sizeof(struct brw_cc_unit_state
),
281 sizeof(struct brw_wm_prog_key
),
282 sizeof(struct brw_wm_prog_data
),
286 "SAMPLER_DEFAULT_COLOR",
287 BRW_SAMPLER_DEFAULT_COLOR
,
288 sizeof(struct brw_sampler_default_color
),
295 0, /* variable key/data size */
302 sizeof(struct brw_wm_unit_state
),
309 sizeof(struct brw_sf_prog_key
),
310 sizeof(struct brw_sf_prog_data
),
316 sizeof(struct brw_sf_viewport
),
323 sizeof(struct brw_sf_unit_state
),
330 sizeof(struct brw_vs_unit_state
),
337 sizeof(struct brw_vs_prog_key
),
338 sizeof(struct brw_vs_prog_data
),
344 sizeof(struct brw_clip_unit_state
),
351 sizeof(struct brw_clip_prog_key
),
352 sizeof(struct brw_clip_prog_data
),
358 sizeof(struct brw_gs_unit_state
),
365 sizeof(struct brw_gs_prog_key
),
366 sizeof(struct brw_gs_prog_data
),
372 sizeof(struct brw_surface_state
),
379 sizeof(struct brw_surface_binding_table
),
385 /* When we lose hardware context, need to invalidate the surface cache
386 * as these structs must be explicitly re-uploaded. They are subject
387 * to fixup by the memory manager as they contain absolute agp
388 * offsets, so we need to ensure there is a fresh version of the
389 * struct available to receive the fixup.
391 * XXX: Need to ensure that there aren't two versions of a surface or
392 * bufferobj with different backing data active in the same buffer at
393 * once? Otherwise the cache could confuse them. Maybe better not to
396 * --> Isn't this the same as saying need to ensure batch is flushed
397 * before new data is uploaded to an existing buffer? We
398 * already try to make sure of that.
400 static void clear_cache( struct brw_cache
*cache
)
402 struct brw_cache_item
*c
, *next
;
405 for (i
= 0; i
< cache
->size
; i
++) {
406 for (c
= cache
->items
[i
]; c
; c
= next
) {
408 free((void *)c
->key
);
411 cache
->items
[i
] = NULL
;
417 void brw_clear_all_caches( struct brw_context
*brw
)
421 if (INTEL_DEBUG
& DEBUG_STATE
)
422 _mesa_printf("%s\n", __FUNCTION__
);
424 for (i
= 0; i
< BRW_MAX_CACHE
; i
++)
425 clear_cache(&brw
->cache
[i
]);
427 if (brw
->curbe
.last_buf
) {
428 _mesa_free(brw
->curbe
.last_buf
);
429 brw
->curbe
.last_buf
= NULL
;
432 brw
->state
.dirty
.mesa
|= ~0;
433 brw
->state
.dirty
.brw
|= ~0;
434 brw
->state
.dirty
.cache
|= ~0;
441 void brw_destroy_caches( struct brw_context
*brw
)
445 for (i
= 0; i
< BRW_MAX_CACHE
; i
++)
446 clear_cache(&brw
->cache
[i
]);