Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5562 → Rev 5563

/contrib/sdk/sources/Mesa/mesa-9.2.5/src/gallium/drivers/ilo/ilo_cp.h
0,0 → 1,363
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2012-2013 LunarG, Inc.
*
* 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 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.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#ifndef ILO_CP_H
#define ILO_CP_H
 
#include "intel_winsys.h"
 
#include "ilo_common.h"
 
struct ilo_cp;
 
enum ilo_cp_ring {
ILO_CP_RING_RENDER,
ILO_CP_RING_BLT,
 
ILO_CP_RING_COUNT,
};
 
typedef void (*ilo_cp_callback)(struct ilo_cp *cp, void *data);
 
struct ilo_cp_owner {
ilo_cp_callback release_callback;
void *release_data;
};
 
/**
* Command parser.
*/
struct ilo_cp {
struct intel_winsys *winsys;
struct intel_context *render_ctx;
 
ilo_cp_callback flush_callback;
void *flush_callback_data;
 
const struct ilo_cp_owner *owner;
int owner_reserve;
 
enum ilo_cp_ring ring;
bool no_implicit_flush;
unsigned one_off_flags;
 
int bo_size;
struct intel_bo *bo;
uint32_t *sys;
 
uint32_t *ptr;
int size, used, stolen;
 
int cmd_cur, cmd_end;
};
 
/**
* Jump buffer to save command parser state for rewind.
*/
struct ilo_cp_jmp_buf {
intptr_t id;
int size, used, stolen;
int reloc_count;
};
 
struct ilo_cp *
ilo_cp_create(struct intel_winsys *winsys, bool direct_map);
 
void
ilo_cp_destroy(struct ilo_cp *cp);
 
void
ilo_cp_flush(struct ilo_cp *cp);
 
void
ilo_cp_dump(struct ilo_cp *cp);
 
void
ilo_cp_setjmp(struct ilo_cp *cp, struct ilo_cp_jmp_buf *jmp);
 
void
ilo_cp_longjmp(struct ilo_cp *cp, const struct ilo_cp_jmp_buf *jmp);
 
/**
* Return true if the parser buffer is empty.
*/
static inline bool
ilo_cp_empty(struct ilo_cp *cp)
{
return !cp->used;
}
 
/**
* Return the remaining space (in dwords) in the parser buffer.
*/
static inline int
ilo_cp_space(struct ilo_cp *cp)
{
return cp->size - cp->used;
}
 
/**
* Internal function called by functions that flush implicitly.
*/
static inline void
ilo_cp_implicit_flush(struct ilo_cp *cp)
{
if (cp->no_implicit_flush) {
assert(!"unexpected command parser flush");
/* discard the commands */
cp->used = 0;
}
 
ilo_cp_flush(cp);
}
 
/**
* Set the ring buffer.
*/
static inline void
ilo_cp_set_ring(struct ilo_cp *cp, enum ilo_cp_ring ring)
{
if (cp->ring != ring) {
ilo_cp_implicit_flush(cp);
cp->ring = ring;
}
}
 
/**
* Assert that no function should flush implicitly.
*/
static inline void
ilo_cp_assert_no_implicit_flush(struct ilo_cp *cp, bool enable)
{
cp->no_implicit_flush = enable;
}
 
/**
* Set one-off flags. They will be cleared after flushing.
*/
static inline void
ilo_cp_set_one_off_flags(struct ilo_cp *cp, unsigned flags)
{
cp->one_off_flags |= flags;
}
 
/**
* Set flush callback. The callback is invoked after the bo has been
* successfully executed, and before the bo is reallocated.
*/
static inline void
ilo_cp_set_flush_callback(struct ilo_cp *cp, ilo_cp_callback callback,
void *data)
{
cp->flush_callback = callback;
cp->flush_callback_data = data;
}
 
/**
* Set the parser owner. If this is a new owner, the previous owner is
* notified and the space it reserved is reclaimed.
*
* \return true if this is a new owner
*/
static inline bool
ilo_cp_set_owner(struct ilo_cp *cp, const struct ilo_cp_owner *owner,
int reserve)
{
const bool new_owner = (cp->owner != owner);
 
/* release current owner */
if (new_owner && cp->owner) {
const bool no_implicit_flush = cp->no_implicit_flush;
 
/* reclaim the reserved space */
cp->size += cp->owner_reserve;
cp->owner_reserve = 0;
 
/* invoke the release callback */
cp->no_implicit_flush = true;
cp->owner->release_callback(cp, cp->owner->release_data);
cp->no_implicit_flush = no_implicit_flush;
 
cp->owner = NULL;
}
 
if (cp->owner_reserve != reserve) {
const int extra = reserve - cp->owner_reserve;
 
if (cp->used > cp->size - extra) {
ilo_cp_implicit_flush(cp);
assert(cp->used <= cp->size - reserve);
 
cp->size -= reserve;
cp->owner_reserve = reserve;
}
else {
cp->size -= extra;
cp->owner_reserve += extra;
}
}
 
/* set owner last because of the possible flush above */
cp->owner = owner;
 
return new_owner;
}
 
/**
* Begin writing a command.
*/
static inline void
ilo_cp_begin(struct ilo_cp *cp, int cmd_size)
{
if (cp->used + cmd_size > cp->size) {
ilo_cp_implicit_flush(cp);
assert(cp->used + cmd_size <= cp->size);
}
 
assert(cp->cmd_cur == cp->cmd_end);
cp->cmd_cur = cp->used;
cp->cmd_end = cp->cmd_cur + cmd_size;
cp->used = cp->cmd_end;
}
 
/**
* Begin writing data to a space stolen from the top of the parser buffer.
*
* \param desc informative description of the data to be written
* \param data_size in dwords
* \param align in dwords
* \param bo_offset in bytes to the stolen space
*/
static inline void
ilo_cp_steal(struct ilo_cp *cp, const char *desc,
int data_size, int align, uint32_t *bo_offset)
{
int pad, steal;
 
if (!align)
align = 1;
 
pad = (cp->bo_size - cp->stolen - data_size) % align;
steal = data_size + pad;
 
/* flush if there is not enough space after stealing */
if (cp->used > cp->size - steal) {
ilo_cp_implicit_flush(cp);
 
pad = (cp->bo_size - cp->stolen - data_size) % align;
steal = data_size + steal;
 
assert(cp->used <= cp->size - steal);
}
 
cp->size -= steal;
cp->stolen += steal;
 
assert(cp->cmd_cur == cp->cmd_end);
cp->cmd_cur = cp->bo_size - cp->stolen;
cp->cmd_end = cp->cmd_cur + data_size;
 
/* offset in cp->bo */
if (bo_offset)
*bo_offset = cp->cmd_cur * 4;
}
 
/**
* Write a dword to the parser buffer. This function must be enclosed by
* ilo_cp_begin()/ilo_cp_steal() and ilo_cp_end().
*/
static inline void
ilo_cp_write(struct ilo_cp *cp, uint32_t val)
{
assert(cp->cmd_cur < cp->cmd_end);
cp->ptr[cp->cmd_cur++] = val;
}
 
/**
* Write multiple dwords to the parser buffer.
*/
static inline void
ilo_cp_write_multi(struct ilo_cp *cp, const void *vals, int num_vals)
{
assert(cp->cmd_cur + num_vals <= cp->cmd_end);
memcpy(cp->ptr + cp->cmd_cur, vals, num_vals * 4);
cp->cmd_cur += num_vals;
}
 
/**
* Write a bo to the parser buffer. In addition to writing the offset of the
* bo to the buffer, it also emits a relocation.
*/
static inline void
ilo_cp_write_bo(struct ilo_cp *cp, uint32_t val, struct intel_bo *bo,
uint32_t read_domains, uint32_t write_domain)
{
if (bo) {
intel_bo_emit_reloc(cp->bo, cp->cmd_cur * 4,
bo, val, read_domains, write_domain);
 
ilo_cp_write(cp, val + intel_bo_get_offset(bo));
}
else {
ilo_cp_write(cp, val);
}
}
 
/**
* End a command. Every ilo_cp_begin() or ilo_cp_steal() must have a
* matching ilo_cp_end().
*/
static inline void
ilo_cp_end(struct ilo_cp *cp)
{
assert(cp->cmd_cur == cp->cmd_end);
}
 
/**
* A variant of ilo_cp_steal() where the data are written via the returned
* pointer.
*
* \return ptr pointer where the data are written to. It is valid until any
* change is made to the parser.
*/
static inline void *
ilo_cp_steal_ptr(struct ilo_cp *cp, const char *desc,
int data_size, int align, uint32_t *bo_offset)
{
void *ptr;
 
ilo_cp_steal(cp, desc, data_size, align, bo_offset);
 
ptr = &cp->ptr[cp->cmd_cur];
cp->cmd_cur = cp->cmd_end;
 
ilo_cp_end(cp);
 
return ptr;
}
 
#endif /* ILO_CP_H */