mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 01:38:06 +02:00
nouveau: say goodbye to the old DRI driver...
This commit is contained in:
parent
4fab47b13c
commit
93115c4b23
63 changed files with 1 additions and 21640 deletions
|
|
@ -70,4 +70,4 @@ WINDOW_SYSTEM=dri
|
|||
# gamma are missing because they have not been converted to use the new
|
||||
# interface.
|
||||
DRI_DIRS = i810 i915 mach64 mga r128 r200 r300 radeon s3v \
|
||||
savage sis tdfx trident unichrome ffb nouveau
|
||||
savage sis tdfx trident unichrome ffb
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
# src/mesa/drivers/dri/nouveau/Makefile
|
||||
|
||||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = nouveau_dri.so
|
||||
|
||||
MINIGLX_SOURCES =
|
||||
|
||||
DRIVER_SOURCES = \
|
||||
nouveau_bufferobj.c \
|
||||
nouveau_card.c \
|
||||
nouveau_context.c \
|
||||
nouveau_driver.c \
|
||||
nouveau_fbo.c \
|
||||
nouveau_fifo.c \
|
||||
nouveau_lock.c \
|
||||
nouveau_mem.c \
|
||||
nouveau_object.c \
|
||||
nouveau_screen.c \
|
||||
nouveau_span.c \
|
||||
nouveau_state.c \
|
||||
nouveau_state_cache.c \
|
||||
nouveau_shader.c \
|
||||
nouveau_shader_0.c \
|
||||
nouveau_shader_1.c \
|
||||
nouveau_shader_2.c \
|
||||
nouveau_tex.c \
|
||||
nouveau_swtcl.c \
|
||||
nouveau_sync.c \
|
||||
nouveau_query.c \
|
||||
nv04_state.c \
|
||||
nv04_swtcl.c \
|
||||
nv10_state.c \
|
||||
nv10_swtcl.c \
|
||||
nv20_state.c \
|
||||
nv20_vertprog.c \
|
||||
nv30_state.c \
|
||||
nv30_fragprog.c \
|
||||
nv30_vertprog.c \
|
||||
nv40_fragprog.c \
|
||||
nv40_vertprog.c \
|
||||
nv50_state.c
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_SOURCES) \
|
||||
$(DRIVER_SOURCES)
|
||||
|
||||
ASM_SOURCES =
|
||||
|
||||
|
||||
include ../Makefile.template
|
||||
|
||||
symlinks:
|
||||
|
|
@ -1,627 +0,0 @@
|
|||
#include "bufferobj.h"
|
||||
#include "enums.h"
|
||||
|
||||
#include "nouveau_bufferobj.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_mem.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_object.h"
|
||||
|
||||
#define NOUVEAU_MEM_FREE(mem) do { \
|
||||
nouveau_mem_free(ctx, (mem)); \
|
||||
(mem) = NULL; \
|
||||
} while(0)
|
||||
|
||||
#define DEBUG(fmt,args...) do { \
|
||||
if (NOUVEAU_DEBUG & DEBUG_BUFFEROBJ) { \
|
||||
fprintf(stderr, "%s: "fmt, __func__, ##args); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static GLboolean
|
||||
nouveau_bo_download_from_screen(GLcontext *ctx, GLuint offset, GLuint size,
|
||||
struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
nouveau_mem *in_mem;
|
||||
|
||||
DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size);
|
||||
|
||||
/* If there's a permanent backing store, blit directly into it */
|
||||
if (nbo->cpu_mem) {
|
||||
if (nbo->cpu_mem != nbo->gpu_mem) {
|
||||
DEBUG("..cpu_mem\n");
|
||||
nouveau_memformat_flat_emit(ctx, nbo->cpu_mem,
|
||||
nbo->gpu_mem,
|
||||
offset, offset, size);
|
||||
}
|
||||
} else {
|
||||
DEBUG("..sys_mem\n");
|
||||
in_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP, size, 0);
|
||||
if (in_mem) {
|
||||
DEBUG("....via GART\n");
|
||||
/* otherwise, try blitting to faster memory and
|
||||
* copying from there
|
||||
*/
|
||||
nouveau_memformat_flat_emit(ctx, in_mem, nbo->gpu_mem,
|
||||
0, offset, size);
|
||||
nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier,
|
||||
NvSubMemFormat);
|
||||
_mesa_memcpy(nbo->cpu_mem_sys + offset,
|
||||
in_mem->map, size);
|
||||
NOUVEAU_MEM_FREE(in_mem);
|
||||
} else {
|
||||
DEBUG("....direct VRAM copy\n");
|
||||
/* worst case, copy directly from vram */
|
||||
_mesa_memcpy(nbo->cpu_mem_sys + offset,
|
||||
nbo->gpu_mem + offset,
|
||||
size);
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
nouveau_bo_upload_to_screen(GLcontext *ctx, GLuint offset, GLuint size,
|
||||
struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
nouveau_mem *out_mem;
|
||||
|
||||
DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size);
|
||||
|
||||
if (nbo->cpu_mem) {
|
||||
if (nbo->cpu_mem != nbo->gpu_mem) {
|
||||
DEBUG("..cpu_mem\n");
|
||||
nouveau_memformat_flat_emit(ctx, nbo->gpu_mem,
|
||||
nbo->cpu_mem,
|
||||
offset, offset, size);
|
||||
}
|
||||
} else {
|
||||
out_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP |
|
||||
NOUVEAU_MEM_MAPPED,
|
||||
size, 0);
|
||||
if (out_mem) {
|
||||
DEBUG("....via GART\n");
|
||||
_mesa_memcpy(out_mem->map,
|
||||
nbo->cpu_mem_sys + offset, size);
|
||||
nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, out_mem,
|
||||
offset, 0, size);
|
||||
nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier,
|
||||
NvSubMemFormat);
|
||||
NOUVEAU_MEM_FREE(out_mem);
|
||||
} else {
|
||||
DEBUG("....direct VRAM copy\n");
|
||||
_mesa_memcpy(nbo->gpu_mem->map + offset,
|
||||
nbo->cpu_mem_sys + offset,
|
||||
size);
|
||||
}
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
|
||||
DEBUG("bo=%p\n", bo);
|
||||
|
||||
if (bo->OnCard)
|
||||
return GL_TRUE;
|
||||
assert(nbo->gpu_mem_flags);
|
||||
|
||||
nbo->gpu_mem = nouveau_mem_alloc(ctx, nbo->gpu_mem_flags |
|
||||
NOUVEAU_MEM_MAPPED,
|
||||
bo->Size, 0);
|
||||
assert(nbo->gpu_mem);
|
||||
|
||||
if (nbo->cpu_mem_flags) {
|
||||
if ((nbo->cpu_mem_flags|NOUVEAU_MEM_MAPPED) != nbo->gpu_mem->type) {
|
||||
DEBUG("..need cpu_mem buffer\n");
|
||||
|
||||
nbo->cpu_mem = nouveau_mem_alloc(ctx,
|
||||
nbo->cpu_mem_flags |
|
||||
NOUVEAU_MEM_MAPPED,
|
||||
bo->Size, 0);
|
||||
|
||||
if (nbo->cpu_mem) {
|
||||
DEBUG("....alloc ok, kill sys_mem buffer\n");
|
||||
_mesa_memcpy(nbo->cpu_mem->map,
|
||||
nbo->cpu_mem_sys, bo->Size);
|
||||
FREE(nbo->cpu_mem_sys);
|
||||
}
|
||||
} else {
|
||||
DEBUG("..cpu direct access to GPU buffer\n");
|
||||
nbo->cpu_mem = nbo->gpu_mem;
|
||||
}
|
||||
}
|
||||
nouveau_bo_upload_to_screen(ctx, 0, bo->Size, bo);
|
||||
|
||||
bo->OnCard = GL_TRUE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
GLuint nr_dirty;
|
||||
|
||||
DEBUG("bo=%p\n", bo);
|
||||
if (!bo->OnCard)
|
||||
return GL_TRUE;
|
||||
|
||||
nr_dirty = nouveau_bo_download_dirty(ctx, bo);
|
||||
if (nbo->cpu_mem) {
|
||||
if (nr_dirty && nbo->cpu_mem != nbo->gpu_mem)
|
||||
nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier,
|
||||
NvSubMemFormat);
|
||||
DEBUG("..destroy cpu_mem buffer\n");
|
||||
nbo->cpu_mem_sys = malloc(bo->Size);
|
||||
assert(nbo->cpu_mem_sys);
|
||||
_mesa_memcpy(nbo->cpu_mem_sys, nbo->cpu_mem->map, bo->Size);
|
||||
if (nbo->cpu_mem == nbo->gpu_mem)
|
||||
nbo->cpu_mem = NULL;
|
||||
else
|
||||
NOUVEAU_MEM_FREE(nbo->cpu_mem);
|
||||
}
|
||||
NOUVEAU_MEM_FREE(nbo->gpu_mem);
|
||||
|
||||
bo->OnCard = GL_FALSE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_bo_choose_storage_method(GLcontext *ctx, GLenum usage,
|
||||
struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
GLuint gpu_type = 0;
|
||||
GLuint cpu_type = 0;
|
||||
|
||||
switch (usage) {
|
||||
/* Client source, changes often, used by GL many times */
|
||||
case GL_DYNAMIC_DRAW_ARB:
|
||||
gpu_type = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE;
|
||||
cpu_type = NOUVEAU_MEM_AGP;
|
||||
break;
|
||||
/* GL source, changes often, client reads many times */
|
||||
case GL_DYNAMIC_READ_ARB:
|
||||
/* Client source, specified once, used by GL many times */
|
||||
case GL_STATIC_DRAW_ARB:
|
||||
/* GL source, specified once, client reads many times */
|
||||
case GL_STATIC_READ_ARB:
|
||||
/* Client source, specified once, used by GL a few times */
|
||||
case GL_STREAM_DRAW_ARB:
|
||||
/* GL source, specified once, client reads a few times */
|
||||
case GL_STREAM_READ_ARB:
|
||||
/* GL source, changes often, used by GL many times*/
|
||||
case GL_DYNAMIC_COPY_ARB:
|
||||
/* GL source, specified once, used by GL many times */
|
||||
case GL_STATIC_COPY_ARB:
|
||||
/* GL source, specified once, used by GL a few times */
|
||||
case GL_STREAM_COPY_ARB:
|
||||
gpu_type = NOUVEAU_MEM_FB;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
nbo->gpu_mem_flags = gpu_type;
|
||||
nbo->cpu_mem_flags = cpu_type;
|
||||
nbo->usage = usage;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access,
|
||||
GLsizeiptrARB size,
|
||||
const GLvoid *data,
|
||||
GLenum usage,
|
||||
struct gl_buffer_object *bo, int flags)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
|
||||
DEBUG("bo=%p\n", bo);
|
||||
|
||||
/* Free up previous buffers if we can't reuse them */
|
||||
if (nbo->usage != usage ||
|
||||
(nbo->gpu_mem && (nbo->gpu_mem->size != size))) {
|
||||
if (nbo->cpu_mem_sys)
|
||||
FREE(nbo->cpu_mem_sys);
|
||||
if (nbo->cpu_mem) {
|
||||
if (nbo->cpu_mem != nbo->gpu_mem)
|
||||
NOUVEAU_MEM_FREE(nbo->cpu_mem);
|
||||
else
|
||||
nbo->cpu_mem = NULL;
|
||||
}
|
||||
if (nbo->gpu_mem)
|
||||
NOUVEAU_MEM_FREE(nbo->gpu_mem);
|
||||
|
||||
bo->OnCard = GL_FALSE;
|
||||
nbo->cpu_mem_sys = calloc(1, size);
|
||||
}
|
||||
|
||||
nouveau_bo_choose_storage_method(ctx, usage, bo);
|
||||
/* Force off flags that may not be ok for a given buffer */
|
||||
nbo->gpu_mem_flags &= valid_gpu_access;
|
||||
|
||||
bo->Usage = usage;
|
||||
bo->Size = size;
|
||||
|
||||
if (data) {
|
||||
GLvoid *map = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, bo);
|
||||
#ifdef MESA_BIG_ENDIAN
|
||||
int i;
|
||||
if (flags) {
|
||||
for (i = 0; i < size; i+=4) {
|
||||
uint32_t _data = *(unsigned int *)(data+i);
|
||||
_data = ((_data >> 16) | ((_data & 0xffff) << 16));
|
||||
*(unsigned int *)(map+i) = _data;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
_mesa_memcpy(map, data, size);
|
||||
(void)flags; /* get rid of warning */
|
||||
nouveau_bo_dirty_all(ctx, GL_FALSE, bo);
|
||||
nouveau_bo_unmap(ctx, bo);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
nouveau_bo_map(GLcontext *ctx, GLenum access, struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
|
||||
DEBUG("bo=%p, access=%s\n", bo, _mesa_lookup_enum_by_nr(access));
|
||||
|
||||
if (bo->OnCard &&
|
||||
(access == GL_READ_ONLY_ARB || access == GL_READ_WRITE_ARB)) {
|
||||
GLuint nr_dirty;
|
||||
|
||||
DEBUG("..on card\n");
|
||||
nr_dirty = nouveau_bo_download_dirty(ctx, bo);
|
||||
|
||||
/* nouveau_bo_download_dirty won't wait unless it needs to
|
||||
* free a temp buffer, which isn't the case if cpu_mem is
|
||||
* present.
|
||||
*/
|
||||
if (nr_dirty && nbo->cpu_mem && nbo->cpu_mem != nbo->gpu_mem)
|
||||
nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier,
|
||||
NvSubMemFormat);
|
||||
}
|
||||
|
||||
if (nbo->cpu_mem) {
|
||||
DEBUG("..access via cpu_mem\n");
|
||||
return nbo->cpu_mem->map;
|
||||
} else {
|
||||
DEBUG("..access via cpu_mem_sys\n");
|
||||
return nbo->cpu_mem_sys;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo)
|
||||
{
|
||||
DEBUG("unmap bo=%p\n", bo);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
|
||||
assert(nbo->mapped == GL_FALSE);
|
||||
|
||||
DEBUG("gpu_ref\n");
|
||||
|
||||
if (!bo->OnCard) {
|
||||
nouveau_bo_move_in(ctx, bo);
|
||||
bo->OnCard = GL_TRUE;
|
||||
}
|
||||
nouveau_bo_upload_dirty(ctx, bo);
|
||||
|
||||
return nouveau_mem_gpu_offset_get(ctx, nbo->gpu_mem);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card,
|
||||
uint32_t offset, uint32_t size,
|
||||
struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
nouveau_bufferobj_dirty *dirty;
|
||||
uint32_t start = offset;
|
||||
uint32_t end = offset + size;
|
||||
int i;
|
||||
|
||||
if (nbo->cpu_mem == nbo->gpu_mem)
|
||||
return;
|
||||
|
||||
dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty;
|
||||
|
||||
DEBUG("on_card=%d, offset=%d, size=%d, bo=%p\n",
|
||||
on_card, offset, size, bo);
|
||||
|
||||
for (i=0; i<dirty->nr_dirty; i++) {
|
||||
nouveau_bufferobj_region *r = &dirty->dirty[i];
|
||||
|
||||
/* already dirty */
|
||||
if (start >= r->start && end <= r->end) {
|
||||
DEBUG("..already dirty\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* add to the end of a region */
|
||||
if (start >= r->start && start <= r->end) {
|
||||
if (end > r->end) {
|
||||
DEBUG("..extend end of region\n");
|
||||
r->end = end;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* add to the start of a region */
|
||||
if (start < r->start && end >= r->end) {
|
||||
DEBUG("..extend start of region\n");
|
||||
r->start = start;
|
||||
/* .. and to the end */
|
||||
if (end > r->end) {
|
||||
DEBUG("....and end\n");
|
||||
r->end = end;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* new region */
|
||||
DEBUG("..new dirty\n");
|
||||
dirty->nr_dirty++;
|
||||
dirty->dirty = realloc(dirty->dirty,
|
||||
sizeof(nouveau_bufferobj_region) *
|
||||
dirty->nr_dirty);
|
||||
dirty->dirty[dirty->nr_dirty - 1].start = start;
|
||||
dirty->dirty[dirty->nr_dirty - 1].end = end;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card,
|
||||
struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
nouveau_bufferobj_dirty *dirty;
|
||||
|
||||
dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty;
|
||||
|
||||
DEBUG("dirty all\n");
|
||||
if (dirty->nr_dirty) {
|
||||
FREE(dirty->dirty);
|
||||
dirty->dirty = NULL;
|
||||
dirty->nr_dirty = 0;
|
||||
}
|
||||
|
||||
nouveau_bo_dirty_linear(ctx, on_card, 0, bo->Size, bo);
|
||||
}
|
||||
|
||||
GLuint
|
||||
nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
nouveau_bufferobj_dirty *dirty = &nbo->cpu_dirty;
|
||||
GLuint nr_dirty;
|
||||
int i;
|
||||
|
||||
nr_dirty = dirty->nr_dirty;
|
||||
if (!nr_dirty) {
|
||||
DEBUG("clean\n");
|
||||
return nr_dirty;
|
||||
}
|
||||
|
||||
for (i=0; i<nr_dirty; i++) {
|
||||
nouveau_bufferobj_region *r = &dirty->dirty[i];
|
||||
|
||||
DEBUG("dirty %d: o=0x%08x, s=0x%08x\n",
|
||||
i, r->start, r->end - r->start);
|
||||
nouveau_bo_upload_to_screen(ctx,
|
||||
r->start, r->end - r->start, bo);
|
||||
}
|
||||
|
||||
FREE(dirty->dirty);
|
||||
dirty->dirty = NULL;
|
||||
dirty->nr_dirty = 0;
|
||||
|
||||
return nr_dirty;
|
||||
}
|
||||
|
||||
GLuint
|
||||
nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
|
||||
nouveau_bufferobj_dirty *dirty = &nbo->gpu_dirty;
|
||||
GLuint nr_dirty;
|
||||
int i;
|
||||
|
||||
nr_dirty = dirty->nr_dirty;
|
||||
if (nr_dirty) {
|
||||
DEBUG("clean\n");
|
||||
return nr_dirty;
|
||||
}
|
||||
|
||||
for (i=0; i<nr_dirty; i++) {
|
||||
nouveau_bufferobj_region *r = &dirty->dirty[i];
|
||||
|
||||
DEBUG("dirty %d: o=0x%08x, s=0x%08x\n",
|
||||
i, r->start, r->end - r->start);
|
||||
nouveau_bo_download_from_screen(ctx,
|
||||
r->start,
|
||||
r->end - r->start, bo);
|
||||
}
|
||||
|
||||
FREE(dirty->dirty);
|
||||
dirty->dirty = NULL;
|
||||
dirty->nr_dirty = 0;
|
||||
|
||||
return nr_dirty;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauBindBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
|
||||
{
|
||||
}
|
||||
|
||||
static struct gl_buffer_object *
|
||||
nouveauNewBufferObject(GLcontext *ctx, GLuint buffer, GLenum target)
|
||||
{
|
||||
nouveau_buffer_object *nbo;
|
||||
|
||||
nbo = CALLOC_STRUCT(nouveau_buffer_object_t);
|
||||
if (nbo)
|
||||
_mesa_initialize_buffer_object(&nbo->mesa, buffer, target);
|
||||
DEBUG("bo=%p\n", nbo);
|
||||
|
||||
return nbo ? &nbo->mesa : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj)
|
||||
{
|
||||
nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj;
|
||||
|
||||
if (nbo->gpu_dirty.nr_dirty)
|
||||
FREE(nbo->gpu_dirty.dirty);
|
||||
if (nbo->cpu_dirty.nr_dirty)
|
||||
FREE(nbo->cpu_dirty.dirty);
|
||||
if (nbo->cpu_mem) nouveau_mem_free(ctx, nbo->cpu_mem);
|
||||
if (nbo->gpu_mem) nouveau_mem_free(ctx, nbo->gpu_mem);
|
||||
|
||||
_mesa_delete_buffer_object(ctx, obj);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
|
||||
const GLvoid *data, GLenum usage,
|
||||
struct gl_buffer_object *obj)
|
||||
{
|
||||
GLuint gpu_flags;
|
||||
|
||||
DEBUG("target=%s, size=%d, data=%p, usage=%s, obj=%p\n",
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
(GLuint)size, data,
|
||||
_mesa_lookup_enum_by_nr(usage),
|
||||
obj);
|
||||
|
||||
switch (target) {
|
||||
case GL_ELEMENT_ARRAY_BUFFER_ARB:
|
||||
gpu_flags = 0;
|
||||
break;
|
||||
default:
|
||||
gpu_flags = NOUVEAU_BO_VRAM_OK | NOUVEAU_BO_GART_OK;
|
||||
break;
|
||||
}
|
||||
nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
|
||||
GLsizeiptrARB size, const GLvoid *data,
|
||||
struct gl_buffer_object *obj)
|
||||
{
|
||||
GLvoid *out;
|
||||
|
||||
DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n",
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
(GLuint)offset, (GLuint)size, data, obj);
|
||||
|
||||
out = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, obj);
|
||||
_mesa_memcpy(out + offset, data, size);
|
||||
nouveau_bo_dirty_linear(ctx, GL_FALSE, offset, size, obj);
|
||||
nouveau_bo_unmap(ctx, obj);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset,
|
||||
GLsizeiptrARB size, GLvoid *data,
|
||||
struct gl_buffer_object *obj)
|
||||
{
|
||||
const GLvoid *in;
|
||||
|
||||
DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n",
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
(GLuint)offset, (GLuint)size, data, obj);
|
||||
|
||||
in = nouveau_bo_map(ctx, GL_READ_ONLY_ARB, obj);
|
||||
_mesa_memcpy(data, in + offset, size);
|
||||
nouveau_bo_unmap(ctx, obj);
|
||||
}
|
||||
|
||||
static void *
|
||||
nouveauMapBuffer(GLcontext *ctx, GLenum target, GLenum access,
|
||||
struct gl_buffer_object *obj)
|
||||
{
|
||||
DEBUG("target=%s, access=%s, obj=%p\n",
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
_mesa_lookup_enum_by_nr(access),
|
||||
obj
|
||||
);
|
||||
|
||||
/* Already mapped.. */
|
||||
if (obj->Pointer)
|
||||
return NULL;
|
||||
|
||||
/* Have to pass READ_WRITE here, nouveau_bo_map will only ensure that
|
||||
* the cpu_mem buffer is up-to-date if we ask for read access.
|
||||
*
|
||||
* However, even if the client only asks for write access, we're still
|
||||
* forced to reupload the entire buffer. So, we need the cpu_mem buffer
|
||||
* to have the correct data all the time.
|
||||
*/
|
||||
obj->Pointer = nouveau_bo_map(ctx, GL_READ_WRITE_ARB, obj);
|
||||
|
||||
/* The GL spec says that a client attempting to write to a bufferobj
|
||||
* mapped READ_ONLY object may have unpredictable results, possibly
|
||||
* even program termination.
|
||||
*
|
||||
* We're going to use this, and only mark the buffer as dirtied if
|
||||
* the client asks for write access.
|
||||
*/
|
||||
if (target != GL_READ_ONLY_ARB) {
|
||||
/* We have no way of knowing what was modified by the client,
|
||||
* so the entire buffer gets dirtied. */
|
||||
nouveau_bo_dirty_all(ctx, GL_FALSE, obj);
|
||||
}
|
||||
|
||||
return obj->Pointer;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
|
||||
{
|
||||
DEBUG("target=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), obj);
|
||||
|
||||
assert(obj->Pointer);
|
||||
|
||||
nouveau_bo_unmap(ctx, obj);
|
||||
obj->Pointer = NULL;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nouveauInitBufferObjects(GLcontext *ctx)
|
||||
{
|
||||
ctx->Driver.BindBuffer = nouveauBindBuffer;
|
||||
ctx->Driver.NewBufferObject = nouveauNewBufferObject;
|
||||
ctx->Driver.DeleteBuffer = nouveauDeleteBuffer;
|
||||
ctx->Driver.BufferData = nouveauBufferData;
|
||||
ctx->Driver.BufferSubData = nouveauBufferSubData;
|
||||
ctx->Driver.GetBufferSubData = nouveauGetBufferSubData;
|
||||
ctx->Driver.MapBuffer = nouveauMapBuffer;
|
||||
ctx->Driver.UnmapBuffer = nouveauUnmapBuffer;
|
||||
}
|
||||
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
#ifndef __NOUVEAU_BUFFEROBJ_H__
|
||||
#define __NOUVEAU_BUFFEROBJ_H__
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "nouveau_mem.h"
|
||||
|
||||
#define NOUVEAU_BO_VRAM_OK (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE)
|
||||
#define NOUVEAU_BO_GART_OK (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE)
|
||||
|
||||
typedef struct nouveau_bufferobj_region_t {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
} nouveau_bufferobj_region;
|
||||
|
||||
typedef struct nouveau_bufferobj_dirty_t {
|
||||
nouveau_bufferobj_region *dirty;
|
||||
int nr_dirty;
|
||||
} nouveau_bufferobj_dirty;
|
||||
|
||||
typedef struct nouveau_buffer_object_t {
|
||||
/* Base class, must be first */
|
||||
struct gl_buffer_object mesa;
|
||||
|
||||
GLboolean mapped;
|
||||
GLenum usage;
|
||||
|
||||
/* Memory used for GPU access to the buffer*/
|
||||
GLuint gpu_mem_flags;
|
||||
nouveau_mem * gpu_mem;
|
||||
nouveau_bufferobj_dirty gpu_dirty;
|
||||
|
||||
/* Memory used for CPU access to the buffer */
|
||||
GLuint cpu_mem_flags;
|
||||
nouveau_mem * cpu_mem;
|
||||
GLvoid * cpu_mem_sys;
|
||||
nouveau_bufferobj_dirty cpu_dirty;
|
||||
} nouveau_buffer_object;
|
||||
|
||||
extern void
|
||||
nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access,
|
||||
GLsizeiptrARB size, const GLvoid *data, GLenum usage,
|
||||
struct gl_buffer_object *bo, int flags);
|
||||
|
||||
extern GLboolean
|
||||
nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo);
|
||||
|
||||
extern GLboolean
|
||||
nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo);
|
||||
|
||||
extern void *
|
||||
nouveau_bo_map(GLcontext *ctx, GLenum usage, struct gl_buffer_object *bo);
|
||||
|
||||
extern void
|
||||
nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo);
|
||||
|
||||
extern uint32_t
|
||||
nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo);
|
||||
|
||||
extern void
|
||||
nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card,
|
||||
uint32_t offset, uint32_t size,
|
||||
struct gl_buffer_object *bo);
|
||||
|
||||
extern void
|
||||
nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card,
|
||||
struct gl_buffer_object *bo);
|
||||
|
||||
extern GLuint
|
||||
nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo);
|
||||
|
||||
extern GLuint
|
||||
nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo);
|
||||
|
||||
extern void
|
||||
nouveauInitBufferObjects(GLcontext *ctx);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
|
||||
#include "nouveau_card.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_card_list.h"
|
||||
|
||||
|
||||
nouveau_card* nouveau_card_lookup(uint32_t device_id)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<sizeof(nouveau_card_list)/sizeof(nouveau_card)-1;i++)
|
||||
if (nouveau_card_list[i].id==(device_id&0xffff))
|
||||
return &(nouveau_card_list[i]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_CARD_H__
|
||||
#define __NOUVEAU_CARD_H__
|
||||
|
||||
#include "dri_util.h"
|
||||
#include "drm.h"
|
||||
#include "nouveau_drm.h"
|
||||
|
||||
typedef struct nouveau_card_t {
|
||||
uint16_t id; /* last 4 digits of pci id, last digit is always 0 */
|
||||
char* name; /* the user-friendly card name */
|
||||
uint32_t class_3d; /* the object class this card uses for 3D */
|
||||
uint32_t type; /* the major card family */
|
||||
uint32_t flags;
|
||||
}
|
||||
nouveau_card;
|
||||
|
||||
#define NV_HAS_LMA 0x00000001
|
||||
|
||||
extern nouveau_card* nouveau_card_lookup(uint32_t device_id);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
static nouveau_card nouveau_card_list[]={
|
||||
{0x0020, "RIVA TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x0029, "RIVA TNT2 Ultra", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x002A, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x002B, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x002C, "Vanta/Vanta LT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x002D, "RIVA TNT2 Model 64/Model 64 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x002E, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x002F, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x0040, "GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0041, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0042, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0043, "NV40.3", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0044, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0045, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0046, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0047, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0048, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0049, "NV40GL", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x004D, "Quadro FX 4000", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x004E, "Quadro FX 4000", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0090, "GeForce 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0091, "GeForce 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0092, "GeForce 7800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0093, "GeForce 7800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0098, "GeForce Go 7800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0099, "GE Force Go 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x009D, "Quadro FX4500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00A0, "Aladdin TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x00C0, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00C1, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00C2, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00C3, "Geforce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00C8, "GeForce Go 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00C9, "GeForce Go 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00CC, "Quadro FX Go1400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00CD, "Quadro FX 3450/4000 SDI", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00CE, "Quadro FX 1400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F0, "GeForce 6800/GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F1, "GeForce 6600/GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F2, "GeForce 6600/GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F3, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F4, "GeForce 6600 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F5, "GeForce 7800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F6, "GeForce 6600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F8, "Quadro FX 3400/4400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00F9, "GeForce 6800 Ultra/GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x00FA, "GeForce PCX 5750", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x00FB, "GeForce PCX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x00FC, "Quadro FX 330/GeForce PCX 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x00FD, "Quadro FX 330/Quadro NVS280", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x00FE, "Quadro FX 1300", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x00FF, "GeForce PCX 4300", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0100, "GeForce 256 SDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0},
|
||||
{0x0101, "GeForce 256 DDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0},
|
||||
{0x0103, "Quadro", NV10_TCL_PRIMITIVE_3D, NV_10, 0},
|
||||
{0x0110, "GeForce2 MX/MX 400", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x0111, "GeForce2 MX 100 DDR/200 DDR", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x0112, "GeForce2 Go", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x0113, "Quadro2 MXR/EX/Go", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x0140, "GeForce 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0141, "GeForce 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0142, "GeForce 6600 PCIe", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0144, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0145, "GeForce 6610 XL", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0146, "Geforce Go 6600TE/6200TE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0148, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0149, "GeForce Go 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x014A, "Quadro NVS 440", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x014C, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x014D, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x014E, "Quadro FX 540", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x014F, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0150, "GeForce2 GTS/Pro", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x0151, "GeForce2 Ti", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x0152, "GeForce2 Ultra, Bladerunner", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x0153, "Quadro2 Pro", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x0161, "GeForce 6200 TurboCache(TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0162, "GeForce 6200 SE TurboCache (TM)", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0163, "GeForce 6200 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0164, "GeForce Go 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0165, "Quadro NVS 285", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0166, "GeForce Go 6400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0167, "GeForce Go 6200 TurboCache", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0168, "GeForce Go 6200 TurboCache", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0170, "GeForce4 MX 460", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0171, "GeForce4 MX 440", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0172, "GeForce4 MX 420", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0173, "GeForce4 MX 440-SE", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0174, "GeForce4 440 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0175, "GeForce4 420 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0176, "GeForce4 420 Go 32M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0177, "GeForce4 460 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0178, "Quadro4 550 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0179, "GeForce4 420 Go 32M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x017A, "Quadro4 200/400 NVS", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x017B, "Quadro4 550 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x017C, "Quadro4 500 GoGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x017D, "GeForce4 410 Go 16M", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0181, "GeForce4 MX 440 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0182, "GeForce4 MX 440SE AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0183, "GeForce4 MX 420 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0185, "GeForce4 MX 4000 AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0186, "GeForce4 448 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0187, "GeForce4 488 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0188, "Quadro4 580 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x018A, "Quadro4 NVS AGP 8x", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x018B, "Quadro4 380 XGL", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x018C, "Quadro NVS 50 PCI", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x018D, "GeForce4 448 Go", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0191, "GeForce 8800 GTX", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0},
|
||||
{0x0193, "GeForce 8800 GTS", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0},
|
||||
{0x01A0, "GeForce2 MX Integrated Graphics", NV11_TCL_PRIMITIVE_3D, NV_11, 0},
|
||||
{0x01D1, "GeForce 7300 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x01D3, "GeForce 7300 SE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x01D6, "GeForce Go 7200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x01D7, "Quadro NVS 110M / GeForce Go 7300", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x01D8, "GeForce Go 7400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x01DA, "Quadro NVS 110M", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x01DF, "GeForce 7300 GS", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x01F0, "GeForce4 MX - nForce GPU", NV17_TCL_PRIMITIVE_3D, NV_17, 0},
|
||||
{0x0200, "GeForce3", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
|
||||
{0x0201, "GeForce3 Ti 200", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
|
||||
{0x0202, "GeForce3 Ti 500", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
|
||||
{0x0203, "Quadro DCC", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
|
||||
{0x0211, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0212, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0215, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0218, "GeForce 6800 XT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0221, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0240, "GeForce 6150", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0242, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0244, "Geforce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_20, 0},
|
||||
{0x0290, "GeForce 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0291, "GeForce 7900 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0292, "GeForce 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0298, "GeForce Go 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0299, "GeForce Go 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x029A, "Quadro FX 2500M", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x029B, "Quadro FX 1500M", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x029C, "Quadro FX 5500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x029D, "Quadro FX 3500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x029E, "Quadro FX 1500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x029F, "Quadro FX 4500 X2", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x02A0, "XGPU", NV20_TCL_PRIMITIVE_3D, NV_20, 0},
|
||||
{0x02E1, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0300, "GeForce FX", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0301, "GeForce FX 5800 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0302, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0308, "Quadro FX 2000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0309, "Quadro FX 1000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0311, "GeForce FX 5600 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0312, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0313, "NV31", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0314, "GeForce FX 5600XT", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0316, "NV31M", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0317, "NV31M Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x031A, "GeForce FX Go5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x031B, "GeForce FX Go5650", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x031C, "NVIDIA Quadro FX Go700", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0},
|
||||
{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0},
|
||||
{0x0330, "GeForce FX 5900 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0331, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0332, "GeForce FX 5900XT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0333, "GeForce FX 5950 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0334, "GeForce FX 5900ZT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0338, "Quadro FX 3000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x033F, "Quadro FX 700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0341, "GeForce FX 5700 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0342, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0343, "GeForce FX 5700LE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0344, "GeForce FX 5700VE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0345, "NV36.5", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0347, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0348, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0349, "NV36M Pro", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x034B, "NV36MAP", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x034C, "Quadro FX Go1000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x034E, "Quadro FX 1100", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x034F, "NV36GL", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0},
|
||||
{0x0391, "GeForce 7600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0392, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0393, "GeForce 7300 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x0398, "GeForce Go 7600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0},
|
||||
{0x03D0, "GeForce 6100 nForce 430", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x03D1, "GeForce 6100 nForce 405", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x03D2, "GeForce 6100 nForce 400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x03D5, "GeForce 6100 nForce 420", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0},
|
||||
{0x0020, "TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x0028, "TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x0029, "UTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x002C, "VTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
{0x00A0, "ITNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0},
|
||||
};
|
||||
|
|
@ -1,422 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "glheader.h"
|
||||
#include "context.h"
|
||||
#include "simple_list.h"
|
||||
#include "imports.h"
|
||||
#include "matrix.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "framebuffer.h"
|
||||
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "tnl/t_vp_build.h"
|
||||
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_driver.h"
|
||||
//#include "nouveau_state.h"
|
||||
#include "nouveau_span.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_tex.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_lock.h"
|
||||
#include "nouveau_query.h"
|
||||
#include "nv04_swtcl.h"
|
||||
#include "nv10_swtcl.h"
|
||||
|
||||
#include "vblank.h"
|
||||
#include "utils.h"
|
||||
#include "texmem.h"
|
||||
#include "xmlpool.h" /* for symbolic values of enum-type options */
|
||||
|
||||
#ifndef NOUVEAU_DEBUG
|
||||
int NOUVEAU_DEBUG = 0;
|
||||
#endif
|
||||
|
||||
static const struct dri_debug_control debug_control[] =
|
||||
{
|
||||
{ "shaders" , DEBUG_SHADERS },
|
||||
{ "mem" , DEBUG_MEM },
|
||||
{ "bufferobj" , DEBUG_BUFFEROBJ },
|
||||
{ NULL , 0 }
|
||||
};
|
||||
|
||||
#define need_GL_ARB_vertex_program
|
||||
#define need_GL_ARB_occlusion_query
|
||||
#include "extension_helper.h"
|
||||
|
||||
const struct dri_extension common_extensions[] =
|
||||
{
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const struct dri_extension nv10_extensions[] =
|
||||
{
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const struct dri_extension nv20_extensions[] =
|
||||
{
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const struct dri_extension nv30_extensions[] =
|
||||
{
|
||||
{ "GL_ARB_fragment_program", NULL },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const struct dri_extension nv40_extensions[] =
|
||||
{
|
||||
/* ARB_vp can be moved to nv20/30 once the shader backend has been
|
||||
* written for those cards.
|
||||
*/
|
||||
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
|
||||
{ "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
const struct dri_extension nv50_extensions[] =
|
||||
{
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/* Create the device specific context.
|
||||
*/
|
||||
GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate )
|
||||
{
|
||||
GLcontext *ctx, *shareCtx;
|
||||
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
|
||||
struct dd_function_table functions;
|
||||
nouveauContextPtr nmesa;
|
||||
nouveauScreenPtr screen;
|
||||
|
||||
/* Allocate the context */
|
||||
nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) );
|
||||
if ( !nmesa )
|
||||
return GL_FALSE;
|
||||
|
||||
nmesa->driContext = driContextPriv;
|
||||
nmesa->driScreen = sPriv;
|
||||
nmesa->driDrawable = NULL;
|
||||
nmesa->hHWContext = driContextPriv->hHWContext;
|
||||
nmesa->driHwLock = &sPriv->pSAREA->lock;
|
||||
nmesa->driFd = sPriv->fd;
|
||||
|
||||
nmesa->screen = (nouveauScreenPtr)(sPriv->private);
|
||||
screen=nmesa->screen;
|
||||
|
||||
/* Create the hardware context */
|
||||
if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_PHYSICAL,
|
||||
&nmesa->vram_phys))
|
||||
return GL_FALSE;
|
||||
if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_SIZE,
|
||||
&nmesa->vram_size))
|
||||
return GL_FALSE;
|
||||
if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_PHYSICAL,
|
||||
&nmesa->gart_phys))
|
||||
return GL_FALSE;
|
||||
if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_SIZE,
|
||||
&nmesa->gart_size))
|
||||
return GL_FALSE;
|
||||
if (!nouveauFifoInit(nmesa))
|
||||
return GL_FALSE;
|
||||
nouveauObjectInit(nmesa);
|
||||
|
||||
|
||||
/* Init default driver functions then plug in our nouveau-specific functions
|
||||
* (the texture functions are especially important)
|
||||
*/
|
||||
_mesa_init_driver_functions( &functions );
|
||||
nouveauDriverInitFunctions( &functions );
|
||||
nouveauTexInitFunctions( &functions );
|
||||
|
||||
/* Allocate the Mesa context */
|
||||
if (sharedContextPrivate)
|
||||
shareCtx = ((nouveauContextPtr) sharedContextPrivate)->glCtx;
|
||||
else
|
||||
shareCtx = NULL;
|
||||
nmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
|
||||
&functions, (void *) nmesa);
|
||||
if (!nmesa->glCtx) {
|
||||
FREE(nmesa);
|
||||
return GL_FALSE;
|
||||
}
|
||||
driContextPriv->driverPrivate = nmesa;
|
||||
ctx = nmesa->glCtx;
|
||||
|
||||
/* Parse configuration files */
|
||||
driParseConfigFiles (&nmesa->optionCache, &screen->optionCache,
|
||||
screen->driScreen->myNum, "nouveau");
|
||||
|
||||
nmesa->sarea = (struct drm_nouveau_sarea *)((char *)sPriv->pSAREA +
|
||||
screen->sarea_priv_offset);
|
||||
|
||||
/* Enable any supported extensions */
|
||||
driInitExtensions(ctx, common_extensions, GL_TRUE);
|
||||
if (nmesa->screen->card->type >= NV_10)
|
||||
driInitExtensions(ctx, nv10_extensions, GL_FALSE);
|
||||
if (nmesa->screen->card->type >= NV_20)
|
||||
driInitExtensions(ctx, nv20_extensions, GL_FALSE);
|
||||
if (nmesa->screen->card->type >= NV_30)
|
||||
driInitExtensions(ctx, nv30_extensions, GL_FALSE);
|
||||
if (nmesa->screen->card->type >= NV_40)
|
||||
driInitExtensions(ctx, nv40_extensions, GL_FALSE);
|
||||
if (nmesa->screen->card->type >= NV_50)
|
||||
driInitExtensions(ctx, nv50_extensions, GL_FALSE);
|
||||
|
||||
nmesa->current_primitive = -1;
|
||||
|
||||
nouveauShaderInitFuncs(ctx);
|
||||
/* Install Mesa's fixed-function texenv shader support */
|
||||
if (nmesa->screen->card->type >= NV_40)
|
||||
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
|
||||
|
||||
/* Initialize the swrast */
|
||||
_swrast_CreateContext( ctx );
|
||||
_vbo_CreateContext( ctx );
|
||||
_tnl_CreateContext( ctx );
|
||||
_swsetup_CreateContext( ctx );
|
||||
|
||||
_math_matrix_ctr(&nmesa->viewport);
|
||||
|
||||
nouveauDDInitStateFuncs( ctx );
|
||||
nouveauSpanInitFunctions( ctx );
|
||||
nouveauDDInitState( nmesa );
|
||||
switch(nmesa->screen->card->type)
|
||||
{
|
||||
case NV_04:
|
||||
case NV_05:
|
||||
nv04TriInitFunctions( ctx );
|
||||
break;
|
||||
case NV_10:
|
||||
case NV_11:
|
||||
case NV_17:
|
||||
case NV_20:
|
||||
case NV_30:
|
||||
case NV_40:
|
||||
case NV_44:
|
||||
case NV_50:
|
||||
default:
|
||||
nv10TriInitFunctions( ctx );
|
||||
break;
|
||||
}
|
||||
|
||||
nouveauInitBufferObjects(ctx);
|
||||
if (!nouveauSyncInitFuncs(ctx))
|
||||
return GL_FALSE;
|
||||
nouveauQueryInitFuncs(ctx);
|
||||
nmesa->hw_func.InitCard(nmesa);
|
||||
nouveauInitState(ctx);
|
||||
|
||||
driContextPriv->driverPrivate = (void *)nmesa;
|
||||
|
||||
NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ),
|
||||
debug_control );
|
||||
|
||||
if (driQueryOptionb(&nmesa->optionCache, "no_rast")) {
|
||||
fprintf(stderr, "disabling 3D acceleration\n");
|
||||
FALLBACK(nmesa, NOUVEAU_FALLBACK_DISABLE, 1);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Destroy the device specific context. */
|
||||
void nouveauDestroyContext( __DRIcontextPrivate *driContextPriv )
|
||||
{
|
||||
nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
|
||||
|
||||
assert(nmesa);
|
||||
if ( nmesa ) {
|
||||
/* free the option cache */
|
||||
driDestroyOptionCache (&nmesa->optionCache);
|
||||
|
||||
FREE( nmesa );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Force the context `c' to be the current context and associate with it
|
||||
* buffer `b'.
|
||||
*/
|
||||
GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
__DRIdrawablePrivate *driReadPriv )
|
||||
{
|
||||
if ( driContextPriv ) {
|
||||
nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
|
||||
struct gl_framebuffer *draw_fb =
|
||||
(struct gl_framebuffer*)driDrawPriv->driverPrivate;
|
||||
struct gl_framebuffer *read_fb =
|
||||
(struct gl_framebuffer*)driReadPriv->driverPrivate;
|
||||
|
||||
if (driDrawPriv->swap_interval == (unsigned)-1) {
|
||||
driDrawPriv->vblFlags =
|
||||
driGetDefaultVBlankFlags(&nmesa->optionCache);
|
||||
|
||||
driDrawableInitVBlank(driDrawPriv);
|
||||
}
|
||||
|
||||
nmesa->driDrawable = driDrawPriv;
|
||||
|
||||
_mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
|
||||
driDrawPriv->w, driDrawPriv->h);
|
||||
if (draw_fb != read_fb) {
|
||||
_mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
|
||||
driReadPriv->w,
|
||||
driReadPriv->h);
|
||||
}
|
||||
_mesa_make_current(nmesa->glCtx, draw_fb, read_fb);
|
||||
|
||||
nouveau_build_framebuffer(nmesa->glCtx,
|
||||
driDrawPriv->driverPrivate);
|
||||
} else {
|
||||
_mesa_make_current( NULL, NULL, NULL );
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Force the context `c' to be unbound from its buffer.
|
||||
*/
|
||||
GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
|
||||
{
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nouveauDoSwapBuffers(nouveauContextPtr nmesa, __DRIdrawablePrivate *dPriv)
|
||||
{
|
||||
struct gl_framebuffer *fb;
|
||||
nouveauScreenPtr screen = dPriv->driScreenPriv->private;
|
||||
nouveau_renderbuffer_t *src;
|
||||
drm_clip_rect_t *box;
|
||||
int nbox, i;
|
||||
|
||||
fb = (struct gl_framebuffer *)dPriv->driverPrivate;
|
||||
if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
|
||||
src = (nouveau_renderbuffer_t *)
|
||||
fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
|
||||
} else {
|
||||
src = (nouveau_renderbuffer_t *)
|
||||
fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
|
||||
}
|
||||
|
||||
LOCK_HARDWARE(nmesa);
|
||||
nbox = dPriv->numClipRects;
|
||||
box = dPriv->pClipRects;
|
||||
|
||||
if (nbox) {
|
||||
BEGIN_RING_SIZE(NvSubCtxSurf2D,
|
||||
NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
|
||||
if (src->mesa._ActualFormat == GL_RGBA8)
|
||||
OUT_RING (6); /* X8R8G8B8 */
|
||||
else
|
||||
OUT_RING (4); /* R5G6B5 */
|
||||
OUT_RING(((screen->frontPitch * screen->fbFormat) << 16) |
|
||||
src->pitch);
|
||||
OUT_RING(src->offset);
|
||||
OUT_RING(screen->frontOffset);
|
||||
}
|
||||
|
||||
for (i=0; i<nbox; i++, box++) {
|
||||
BEGIN_RING_SIZE(NvSubImageBlit, NV_IMAGE_BLIT_POINT_IN, 3);
|
||||
OUT_RING (((box->y1 - dPriv->y) << 16) |
|
||||
(box->x1 - dPriv->x));
|
||||
OUT_RING ((box->y1 << 16) | box->x1);
|
||||
OUT_RING (((box->y2 - box->y1) << 16) |
|
||||
(box->x2 - box->x1));
|
||||
}
|
||||
FIRE_RING();
|
||||
|
||||
UNLOCK_HARDWARE(nmesa);
|
||||
}
|
||||
|
||||
void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv)
|
||||
{
|
||||
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||
nouveauContextPtr nmesa = dPriv->driContextPriv->driverPrivate;
|
||||
|
||||
if (nmesa->glCtx->Visual.doubleBufferMode) {
|
||||
_mesa_notifySwapBuffers(nmesa->glCtx);
|
||||
nouveauDoSwapBuffers(nmesa, dPriv);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
}
|
||||
|
||||
void nouveauClearBuffer(GLcontext *ctx, nouveau_renderbuffer_t *buffer,
|
||||
int fill, int mask)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
int dimensions;
|
||||
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: only support 32 bits atm */
|
||||
|
||||
/* Surface that we will work on */
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D);
|
||||
|
||||
BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
|
||||
OUT_RING(0x0b); /* Y32 color format */
|
||||
OUT_RING((buffer->pitch<<16)|buffer->pitch);
|
||||
OUT_RING(buffer->offset);
|
||||
OUT_RING(buffer->offset);
|
||||
|
||||
/* Now clear a rectangle */
|
||||
dimensions = ((buffer->mesa.Height)<<16) | (buffer->mesa.Width);
|
||||
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubGdiRectText, NvGdiRectText);
|
||||
|
||||
BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
|
||||
OUT_RING(3); /* SRCCOPY */
|
||||
|
||||
BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_TL, 5);
|
||||
OUT_RING(0); /* top left */
|
||||
OUT_RING(dimensions); /* bottom right */
|
||||
OUT_RING(fill);
|
||||
OUT_RING(0); /* top left */
|
||||
OUT_RING(dimensions); /* bottom right */
|
||||
}
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_CONTEXT_H__
|
||||
#define __NOUVEAU_CONTEXT_H__
|
||||
|
||||
#include "dri_util.h"
|
||||
#include "drm.h"
|
||||
#include "nouveau_drm.h"
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "tnl/t_vertex.h"
|
||||
|
||||
#include "nouveau_fbo.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_shader.h"
|
||||
#include "nouveau_state_cache.h"
|
||||
#include "nouveau_sync.h"
|
||||
|
||||
#include "xmlconfig.h"
|
||||
|
||||
typedef struct nouveau_fifo {
|
||||
struct drm_nouveau_channel_alloc drm;
|
||||
uint32_t *pushbuf;
|
||||
uint32_t *mmio;
|
||||
uint32_t *notifier_block;
|
||||
uint32_t current;
|
||||
uint32_t put;
|
||||
uint32_t free;
|
||||
uint32_t max;
|
||||
} nouveau_fifo_t;
|
||||
|
||||
#define TAG(x) nouveau##x
|
||||
#include "tnl_dd/t_dd_vertex.h"
|
||||
#undef TAG
|
||||
|
||||
/* Subpixel offsets for window coordinates (triangles): */
|
||||
#define SUBPIXEL_X (0.0F)
|
||||
#define SUBPIXEL_Y (0.125F)
|
||||
|
||||
struct nouveau_context;
|
||||
|
||||
typedef void (*nouveau_tri_func)( struct nouveau_context*,
|
||||
nouveauVertex *,
|
||||
nouveauVertex *,
|
||||
nouveauVertex * );
|
||||
|
||||
typedef void (*nouveau_line_func)( struct nouveau_context*,
|
||||
nouveauVertex *,
|
||||
nouveauVertex * );
|
||||
|
||||
typedef void (*nouveau_point_func)( struct nouveau_context*,
|
||||
nouveauVertex * );
|
||||
|
||||
typedef struct nouveau_hw_func_t {
|
||||
/* Initialise any card-specific non-GL related state */
|
||||
GLboolean (*InitCard)(struct nouveau_context *);
|
||||
/* Update buffer offset/pitch/format */
|
||||
GLboolean (*BindBuffers)(struct nouveau_context *, int num_color,
|
||||
nouveau_renderbuffer_t **color,
|
||||
nouveau_renderbuffer_t *depth);
|
||||
/* Update anything that depends on the window position/size */
|
||||
void (*WindowMoved)(struct nouveau_context *);
|
||||
|
||||
/* Update projection matrix */
|
||||
void (*UpdateProjectionMatrix)(GLcontext *);
|
||||
|
||||
/* Update modelview matrix (used for lighting and vertex weight) */
|
||||
void (*UpdateModelviewMatrix)(GLcontext *);
|
||||
} nouveau_hw_func;
|
||||
|
||||
typedef struct nouveau_context {
|
||||
/* Mesa context */
|
||||
GLcontext *glCtx;
|
||||
|
||||
/* The per-context fifo */
|
||||
nouveau_fifo_t fifo;
|
||||
|
||||
/* Physical addresses of AGP/VRAM apertures */
|
||||
uint64_t vram_phys;
|
||||
uint64_t vram_size;
|
||||
uint64_t gart_phys;
|
||||
uint64_t gart_size;
|
||||
|
||||
/* Channel synchronisation */
|
||||
struct drm_nouveau_notifierobj_alloc *syncNotifier;
|
||||
|
||||
/* ARB_occlusion_query / EXT_timer_query */
|
||||
GLuint query_object_max;
|
||||
GLboolean * query_alloc;
|
||||
struct drm_nouveau_notifierobj_alloc *queryNotifier;
|
||||
|
||||
/* Additional hw-specific functions */
|
||||
nouveau_hw_func hw_func;
|
||||
|
||||
/* FIXME : do we want to put all state into a separate struct ? */
|
||||
/* State for tris */
|
||||
GLuint color_offset;
|
||||
GLuint specular_offset;
|
||||
|
||||
/* Vertex state */
|
||||
GLuint vertex_size;
|
||||
GLubyte *verts;
|
||||
struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
|
||||
GLuint vertex_attr_count;
|
||||
|
||||
/* Color and depth renderbuffers */
|
||||
nouveau_renderbuffer_t *color_buffer;
|
||||
nouveau_renderbuffer_t *depth_buffer;
|
||||
|
||||
/* Depth/stencil clear value */
|
||||
uint32_t clear_value;
|
||||
|
||||
/* Light state */
|
||||
GLboolean lighting_enabled;
|
||||
uint32_t enabled_lights;
|
||||
|
||||
/* Cached state */
|
||||
nouveau_state_cache state_cache;
|
||||
|
||||
/* The drawing fallbacks */
|
||||
GLuint Fallback;
|
||||
nouveau_tri_func draw_tri;
|
||||
nouveau_line_func draw_line;
|
||||
nouveau_point_func draw_point;
|
||||
|
||||
/* Cliprects information */
|
||||
GLuint numClipRects;
|
||||
drm_clip_rect_t *pClipRects;
|
||||
drm_clip_rect_t osClipRect;
|
||||
GLuint drawX, drawY, drawW, drawH;
|
||||
|
||||
/* The rendering context information */
|
||||
GLenum current_primitive; /* the current primitive enum */
|
||||
DECLARE_RENDERINPUTS(render_inputs_bitset); /* the current render inputs */
|
||||
|
||||
/* Shader state */
|
||||
nvsFunc VPfunc;
|
||||
nvsFunc FPfunc;
|
||||
nouveauShader *current_fragprog;
|
||||
nouveauShader *current_vertprog;
|
||||
nouveauShader *passthrough_vp;
|
||||
nouveauShader *passthrough_fp;
|
||||
|
||||
nouveauScreenRec *screen;
|
||||
struct drm_nouveau_sarea *sarea;
|
||||
|
||||
__DRIcontextPrivate *driContext; /* DRI context */
|
||||
__DRIscreenPrivate *driScreen; /* DRI screen */
|
||||
__DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
|
||||
GLint lastStamp;
|
||||
|
||||
drm_context_t hHWContext;
|
||||
drm_hw_lock_t *driHwLock;
|
||||
int driFd;
|
||||
|
||||
/* Configuration cache */
|
||||
driOptionCache optionCache;
|
||||
|
||||
GLuint new_state;
|
||||
GLuint new_render_state;
|
||||
GLuint render_index;
|
||||
GLmatrix viewport;
|
||||
GLfloat depth_scale;
|
||||
|
||||
}nouveauContextRec, *nouveauContextPtr;
|
||||
|
||||
|
||||
#define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx))
|
||||
|
||||
/* Flags for software fallback cases: */
|
||||
#define NOUVEAU_FALLBACK_TEXTURE 0x0001
|
||||
#define NOUVEAU_FALLBACK_DRAW_BUFFER 0x0002
|
||||
#define NOUVEAU_FALLBACK_READ_BUFFER 0x0004
|
||||
#define NOUVEAU_FALLBACK_STENCIL 0x0008
|
||||
#define NOUVEAU_FALLBACK_RENDER_MODE 0x0010
|
||||
#define NOUVEAU_FALLBACK_LOGICOP 0x0020
|
||||
#define NOUVEAU_FALLBACK_SEP_SPECULAR 0x0040
|
||||
#define NOUVEAU_FALLBACK_BLEND_EQ 0x0080
|
||||
#define NOUVEAU_FALLBACK_BLEND_FUNC 0x0100
|
||||
#define NOUVEAU_FALLBACK_PROJTEX 0x0200
|
||||
#define NOUVEAU_FALLBACK_DISABLE 0x0400
|
||||
|
||||
|
||||
extern GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
|
||||
__DRIcontextPrivate *driContextPriv,
|
||||
void *sharedContextPrivate );
|
||||
|
||||
extern void nouveauDestroyContext( __DRIcontextPrivate * );
|
||||
|
||||
extern GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
__DRIdrawablePrivate *driReadPriv );
|
||||
|
||||
extern GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv );
|
||||
|
||||
extern void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
|
||||
__DRIdrawablePrivate *dPriv);
|
||||
|
||||
extern void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv);
|
||||
|
||||
extern void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv,
|
||||
int x, int y, int w, int h);
|
||||
|
||||
extern void nouveauClearBuffer(GLcontext *ctx, nouveau_renderbuffer_t *buffer,
|
||||
int fill, int mask);
|
||||
|
||||
/* Debugging utils: */
|
||||
extern int NOUVEAU_DEBUG;
|
||||
|
||||
#define DEBUG_SHADERS 0x00000001
|
||||
#define DEBUG_MEM 0x00000002
|
||||
#define DEBUG_BUFFEROBJ 0x00000004
|
||||
|
||||
#endif /* __NOUVEAU_CONTEXT_H__ */
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin, Sylvain Munaut
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
#define NV03_STATUS 0x004006b0
|
||||
#define NV04_STATUS 0x00400700
|
||||
|
||||
#define NV03_FIFO_REGS_SIZE 0x10000
|
||||
# define NV03_FIFO_REGS_DMAPUT 0x00000040
|
||||
# define NV03_FIFO_REGS_DMAGET 0x00000044
|
||||
|
||||
/* Fifo commands. These are not regs, neither masks */
|
||||
#define NV03_FIFO_CMD_JUMP 0x20000000
|
||||
#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc
|
||||
#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK))
|
||||
|
||||
|
||||
#define NONINC_METHOD 0x40000000
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef _NOUVEAU_DRI_
|
||||
#define _NOUVEAU_DRI_
|
||||
|
||||
#include "xf86drm.h"
|
||||
#include "drm.h"
|
||||
#include "nouveau_drm.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t device_id; /**< \brief PCI device ID */
|
||||
uint32_t width; /**< \brief width in pixels of display */
|
||||
uint32_t height; /**< \brief height in scanlines of display */
|
||||
uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */
|
||||
uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */
|
||||
|
||||
uint32_t bus_type; /**< \brief ths bus type */
|
||||
uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */
|
||||
|
||||
uint32_t front_offset; /**< \brief front buffer offset */
|
||||
uint32_t front_pitch; /**< \brief front buffer pitch */
|
||||
uint32_t back_offset; /**< \brief private back buffer offset */
|
||||
uint32_t back_pitch; /**< \brief private back buffer pitch */
|
||||
uint32_t depth_offset; /**< \brief private depth buffer offset */
|
||||
uint32_t depth_pitch; /**< \brief private depth buffer pitch */
|
||||
|
||||
} NOUVEAUDRIRec, *NOUVEAUDRIPtr;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,218 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "nouveau_context.h"
|
||||
//#include "nouveau_state.h"
|
||||
#include "nouveau_lock.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_driver.h"
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#include "context.h"
|
||||
#include "framebuffer.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "colormac.h"
|
||||
|
||||
/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */
|
||||
GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa,
|
||||
unsigned int param,
|
||||
uint64_t* value)
|
||||
{
|
||||
struct drm_nouveau_getparam getp;
|
||||
|
||||
getp.param = param;
|
||||
if (!value || drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_GETPARAM,
|
||||
&getp, sizeof(getp)))
|
||||
return GL_FALSE;
|
||||
*value = getp.value;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */
|
||||
GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa,
|
||||
unsigned int param,
|
||||
uint64_t value)
|
||||
{
|
||||
struct drm_nouveau_setparam setp;
|
||||
|
||||
setp.param = param;
|
||||
setp.value = value;
|
||||
if (drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_SETPARAM, &setp,
|
||||
sizeof(setp)))
|
||||
return GL_FALSE;
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Return the width and height of the current color buffer */
|
||||
static void nouveauGetBufferSize( GLframebuffer *buffer,
|
||||
GLuint *width, GLuint *height )
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
LOCK_HARDWARE( nmesa );
|
||||
*width = nmesa->driDrawable->w;
|
||||
*height = nmesa->driDrawable->h;
|
||||
UNLOCK_HARDWARE( nmesa );
|
||||
}
|
||||
|
||||
/* glGetString */
|
||||
static const GLubyte *nouveauGetString( GLcontext *ctx, GLenum name )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
static char buffer[128];
|
||||
const char * card_name = "Unknown";
|
||||
GLuint agp_mode = 0;
|
||||
|
||||
switch ( name ) {
|
||||
case GL_VENDOR:
|
||||
return (GLubyte *)DRIVER_AUTHOR;
|
||||
|
||||
case GL_RENDERER:
|
||||
card_name=nmesa->screen->card->name;
|
||||
|
||||
switch(nmesa->screen->bus_type)
|
||||
{
|
||||
case NV_PCI:
|
||||
case NV_PCIE:
|
||||
default:
|
||||
agp_mode=0;
|
||||
break;
|
||||
case NV_AGP:
|
||||
agp_mode=nmesa->screen->agp_mode;
|
||||
break;
|
||||
}
|
||||
driGetRendererString( buffer, card_name, DRIVER_DATE,
|
||||
agp_mode );
|
||||
return (GLubyte *)buffer;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* glFlush */
|
||||
static void nouveauFlush( GLcontext *ctx )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT)
|
||||
nouveauDoSwapBuffers(nmesa, nmesa->driDrawable);
|
||||
FIRE_RING();
|
||||
}
|
||||
|
||||
/* glFinish */
|
||||
static void nouveauFinish( GLcontext *ctx )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
nouveauFlush( ctx );
|
||||
nouveauWaitForIdle( nmesa );
|
||||
}
|
||||
|
||||
/* glClear */
|
||||
static void nouveauClear( GLcontext *ctx, GLbitfield mask )
|
||||
{
|
||||
uint32_t clear_value;
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
/* FIXME: should we clear front buffer, even if asked to do it? */
|
||||
if (mask & (BUFFER_BIT_FRONT_LEFT|BUFFER_BIT_BACK_LEFT)) {
|
||||
GLubyte c[4];
|
||||
int color_bits = 32;
|
||||
int color_mask = 0xffffffff;
|
||||
|
||||
UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,ctx->Color.ClearColor);
|
||||
clear_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]);
|
||||
|
||||
if (ctx->DrawBuffer) {
|
||||
/* FIXME: find correct color buffer, instead of [0] */
|
||||
if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
|
||||
color_bits = ctx->DrawBuffer->_ColorDrawBuffers[0]->RedBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->GreenBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->BlueBits;
|
||||
color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->AlphaBits;
|
||||
}
|
||||
}
|
||||
|
||||
if (color_bits<24) {
|
||||
clear_value = PACK_COLOR_565(c[0],c[1],c[2]);
|
||||
color_mask = 0xffff;
|
||||
}
|
||||
|
||||
nouveauClearBuffer(ctx, nmesa->color_buffer,
|
||||
clear_value, color_mask);
|
||||
}
|
||||
|
||||
if (mask & (BUFFER_BIT_DEPTH)) {
|
||||
int depth_bits = 24;
|
||||
int depth_mask;
|
||||
if (ctx->DrawBuffer) {
|
||||
if (ctx->DrawBuffer->_DepthBuffer) {
|
||||
depth_bits = ctx->DrawBuffer->_DepthBuffer->DepthBits;
|
||||
}
|
||||
}
|
||||
|
||||
switch(depth_bits) {
|
||||
case 16:
|
||||
clear_value = (uint32_t) (ctx->Depth.Clear * 32767.0);
|
||||
depth_mask = 0xffff;
|
||||
break;
|
||||
default:
|
||||
clear_value = ((uint32_t) (ctx->Depth.Clear * 16777215.0)) << 8;
|
||||
depth_mask = 0xffffff00;
|
||||
break;
|
||||
}
|
||||
|
||||
nouveauClearBuffer(ctx, nmesa->depth_buffer,
|
||||
clear_value, depth_mask);
|
||||
}
|
||||
|
||||
if (mask & (BUFFER_BIT_STENCIL)) {
|
||||
int stencil_bits = 0;
|
||||
if (ctx->DrawBuffer) {
|
||||
if (ctx->DrawBuffer->_StencilBuffer) {
|
||||
stencil_bits = ctx->DrawBuffer->_StencilBuffer->StencilBits;
|
||||
}
|
||||
}
|
||||
|
||||
if (stencil_bits>0) {
|
||||
nouveauClearBuffer(ctx, nmesa->depth_buffer,
|
||||
ctx->Stencil.Clear, (1<<stencil_bits)-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nouveauDriverInitFunctions( struct dd_function_table *functions )
|
||||
{
|
||||
functions->GetBufferSize = nouveauGetBufferSize;
|
||||
functions->ResizeBuffers = _mesa_resize_framebuffer;
|
||||
functions->GetString = nouveauGetString;
|
||||
functions->Flush = nouveauFlush;
|
||||
functions->Finish = nouveauFinish;
|
||||
functions->Clear = nouveauClear;
|
||||
}
|
||||
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_DRIVER_H__
|
||||
#define __NOUVEAU_DRIVER_H__
|
||||
|
||||
#define DRIVER_DATE "20060219"
|
||||
#define DRIVER_AUTHOR "Stephane Marchesin"
|
||||
|
||||
extern void nouveauDriverInitFunctions( struct dd_function_table *functions );
|
||||
extern GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa, unsigned int param,
|
||||
uint64_t *value);
|
||||
extern GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa, unsigned int param,
|
||||
uint64_t value);
|
||||
|
||||
#endif /* __NOUVEAU_DRIVER_H__ */
|
||||
|
||||
|
|
@ -1,289 +0,0 @@
|
|||
#include "utils.h"
|
||||
#include "framebuffer.h"
|
||||
#include "renderbuffer.h"
|
||||
#include "fbobject.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_fbo.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_reg.h"
|
||||
|
||||
static GLboolean
|
||||
nouveau_renderbuffer_pixelformat(nouveau_renderbuffer_t * nrb,
|
||||
GLenum internalFormat)
|
||||
{
|
||||
nrb->mesa.InternalFormat = internalFormat;
|
||||
|
||||
/*TODO: We probably want to extend this a bit, and maybe make
|
||||
* card-specific?
|
||||
*/
|
||||
switch (internalFormat) {
|
||||
case GL_RGBA:
|
||||
case GL_RGBA8:
|
||||
nrb->mesa._BaseFormat = GL_RGBA;
|
||||
nrb->mesa._ActualFormat = GL_RGBA8;
|
||||
nrb->mesa.DataType = GL_UNSIGNED_BYTE;
|
||||
nrb->mesa.RedBits = 8;
|
||||
nrb->mesa.GreenBits = 8;
|
||||
nrb->mesa.BlueBits = 8;
|
||||
nrb->mesa.AlphaBits = 8;
|
||||
nrb->cpp = 4;
|
||||
break;
|
||||
case GL_RGB:
|
||||
case GL_RGB5:
|
||||
nrb->mesa._BaseFormat = GL_RGB;
|
||||
nrb->mesa._ActualFormat = GL_RGB5;
|
||||
nrb->mesa.DataType = GL_UNSIGNED_BYTE;
|
||||
nrb->mesa.RedBits = 5;
|
||||
nrb->mesa.GreenBits = 6;
|
||||
nrb->mesa.BlueBits = 5;
|
||||
nrb->mesa.AlphaBits = 0;
|
||||
nrb->cpp = 2;
|
||||
break;
|
||||
case GL_DEPTH_COMPONENT16:
|
||||
nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT;
|
||||
nrb->mesa._ActualFormat = GL_DEPTH_COMPONENT16;
|
||||
nrb->mesa.DataType = GL_UNSIGNED_SHORT;
|
||||
nrb->mesa.DepthBits = 16;
|
||||
nrb->cpp = 2;
|
||||
break;
|
||||
case GL_DEPTH_COMPONENT24:
|
||||
nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT;
|
||||
nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
|
||||
nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
|
||||
nrb->mesa.DepthBits = 24;
|
||||
nrb->cpp = 4;
|
||||
break;
|
||||
case GL_STENCIL_INDEX8_EXT:
|
||||
nrb->mesa._BaseFormat = GL_STENCIL_INDEX;
|
||||
nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
|
||||
nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
|
||||
nrb->mesa.StencilBits = 8;
|
||||
nrb->cpp = 4;
|
||||
break;
|
||||
case GL_DEPTH24_STENCIL8_EXT:
|
||||
nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT;
|
||||
nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT;
|
||||
nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT;
|
||||
nrb->mesa.DepthBits = 24;
|
||||
nrb->mesa.StencilBits = 8;
|
||||
nrb->cpp = 4;
|
||||
break;
|
||||
default:
|
||||
return GL_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
|
||||
GLenum internalFormat,
|
||||
GLuint width, GLuint height)
|
||||
{
|
||||
nouveau_renderbuffer_t *nrb = (nouveau_renderbuffer_t *) rb;
|
||||
|
||||
if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) {
|
||||
fprintf(stderr, "%s: unknown internalFormat\n", __func__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* If this buffer isn't statically alloc'd, we may need to ask the
|
||||
* drm for more memory */
|
||||
if (rb->Width != width || rb->Height != height) {
|
||||
GLuint pitch;
|
||||
|
||||
/* align pitches to 64 bytes */
|
||||
pitch = ((width * nrb->cpp) + 63) & ~63;
|
||||
|
||||
if (nrb->mem)
|
||||
nouveau_mem_free(ctx, nrb->mem);
|
||||
nrb->mem = nouveau_mem_alloc(ctx,
|
||||
NOUVEAU_MEM_FB |
|
||||
NOUVEAU_MEM_MAPPED,
|
||||
pitch * height, 0);
|
||||
if (!nrb->mem)
|
||||
return GL_FALSE;
|
||||
|
||||
/* update nouveau_renderbuffer info */
|
||||
nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem);
|
||||
nrb->pitch = pitch;
|
||||
}
|
||||
|
||||
rb->Width = width;
|
||||
rb->Height = height;
|
||||
rb->InternalFormat = internalFormat;
|
||||
|
||||
nouveauSpanSetFunctions(nrb);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_renderbuffer_delete(struct gl_renderbuffer *rb)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
nouveau_renderbuffer_t *nrb = (nouveau_renderbuffer_t *) rb;
|
||||
|
||||
if (nrb->mem)
|
||||
nouveau_mem_free(ctx, nrb->mem);
|
||||
FREE(nrb);
|
||||
}
|
||||
|
||||
nouveau_renderbuffer_t *
|
||||
nouveau_renderbuffer_new(GLenum internalFormat)
|
||||
{
|
||||
nouveau_renderbuffer_t *nrb;
|
||||
|
||||
nrb = CALLOC_STRUCT(nouveau_renderbuffer);
|
||||
if (!nrb)
|
||||
return NULL;
|
||||
|
||||
_mesa_init_renderbuffer(&nrb->mesa, 0);
|
||||
|
||||
if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) {
|
||||
fprintf(stderr, "%s: unknown internalFormat\n", __func__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
|
||||
nrb->mesa.Delete = nouveau_renderbuffer_delete;
|
||||
|
||||
return nrb;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa,
|
||||
nouveau_renderbuffer_t * nrb)
|
||||
{
|
||||
nmesa->numClipRects = 1;
|
||||
nmesa->pClipRects = &nmesa->osClipRect;
|
||||
nmesa->osClipRect.x1 = 0;
|
||||
nmesa->osClipRect.y1 = 0;
|
||||
nmesa->osClipRect.x2 = nrb->mesa.Width;
|
||||
nmesa->osClipRect.y2 = nrb->mesa.Height;
|
||||
nmesa->drawX = 0;
|
||||
nmesa->drawY = 0;
|
||||
nmesa->drawW = nrb->mesa.Width;
|
||||
nmesa->drawH = nrb->mesa.Height;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_window_moved(GLcontext * ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_renderbuffer_t *nrb;
|
||||
|
||||
nrb = (nouveau_renderbuffer_t *) ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
if (!nrb)
|
||||
return;
|
||||
|
||||
nouveau_cliprects_renderbuffer_set(nmesa, nrb);
|
||||
|
||||
/* Viewport depends on window size/position, nouveauCalcViewport
|
||||
* will take care of calling the hw-specific WindowMoved
|
||||
*/
|
||||
ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
|
||||
ctx->Viewport.Width, ctx->Viewport.Height);
|
||||
/* Scissor depends on window position */
|
||||
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
||||
ctx->Scissor.Width, ctx->Scissor.Height);
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_renderbuffer_t *color[MAX_DRAW_BUFFERS];
|
||||
nouveau_renderbuffer_t *depth;
|
||||
|
||||
_mesa_update_framebuffer(ctx);
|
||||
_mesa_update_draw_buffer_bounds(ctx);
|
||||
|
||||
color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0];
|
||||
if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped)
|
||||
depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer->Wrapped;
|
||||
else
|
||||
depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer;
|
||||
|
||||
if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth))
|
||||
return GL_FALSE;
|
||||
nouveau_window_moved(ctx);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauDrawBuffer(GLcontext *ctx, GLenum buffer)
|
||||
{
|
||||
nouveau_build_framebuffer(ctx, ctx->DrawBuffer);
|
||||
}
|
||||
|
||||
static struct gl_framebuffer *
|
||||
nouveauNewFramebuffer(GLcontext *ctx, GLuint name)
|
||||
{
|
||||
return _mesa_new_framebuffer(ctx, name);
|
||||
}
|
||||
|
||||
static struct gl_renderbuffer *
|
||||
nouveauNewRenderbuffer(GLcontext *ctx, GLuint name)
|
||||
{
|
||||
nouveau_renderbuffer_t *nrb;
|
||||
|
||||
nrb = CALLOC_STRUCT(nouveau_renderbuffer);
|
||||
if (!nrb)
|
||||
return NULL;
|
||||
|
||||
_mesa_init_renderbuffer(&nrb->mesa, name);
|
||||
|
||||
nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
|
||||
nrb->mesa.Delete = nouveau_renderbuffer_delete;
|
||||
return &nrb->mesa;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauBindFramebuffer(GLcontext *ctx, GLenum target,
|
||||
struct gl_framebuffer *fb,
|
||||
struct gl_framebuffer *fbread)
|
||||
{
|
||||
if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
|
||||
nouveau_build_framebuffer(ctx, fb);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauFramebufferRenderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||
GLenum attachment, struct gl_renderbuffer *rb)
|
||||
{
|
||||
_mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
|
||||
nouveau_build_framebuffer(ctx, fb);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauRenderTexture(GLcontext * ctx, struct gl_framebuffer *fb,
|
||||
struct gl_renderbuffer_attachment *att)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauFinishRenderTexture(GLcontext * ctx,
|
||||
struct gl_renderbuffer_attachment *att)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nouveauInitBufferFuncs(struct dd_function_table *func)
|
||||
{
|
||||
func->DrawBuffer = nouveauDrawBuffer;
|
||||
|
||||
func->NewFramebuffer = nouveauNewFramebuffer;
|
||||
func->NewRenderbuffer = nouveauNewRenderbuffer;
|
||||
func->BindFramebuffer = nouveauBindFramebuffer;
|
||||
func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer;
|
||||
func->RenderTexture = nouveauRenderTexture;
|
||||
func->FinishRenderTexture = nouveauFinishRenderTexture;
|
||||
}
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef __NOUVEAU_BUFFERS_H__
|
||||
#define __NOUVEAU_BUFFERS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mtypes.h"
|
||||
#include "utils.h"
|
||||
#include "renderbuffer.h"
|
||||
|
||||
#include "nouveau_mem.h"
|
||||
|
||||
typedef struct nouveau_renderbuffer {
|
||||
struct gl_renderbuffer mesa; /* must be first! */
|
||||
|
||||
nouveau_mem *mem;
|
||||
void *map;
|
||||
|
||||
int cpp;
|
||||
uint32_t offset;
|
||||
uint32_t pitch;
|
||||
} nouveau_renderbuffer_t;
|
||||
|
||||
extern nouveau_renderbuffer_t *nouveau_renderbuffer_new(GLenum internalFormat);
|
||||
extern void nouveau_window_moved(GLcontext *);
|
||||
extern GLboolean nouveau_build_framebuffer(GLcontext *,
|
||||
struct gl_framebuffer *);
|
||||
extern nouveau_renderbuffer_t *nouveau_current_draw_buffer(GLcontext *);
|
||||
|
||||
extern void nouveauInitBufferFuncs(struct dd_function_table *);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "vblank.h"
|
||||
#include <errno.h>
|
||||
#include "mtypes.h"
|
||||
#include "macros.h"
|
||||
#include "dd.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_lock.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_sync.h"
|
||||
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
int nouveau_fifo_remaining=0;
|
||||
#endif
|
||||
|
||||
|
||||
#define RING_SKIPS 8
|
||||
|
||||
void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size)
|
||||
{
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
return;
|
||||
#endif
|
||||
u_int32_t fifo_get;
|
||||
while(nmesa->fifo.free < size+1) {
|
||||
fifo_get = NV_FIFO_READ_GET();
|
||||
|
||||
if(nmesa->fifo.put >= fifo_get) {
|
||||
nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current;
|
||||
if(nmesa->fifo.free < size+1) {
|
||||
OUT_RING(NV03_FIFO_CMD_JUMP |
|
||||
nmesa->fifo.drm.put_base);
|
||||
if(fifo_get <= RING_SKIPS) {
|
||||
if(nmesa->fifo.put <= RING_SKIPS) /* corner case - will be idle */
|
||||
NV_FIFO_WRITE_PUT(RING_SKIPS + 1);
|
||||
do { fifo_get = NV_FIFO_READ_GET(); }
|
||||
while(fifo_get <= RING_SKIPS);
|
||||
}
|
||||
NV_FIFO_WRITE_PUT(RING_SKIPS);
|
||||
nmesa->fifo.current = nmesa->fifo.put = RING_SKIPS;
|
||||
nmesa->fifo.free = fifo_get - (RING_SKIPS + 1);
|
||||
}
|
||||
} else
|
||||
nmesa->fifo.free = fifo_get - nmesa->fifo.current - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the channel to be idle
|
||||
*/
|
||||
void nouveauWaitForIdleLocked(nouveauContextPtr nmesa)
|
||||
{
|
||||
/* Wait for FIFO idle */
|
||||
FIRE_RING();
|
||||
while(RING_AHEAD()>0);
|
||||
|
||||
/* Wait on notifier to indicate all commands in the channel have
|
||||
* been completed.
|
||||
*/
|
||||
nouveau_notifier_wait_nop(nmesa->glCtx, nmesa->syncNotifier, NvSub3D);
|
||||
}
|
||||
|
||||
void nouveauWaitForIdle(nouveauContextPtr nmesa)
|
||||
{
|
||||
LOCK_HARDWARE(nmesa);
|
||||
nouveauWaitForIdleLocked(nmesa);
|
||||
UNLOCK_HARDWARE(nmesa);
|
||||
}
|
||||
|
||||
// here we call the fifo initialization ioctl and fill in stuff accordingly
|
||||
GLboolean nouveauFifoInit(nouveauContextPtr nmesa)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
return GL_TRUE;
|
||||
#endif
|
||||
|
||||
nmesa->fifo.drm.fb_ctxdma_handle = NvDmaFB;
|
||||
nmesa->fifo.drm.tt_ctxdma_handle = NvDmaTT;
|
||||
ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_CHANNEL_ALLOC,
|
||||
&nmesa->fifo.drm, sizeof(nmesa->fifo.drm));
|
||||
if (ret) {
|
||||
FATAL("Fifo initialization ioctl failed (returned %d)\n", ret);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
ret = drmMap(nmesa->driFd, nmesa->fifo.drm.cmdbuf,
|
||||
nmesa->fifo.drm.cmdbuf_size, &nmesa->fifo.pushbuf);
|
||||
if (ret) {
|
||||
FATAL("Unable to map the fifo (returned %d)\n", ret);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
ret = drmMap(nmesa->driFd, nmesa->fifo.drm.ctrl,
|
||||
nmesa->fifo.drm.ctrl_size, &nmesa->fifo.mmio);
|
||||
if (ret) {
|
||||
FATAL("Unable to map the control regs (returned %d)\n", ret);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
ret = drmMap(nmesa->driFd, nmesa->fifo.drm.notifier,
|
||||
nmesa->fifo.drm.notifier_size,
|
||||
&nmesa->fifo.notifier_block);
|
||||
if (ret) {
|
||||
FATAL("Unable to map the notifier block (returned %d)\n", ret);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* Setup our initial FIFO tracking params */
|
||||
nmesa->fifo.current = 0;
|
||||
nmesa->fifo.put = 0;
|
||||
nmesa->fifo.max = (nmesa->fifo.drm.cmdbuf_size >> 2) - 1;
|
||||
nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current;
|
||||
|
||||
for (i=0; i<RING_SKIPS; i++)
|
||||
OUT_RING(0);
|
||||
nmesa->fifo.free -= RING_SKIPS;
|
||||
|
||||
MESSAGE("Fifo init ok. Using context %d\n", nmesa->fifo.drm.channel);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_FIFO_H__
|
||||
#define __NOUVEAU_FIFO_H__
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_ctrlreg.h"
|
||||
#include "nouveau_state_cache.h"
|
||||
|
||||
//#define NOUVEAU_RING_TRACE
|
||||
//#define NOUVEAU_RING_DEBUG
|
||||
//#define NOUVEAU_STATE_CACHE_DISABLE
|
||||
|
||||
#ifndef NOUVEAU_RING_TRACE
|
||||
#define NOUVEAU_RING_TRACE 0
|
||||
#else
|
||||
#undef NOUVEAU_RING_TRACE
|
||||
#define NOUVEAU_RING_TRACE 1
|
||||
#endif
|
||||
|
||||
#define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg))
|
||||
|
||||
#define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4))
|
||||
#define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value;
|
||||
#define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.drm.put_base) >> 2)
|
||||
#define NV_FIFO_WRITE_PUT(val) do { \
|
||||
if (NOUVEAU_RING_TRACE) {\
|
||||
printf("FIRE_RING : 0x%08x\n", nmesa->fifo.current << 2); \
|
||||
fflush(stdout); \
|
||||
sleep(1); \
|
||||
} \
|
||||
NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.drm.put_base); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* Ring/fifo interface
|
||||
*
|
||||
* - Begin a ring section with BEGIN_RING_SIZE (if you know the full size in advance)
|
||||
* - Output stuff to the ring with either OUT_RINGp (outputs a raw mem chunk), OUT_RING (1 uint32_t) or OUT_RINGf (1 float)
|
||||
* - RING_AVAILABLE returns the available fifo (in uint32_ts)
|
||||
* - RING_AHEAD returns how much ahead of the last submission point we are
|
||||
* - FIRE_RING fires whatever we have that wasn't fired before
|
||||
* - WAIT_RING waits for size (in uint32_ts) to be available in the fifo
|
||||
*/
|
||||
|
||||
/* Enable for ring debugging. Prints out writes to the ring buffer
|
||||
* but does not actually write to it.
|
||||
*/
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
|
||||
extern int nouveau_fifo_remaining;
|
||||
|
||||
#define OUT_RINGp(ptr,sz) do { \
|
||||
uint32_t* p=(uint32_t*)(ptr); \
|
||||
int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;i<sz;i++) printf(" 0x%08x %f\n", *(p+i), *((float*)(p+i))); \
|
||||
nouveau_fifo_remaining-=sz; \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
printf("OUT_RINGn: 0x%08x (%s)\n", n, __func__); \
|
||||
nouveau_fifo_remaining--; \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RINGf(n) do { \
|
||||
printf("OUT_RINGf: %.04f (%s)\n", n, __func__); \
|
||||
nouveau_fifo_remaining--; \
|
||||
}while(0)
|
||||
|
||||
#define BEGIN_RING_SIZE(subchannel,tag,size) do { \
|
||||
if (nouveau_fifo_remaining!=0) \
|
||||
printf("RING ERROR : remaining %d\n",nouveau_fifo_remaining); \
|
||||
nouveau_state_cache_flush(nmesa); \
|
||||
if (nmesa->fifo.free <= (size)) \
|
||||
WAIT_RING(nmesa,(size)); \
|
||||
OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \
|
||||
nmesa->fifo.free -= ((size) + 1); \
|
||||
nouveau_fifo_remaining=size; \
|
||||
}while(0)
|
||||
|
||||
#else
|
||||
|
||||
#define OUT_RINGp(ptr,sz) do{ \
|
||||
if (NOUVEAU_RING_TRACE) { \
|
||||
uint32_t* p=(uint32_t*)(ptr); \
|
||||
int i; printf("OUT_RINGp: (size 0x%x dwords) (%s)\n",sz, __func__); for(i=0;i<sz;i++) printf(" [0x%08x] 0x%08x %f\n", (nmesa->fifo.current+i) << 2, *(p+i), *((float*)(p+i))); \
|
||||
} \
|
||||
memcpy(nmesa->fifo.pushbuf+nmesa->fifo.current,ptr,(sz)*4); \
|
||||
nmesa->fifo.current+=(sz); \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (NOUVEAU_RING_TRACE) \
|
||||
printf("OUT_RINGn: [0x%08x] 0x%08x (%s)\n", nmesa->fifo.current << 2, n, __func__); \
|
||||
nmesa->fifo.pushbuf[nmesa->fifo.current++]=(n); \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RINGf(n) do { \
|
||||
if (NOUVEAU_RING_TRACE) \
|
||||
printf("OUT_RINGf: [0x%08x] %.04f (%s)\n", nmesa->fifo.current << 2, n, __func__); \
|
||||
*((float*)(nmesa->fifo.pushbuf+nmesa->fifo.current++))=(n); \
|
||||
}while(0)
|
||||
|
||||
#define BEGIN_RING_SIZE(subchannel,tag,size) do { \
|
||||
nouveau_state_cache_flush(nmesa); \
|
||||
if (nmesa->fifo.free <= (size)) \
|
||||
WAIT_RING(nmesa,(size)); \
|
||||
OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \
|
||||
nmesa->fifo.free -= ((size) + 1); \
|
||||
}while(0)
|
||||
|
||||
#endif
|
||||
|
||||
extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size);
|
||||
extern void nouveau_state_cache_flush(nouveauContextPtr nmesa);
|
||||
extern void nouveau_state_cache_init(nouveauContextPtr nmesa);
|
||||
|
||||
#ifdef NOUVEAU_STATE_CACHE_DISABLE
|
||||
#define BEGIN_RING_CACHE(subc,tag,size) BEGIN_RING_SIZE((subc), (tag), (size))
|
||||
#define OUT_RING_CACHE(n) OUT_RING((n))
|
||||
#define OUT_RING_CACHEf(n) OUT_RINGf((n))
|
||||
#define OUT_RING_CACHEp(ptr, sz) OUT_RINGp((ptr), (sz))
|
||||
#define OUT_RING_CACHE_FORCE(n) OUT_RING((n))
|
||||
#define OUT_RING_CACHE_FORCEf(n) OUT_RINGf((n))
|
||||
#define OUT_RING_CACHE_FORCEp(ptr, sz) OUT_RINGp((ptr), (sz))
|
||||
#else
|
||||
#define BEGIN_RING_CACHE(subchannel,tag,size) do { \
|
||||
nmesa->state_cache.dirty=1; \
|
||||
nmesa->state_cache.current_pos=((tag)/4); \
|
||||
assert(nmesa->state_cache.current_pos + size <= NOUVEAU_STATE_CACHE_ENTRIES); \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING_CACHE(n) do { \
|
||||
if (nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value!=(n)) { \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \
|
||||
nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value=(n); \
|
||||
} \
|
||||
nmesa->state_cache.current_pos++; \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING_CACHEf(n) do { \
|
||||
if ((*(GLfloat*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))!=(n)){ \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \
|
||||
nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \
|
||||
(*(GLfloat*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\
|
||||
} \
|
||||
nmesa->state_cache.current_pos++; \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING_CACHEp(ptr,sz) do { \
|
||||
GLuint* p=(GLuint*)(ptr); \
|
||||
int i; \
|
||||
for(i=0;i<sz;i++) \
|
||||
OUT_RING_CACHE(*(p+i)); \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING_CACHE_FORCE(n) do { \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \
|
||||
nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value=(n); \
|
||||
nmesa->state_cache.current_pos++; \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING_CACHE_FORCEf(n) do { \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \
|
||||
nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \
|
||||
(*(GLfloat*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\
|
||||
nmesa->state_cache.current_pos++; \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING_CACHE_FORCEp(ptr,sz) do { \
|
||||
GLuint* p=(GLuint*)(ptr); \
|
||||
int i; \
|
||||
for(i=0;i<sz;i++) \
|
||||
OUT_RING_CACHE_FORCE(*(p+i)); \
|
||||
}while(0)
|
||||
#endif
|
||||
|
||||
#define RING_AVAILABLE() (nmesa->fifo.free-1)
|
||||
|
||||
#define RING_AHEAD() ((nmesa->fifo.put<=nmesa->fifo.current)?(nmesa->fifo.current-nmesa->fifo.put):nmesa->fifo.max-nmesa->fifo.put+nmesa->fifo.current)
|
||||
|
||||
#define FIRE_RING() do { \
|
||||
if (nmesa->fifo.current!=nmesa->fifo.put) { \
|
||||
nmesa->fifo.put=nmesa->fifo.current; \
|
||||
NV_FIFO_WRITE_PUT(nmesa->fifo.put); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
extern void nouveauWaitForIdle(nouveauContextPtr nmesa);
|
||||
extern void nouveauWaitForIdleLocked(nouveauContextPtr nmesa);
|
||||
extern GLboolean nouveauFifoInit(nouveauContextPtr nmesa);
|
||||
|
||||
#endif /* __NOUVEAU_FIFO_H__ */
|
||||
|
||||
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "nouveau_context.h"
|
||||
#include "nouveau_lock.h"
|
||||
|
||||
#include "drirenderbuffer.h"
|
||||
#include "framebuffer.h"
|
||||
|
||||
|
||||
/* Update the hardware state. This is called if another context has
|
||||
* grabbed the hardware lock, which includes the X server. This
|
||||
* function also updates the driver's window state after the X server
|
||||
* moves, resizes or restacks a window -- the change will be reflected
|
||||
* in the drawable position and clip rects. Since the X server grabs
|
||||
* the hardware lock when it changes the window state, this routine will
|
||||
* automatically be called after such a change.
|
||||
*/
|
||||
void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags )
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = nmesa->driDrawable;
|
||||
__DRIscreenPrivate *sPriv = nmesa->driScreen;
|
||||
struct drm_nouveau_sarea *sarea = nmesa->sarea;
|
||||
|
||||
drmGetLock( nmesa->driFd, nmesa->hHWContext, flags );
|
||||
|
||||
/* The window might have moved, so we might need to get new clip
|
||||
* rects.
|
||||
*
|
||||
* NOTE: This releases and regrabs the hw lock to allow the X server
|
||||
* to respond to the DRI protocol request for new drawable info.
|
||||
* Since the hardware state depends on having the latest drawable
|
||||
* clip rects, all state checking must be done _after_ this call.
|
||||
*/
|
||||
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
|
||||
|
||||
/* If timestamps don't match, the window has been changed */
|
||||
if (nmesa->lastStamp != dPriv->lastStamp) {
|
||||
struct gl_framebuffer *fb = (struct gl_framebuffer *)dPriv->driverPrivate;
|
||||
|
||||
/* _mesa_resize_framebuffer will take care of calling the renderbuffer's
|
||||
* AllocStorage function if we need more memory to hold it */
|
||||
if (fb->Width != dPriv->w || fb->Height != dPriv->h) {
|
||||
_mesa_resize_framebuffer(nmesa->glCtx, fb, dPriv->w, dPriv->h);
|
||||
/* resize buffers, will call nouveau_window_moved */
|
||||
nouveau_build_framebuffer(nmesa->glCtx, fb);
|
||||
} else {
|
||||
nouveau_window_moved(nmesa->glCtx);
|
||||
}
|
||||
|
||||
nmesa->lastStamp = dPriv->lastStamp;
|
||||
}
|
||||
|
||||
nmesa->numClipRects = dPriv->numClipRects;
|
||||
nmesa->pClipRects = dPriv->pClipRects;
|
||||
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_LOCK_H__
|
||||
#define __NOUVEAU_LOCK_H__
|
||||
|
||||
#include "nouveau_context.h"
|
||||
|
||||
extern void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags );
|
||||
|
||||
/*
|
||||
* !!! We may want to separate locks from locks with validation. This
|
||||
* could be used to improve performance for those things commands that
|
||||
* do not do any drawing !!!
|
||||
*/
|
||||
|
||||
/* Lock the hardware and validate our state.
|
||||
*/
|
||||
#define LOCK_HARDWARE( nmesa ) \
|
||||
do { \
|
||||
char __ret = 0; \
|
||||
DEBUG_CHECK_LOCK(); \
|
||||
DRM_CAS( nmesa->driHwLock, nmesa->hHWContext, \
|
||||
(DRM_LOCK_HELD | nmesa->hHWContext), __ret ); \
|
||||
if ( __ret ) \
|
||||
nouveauGetLock( nmesa, 0 ); \
|
||||
DEBUG_LOCK(); \
|
||||
} while (0)
|
||||
|
||||
/* Unlock the hardware.
|
||||
*/
|
||||
#define UNLOCK_HARDWARE( nmesa ) \
|
||||
do { \
|
||||
DRM_UNLOCK( nmesa->driFd, \
|
||||
nmesa->driHwLock, \
|
||||
nmesa->hHWContext ); \
|
||||
DEBUG_RESET(); \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_LOCK()
|
||||
#define DEBUG_RESET()
|
||||
#define DEBUG_CHECK_LOCK()
|
||||
|
||||
|
||||
#endif /* __NOUVEAU_LOCK_H__ */
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
#include "mtypes.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_mem.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_reg.h"
|
||||
|
||||
#define MAX_MEMFMT_LENGTH 32768
|
||||
|
||||
/* Unstrided blit using NV_MEMORY_TO_MEMORY_FORMAT */
|
||||
GLboolean
|
||||
nouveau_memformat_flat_emit(GLcontext * ctx,
|
||||
nouveau_mem * dst, nouveau_mem * src,
|
||||
GLuint dst_offset, GLuint src_offset,
|
||||
GLuint size)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
uint32_t src_handle, dst_handle;
|
||||
GLuint count;
|
||||
|
||||
if (src_offset + size > src->size) {
|
||||
MESSAGE("src out of nouveau_mem bounds\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
if (dst_offset + size > dst->size) {
|
||||
MESSAGE("dst out of nouveau_mem bounds\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT;
|
||||
dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT;
|
||||
src_offset += nouveau_mem_gpu_offset_get(ctx, src);
|
||||
dst_offset += nouveau_mem_gpu_offset_get(ctx, dst);
|
||||
|
||||
BEGIN_RING_SIZE(NvSubMemFormat,
|
||||
NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2);
|
||||
OUT_RING(src_handle);
|
||||
OUT_RING(dst_handle);
|
||||
|
||||
count = (size / MAX_MEMFMT_LENGTH) +
|
||||
((size % MAX_MEMFMT_LENGTH) ? 1 : 0);
|
||||
|
||||
while (count--) {
|
||||
GLuint length =
|
||||
(size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size;
|
||||
|
||||
BEGIN_RING_SIZE(NvSubMemFormat,
|
||||
NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
|
||||
OUT_RING(src_offset);
|
||||
OUT_RING(dst_offset);
|
||||
OUT_RING(0); /* pitch in */
|
||||
OUT_RING(0); /* pitch out */
|
||||
OUT_RING(length); /* line length */
|
||||
OUT_RING(1); /* number of lines */
|
||||
OUT_RING((1 << 8) /* dst_inc */ |(1 << 0) /* src_inc */ );
|
||||
OUT_RING(0); /* buffer notify? */
|
||||
FIRE_RING();
|
||||
|
||||
src_offset += length;
|
||||
dst_offset += length;
|
||||
size -= length;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void nouveau_mem_free(GLcontext * ctx, nouveau_mem * mem)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
struct drm_nouveau_mem_free memf;
|
||||
|
||||
if (NOUVEAU_DEBUG & DEBUG_MEM) {
|
||||
fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n",
|
||||
__func__, mem->type, (GLuint) mem->offset,
|
||||
(GLuint) mem->size);
|
||||
}
|
||||
|
||||
if (mem->map)
|
||||
drmUnmap(mem->map, mem->size);
|
||||
memf.flags = mem->type;
|
||||
memf.offset = mem->offset;
|
||||
drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf,
|
||||
sizeof(memf));
|
||||
FREE(mem);
|
||||
}
|
||||
|
||||
nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, uint32_t flags, GLuint size,
|
||||
GLuint align)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
struct drm_nouveau_mem_alloc mema;
|
||||
nouveau_mem *mem;
|
||||
int ret;
|
||||
|
||||
if (NOUVEAU_DEBUG & DEBUG_MEM) {
|
||||
fprintf(stderr,
|
||||
"%s: requested: flags=0x%x, size=0x%x, align=0x%x\n",
|
||||
__func__, flags, (GLuint) size, align);
|
||||
}
|
||||
|
||||
mem = CALLOC(sizeof(nouveau_mem));
|
||||
if (!mem)
|
||||
return NULL;
|
||||
|
||||
mema.flags = flags;
|
||||
mema.size = mem->size = size;
|
||||
mema.alignment = align;
|
||||
mem->map = NULL;
|
||||
ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC,
|
||||
&mema, sizeof(mema));
|
||||
if (ret) {
|
||||
FREE(mem);
|
||||
return NULL;
|
||||
}
|
||||
mem->offset = mema.offset;
|
||||
mem->type = mema.flags;
|
||||
|
||||
if (NOUVEAU_DEBUG & DEBUG_MEM) {
|
||||
fprintf(stderr,
|
||||
"%s: actual: type=0x%x, offset=0x%x, size=0x%x\n",
|
||||
__func__, mem->type, (GLuint) mem->offset,
|
||||
(GLuint) mem->size);
|
||||
}
|
||||
|
||||
if (flags & NOUVEAU_MEM_MAPPED)
|
||||
ret = drmMap(nmesa->driFd, mema.map_handle, mem->size,
|
||||
&mem->map);
|
||||
if (ret) {
|
||||
mem->map = NULL;
|
||||
nouveau_mem_free(ctx, mem);
|
||||
mem = NULL;
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
uint32_t nouveau_mem_gpu_offset_get(GLcontext * ctx, nouveau_mem * mem)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
return mem->offset;
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef __NOUVEAU_MEM_H__
|
||||
#define __NOUVEAU_MEM_H__
|
||||
|
||||
typedef struct nouveau_mem_t {
|
||||
int type;
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
void *map;
|
||||
} nouveau_mem;
|
||||
|
||||
extern nouveau_mem *nouveau_mem_alloc(GLcontext *, uint32_t flags,
|
||||
GLuint size, GLuint align);
|
||||
extern void nouveau_mem_free(GLcontext *, nouveau_mem *);
|
||||
extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *, nouveau_mem *);
|
||||
|
||||
extern GLboolean nouveau_memformat_flat_emit(GLcontext *,
|
||||
nouveau_mem *dst,
|
||||
nouveau_mem *src,
|
||||
GLuint dst_offset,
|
||||
GLuint src_offset,
|
||||
GLuint size);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
Copyright 2006 Stephane Marchesin. All Rights Reserved
|
||||
|
||||
The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
This notice must be preserved.
|
||||
|
||||
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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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:
|
||||
* Keith Whitwell <keith@tungstengraphics.com>
|
||||
* Nicolai Haehnle <prefect_@gmx.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_MSG_H__
|
||||
#define __NOUVEAU_MSG_H__
|
||||
|
||||
#define WARN_ONCE(a, ...) do {\
|
||||
static int warn##__LINE__=1;\
|
||||
if(warn##__LINE__){\
|
||||
fprintf(stderr, "*********************************WARN_ONCE*********************************\n");\
|
||||
fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__);\
|
||||
fprintf(stderr, a, ## __VA_ARGS__);\
|
||||
fprintf(stderr, "***************************************************************************\n");\
|
||||
warn##__LINE__=0;\
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
#define MESSAGE(a, ...) do{\
|
||||
fprintf(stderr, "************************************INFO***********************************\n");\
|
||||
fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__); \
|
||||
fprintf(stderr, a, ## __VA_ARGS__);\
|
||||
fprintf(stderr, "***************************************************************************\n");\
|
||||
}while(0)
|
||||
|
||||
#define FATAL(a, ...) do{\
|
||||
fprintf(stderr, "***********************************FATAL***********************************\n");\
|
||||
fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__); \
|
||||
fprintf(stderr, a, ## __VA_ARGS__);\
|
||||
fprintf(stderr, "***************************************************************************\n");\
|
||||
}while(0)
|
||||
|
||||
#endif /* __NOUVEAU_MSG_H__ */
|
||||
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_reg.h"
|
||||
|
||||
|
||||
GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa,
|
||||
uint32_t handle, int class)
|
||||
{
|
||||
struct drm_nouveau_grobj_alloc cto;
|
||||
int ret;
|
||||
|
||||
cto.channel = nmesa->fifo.drm.channel;
|
||||
cto.handle = handle;
|
||||
cto.class = class;
|
||||
ret = drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_GROBJ_ALLOC,
|
||||
&cto, sizeof(cto));
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle)
|
||||
{
|
||||
BEGIN_RING_SIZE(subchannel, 0, 1);
|
||||
OUT_RING(handle);
|
||||
}
|
||||
|
||||
void nouveauObjectInit(nouveauContextPtr nmesa)
|
||||
{
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
return;
|
||||
#endif
|
||||
|
||||
nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d);
|
||||
if (nmesa->screen->card->type>=NV_10) {
|
||||
nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D);
|
||||
} else {
|
||||
nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D);
|
||||
nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D);
|
||||
}
|
||||
if (nmesa->screen->card->type>=NV_11) {
|
||||
nouveauCreateContextObject(nmesa, NvImageBlit, NV11_IMAGE_BLIT);
|
||||
} else {
|
||||
nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT);
|
||||
}
|
||||
if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<NV_20)) {
|
||||
nouveauCreateContextObject(nmesa, NvGdiRectText, NV04_GDI_RECTANGLE_TEXT);
|
||||
nouveauCreateContextObject(nmesa, NvRasterOp, NV03_PRIMITIVE_RASTER_OP);
|
||||
nouveauCreateContextObject(nmesa, NvPattern, NV04_IMAGE_PATTERN);
|
||||
}
|
||||
nouveauCreateContextObject(nmesa, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT);
|
||||
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D);
|
||||
BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY0, 2);
|
||||
OUT_RING(NvDmaFB);
|
||||
OUT_RING(NvDmaFB);
|
||||
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubImageBlit, NvImageBlit);
|
||||
BEGIN_RING_SIZE(NvSubImageBlit, NV_IMAGE_BLIT_SET_SURFACES_2D, 1);
|
||||
OUT_RING(NvCtxSurf2D);
|
||||
BEGIN_RING_SIZE(NvSubImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
|
||||
OUT_RING(3); /* SRCCOPY */
|
||||
|
||||
if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<NV_20)) {
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubPattern, NvPattern);
|
||||
|
||||
BEGIN_RING_SIZE(NvSubPattern, NV04_IMAGE_PATTERN_COLOR_FORMAT, 4);
|
||||
OUT_RING(1); /* A16R5G6B5 */
|
||||
OUT_RING(1); /* little endian */
|
||||
OUT_RING(0); /* 8x8 */
|
||||
OUT_RING(1); /* monochrome */
|
||||
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubRasterOp, NvRasterOp);
|
||||
|
||||
BEGIN_RING_SIZE(NvSubRasterOp, NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY, 1);
|
||||
OUT_RING(NvSyncNotify);
|
||||
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubGdiRectText, NvGdiRectText);
|
||||
|
||||
BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY, 1);
|
||||
OUT_RING(NvSyncNotify);
|
||||
BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_PATTERN, 2);
|
||||
OUT_RING(NvPattern);
|
||||
OUT_RING(NvRasterOp);
|
||||
BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
|
||||
OUT_RING(NvCtxSurf2D);
|
||||
BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_FORMAT, 2);
|
||||
OUT_RING(1); /* X1R5G5B5 */
|
||||
OUT_RING(1); /* little endian */
|
||||
}
|
||||
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubMemFormat, NvMemFormat);
|
||||
|
||||
nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef __NOUVEAU_OBJECT_H__
|
||||
#define __NOUVEAU_OBJECT_H__
|
||||
|
||||
#include "nouveau_context.h"
|
||||
|
||||
void nouveauObjectInit(nouveauContextPtr nmesa);
|
||||
|
||||
enum DMAObjects {
|
||||
Nv3D = 0x80000019,
|
||||
NvCtxSurf2D = 0x80000020,
|
||||
NvImageBlit = 0x80000021,
|
||||
NvMemFormat = 0x80000022,
|
||||
NvCtxSurf3D = 0x80000023,
|
||||
NvGdiRectText = 0x80000024,
|
||||
NvPattern = 0x80000025,
|
||||
NvRasterOp = 0x80000026,
|
||||
NvDmaFB = 0xD0FB0001,
|
||||
NvDmaTT = 0xD0AA0001,
|
||||
NvSyncNotify = 0xD0000001,
|
||||
NvQueryNotify = 0xD0000002
|
||||
};
|
||||
|
||||
enum DMASubchannel {
|
||||
NvSubCtxSurf2D = 0,
|
||||
NvSubImageBlit = 1,
|
||||
NvSubMemFormat = 2,
|
||||
NvSubCtxSurf3D = 3,
|
||||
NvSubGdiRectText= 4,
|
||||
NvSubPattern = 5,
|
||||
NvSubRasterOp = 6,
|
||||
NvSub3D = 7,
|
||||
};
|
||||
|
||||
extern void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle);
|
||||
|
||||
extern GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa,
|
||||
uint32_t handle, int class);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Ben Skeggs.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* GL_ARB_occlusion_query support for NV20/30/40 */
|
||||
|
||||
#include "mtypes.h"
|
||||
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_sync.h"
|
||||
#include "nouveau_query.h"
|
||||
|
||||
static struct gl_query_object *
|
||||
nouveauNewQueryObject(GLcontext *ctx, GLuint id)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_query_object *nq;
|
||||
int i;
|
||||
|
||||
for (i=0; i<nmesa->query_object_max; i++)
|
||||
if (nmesa->query_alloc[i] == GL_FALSE)
|
||||
break;
|
||||
if (i==nmesa->query_object_max)
|
||||
return NULL;
|
||||
|
||||
nq = CALLOC_STRUCT(nouveau_query_object_t);
|
||||
if (nq) {
|
||||
nq->notifier_id = i;
|
||||
|
||||
nq->mesa.Id = id;
|
||||
nq->mesa.Result = 0;
|
||||
nq->mesa.Active = GL_FALSE;
|
||||
nq->mesa.Ready = GL_TRUE;
|
||||
}
|
||||
|
||||
return (struct gl_query_object *)nq;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_query_object *nq = (nouveau_query_object *)q;
|
||||
|
||||
nouveau_notifier_reset(ctx, nmesa->queryNotifier, nq->notifier_id);
|
||||
|
||||
switch (nmesa->screen->card->type) {
|
||||
case NV_20:
|
||||
BEGIN_RING_CACHE(NvSub3D, 0x17c8, 1);
|
||||
OUT_RING_CACHE (1);
|
||||
BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
|
||||
OUT_RING_CACHE (1);
|
||||
break;
|
||||
case NV_30:
|
||||
case NV_40:
|
||||
case NV_44:
|
||||
/* I don't think this is OCC_QUERY enable, but it *is* needed to make
|
||||
* the SET_OBJECT7 notifier block work with STORE_RESULT.
|
||||
*
|
||||
* Also, this appears to reset the pixel pass counter */
|
||||
BEGIN_RING_SIZE(NvSub3D,
|
||||
NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE,
|
||||
1);
|
||||
OUT_RING (1);
|
||||
/* Probably OCC_QUERY_ENABLE */
|
||||
BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
|
||||
OUT_RING_CACHE (1);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE("no support for this card\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauUpdateQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_query_object *nq = (nouveau_query_object *)q;
|
||||
int status;
|
||||
|
||||
status = nouveau_notifier_status(ctx, nmesa->queryNotifier,
|
||||
nq->notifier_id);
|
||||
|
||||
q->Ready = (status == NV_NOTIFY_STATE_STATUS_COMPLETED);
|
||||
if (q->Ready)
|
||||
q->Result = nouveau_notifier_return_val(ctx,
|
||||
nmesa->queryNotifier,
|
||||
nq->notifier_id);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauWaitQueryResult(GLcontext *ctx, GLenum target, struct gl_query_object *q)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nouveau_query_object *nq = (nouveau_query_object *)q;
|
||||
|
||||
nouveau_notifier_wait_status(ctx, nmesa->queryNotifier, nq->notifier_id,
|
||||
NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
|
||||
nouveauUpdateQuery(ctx, target, q);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
|
||||
{
|
||||
nouveau_query_object *nq = (nouveau_query_object *)q;
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
switch (nmesa->screen->card->type) {
|
||||
case NV_20:
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x17d0, 1);
|
||||
OUT_RING (0x01000000 | nq->notifier_id*32);
|
||||
break;
|
||||
case NV_30:
|
||||
case NV_40:
|
||||
case NV_44:
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STORE_RESULT, 1);
|
||||
OUT_RING (0x01000000 | nq->notifier_id*32);
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE("no support for this card\n");
|
||||
break;
|
||||
}
|
||||
FIRE_RING();
|
||||
|
||||
/*XXX: wait for query to complete, mesa doesn't give the driver
|
||||
* an interface to query the status of a query object so
|
||||
* this has to stall the channel.
|
||||
*/
|
||||
nouveauWaitQueryResult(ctx, target, q);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
|
||||
OUT_RING_CACHE (0);
|
||||
}
|
||||
|
||||
void
|
||||
nouveauQueryInitFuncs(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (nmesa->screen->card->type < NV_20)
|
||||
return;
|
||||
|
||||
/* Reserve half the notifier block for use as query objects */
|
||||
nmesa->query_object_max = (nmesa->fifo.drm.notifier_size / 2) / 32;
|
||||
nmesa->queryNotifier =
|
||||
nouveau_notifier_new(ctx, NvQueryNotify,
|
||||
nmesa->query_object_max);
|
||||
nmesa->query_alloc = calloc(nmesa->query_object_max, sizeof(GLboolean));
|
||||
|
||||
switch (nmesa->screen->card->type) {
|
||||
case NV_20:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
|
||||
OUT_RING_CACHE (NvQueryNotify);
|
||||
break;
|
||||
case NV_30:
|
||||
case NV_40:
|
||||
case NV_44:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT7, 1);
|
||||
OUT_RING_CACHE (NvQueryNotify);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
ctx->Driver.NewQueryObject = nouveauNewQueryObject;
|
||||
ctx->Driver.BeginQuery = nouveauBeginQuery;
|
||||
ctx->Driver.EndQuery = nouveauEndQuery;
|
||||
#if 0
|
||||
ctx->Driver.UpdateQuery = nouveauUpdateQuery;
|
||||
ctx->Driver.WaitQueryResult = nouveauWaitQueryResult;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Ben Skeggs.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NOUVEAU_QUERY_H__
|
||||
#define __NOUVEAU_QUERY_H__
|
||||
|
||||
typedef struct nouveau_query_object_t {
|
||||
struct gl_query_object mesa;
|
||||
|
||||
int notifier_id;
|
||||
} nouveau_query_object;
|
||||
|
||||
extern void nouveauQueryInitFuncs(GLcontext *ctx);
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,325 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "glheader.h"
|
||||
#include "imports.h"
|
||||
#include "mtypes.h"
|
||||
#include "framebuffer.h"
|
||||
#include "renderbuffer.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_screen.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_span.h"
|
||||
#include "nouveau_msg.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "context.h"
|
||||
#include "vblank.h"
|
||||
#include "drirenderbuffer.h"
|
||||
|
||||
#include "GL/internal/dri_interface.h"
|
||||
|
||||
#include "xmlpool.h"
|
||||
|
||||
PUBLIC const char __driConfigOptions[] =
|
||||
DRI_CONF_BEGIN
|
||||
DRI_CONF_SECTION_DEBUG
|
||||
DRI_CONF_NO_RAST(false)
|
||||
DRI_CONF_SECTION_END
|
||||
DRI_CONF_END;
|
||||
static const GLuint __driNConfigOptions = 1;
|
||||
|
||||
extern const struct dri_extension common_extensions[];
|
||||
extern const struct dri_extension nv10_extensions[];
|
||||
extern const struct dri_extension nv20_extensions[];
|
||||
extern const struct dri_extension nv30_extensions[];
|
||||
extern const struct dri_extension nv40_extensions[];
|
||||
extern const struct dri_extension nv50_extensions[];
|
||||
|
||||
static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv)
|
||||
{
|
||||
nouveauScreenPtr screen;
|
||||
NOUVEAUDRIPtr dri_priv=(NOUVEAUDRIPtr)sPriv->pDevPriv;
|
||||
|
||||
/* allocate screen */
|
||||
screen = (nouveauScreenPtr) CALLOC( sizeof(*screen) );
|
||||
if ( !screen ) {
|
||||
__driUtilMessage("%s: Could not allocate memory for screen structure",__FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen->card=nouveau_card_lookup(dri_priv->device_id);
|
||||
if (!screen->card) {
|
||||
__driUtilMessage("%s: Unknown card type 0x%04x:0x%04x\n",
|
||||
__func__, dri_priv->device_id >> 16, dri_priv->device_id & 0xFFFF);
|
||||
FREE(screen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* parse information in __driConfigOptions */
|
||||
driParseOptionInfo (&screen->optionCache,__driConfigOptions, __driNConfigOptions);
|
||||
|
||||
screen->fbFormat = dri_priv->bpp / 8;
|
||||
screen->frontOffset = dri_priv->front_offset;
|
||||
screen->frontPitch = dri_priv->front_pitch;
|
||||
screen->backOffset = dri_priv->back_offset;
|
||||
screen->backPitch = dri_priv->back_pitch;
|
||||
screen->depthOffset = dri_priv->depth_offset;
|
||||
screen->depthPitch = dri_priv->depth_pitch;
|
||||
|
||||
screen->driScreen = sPriv;
|
||||
return screen;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauDestroyScreen(__DRIscreenPrivate *sPriv)
|
||||
{
|
||||
nouveauScreenPtr screen = (nouveauScreenPtr)sPriv->private;
|
||||
|
||||
if (!screen) return;
|
||||
|
||||
/* free all option information */
|
||||
driDestroyOptionInfo (&screen->optionCache);
|
||||
|
||||
FREE(screen);
|
||||
sPriv->private = NULL;
|
||||
}
|
||||
|
||||
static GLboolean nouveauInitDriver(__DRIscreenPrivate *sPriv)
|
||||
{
|
||||
sPriv->private = (void *) nouveauCreateScreen( sPriv );
|
||||
if ( !sPriv->private ) {
|
||||
nouveauDestroyScreen( sPriv );
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Mesa framebuffer and renderbuffers for a given window/drawable.
|
||||
*
|
||||
* \todo This function (and its interface) will need to be updated to support
|
||||
* pbuffers.
|
||||
*/
|
||||
static GLboolean
|
||||
nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv,
|
||||
__DRIdrawablePrivate *driDrawPriv,
|
||||
const __GLcontextModes *mesaVis,
|
||||
GLboolean isPixmap)
|
||||
{
|
||||
nouveauScreenPtr screen = (nouveauScreenPtr) driScrnPriv->private;
|
||||
nouveau_renderbuffer_t *nrb;
|
||||
struct gl_framebuffer *fb;
|
||||
const GLboolean swAccum = mesaVis->accumRedBits > 0;
|
||||
const GLboolean swStencil = (mesaVis->stencilBits > 0 &&
|
||||
mesaVis->depthBits != 24);
|
||||
GLenum color_format = screen->fbFormat == 4 ? GL_RGBA8 : GL_RGB5;
|
||||
|
||||
if (isPixmap)
|
||||
return GL_FALSE; /* not implemented */
|
||||
|
||||
fb = _mesa_create_framebuffer(mesaVis);
|
||||
if (!fb)
|
||||
return GL_FALSE;
|
||||
|
||||
/* Front buffer */
|
||||
nrb = nouveau_renderbuffer_new(color_format);
|
||||
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &nrb->mesa);
|
||||
|
||||
if (mesaVis->doubleBufferMode) {
|
||||
nrb = nouveau_renderbuffer_new(color_format);
|
||||
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa);
|
||||
}
|
||||
|
||||
if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) {
|
||||
nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT);
|
||||
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa);
|
||||
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &nrb->mesa);
|
||||
} else
|
||||
if (mesaVis->depthBits == 24) {
|
||||
nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24);
|
||||
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa);
|
||||
} else
|
||||
if (mesaVis->depthBits == 16) {
|
||||
nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16);
|
||||
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa);
|
||||
}
|
||||
|
||||
_mesa_add_soft_renderbuffers(fb,
|
||||
GL_FALSE, /* color */
|
||||
GL_FALSE, /* depth */
|
||||
swStencil,
|
||||
swAccum,
|
||||
GL_FALSE, /* alpha */
|
||||
GL_FALSE /* aux */);
|
||||
|
||||
driDrawPriv->driverPrivate = (void *) fb;
|
||||
return (driDrawPriv->driverPrivate != NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nouveauDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
|
||||
{
|
||||
_mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
|
||||
}
|
||||
|
||||
static int
|
||||
nouveauGetSwapInfo(__DRIdrawablePrivate *dpriv, __DRIswapInfo *sInfo)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static __DRIconfig **
|
||||
nouveauFillInModes( __DRIscreenPrivate *psp,
|
||||
unsigned pixel_bits, unsigned depth_bits,
|
||||
unsigned stencil_bits, GLboolean have_back_buffer )
|
||||
{
|
||||
unsigned depth_buffer_factor;
|
||||
unsigned back_buffer_factor;
|
||||
|
||||
/* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
|
||||
* support pageflipping at all.
|
||||
*/
|
||||
static const GLenum back_buffer_modes[] = {
|
||||
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
|
||||
};
|
||||
|
||||
u_int8_t depth_bits_array[4] = { 0, 16, 24, 24 };
|
||||
u_int8_t stencil_bits_array[4] = { 0, 0, 0, 8 };
|
||||
|
||||
depth_buffer_factor = 4;
|
||||
back_buffer_factor = (have_back_buffer) ? 3 : 1;
|
||||
|
||||
if (pixel_bits == 16)
|
||||
return driCreateConfigs(GL_RGB,
|
||||
GL_UNSIGNED_SHORT_5_6_5,
|
||||
depth_bits_array,
|
||||
stencil_bits_array,
|
||||
depth_buffer_factor,
|
||||
back_buffer_modes,
|
||||
back_buffer_factor);
|
||||
else
|
||||
return driCreateConfigs(GL_RGBA,
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
depth_bits_array,
|
||||
stencil_bits_array,
|
||||
depth_buffer_factor,
|
||||
back_buffer_modes,
|
||||
back_buffer_factor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the driver specific part of the createNewScreen entry point.
|
||||
*
|
||||
* \todo maybe fold this into intelInitDriver
|
||||
*
|
||||
* \return the __GLcontextModes supported by this driver
|
||||
*/
|
||||
static const __DRIconfig **
|
||||
nouveauInitScreen(__DRIscreenPrivate *psp)
|
||||
{
|
||||
static const __DRIversion ddx_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
|
||||
static const __DRIversion dri_expected = { 4, 0, 0 };
|
||||
static const __DRIversion drm_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
|
||||
NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv;
|
||||
|
||||
WARN_ONCE("\nThis driver is not currently maintained\n\n"
|
||||
"Current work on 3D is in the gallium-0.1 branch of:\n"
|
||||
" git://anongit.freedesktop.org/git/nouveau/mesa\n");
|
||||
|
||||
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10
|
||||
#error nouveau_drm.h version does not match expected version
|
||||
#endif
|
||||
|
||||
if (!driCheckDriDdxDrmVersions2("nouveau",
|
||||
&psp->dri_version, & dri_expected,
|
||||
&psp->ddx_version, & ddx_expected,
|
||||
&psp->drm_version, & drm_expected))
|
||||
return NULL;
|
||||
|
||||
// temporary lock step versioning
|
||||
if (drm_expected.patch != psp->drm_version.patch) {
|
||||
__driUtilMessage("%s: wrong DRM version, expected %d, got %d\n",
|
||||
__func__,
|
||||
drm_expected.patch, psp->drm_version.patch);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Calling driInitExtensions here, with a NULL context
|
||||
* pointer, does not actually enable the extensions. It just
|
||||
* makes sure that all the dispatch offsets for all the
|
||||
* extensions that *might* be enables are known. This is
|
||||
* needed because the dispatch offsets need to be known when
|
||||
* _mesa_context_create is called, but we can't enable the
|
||||
* extensions until we have a context pointer.
|
||||
*
|
||||
* Hello chicken. Hello egg. How are you two today?
|
||||
*/
|
||||
driInitExtensions( NULL, common_extensions, GL_FALSE );
|
||||
driInitExtensions( NULL, nv10_extensions, GL_FALSE );
|
||||
driInitExtensions( NULL, nv10_extensions, GL_FALSE );
|
||||
driInitExtensions( NULL, nv30_extensions, GL_FALSE );
|
||||
driInitExtensions( NULL, nv40_extensions, GL_FALSE );
|
||||
driInitExtensions( NULL, nv50_extensions, GL_FALSE );
|
||||
|
||||
if (!nouveauInitDriver(psp))
|
||||
return NULL;
|
||||
|
||||
return (const __DRIconfig **)
|
||||
nouveauFillInModes(psp,
|
||||
dri_priv->bpp,
|
||||
(dri_priv->bpp == 16) ? 16 : 24,
|
||||
(dri_priv->bpp == 16) ? 0 : 8,
|
||||
1);
|
||||
}
|
||||
|
||||
const struct __DriverAPIRec driDriverAPI = {
|
||||
.InitScreen = nouveauInitScreen,
|
||||
.DestroyScreen = nouveauDestroyScreen,
|
||||
.CreateContext = nouveauCreateContext,
|
||||
.DestroyContext = nouveauDestroyContext,
|
||||
.CreateBuffer = nouveauCreateBuffer,
|
||||
.DestroyBuffer = nouveauDestroyBuffer,
|
||||
.SwapBuffers = nouveauSwapBuffers,
|
||||
.MakeCurrent = nouveauMakeCurrent,
|
||||
.UnbindContext = nouveauUnbindContext,
|
||||
.GetSwapInfo = nouveauGetSwapInfo,
|
||||
.GetDrawableMSC = driDrawableGetMSC32,
|
||||
.WaitForMSC = driWaitForMSC32,
|
||||
.WaitForSBC = NULL,
|
||||
.SwapBuffersMSC = NULL,
|
||||
.CopySubBuffer = nouveauCopySubBuffer
|
||||
};
|
||||
|
||||
const __DRIextension *__driDriverExtensions[] = {
|
||||
&driCoreExtension.base,
|
||||
&driLegacyExtension.base,
|
||||
NULL
|
||||
};
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_SCREEN_H__
|
||||
#define __NOUVEAU_SCREEN_H__
|
||||
|
||||
#include "xmlconfig.h"
|
||||
|
||||
#include "nouveau_dri.h"
|
||||
#include "nouveau_card.h"
|
||||
|
||||
typedef struct {
|
||||
nouveau_card* card;
|
||||
u_int32_t bus_type;
|
||||
u_int32_t agp_mode;
|
||||
|
||||
GLint fbFormat;
|
||||
|
||||
GLuint frontOffset;
|
||||
GLuint frontPitch;
|
||||
GLuint backOffset;
|
||||
GLuint backPitch;
|
||||
|
||||
GLuint depthOffset;
|
||||
GLuint depthPitch;
|
||||
GLuint spanOffset;
|
||||
|
||||
__DRIscreenPrivate *driScreen;
|
||||
unsigned int sarea_priv_offset;
|
||||
|
||||
/* Configuration cache with default values for all contexts */
|
||||
driOptionCache optionCache;
|
||||
|
||||
} nouveauScreenRec, *nouveauScreenPtr;
|
||||
|
||||
|
||||
#endif /* __NOUVEAU_SCREEN_H__ */
|
||||
|
|
@ -1,833 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Ben Skeggs.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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:
|
||||
* Ben Skeggs <darktama@iinet.net.au>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "macros.h"
|
||||
#include "enums.h"
|
||||
#include "extensions.h"
|
||||
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
/*#include "shader/arbprogparse.h"*/
|
||||
#include "tnl/tnl.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_shader.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Mesa entry points
|
||||
*/
|
||||
static void
|
||||
nouveauBindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog)
|
||||
{
|
||||
NVSDBG("target=%s, prog=%p\n", _mesa_lookup_enum_by_nr(target), prog);
|
||||
}
|
||||
|
||||
static struct gl_program *
|
||||
nouveauNewProgram(GLcontext *ctx, GLenum target, GLuint id)
|
||||
{
|
||||
nouveauShader *nvs;
|
||||
|
||||
NVSDBG("target=%s, id=%d\n", _mesa_lookup_enum_by_nr(target), id);
|
||||
|
||||
nvs = CALLOC_STRUCT(_nouveauShader);
|
||||
NVSDBG("prog=%p\n", nvs);
|
||||
switch (target) {
|
||||
case GL_VERTEX_PROGRAM_ARB:
|
||||
return _mesa_init_vertex_program(ctx, &nvs->mesa.vp, target, id);
|
||||
case GL_FRAGMENT_PROGRAM_ARB:
|
||||
return _mesa_init_fragment_program(ctx, &nvs->mesa.fp, target, id);
|
||||
default:
|
||||
_mesa_problem(ctx, "Unsupported shader target");
|
||||
break;
|
||||
}
|
||||
|
||||
FREE(nvs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauDeleteProgram(GLcontext *ctx, struct gl_program *prog)
|
||||
{
|
||||
nouveauShader *nvs = (nouveauShader *)prog;
|
||||
|
||||
NVSDBG("prog=%p\n", prog);
|
||||
|
||||
if (nvs->translated)
|
||||
FREE(nvs->program);
|
||||
_mesa_delete_program(ctx, prog);
|
||||
}
|
||||
|
||||
static void
|
||||
nouveauProgramStringNotify(GLcontext *ctx, GLenum target,
|
||||
struct gl_program *prog)
|
||||
{
|
||||
nouveauShader *nvs = (nouveauShader *)prog;
|
||||
|
||||
NVSDBG("target=%s, prog=%p\n", _mesa_lookup_enum_by_nr(target), prog);
|
||||
|
||||
if (nvs->translated)
|
||||
FREE(nvs->program);
|
||||
|
||||
nvs->error = GL_FALSE;
|
||||
nvs->translated = GL_FALSE;
|
||||
|
||||
_tnl_program_string(ctx, target, prog);
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
nouveauIsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
|
||||
{
|
||||
nouveauShader *nvs = (nouveauShader *)prog;
|
||||
|
||||
NVSDBG("target=%s, prog=%p\n", _mesa_lookup_enum_by_nr(target), prog);
|
||||
|
||||
return nvs->translated;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
struct gl_program_parameter_list *plist;
|
||||
int i;
|
||||
|
||||
NVSDBG("prog=%p\n", nvs);
|
||||
|
||||
/* Translate to HW format now if necessary */
|
||||
if (!nvs->translated) {
|
||||
/* Mesa ASM shader -> nouveauShader */
|
||||
if (!nouveau_shader_pass0(ctx, nvs))
|
||||
return GL_FALSE;
|
||||
/* Basic dead code elimination + register usage info */
|
||||
if (!nouveau_shader_pass1(nvs))
|
||||
return GL_FALSE;
|
||||
/* nouveauShader -> HW bytecode, HW register alloc */
|
||||
if (!nouveau_shader_pass2(nvs))
|
||||
return GL_FALSE;
|
||||
assert(nvs->translated);
|
||||
assert(nvs->program);
|
||||
}
|
||||
|
||||
/* Update state parameters */
|
||||
plist = nvs->mesa.vp.Base.Parameters;
|
||||
_mesa_load_state_parameters(ctx, plist);
|
||||
for (i=0; i<nvs->param_high; i++) {
|
||||
if (!nvs->params[i].in_use)
|
||||
continue;
|
||||
|
||||
if (!nvs->on_hardware) {
|
||||
/* if we've been kicked off the hardware there's no guarantee our
|
||||
* consts are still there.. reupload them all
|
||||
*/
|
||||
nvs->func->UpdateConst(ctx, nvs, i);
|
||||
} else if (nvs->params[i].source_val) {
|
||||
/* update any changed state parameters */
|
||||
if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val))
|
||||
nvs->func->UpdateConst(ctx, nvs, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Upload program to hardware, this must come after state param update
|
||||
* as >=NV30 fragprogs inline consts into the bytecode.
|
||||
*/
|
||||
if (!nvs->on_hardware) {
|
||||
nouveauShader **current;
|
||||
|
||||
if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB)
|
||||
current = &nmesa->current_vertprog;
|
||||
else
|
||||
current = &nmesa->current_fragprog;
|
||||
if (*current) (*current)->on_hardware = 0;
|
||||
|
||||
nvs->func->UploadToHW(ctx, nvs);
|
||||
nvs->on_hardware = 1;
|
||||
|
||||
*current = nvs;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
nouveauShader *
|
||||
nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text)
|
||||
{
|
||||
nouveauShader *nvs;
|
||||
|
||||
nvs = CALLOC_STRUCT(_nouveauShader);
|
||||
if (!nvs)
|
||||
return NULL;
|
||||
|
||||
if (target == GL_VERTEX_PROGRAM_ARB) {
|
||||
_mesa_init_vertex_program(ctx, &nvs->mesa.vp, GL_VERTEX_PROGRAM_ARB, 0);
|
||||
_mesa_parse_arb_vertex_program(ctx,
|
||||
GL_VERTEX_PROGRAM_ARB,
|
||||
text,
|
||||
strlen(text),
|
||||
&nvs->mesa.vp);
|
||||
} else if (target == GL_FRAGMENT_PROGRAM_ARB) {
|
||||
_mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||
_mesa_parse_arb_fragment_program(ctx,
|
||||
GL_FRAGMENT_PROGRAM_ARB,
|
||||
text,
|
||||
strlen(text),
|
||||
&nvs->mesa.fp);
|
||||
}
|
||||
|
||||
nouveau_shader_pass0(ctx, nvs);
|
||||
nouveau_shader_pass1(nvs);
|
||||
nouveau_shader_pass2(nvs);
|
||||
|
||||
return nvs;
|
||||
}
|
||||
|
||||
static void
|
||||
nvsBuildPassthroughVP(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
const char *vp_text =
|
||||
"!!ARBvp1.0\n"
|
||||
"OPTION ARB_position_invariant;"
|
||||
""
|
||||
"MOV result.color, vertex.color;\n"
|
||||
"MOV result.texcoord[0], vertex.texcoord[0];\n"
|
||||
"MOV result.texcoord[1], vertex.texcoord[1];\n"
|
||||
"MOV result.texcoord[2], vertex.texcoord[2];\n"
|
||||
"MOV result.texcoord[3], vertex.texcoord[3];\n"
|
||||
"MOV result.texcoord[4], vertex.texcoord[4];\n"
|
||||
"MOV result.texcoord[5], vertex.texcoord[5];\n"
|
||||
"MOV result.texcoord[6], vertex.texcoord[6];\n"
|
||||
"MOV result.texcoord[7], vertex.texcoord[7];\n"
|
||||
"END";
|
||||
|
||||
nmesa->passthrough_vp = nvsBuildTextShader(ctx,
|
||||
GL_VERTEX_PROGRAM_ARB,
|
||||
vp_text);
|
||||
}
|
||||
|
||||
static void
|
||||
nvsBuildPassthroughFP(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
const char *fp_text =
|
||||
"!!ARBfp1.0\n"
|
||||
"MOV result.color, fragment.color;\n"
|
||||
"END";
|
||||
|
||||
nmesa->passthrough_fp = nvsBuildTextShader(ctx,
|
||||
GL_FRAGMENT_PROGRAM_ARB,
|
||||
fp_text);
|
||||
}
|
||||
|
||||
void
|
||||
nouveauShaderInitFuncs(GLcontext * ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
switch (nmesa->screen->card->type) {
|
||||
case NV_20:
|
||||
NV20VPInitShaderFuncs(&nmesa->VPfunc);
|
||||
break;
|
||||
case NV_30:
|
||||
NV30VPInitShaderFuncs(&nmesa->VPfunc);
|
||||
NV30FPInitShaderFuncs(&nmesa->FPfunc);
|
||||
break;
|
||||
case NV_40:
|
||||
case NV_44:
|
||||
NV40VPInitShaderFuncs(&nmesa->VPfunc);
|
||||
NV40FPInitShaderFuncs(&nmesa->FPfunc);
|
||||
break;
|
||||
case NV_50:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Build a vertex program that simply passes through all attribs.
|
||||
* Needed to do swtcl on nv40
|
||||
*/
|
||||
if (nmesa->screen->card->type >= NV_40)
|
||||
nvsBuildPassthroughVP(ctx);
|
||||
|
||||
/* Needed on NV30, even when using swtcl, if you want to get colours */
|
||||
if (nmesa->screen->card->type >= NV_30)
|
||||
nvsBuildPassthroughFP(ctx);
|
||||
|
||||
ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst;
|
||||
ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst;
|
||||
ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst;
|
||||
ctx->Const.VertexProgram.MaxNativeTexIndirections =
|
||||
ctx->Const.VertexProgram.MaxNativeTexInstructions;
|
||||
ctx->Const.VertexProgram.MaxNativeAttribs = nmesa->VPfunc.MaxAttrib;
|
||||
ctx->Const.VertexProgram.MaxNativeTemps = nmesa->VPfunc.MaxTemp;
|
||||
ctx->Const.VertexProgram.MaxNativeAddressRegs = nmesa->VPfunc.MaxAddress;
|
||||
ctx->Const.VertexProgram.MaxNativeParameters = nmesa->VPfunc.MaxConst;
|
||||
|
||||
if (nmesa->screen->card->type >= NV_30) {
|
||||
ctx->Const.FragmentProgram.MaxNativeInstructions = nmesa->FPfunc.MaxInst;
|
||||
ctx->Const.FragmentProgram.MaxNativeAluInstructions = nmesa->FPfunc.MaxInst;
|
||||
ctx->Const.FragmentProgram.MaxNativeTexInstructions = nmesa->FPfunc.MaxInst;
|
||||
ctx->Const.FragmentProgram.MaxNativeTexIndirections =
|
||||
ctx->Const.FragmentProgram.MaxNativeTexInstructions;
|
||||
ctx->Const.FragmentProgram.MaxNativeAttribs = nmesa->FPfunc.MaxAttrib;
|
||||
ctx->Const.FragmentProgram.MaxNativeTemps = nmesa->FPfunc.MaxTemp;
|
||||
ctx->Const.FragmentProgram.MaxNativeAddressRegs = nmesa->FPfunc.MaxAddress;
|
||||
ctx->Const.FragmentProgram.MaxNativeParameters = nmesa->FPfunc.MaxConst;
|
||||
}
|
||||
|
||||
ctx->Driver.NewProgram = nouveauNewProgram;
|
||||
ctx->Driver.BindProgram = nouveauBindProgram;
|
||||
ctx->Driver.DeleteProgram = nouveauDeleteProgram;
|
||||
ctx->Driver.ProgramStringNotify = nouveauProgramStringNotify;
|
||||
ctx->Driver.IsProgramNative = nouveauIsProgramNative;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Disassembly support structs
|
||||
*/
|
||||
#define CHECK_RANGE(idx, arr) ((idx)<sizeof(_##arr)/sizeof(const char *)) \
|
||||
? _##arr[(idx)] : #arr"_OOB"
|
||||
|
||||
#define NODS (1<<0)
|
||||
#define BRANCH_TR (1<<1)
|
||||
#define BRANCH_EL (1<<2)
|
||||
#define BRANCH_EN (1<<3)
|
||||
#define BRANCH_RE (1<<4)
|
||||
#define BRANCH_ALL (BRANCH_TR|BRANCH_EL|BRANCH_EN)
|
||||
#define COUNT_INC (1<<4)
|
||||
#define COUNT_IND (1<<5)
|
||||
#define COUNT_NUM (1<<6)
|
||||
#define COUNT_ALL (COUNT_INC|COUNT_IND|COUNT_NUM)
|
||||
#define TI_UNIT (1<<7)
|
||||
struct _opcode_info
|
||||
{
|
||||
const char *name;
|
||||
int numsrc;
|
||||
int flags;
|
||||
};
|
||||
|
||||
static struct _opcode_info ops[] = {
|
||||
[NVS_OP_ABS] = {"ABS", 1, 0},
|
||||
[NVS_OP_ADD] = {"ADD", 2, 0},
|
||||
[NVS_OP_ARA] = {"ARA", 1, 0},
|
||||
[NVS_OP_ARL] = {"ARL", 1, 0},
|
||||
[NVS_OP_ARR] = {"ARR", 1, 0},
|
||||
[NVS_OP_BRA] = {"BRA", 0, NODS | BRANCH_TR},
|
||||
[NVS_OP_BRK] = {"BRK", 0, NODS},
|
||||
[NVS_OP_CAL] = {"CAL", 0, NODS | BRANCH_TR},
|
||||
[NVS_OP_CMP] = {"CMP", 2, 0},
|
||||
[NVS_OP_COS] = {"COS", 1, 0},
|
||||
[NVS_OP_DIV] = {"DIV", 2, 0},
|
||||
[NVS_OP_DDX] = {"DDX", 1, 0},
|
||||
[NVS_OP_DDY] = {"DDY", 1, 0},
|
||||
[NVS_OP_DP2] = {"DP2", 2, 0},
|
||||
[NVS_OP_DP2A] = {"DP2A", 3, 0},
|
||||
[NVS_OP_DP3] = {"DP3", 2, 0},
|
||||
[NVS_OP_DP4] = {"DP4", 2, 0},
|
||||
[NVS_OP_DPH] = {"DPH", 2, 0},
|
||||
[NVS_OP_DST] = {"DST", 2, 0},
|
||||
[NVS_OP_EX2] = {"EX2", 1, 0},
|
||||
[NVS_OP_EXP] = {"EXP", 1, 0},
|
||||
[NVS_OP_FLR] = {"FLR", 1, 0},
|
||||
[NVS_OP_FRC] = {"FRC", 1, 0},
|
||||
[NVS_OP_IF] = {"IF", 0, NODS | BRANCH_EL | BRANCH_EN},
|
||||
[NVS_OP_KIL] = {"KIL", 1, 0},
|
||||
[NVS_OP_LG2] = {"LG2", 1, 0},
|
||||
[NVS_OP_LIT] = {"LIT", 1, 0},
|
||||
[NVS_OP_LOG] = {"LOG", 1, 0},
|
||||
[NVS_OP_LOOP] = {"LOOP", 0, NODS | COUNT_ALL | BRANCH_EN},
|
||||
[NVS_OP_LRP] = {"LRP", 3, 0},
|
||||
[NVS_OP_MAD] = {"MAD", 3, 0},
|
||||
[NVS_OP_MAX] = {"MAX", 2, 0},
|
||||
[NVS_OP_MIN] = {"MIN", 2, 0},
|
||||
[NVS_OP_MOV] = {"MOV", 1, 0},
|
||||
[NVS_OP_MUL] = {"MUL", 2, 0},
|
||||
[NVS_OP_NRM] = {"NRM", 1, 0},
|
||||
[NVS_OP_PK2H] = {"PK2H", 1, 0},
|
||||
[NVS_OP_PK2US] = {"PK2US", 1, 0},
|
||||
[NVS_OP_PK4B] = {"PK4B", 1, 0},
|
||||
[NVS_OP_PK4UB] = {"PK4UB", 1, 0},
|
||||
[NVS_OP_POW] = {"POW", 2, 0},
|
||||
[NVS_OP_POPA] = {"POPA", 0, 0},
|
||||
[NVS_OP_PUSHA] = {"PUSHA", 1, NODS},
|
||||
[NVS_OP_RCC] = {"RCC", 1, 0},
|
||||
[NVS_OP_RCP] = {"RCP", 1, 0},
|
||||
[NVS_OP_REP] = {"REP", 0, NODS | BRANCH_EN | COUNT_NUM},
|
||||
[NVS_OP_RET] = {"RET", 0, NODS},
|
||||
[NVS_OP_RFL] = {"RFL", 1, 0},
|
||||
[NVS_OP_RSQ] = {"RSQ", 1, 0},
|
||||
[NVS_OP_SCS] = {"SCS", 1, 0},
|
||||
[NVS_OP_SEQ] = {"SEQ", 2, 0},
|
||||
[NVS_OP_SFL] = {"SFL", 2, 0},
|
||||
[NVS_OP_SGE] = {"SGE", 2, 0},
|
||||
[NVS_OP_SGT] = {"SGT", 2, 0},
|
||||
[NVS_OP_SIN] = {"SIN", 1, 0},
|
||||
[NVS_OP_SLE] = {"SLE", 2, 0},
|
||||
[NVS_OP_SLT] = {"SLT", 2, 0},
|
||||
[NVS_OP_SNE] = {"SNE", 2, 0},
|
||||
[NVS_OP_SSG] = {"SSG", 1, 0},
|
||||
[NVS_OP_STR] = {"STR", 2, 0},
|
||||
[NVS_OP_SUB] = {"SUB", 2, 0},
|
||||
[NVS_OP_TEX] = {"TEX", 1, TI_UNIT},
|
||||
[NVS_OP_TXB] = {"TXB", 1, TI_UNIT},
|
||||
[NVS_OP_TXD] = {"TXD", 3, TI_UNIT},
|
||||
[NVS_OP_TXL] = {"TXL", 1, TI_UNIT},
|
||||
[NVS_OP_TXP] = {"TXP", 1, TI_UNIT},
|
||||
[NVS_OP_UP2H] = {"UP2H", 1, 0},
|
||||
[NVS_OP_UP2US] = {"UP2US", 1, 0},
|
||||
[NVS_OP_UP4B] = {"UP4B", 1, 0},
|
||||
[NVS_OP_UP4UB] = {"UP4UB", 1, 0},
|
||||
[NVS_OP_X2D] = {"X2D", 3, 0},
|
||||
[NVS_OP_XPD] = {"XPD", 2, 0},
|
||||
[NVS_OP_NOP] = {"NOP", 0, NODS},
|
||||
};
|
||||
|
||||
static struct _opcode_info *
|
||||
_get_op_info(int op)
|
||||
{
|
||||
if (op >= (sizeof(ops) / sizeof(struct _opcode_info)))
|
||||
return NULL;
|
||||
if (ops[op].name == NULL)
|
||||
return NULL;
|
||||
return &ops[op];
|
||||
}
|
||||
|
||||
static const char *_SFR_STRING[] = {
|
||||
[NVS_FR_POSITION] = "position",
|
||||
[NVS_FR_WEIGHT] = "weight",
|
||||
[NVS_FR_NORMAL] = "normal",
|
||||
[NVS_FR_COL0] = "color",
|
||||
[NVS_FR_COL1] = "color.secondary",
|
||||
[NVS_FR_BFC0] = "bfc",
|
||||
[NVS_FR_BFC1] = "bfc.secondary",
|
||||
[NVS_FR_FOGCOORD] = "fogcoord",
|
||||
[NVS_FR_POINTSZ] = "pointsize",
|
||||
[NVS_FR_TEXCOORD0] = "texcoord[0]",
|
||||
[NVS_FR_TEXCOORD1] = "texcoord[1]",
|
||||
[NVS_FR_TEXCOORD2] = "texcoord[2]",
|
||||
[NVS_FR_TEXCOORD3] = "texcoord[3]",
|
||||
[NVS_FR_TEXCOORD4] = "texcoord[4]",
|
||||
[NVS_FR_TEXCOORD5] = "texcoord[5]",
|
||||
[NVS_FR_TEXCOORD6] = "texcoord[6]",
|
||||
[NVS_FR_TEXCOORD7] = "texcoord[7]",
|
||||
[NVS_FR_FRAGDATA0] = "data[0]",
|
||||
[NVS_FR_FRAGDATA1] = "data[1]",
|
||||
[NVS_FR_FRAGDATA2] = "data[2]",
|
||||
[NVS_FR_FRAGDATA3] = "data[3]",
|
||||
[NVS_FR_CLIP0] = "clip_plane[0]",
|
||||
[NVS_FR_CLIP1] = "clip_plane[1]",
|
||||
[NVS_FR_CLIP2] = "clip_plane[2]",
|
||||
[NVS_FR_CLIP3] = "clip_plane[3]",
|
||||
[NVS_FR_CLIP4] = "clip_plane[4]",
|
||||
[NVS_FR_CLIP5] = "clip_plane[5]",
|
||||
[NVS_FR_CLIP6] = "clip_plane[6]",
|
||||
[NVS_FR_FACING] = "facing",
|
||||
};
|
||||
|
||||
#define SFR_STRING(idx) CHECK_RANGE((idx), SFR_STRING)
|
||||
|
||||
static const char *_SWZ_STRING[] = {
|
||||
[NVS_SWZ_X] = "x",
|
||||
[NVS_SWZ_Y] = "y",
|
||||
[NVS_SWZ_Z] = "z",
|
||||
[NVS_SWZ_W] = "w"
|
||||
};
|
||||
|
||||
#define SWZ_STRING(idx) CHECK_RANGE((idx), SWZ_STRING)
|
||||
|
||||
static const char *_NVS_PREC_STRING[] = {
|
||||
[NVS_PREC_FLOAT32] = "R",
|
||||
[NVS_PREC_FLOAT16] = "H",
|
||||
[NVS_PREC_FIXED12] = "X",
|
||||
[NVS_PREC_UNKNOWN] = "?"
|
||||
};
|
||||
|
||||
#define NVS_PREC_STRING(idx) CHECK_RANGE((idx), NVS_PREC_STRING)
|
||||
|
||||
static const char *_NVS_COND_STRING[] = {
|
||||
[NVS_COND_FL] = "FL",
|
||||
[NVS_COND_LT] = "LT",
|
||||
[NVS_COND_EQ] = "EQ",
|
||||
[NVS_COND_LE] = "LE",
|
||||
[NVS_COND_GT] = "GT",
|
||||
[NVS_COND_NE] = "NE",
|
||||
[NVS_COND_GE] = "GE",
|
||||
[NVS_COND_TR] = "TR",
|
||||
[NVS_COND_UNKNOWN] = "??"
|
||||
};
|
||||
|
||||
#define NVS_COND_STRING(idx) CHECK_RANGE((idx), NVS_COND_STRING)
|
||||
|
||||
/*****************************************************************************
|
||||
* ShaderFragment dumping
|
||||
*/
|
||||
static void
|
||||
nvsDumpIndent(int lvl)
|
||||
{
|
||||
while (lvl--)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void
|
||||
nvsDumpSwizzle(nvsSwzComp *swz)
|
||||
{
|
||||
printf(".%s%s%s%s",
|
||||
SWZ_STRING(swz[0]),
|
||||
SWZ_STRING(swz[1]), SWZ_STRING(swz[2]), SWZ_STRING(swz[3])
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
nvsDumpReg(nvsInstruction * inst, nvsRegister * reg)
|
||||
{
|
||||
if (reg->negate)
|
||||
printf("-");
|
||||
if (reg->abs)
|
||||
printf("abs(");
|
||||
|
||||
switch (reg->file) {
|
||||
case NVS_FILE_TEMP:
|
||||
printf("R%d", reg->index);
|
||||
nvsDumpSwizzle(reg->swizzle);
|
||||
break;
|
||||
case NVS_FILE_ATTRIB:
|
||||
printf("attrib.%s", SFR_STRING(reg->index));
|
||||
nvsDumpSwizzle(reg->swizzle);
|
||||
break;
|
||||
case NVS_FILE_ADDRESS:
|
||||
printf("A%d", reg->index);
|
||||
break;
|
||||
case NVS_FILE_CONST:
|
||||
if (reg->indexed)
|
||||
printf("const[A%d.%s + %d]",
|
||||
reg->addr_reg, SWZ_STRING(reg->addr_comp), reg->index);
|
||||
else
|
||||
printf("const[%d]", reg->index);
|
||||
nvsDumpSwizzle(reg->swizzle);
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN_FILE");
|
||||
break;
|
||||
}
|
||||
|
||||
if (reg->abs)
|
||||
printf(")");
|
||||
}
|
||||
|
||||
static void
|
||||
nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl)
|
||||
{
|
||||
struct _opcode_info *opr = &ops[inst->op];
|
||||
int i;
|
||||
|
||||
nvsDumpIndent(lvl);
|
||||
printf("%s ", opr->name);
|
||||
|
||||
if (!opr->flags & NODS) {
|
||||
switch (inst->dest.file) {
|
||||
case NVS_FILE_RESULT:
|
||||
printf("result.%s", SFR_STRING(inst->dest.index));
|
||||
break;
|
||||
case NVS_FILE_TEMP:
|
||||
printf("R%d", inst->dest.index);
|
||||
break;
|
||||
case NVS_FILE_ADDRESS:
|
||||
printf("A%d", inst->dest.index);
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN_DST_FILE");
|
||||
break;
|
||||
}
|
||||
|
||||
if (inst->mask != SMASK_ALL) {
|
||||
printf(".");
|
||||
if (inst->mask & SMASK_X)
|
||||
printf("x");
|
||||
if (inst->mask & SMASK_Y)
|
||||
printf("y");
|
||||
if (inst->mask & SMASK_Z)
|
||||
printf("z");
|
||||
if (inst->mask & SMASK_W)
|
||||
printf("w");
|
||||
}
|
||||
|
||||
if (opr->numsrc)
|
||||
printf(", ");
|
||||
}
|
||||
|
||||
for (i = 0; i < opr->numsrc; i++) {
|
||||
nvsDumpReg(inst, &inst->src[i]);
|
||||
if (i != opr->numsrc - 1)
|
||||
printf(", ");
|
||||
}
|
||||
if (opr->flags & TI_UNIT)
|
||||
printf(", texture[%d]", inst->tex_unit);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
nvsDumpFragmentList(nvsFragmentHeader *f, int lvl)
|
||||
{
|
||||
while (f) {
|
||||
switch (f->type) {
|
||||
case NVS_INSTRUCTION:
|
||||
nvsDumpInstruction((nvsInstruction*)f, 0, lvl);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: Only NVS_INSTRUCTION fragments can be in"
|
||||
"nvsFragmentList!\n", __func__);
|
||||
return;
|
||||
}
|
||||
f = f->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* HW shader disassembly
|
||||
*/
|
||||
static void
|
||||
nvsDisasmHWShaderOp(nvsFunc * shader, int merged)
|
||||
{
|
||||
struct _opcode_info *opi;
|
||||
nvsOpcode op;
|
||||
nvsRegFile file;
|
||||
nvsSwzComp swz[4];
|
||||
int i;
|
||||
|
||||
op = shader->GetOpcode(shader, merged);
|
||||
opi = _get_op_info(op);
|
||||
if (!opi) {
|
||||
printf("NO OPINFO!");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s", opi->name);
|
||||
if (shader->GetPrecision &&
|
||||
(!(opi->flags & BRANCH_ALL)) && (!(opi->flags * NODS)) &&
|
||||
(op != NVS_OP_NOP))
|
||||
printf("%s", NVS_PREC_STRING(shader->GetPrecision(shader)));
|
||||
if (shader->SupportsConditional && shader->SupportsConditional(shader)) {
|
||||
if (shader->GetConditionUpdate(shader)) {
|
||||
printf("C%d", shader->GetCondRegID(shader));
|
||||
}
|
||||
}
|
||||
if (shader->GetSaturate && shader->GetSaturate(shader))
|
||||
printf("_SAT");
|
||||
|
||||
if (!(opi->flags & NODS)) {
|
||||
int mask = shader->GetDestMask(shader, merged);
|
||||
|
||||
switch (shader->GetDestFile(shader, merged)) {
|
||||
case NVS_FILE_ADDRESS:
|
||||
printf(" A%d", shader->GetDestID(shader, merged));
|
||||
break;
|
||||
case NVS_FILE_TEMP:
|
||||
printf(" R%d", shader->GetDestID(shader, merged));
|
||||
break;
|
||||
case NVS_FILE_RESULT:
|
||||
printf(" result.%s", (SFR_STRING(shader->GetDestID(shader, merged))));
|
||||
break;
|
||||
default:
|
||||
printf(" BAD_RESULT_FILE");
|
||||
break;
|
||||
}
|
||||
|
||||
if (mask != SMASK_ALL) {
|
||||
printf(".");
|
||||
if (mask & SMASK_X) printf("x");
|
||||
if (mask & SMASK_Y) printf("y");
|
||||
if (mask & SMASK_Z) printf("z");
|
||||
if (mask & SMASK_W) printf("w");
|
||||
}
|
||||
}
|
||||
|
||||
if (shader->SupportsConditional && shader->SupportsConditional(shader) &&
|
||||
shader->GetConditionTest(shader)) {
|
||||
shader->GetCondRegSwizzle(shader, swz);
|
||||
|
||||
printf(" (%s%d.%s%s%s%s)",
|
||||
NVS_COND_STRING(shader->GetCondition(shader)),
|
||||
shader->GetCondRegID(shader),
|
||||
SWZ_STRING(swz[NVS_SWZ_X]),
|
||||
SWZ_STRING(swz[NVS_SWZ_Y]),
|
||||
SWZ_STRING(swz[NVS_SWZ_Z]),
|
||||
SWZ_STRING(swz[NVS_SWZ_W])
|
||||
);
|
||||
}
|
||||
|
||||
/* looping */
|
||||
if (opi->flags & COUNT_ALL) {
|
||||
printf(" { ");
|
||||
if (opi->flags & COUNT_NUM) {
|
||||
printf("%d", shader->GetLoopCount(shader));
|
||||
}
|
||||
if (opi->flags & COUNT_IND) {
|
||||
printf(", %d", shader->GetLoopInitial(shader));
|
||||
}
|
||||
if (opi->flags & COUNT_INC) {
|
||||
printf(", %d", shader->GetLoopIncrement(shader));
|
||||
}
|
||||
printf(" }");
|
||||
}
|
||||
|
||||
/* branching */
|
||||
if (opi->flags & BRANCH_TR)
|
||||
printf(" %d", shader->GetBranch(shader));
|
||||
if (opi->flags & BRANCH_EL)
|
||||
printf(" ELSE %d", shader->GetBranchElse(shader));
|
||||
if (opi->flags & BRANCH_EN)
|
||||
printf(" END %d", shader->GetBranchEnd(shader));
|
||||
|
||||
if (!(opi->flags & NODS) && opi->numsrc)
|
||||
printf(",");
|
||||
printf(" ");
|
||||
|
||||
for (i = 0; i < opi->numsrc; i++) {
|
||||
if (shader->GetSourceAbs(shader, merged, i))
|
||||
printf("abs(");
|
||||
if (shader->GetSourceNegate(shader, merged, i))
|
||||
printf("-");
|
||||
|
||||
file = shader->GetSourceFile(shader, merged, i);
|
||||
switch (file) {
|
||||
case NVS_FILE_TEMP:
|
||||
printf("R%d", shader->GetSourceID(shader, merged, i));
|
||||
break;
|
||||
case NVS_FILE_CONST:
|
||||
if (shader->GetSourceIndexed(shader, merged, i)) {
|
||||
printf("c[A%d.%s + 0x%x]",
|
||||
shader->GetRelAddressRegID(shader),
|
||||
SWZ_STRING(shader->GetRelAddressSwizzle(shader)),
|
||||
shader->GetSourceID(shader, merged, i)
|
||||
);
|
||||
} else {
|
||||
float val[4];
|
||||
|
||||
if (shader->GetSourceConstVal) {
|
||||
shader->GetSourceConstVal(shader, merged, i, val);
|
||||
printf("{ %.02f, %.02f, %.02f, %.02f }",
|
||||
val[0], val[1], val[2], val[3]);
|
||||
} else {
|
||||
printf("c[0x%x]", shader->GetSourceID(shader, merged, i));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NVS_FILE_ATTRIB:
|
||||
if (shader->GetSourceIndexed(shader, merged, i)) {
|
||||
printf("attrib[A%d.%s + %d]",
|
||||
shader->GetRelAddressRegID(shader),
|
||||
SWZ_STRING(shader->GetRelAddressSwizzle(shader)),
|
||||
shader->GetSourceID(shader, merged, i)
|
||||
);
|
||||
}
|
||||
else {
|
||||
printf("attrib.%s",
|
||||
SFR_STRING(shader->GetSourceID(shader, merged, i))
|
||||
);
|
||||
}
|
||||
break;
|
||||
case NVS_FILE_ADDRESS:
|
||||
printf("A%d", shader->GetRelAddressRegID(shader));
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN_SRC_FILE");
|
||||
break;
|
||||
}
|
||||
|
||||
shader->GetSourceSwizzle(shader, merged, i, swz);
|
||||
if (file != NVS_FILE_ADDRESS &&
|
||||
(swz[NVS_SWZ_X] != NVS_SWZ_X || swz[NVS_SWZ_Y] != NVS_SWZ_Y ||
|
||||
swz[NVS_SWZ_Z] != NVS_SWZ_Z || swz[NVS_SWZ_W] != NVS_SWZ_W)) {
|
||||
printf(".%s%s%s%s", SWZ_STRING(swz[NVS_SWZ_X]),
|
||||
SWZ_STRING(swz[NVS_SWZ_Y]),
|
||||
SWZ_STRING(swz[NVS_SWZ_Z]),
|
||||
SWZ_STRING(swz[NVS_SWZ_W]));
|
||||
}
|
||||
|
||||
if (shader->GetSourceAbs(shader, merged, i))
|
||||
printf(")");
|
||||
if (shader->GetSourceScale) {
|
||||
int scale = shader->GetSourceScale(shader, merged, i);
|
||||
if (scale > 1)
|
||||
printf("{scaled %dx}", scale);
|
||||
}
|
||||
if (i < (opi->numsrc - 1))
|
||||
printf(", ");
|
||||
}
|
||||
|
||||
if (shader->IsLastInst(shader))
|
||||
printf(" + END");
|
||||
}
|
||||
|
||||
void
|
||||
nvsDisasmHWShader(nvsPtr nvs)
|
||||
{
|
||||
nvsFunc *shader = nvs->func;
|
||||
unsigned int iaddr = 0;
|
||||
|
||||
if (!nvs->program) {
|
||||
fprintf(stderr, "No HW program present");
|
||||
return;
|
||||
}
|
||||
|
||||
shader->inst = nvs->program;
|
||||
while (1) {
|
||||
if (shader->inst >= (nvs->program + nvs->program_size)) {
|
||||
fprintf(stderr, "Reached end of program, but HW inst has no END");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\t0x%08x:\n", shader->inst[0]);
|
||||
printf("\t0x%08x:\n", shader->inst[1]);
|
||||
printf("\t0x%08x:\n", shader->inst[2]);
|
||||
printf("\t0x%08x:", shader->inst[3]);
|
||||
|
||||
printf("\n\t\tINST %d.0: ", iaddr);
|
||||
nvsDisasmHWShaderOp(shader, 0);
|
||||
if (shader->HasMergedInst(shader)) {
|
||||
printf("\n\t\tINST %d.1: ", iaddr);
|
||||
nvsDisasmHWShaderOp(shader, 1);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if (shader->IsLastInst(shader))
|
||||
break;
|
||||
|
||||
shader->inst += shader->GetOffsetNext(shader);
|
||||
iaddr++;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
|
@ -1,454 +0,0 @@
|
|||
#ifndef __SHADER_COMMON_H__
|
||||
#define __SHADER_COMMON_H__
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "bufferobj.h"
|
||||
|
||||
#define NVSDBG(fmt, args...) do { \
|
||||
if (NOUVEAU_DEBUG & DEBUG_SHADERS) { \
|
||||
fprintf(stderr, "%s: "fmt, __func__, ##args); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
typedef struct _nvsFunc nvsFunc;
|
||||
|
||||
#define NVS_MAX_TEMPS 32
|
||||
#define NVS_MAX_ATTRIBS 16
|
||||
#define NVS_MAX_CONSTS 256
|
||||
#define NVS_MAX_ADDRESS 2
|
||||
#define NVS_MAX_INSNS 4096
|
||||
|
||||
typedef struct _nvs_fragment_header {
|
||||
struct _nvs_fragment_header *parent;
|
||||
struct _nvs_fragment_header *prev;
|
||||
struct _nvs_fragment_header *next;
|
||||
enum {
|
||||
NVS_INSTRUCTION,
|
||||
NVS_BRANCH,
|
||||
NVS_LOOP,
|
||||
NVS_SUBROUTINE
|
||||
} type;
|
||||
} nvsFragmentHeader;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
GLboolean uses_kil;
|
||||
GLuint num_regs;
|
||||
} NV30FP;
|
||||
struct {
|
||||
uint32_t vp_in_reg;
|
||||
uint32_t vp_out_reg;
|
||||
uint32_t clip_enables;
|
||||
} NV30VP;
|
||||
} nvsCardPriv;
|
||||
|
||||
typedef struct _nouveauShader {
|
||||
union {
|
||||
struct gl_vertex_program vp;
|
||||
struct gl_fragment_program fp;
|
||||
} mesa;
|
||||
GLcontext *ctx;
|
||||
nvsFunc *func;
|
||||
|
||||
/* State of the final program */
|
||||
GLboolean error;
|
||||
GLboolean translated;
|
||||
GLboolean on_hardware;
|
||||
unsigned int *program;
|
||||
unsigned int program_size;
|
||||
unsigned int program_alloc_size;
|
||||
unsigned int program_start_id;
|
||||
unsigned int program_current;
|
||||
struct gl_buffer_object *program_buffer;
|
||||
int inst_count;
|
||||
|
||||
nvsCardPriv card_priv;
|
||||
int vp_attrib_map[NVS_MAX_ATTRIBS];
|
||||
|
||||
struct {
|
||||
GLboolean in_use;
|
||||
|
||||
GLfloat *source_val; /* NULL if invariant */
|
||||
float val[4];
|
||||
/* Hardware-specific tracking, currently only nv30_fragprog
|
||||
* makes use of it.
|
||||
*/
|
||||
int *hw_index;
|
||||
int hw_index_cnt;
|
||||
} params[NVS_MAX_CONSTS];
|
||||
int param_high;
|
||||
|
||||
/* Pass-private data */
|
||||
void *pass_rec;
|
||||
|
||||
nvsFragmentHeader *program_tree;
|
||||
} nouveauShader, *nvsPtr;
|
||||
|
||||
typedef enum {
|
||||
NVS_FILE_NONE,
|
||||
NVS_FILE_TEMP,
|
||||
NVS_FILE_ATTRIB,
|
||||
NVS_FILE_CONST,
|
||||
NVS_FILE_RESULT,
|
||||
NVS_FILE_ADDRESS,
|
||||
NVS_FILE_UNKNOWN
|
||||
} nvsRegFile;
|
||||
|
||||
typedef enum {
|
||||
NVS_OP_UNKNOWN = 0,
|
||||
NVS_OP_NOP,
|
||||
NVS_OP_ABS, NVS_OP_ADD, NVS_OP_ARA, NVS_OP_ARL, NVS_OP_ARR,
|
||||
NVS_OP_BRA, NVS_OP_BRK,
|
||||
NVS_OP_CAL, NVS_OP_CMP, NVS_OP_COS,
|
||||
NVS_OP_DDX, NVS_OP_DDY, NVS_OP_DIV, NVS_OP_DP2, NVS_OP_DP2A, NVS_OP_DP3,
|
||||
NVS_OP_DP4, NVS_OP_DPH, NVS_OP_DST,
|
||||
NVS_OP_EX2, NVS_OP_EXP,
|
||||
NVS_OP_FLR, NVS_OP_FRC,
|
||||
NVS_OP_IF,
|
||||
NVS_OP_KIL,
|
||||
NVS_OP_LG2, NVS_OP_LIT, NVS_OP_LOG, NVS_OP_LOOP, NVS_OP_LRP,
|
||||
NVS_OP_MAD, NVS_OP_MAX, NVS_OP_MIN, NVS_OP_MOV, NVS_OP_MUL,
|
||||
NVS_OP_NRM,
|
||||
NVS_OP_PK2H, NVS_OP_PK2US, NVS_OP_PK4B, NVS_OP_PK4UB, NVS_OP_POW,
|
||||
NVS_OP_POPA, NVS_OP_PUSHA,
|
||||
NVS_OP_RCC, NVS_OP_RCP, NVS_OP_REP, NVS_OP_RET, NVS_OP_RFL, NVS_OP_RSQ,
|
||||
NVS_OP_SCS, NVS_OP_SEQ, NVS_OP_SFL, NVS_OP_SGE, NVS_OP_SGT, NVS_OP_SIN,
|
||||
NVS_OP_SLE, NVS_OP_SLT, NVS_OP_SNE, NVS_OP_SSG, NVS_OP_STR, NVS_OP_SUB,
|
||||
NVS_OP_SWZ,
|
||||
NVS_OP_TEX, NVS_OP_TXB, NVS_OP_TXD, NVS_OP_TXL, NVS_OP_TXP,
|
||||
NVS_OP_UP2H, NVS_OP_UP2US, NVS_OP_UP4B, NVS_OP_UP4UB,
|
||||
NVS_OP_X2D, NVS_OP_XPD,
|
||||
NVS_OP_EMUL
|
||||
} nvsOpcode;
|
||||
|
||||
typedef enum {
|
||||
NVS_PREC_FLOAT32,
|
||||
NVS_PREC_FLOAT16,
|
||||
NVS_PREC_FIXED12,
|
||||
NVS_PREC_UNKNOWN
|
||||
} nvsPrecision;
|
||||
|
||||
typedef enum {
|
||||
NVS_SWZ_X = 0,
|
||||
NVS_SWZ_Y = 1,
|
||||
NVS_SWZ_Z = 2,
|
||||
NVS_SWZ_W = 3
|
||||
} nvsSwzComp;
|
||||
|
||||
typedef enum {
|
||||
NVS_FR_POSITION = 0,
|
||||
NVS_FR_WEIGHT = 1,
|
||||
NVS_FR_NORMAL = 2,
|
||||
NVS_FR_COL0 = 3,
|
||||
NVS_FR_COL1 = 4,
|
||||
NVS_FR_FOGCOORD = 5,
|
||||
NVS_FR_TEXCOORD0 = 8,
|
||||
NVS_FR_TEXCOORD1 = 9,
|
||||
NVS_FR_TEXCOORD2 = 10,
|
||||
NVS_FR_TEXCOORD3 = 11,
|
||||
NVS_FR_TEXCOORD4 = 12,
|
||||
NVS_FR_TEXCOORD5 = 13,
|
||||
NVS_FR_TEXCOORD6 = 14,
|
||||
NVS_FR_TEXCOORD7 = 15,
|
||||
NVS_FR_BFC0 = 16,
|
||||
NVS_FR_BFC1 = 17,
|
||||
NVS_FR_POINTSZ = 18,
|
||||
NVS_FR_FRAGDATA0 = 19,
|
||||
NVS_FR_FRAGDATA1 = 20,
|
||||
NVS_FR_FRAGDATA2 = 21,
|
||||
NVS_FR_FRAGDATA3 = 22,
|
||||
NVS_FR_CLIP0 = 23,
|
||||
NVS_FR_CLIP1 = 24,
|
||||
NVS_FR_CLIP2 = 25,
|
||||
NVS_FR_CLIP3 = 26,
|
||||
NVS_FR_CLIP4 = 27,
|
||||
NVS_FR_CLIP5 = 28,
|
||||
NVS_FR_CLIP6 = 29,
|
||||
NVS_FR_FACING = 30,
|
||||
NVS_FR_UNKNOWN
|
||||
} nvsFixedReg;
|
||||
|
||||
typedef enum {
|
||||
NVS_COND_FL, NVS_COND_LT, NVS_COND_EQ, NVS_COND_LE, NVS_COND_GT,
|
||||
NVS_COND_NE, NVS_COND_GE, NVS_COND_TR, NVS_COND_UN,
|
||||
NVS_COND_UNKNOWN
|
||||
} nvsCond;
|
||||
|
||||
typedef struct {
|
||||
nvsRegFile file;
|
||||
unsigned int index;
|
||||
|
||||
unsigned int indexed;
|
||||
unsigned int addr_reg;
|
||||
nvsSwzComp addr_comp;
|
||||
|
||||
nvsSwzComp swizzle[4];
|
||||
int negate;
|
||||
int abs;
|
||||
} nvsRegister;
|
||||
|
||||
static const nvsRegister nvr_unused = {
|
||||
.file = NVS_FILE_ATTRIB,
|
||||
.index = 0,
|
||||
.indexed = 0,
|
||||
.addr_reg = 0,
|
||||
.addr_comp = NVS_SWZ_X,
|
||||
.swizzle = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W},
|
||||
.negate = 0,
|
||||
.abs = 0,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NVS_TEX_TARGET_1D,
|
||||
NVS_TEX_TARGET_2D,
|
||||
NVS_TEX_TARGET_3D,
|
||||
NVS_TEX_TARGET_CUBE,
|
||||
NVS_TEX_TARGET_RECT,
|
||||
NVS_TEX_TARGET_UNKNOWN = 0
|
||||
} nvsTexTarget;
|
||||
|
||||
typedef enum {
|
||||
NVS_SCALE_1X = 0,
|
||||
NVS_SCALE_2X = 1,
|
||||
NVS_SCALE_4X = 2,
|
||||
NVS_SCALE_8X = 3,
|
||||
NVS_SCALE_INV_2X = 5,
|
||||
NVS_SCALE_INV_4X = 6,
|
||||
NVS_SCALE_INV_8X = 7,
|
||||
} nvsScale;
|
||||
|
||||
/* Arith/TEX instructions */
|
||||
typedef struct nvs_instruction {
|
||||
nvsFragmentHeader header;
|
||||
|
||||
nvsOpcode op;
|
||||
unsigned int saturate;
|
||||
|
||||
nvsRegister dest;
|
||||
unsigned int mask;
|
||||
nvsScale dest_scale;
|
||||
|
||||
nvsRegister src[3];
|
||||
|
||||
unsigned int tex_unit;
|
||||
nvsTexTarget tex_target;
|
||||
|
||||
nvsCond cond;
|
||||
nvsSwzComp cond_swizzle[4];
|
||||
int cond_reg;
|
||||
int cond_test;
|
||||
int cond_update;
|
||||
} nvsInstruction;
|
||||
|
||||
/* BRA, CAL, IF */
|
||||
typedef struct nvs_branch {
|
||||
nvsFragmentHeader header;
|
||||
|
||||
nvsOpcode op;
|
||||
|
||||
nvsCond cond;
|
||||
nvsSwzComp cond_swizzle[4];
|
||||
int cond_test;
|
||||
|
||||
nvsFragmentHeader *target_head;
|
||||
nvsFragmentHeader *target_tail;
|
||||
nvsFragmentHeader *else_head;
|
||||
nvsFragmentHeader *else_tail;
|
||||
} nvsBranch;
|
||||
|
||||
/* LOOP+ENDLOOP */
|
||||
typedef struct {
|
||||
nvsFragmentHeader header;
|
||||
|
||||
int count;
|
||||
int initial;
|
||||
int increment;
|
||||
|
||||
nvsFragmentHeader *insn_head;
|
||||
nvsFragmentHeader *insn_tail;
|
||||
} nvsLoop;
|
||||
|
||||
/* label+following instructions */
|
||||
typedef struct nvs_subroutine {
|
||||
nvsFragmentHeader header;
|
||||
|
||||
char * label;
|
||||
nvsFragmentHeader *insn_head;
|
||||
nvsFragmentHeader *insn_tail;
|
||||
} nvsSubroutine;
|
||||
|
||||
#define SMASK_X (1<<0)
|
||||
#define SMASK_Y (1<<1)
|
||||
#define SMASK_Z (1<<2)
|
||||
#define SMASK_W (1<<3)
|
||||
#define SMASK_ALL (SMASK_X|SMASK_Y|SMASK_Z|SMASK_W)
|
||||
|
||||
#define SPOS_ADDRESS 3
|
||||
struct _op_xlat {
|
||||
unsigned int NV;
|
||||
nvsOpcode SOP;
|
||||
int srcpos[3];
|
||||
};
|
||||
#define MOD_OPCODE(t,hw,sop,s0,s1,s2) do { \
|
||||
t[hw].NV = hw; \
|
||||
t[hw].SOP = sop; \
|
||||
t[hw].srcpos[0] = s0; \
|
||||
t[hw].srcpos[1] = s1; \
|
||||
t[hw].srcpos[2] = s2; \
|
||||
} while(0)
|
||||
|
||||
extern unsigned int NVVP_TX_VOP_COUNT;
|
||||
extern unsigned int NVVP_TX_NVS_OP_COUNT;
|
||||
extern struct _op_xlat NVVP_TX_VOP[];
|
||||
extern struct _op_xlat NVVP_TX_SOP[];
|
||||
|
||||
extern unsigned int NVFP_TX_AOP_COUNT;
|
||||
extern unsigned int NVFP_TX_BOP_COUNT;
|
||||
extern struct _op_xlat NVFP_TX_AOP[];
|
||||
extern struct _op_xlat NVFP_TX_BOP[];
|
||||
|
||||
extern void NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz);
|
||||
extern nvsSwzComp NV20VP_TX_SWIZZLE[4];
|
||||
|
||||
#define SCAP_SRC_ABS (1<<0)
|
||||
|
||||
struct _nvsFunc {
|
||||
nvsCardPriv *card_priv;
|
||||
|
||||
unsigned int MaxInst;
|
||||
unsigned int MaxAttrib;
|
||||
unsigned int MaxTemp;
|
||||
unsigned int MaxAddress;
|
||||
unsigned int MaxConst;
|
||||
unsigned int caps;
|
||||
|
||||
unsigned int *inst;
|
||||
void (*UploadToHW) (GLcontext *, nouveauShader *);
|
||||
void (*UpdateConst) (GLcontext *, nouveauShader *, int);
|
||||
|
||||
struct _op_xlat*(*GetOPTXRec) (nvsFunc *, int merged);
|
||||
struct _op_xlat*(*GetOPTXFromSOP) (nvsOpcode, int *id);
|
||||
|
||||
void (*InitInstruction) (nvsFunc *);
|
||||
int (*SupportsOpcode) (nvsFunc *, nvsOpcode);
|
||||
int (*SupportsResultScale) (nvsFunc *, nvsScale);
|
||||
void (*SetOpcode) (nvsFunc *, unsigned int opcode,
|
||||
int slot);
|
||||
void (*SetCCUpdate) (nvsFunc *);
|
||||
void (*SetCondition) (nvsFunc *, int on, nvsCond, int reg,
|
||||
nvsSwzComp *swizzle);
|
||||
void (*SetResult) (nvsFunc *, nvsRegister *,
|
||||
unsigned int mask, int slot);
|
||||
void (*SetResultScale) (nvsFunc *, nvsScale);
|
||||
void (*SetSource) (nvsFunc *, nvsRegister *, int pos);
|
||||
void (*SetTexImageUnit) (nvsFunc *, int unit);
|
||||
void (*SetSaturate) (nvsFunc *);
|
||||
void (*SetLastInst) (nvsFunc *);
|
||||
|
||||
void (*SetBranchTarget) (nvsFunc *, int addr);
|
||||
void (*SetBranchElse) (nvsFunc *, int addr);
|
||||
void (*SetBranchEnd) (nvsFunc *, int addr);
|
||||
void (*SetLoopParams) (nvsFunc *, int cnt, int init, int inc);
|
||||
|
||||
int (*HasMergedInst) (nvsFunc *);
|
||||
int (*IsLastInst) (nvsFunc *);
|
||||
int (*GetOffsetNext) (nvsFunc *);
|
||||
|
||||
int (*GetOpcodeSlot) (nvsFunc *, int merged);
|
||||
unsigned int (*GetOpcodeHW) (nvsFunc *, int slot);
|
||||
nvsOpcode (*GetOpcode) (nvsFunc *, int merged);
|
||||
|
||||
nvsPrecision (*GetPrecision) (nvsFunc *);
|
||||
int (*GetSaturate) (nvsFunc *);
|
||||
|
||||
nvsRegFile (*GetDestFile) (nvsFunc *, int merged);
|
||||
unsigned int (*GetDestID) (nvsFunc *, int merged);
|
||||
unsigned int (*GetDestMask) (nvsFunc *, int merged);
|
||||
|
||||
unsigned int (*GetSourceHW) (nvsFunc *, int merged, int pos);
|
||||
nvsRegFile (*GetSourceFile) (nvsFunc *, int merged, int pos);
|
||||
int (*GetSourceID) (nvsFunc *, int merged, int pos);
|
||||
int (*GetTexImageUnit) (nvsFunc *);
|
||||
int (*GetSourceNegate) (nvsFunc *, int merged, int pos);
|
||||
int (*GetSourceAbs) (nvsFunc *, int merged, int pos);
|
||||
void (*GetSourceSwizzle) (nvsFunc *, int merged, int pos,
|
||||
nvsSwzComp *swz);
|
||||
int (*GetSourceIndexed) (nvsFunc *, int merged, int pos);
|
||||
void (*GetSourceConstVal) (nvsFunc *, int merged, int pos,
|
||||
float *val);
|
||||
int (*GetSourceScale) (nvsFunc *, int merged, int pos);
|
||||
|
||||
int (*GetRelAddressRegID) (nvsFunc *);
|
||||
nvsSwzComp (*GetRelAddressSwizzle) (nvsFunc *);
|
||||
|
||||
int (*SupportsConditional) (nvsFunc *);
|
||||
int (*GetConditionUpdate) (nvsFunc *);
|
||||
int (*GetConditionTest) (nvsFunc *);
|
||||
nvsCond (*GetCondition) (nvsFunc *);
|
||||
void (*GetCondRegSwizzle) (nvsFunc *, nvsSwzComp *swz);
|
||||
int (*GetCondRegID) (nvsFunc *);
|
||||
int (*GetBranch) (nvsFunc *);
|
||||
int (*GetBranchElse) (nvsFunc *);
|
||||
int (*GetBranchEnd) (nvsFunc *);
|
||||
|
||||
int (*GetLoopCount) (nvsFunc *);
|
||||
int (*GetLoopInitial) (nvsFunc *);
|
||||
int (*GetLoopIncrement) (nvsFunc *);
|
||||
};
|
||||
|
||||
static INLINE nvsRegister
|
||||
nvsNegate(nvsRegister reg)
|
||||
{
|
||||
reg.negate = !reg.negate;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE nvsRegister
|
||||
nvsAbs(nvsRegister reg)
|
||||
{
|
||||
reg.abs = 1;
|
||||
return reg;
|
||||
}
|
||||
|
||||
static INLINE nvsRegister
|
||||
nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y,
|
||||
nvsSwzComp z, nvsSwzComp w)
|
||||
{
|
||||
nvsSwzComp sc[4] = { x, y, z, w };
|
||||
nvsSwzComp oc[4];
|
||||
int i;
|
||||
|
||||
for (i=0;i<4;i++)
|
||||
oc[i] = reg.swizzle[i];
|
||||
for (i=0;i<4;i++)
|
||||
reg.swizzle[i] = oc[sc[i]];
|
||||
return reg;
|
||||
}
|
||||
|
||||
#define nvsProgramError(nvs,fmt,args...) do { \
|
||||
fprintf(stderr, "nvsProgramError (%s): "fmt, __func__, ##args); \
|
||||
(nvs)->error = GL_TRUE; \
|
||||
(nvs)->translated = GL_FALSE; \
|
||||
} while(0)
|
||||
|
||||
extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs);
|
||||
extern void nvsDisasmHWShader(nvsPtr);
|
||||
extern void nvsDumpFragmentList(nvsFragmentHeader *f, int lvl);
|
||||
extern nouveauShader *nvsBuildTextShader(GLcontext *ctx, GLenum target,
|
||||
const char *text);
|
||||
|
||||
extern void NV20VPInitShaderFuncs(nvsFunc *);
|
||||
extern void NV30VPInitShaderFuncs(nvsFunc *);
|
||||
extern void NV40VPInitShaderFuncs(nvsFunc *);
|
||||
|
||||
extern void NV30FPInitShaderFuncs(nvsFunc *);
|
||||
extern void NV40FPInitShaderFuncs(nvsFunc *);
|
||||
|
||||
extern void nouveauShaderInitFuncs(GLcontext *ctx);
|
||||
|
||||
extern GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs);
|
||||
extern GLboolean nouveau_shader_pass1(nvsPtr nvs);
|
||||
extern GLboolean nouveau_shader_pass2(nvsPtr nvs);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +0,0 @@
|
|||
#include "glheader.h"
|
||||
#include "macros.h"
|
||||
#include "enums.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_shader.h"
|
||||
|
||||
GLboolean
|
||||
nouveau_shader_pass1(nvsPtr nvs)
|
||||
{
|
||||
NVSDBG("start: nvs=%p\n", nvs);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Ben Skeggs.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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:
|
||||
* Ben Skeggs <darktama@iinet.net.au>
|
||||
*/
|
||||
|
||||
#include "glheader.h"
|
||||
#include "macros.h"
|
||||
#include "enums.h"
|
||||
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_shader.h"
|
||||
#include "nouveau_msg.h"
|
||||
|
||||
struct pass2_rec {
|
||||
/* Map nvsRegister temp ID onto hw temp ID */
|
||||
unsigned int temps[NVS_MAX_TEMPS];
|
||||
/* Track free hw registers */
|
||||
unsigned int hw_temps[NVS_MAX_TEMPS];
|
||||
};
|
||||
|
||||
static int
|
||||
pass2_alloc_hw_temp(nvsPtr nvs)
|
||||
{
|
||||
struct pass2_rec *rec = nvs->pass_rec;
|
||||
int i;
|
||||
|
||||
for (i=0; i<nvs->func->MaxTemp; i++) {
|
||||
/* This is a *horrible* hack.. R0 is both temp0 and result.color
|
||||
* in NV30/40 fragprogs, we can use R0 as a temp before result
|
||||
* is written however..
|
||||
*/
|
||||
if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0)
|
||||
continue;
|
||||
if (rec->hw_temps[i] == 0) {
|
||||
rec->hw_temps[i] = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static nvsRegister
|
||||
pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg)
|
||||
{
|
||||
struct pass2_rec *rec = nvs->pass_rec;
|
||||
|
||||
if (reg.file == NVS_FILE_TEMP) {
|
||||
if (rec->temps[reg.index] == -1)
|
||||
rec->temps[reg.index] = pass2_alloc_hw_temp(nvs);
|
||||
reg.index = rec->temps[reg.index];
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
static void
|
||||
pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst,
|
||||
struct _op_xlat *op, int slot)
|
||||
{
|
||||
nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y,
|
||||
NVS_SWZ_Z, NVS_SWZ_W };
|
||||
nvsFunc *shader = nvs->func;
|
||||
nvsRegister reg;
|
||||
int i;
|
||||
|
||||
shader->SetOpcode(shader, op->NV, slot);
|
||||
if (inst->saturate ) shader->SetSaturate(shader);
|
||||
if (inst->cond_update ) shader->SetCCUpdate(shader);
|
||||
if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond,
|
||||
inst->cond_reg,
|
||||
inst->cond_swizzle);
|
||||
else shader->SetCondition(shader, 0, NVS_COND_TR,
|
||||
0,
|
||||
default_swz);
|
||||
switch (inst->op) {
|
||||
case NVS_OP_TEX:
|
||||
case NVS_OP_TXB:
|
||||
case NVS_OP_TXL:
|
||||
case NVS_OP_TXP:
|
||||
case NVS_OP_TXD:
|
||||
shader->SetTexImageUnit(shader, inst->tex_unit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (op->srcpos[i] != -1) {
|
||||
reg = pass2_mangle_reg(nvs, inst, inst->src[i]);
|
||||
|
||||
shader->SetSource(shader, ®, op->srcpos[i]);
|
||||
|
||||
if (reg.file == NVS_FILE_CONST &&
|
||||
shader->GetSourceConstVal) {
|
||||
int idx_slot =
|
||||
nvs->params[reg.index].hw_index_cnt++;
|
||||
nvs->params[reg.index].hw_index = realloc(
|
||||
nvs->params[reg.index].hw_index,
|
||||
sizeof(int) * idx_slot+1);
|
||||
nvs->params[reg.index].hw_index[idx_slot] =
|
||||
nvs->program_current + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reg = pass2_mangle_reg(nvs, inst, inst->dest);
|
||||
shader->SetResult(shader, ®, inst->mask, slot);
|
||||
|
||||
if (inst->dest_scale != NVS_SCALE_1X) {
|
||||
shader->SetResultScale(shader, inst->dest_scale);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last)
|
||||
{
|
||||
nvsFunc *shader = nvs->func;
|
||||
struct _op_xlat *op;
|
||||
unsigned int hw_inst[8];
|
||||
int slot;
|
||||
int instsz;
|
||||
int i;
|
||||
|
||||
shader->inst = hw_inst;
|
||||
|
||||
/* Assemble this instruction */
|
||||
if (!(op = shader->GetOPTXFromSOP(inst->op, &slot)))
|
||||
return 0;
|
||||
shader->InitInstruction(shader);
|
||||
pass2_add_instruction(nvs, inst, op, slot);
|
||||
if (last)
|
||||
shader->SetLastInst(shader);
|
||||
|
||||
instsz = shader->GetOffsetNext(nvs->func);
|
||||
if (nvs->program_size + instsz >= nvs->program_alloc_size) {
|
||||
nvs->program_alloc_size *= 2;
|
||||
nvs->program = realloc(nvs->program,
|
||||
nvs->program_alloc_size *
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
|
||||
for (i=0; i<instsz; i++)
|
||||
nvs->program[nvs->program_current++] = hw_inst[i];
|
||||
nvs->program_size = nvs->program_current;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
pass2_translate(nvsPtr nvs, nvsFragmentHeader *f)
|
||||
{
|
||||
nvsFunc *shader = nvs->func;
|
||||
GLboolean last;
|
||||
|
||||
while (f) {
|
||||
last = (f == ((nvsSubroutine*)nvs->program_tree)->insn_tail);
|
||||
|
||||
switch (f->type) {
|
||||
case NVS_INSTRUCTION:
|
||||
if (!pass2_assemble_instruction(nvs,
|
||||
(nvsInstruction *)f,
|
||||
last))
|
||||
return GL_FALSE;
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE("Unimplemented fragment type\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
f = f->next;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Translate program into hardware format */
|
||||
GLboolean
|
||||
nouveau_shader_pass2(nvsPtr nvs)
|
||||
{
|
||||
struct pass2_rec *rec;
|
||||
int i;
|
||||
|
||||
NVSDBG("start: nvs=%p\n", nvs);
|
||||
|
||||
rec = calloc(1, sizeof(struct pass2_rec));
|
||||
for (i=0; i<NVS_MAX_TEMPS; i++)
|
||||
rec->temps[i] = -1;
|
||||
nvs->pass_rec = rec;
|
||||
|
||||
/* Start off with allocating 4 uint32_t's for each inst, will be grown
|
||||
* if necessary..
|
||||
*/
|
||||
nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4;
|
||||
nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t));
|
||||
nvs->program_size = 0;
|
||||
nvs->program_current = 0;
|
||||
|
||||
if (!pass2_translate(nvs,
|
||||
((nvsSubroutine*)nvs->program_tree)->insn_head)) {
|
||||
free(nvs->program);
|
||||
nvs->program = NULL;
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* Shrink allocated memory to only what we need */
|
||||
nvs->program = realloc(nvs->program,
|
||||
nvs->program_size * sizeof(uint32_t));
|
||||
nvs->program_alloc_size = nvs->program_size;
|
||||
|
||||
nvs->translated = 1;
|
||||
nvs->on_hardware = 0;
|
||||
|
||||
if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "-----------MESA PROGRAM target=%s, id=0x%x\n",
|
||||
_mesa_lookup_enum_by_nr(
|
||||
nvs->mesa.vp.Base.Target),
|
||||
nvs->mesa.vp.Base.Id);
|
||||
fflush(stdout); fflush(stderr);
|
||||
_mesa_print_program(&nvs->mesa.vp.Base);
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "----------------NV PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
nvsDisasmHWShader(nvs);
|
||||
fflush(stdout); fflush(stderr);
|
||||
fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n");
|
||||
fflush(stdout); fflush(stderr);
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "nouveau_context.h"
|
||||
#include "nouveau_span.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_lock.h"
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
|
||||
#define HAVE_HW_DEPTH_SPANS 0
|
||||
#define HAVE_HW_DEPTH_PIXELS 0
|
||||
#define HAVE_HW_STENCIL_SPANS 0
|
||||
#define HAVE_HW_STENCIL_PIXELS 0
|
||||
|
||||
#define HW_CLIPLOOP() \
|
||||
do { \
|
||||
int _nc = nmesa->numClipRects; \
|
||||
while ( _nc-- ) { \
|
||||
int minx = nmesa->pClipRects[_nc].x1 - nmesa->drawX; \
|
||||
int miny = nmesa->pClipRects[_nc].y1 - nmesa->drawY; \
|
||||
int maxx = nmesa->pClipRects[_nc].x2 - nmesa->drawX; \
|
||||
int maxy = nmesa->pClipRects[_nc].y2 - nmesa->drawY;
|
||||
|
||||
#define LOCAL_VARS \
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \
|
||||
nouveau_renderbuffer_t *nrb = (nouveau_renderbuffer_t *)rb; \
|
||||
GLuint height = nrb->mesa.Height; \
|
||||
GLubyte *map = (GLubyte *)(nrb->map ? nrb->map : nrb->mem->map) + \
|
||||
(nmesa->drawY * nrb->pitch) + (nmesa->drawX * nrb->cpp); \
|
||||
GLuint p; \
|
||||
(void) p;
|
||||
|
||||
#define Y_FLIP( _y ) (height - _y - 1)
|
||||
|
||||
#define HW_LOCK()
|
||||
|
||||
#define HW_UNLOCK()
|
||||
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Color buffers
|
||||
*/
|
||||
|
||||
/* RGB565 */
|
||||
#define SPANTMP_PIXEL_FMT GL_RGB
|
||||
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
|
||||
|
||||
#define TAG(x) nouveau##x##_RGB565
|
||||
#define TAG2(x,y) nouveau##x##_RGB565##y
|
||||
#define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp)
|
||||
#include "spantmp2.h"
|
||||
|
||||
|
||||
/* ARGB8888 */
|
||||
#define SPANTMP_PIXEL_FMT GL_BGRA
|
||||
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
|
||||
#define TAG(x) nouveau##x##_ARGB8888
|
||||
#define TAG2(x,y) nouveau##x##_ARGB8888##y
|
||||
#define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp)
|
||||
#include "spantmp2.h"
|
||||
|
||||
static void nouveauSpanRenderStart(GLcontext * ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
FIRE_RING();
|
||||
LOCK_HARDWARE(nmesa);
|
||||
nouveauWaitForIdleLocked(nmesa);
|
||||
}
|
||||
|
||||
static void nouveauSpanRenderFinish(GLcontext * ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
_swrast_flush(ctx);
|
||||
nouveauWaitForIdleLocked(nmesa);
|
||||
UNLOCK_HARDWARE(nmesa);
|
||||
}
|
||||
|
||||
void nouveauSpanInitFunctions(GLcontext * ctx)
|
||||
{
|
||||
struct swrast_device_driver *swdd =
|
||||
_swrast_GetDeviceDriverReference(ctx);
|
||||
swdd->SpanRenderStart = nouveauSpanRenderStart;
|
||||
swdd->SpanRenderFinish = nouveauSpanRenderFinish;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Plug in the Get/Put routines for the given driRenderbuffer.
|
||||
*/
|
||||
void nouveauSpanSetFunctions(nouveau_renderbuffer_t * nrb)
|
||||
{
|
||||
if (nrb->mesa._ActualFormat == GL_RGBA8)
|
||||
nouveauInitPointers_ARGB8888(&nrb->mesa);
|
||||
else // if (nrb->mesa._ActualFormat == GL_RGB5)
|
||||
nouveauInitPointers_RGB565(&nrb->mesa);
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_SPAN_H__
|
||||
#define __NOUVEAU_SPAN_H__
|
||||
|
||||
#include "drirenderbuffer.h"
|
||||
#include "nouveau_fbo.h"
|
||||
|
||||
extern void nouveauSpanInitFunctions(GLcontext *ctx);
|
||||
extern void nouveauSpanSetFunctions(nouveau_renderbuffer_t *nrb);
|
||||
|
||||
#endif /* __NOUVEAU_SPAN_H__ */
|
||||
|
||||
|
|
@ -1,368 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Jeremy Kolb
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "nouveau_context.h"
|
||||
#include "nouveau_state.h"
|
||||
#include "nouveau_swtcl.h"
|
||||
#include "nouveau_fifo.h"
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
|
||||
static INLINE GLuint nouveauPackColor(GLuint format,
|
||||
GLubyte r, GLubyte g,
|
||||
GLubyte b, GLubyte a)
|
||||
{
|
||||
switch (format) {
|
||||
case 2:
|
||||
return PACK_COLOR_565( r, g, b );
|
||||
case 4:
|
||||
return PACK_COLOR_8888( r, g, b, a);
|
||||
default:
|
||||
fprintf(stderr, "unknown format %d\n", (int)format);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void nouveauCalcViewport(GLcontext *ctx)
|
||||
{
|
||||
/* Calculate the Viewport Matrix */
|
||||
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
const GLfloat *v = ctx->Viewport._WindowMap.m;
|
||||
GLfloat *m = nmesa->viewport.m;
|
||||
GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY + nmesa->drawH;
|
||||
|
||||
nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
|
||||
|
||||
m[MAT_SX] = v[MAT_SX];
|
||||
m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X;
|
||||
m[MAT_SY] = - v[MAT_SY];
|
||||
m[MAT_TY] = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;
|
||||
m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale;
|
||||
m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale;
|
||||
|
||||
nmesa->hw_func.WindowMoved(nmesa);
|
||||
}
|
||||
|
||||
static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
||||
{
|
||||
/*
|
||||
* Need to send (at least on an nv35 the following:
|
||||
* cons = 4 (this may be bytes per pixel)
|
||||
*
|
||||
* The viewport:
|
||||
* 445 0x0000bee0 {size: 0x0 channel: 0x1 cmd: 0x00009ee0} <-- VIEWPORT_SETUP/HEADER ?
|
||||
* 446 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- x * cons
|
||||
* 447 0x00000c80 {size: 0x0 channel: 0x0 cmd: 0x00000c80} <-- (height + x) * cons
|
||||
* 448 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- y * cons
|
||||
* 449 0x00000960 {size: 0x0 channel: 0x0 cmd: 0x00000960} <-- (width + y) * cons
|
||||
* 44a 0x00082a00 {size: 0x2 channel: 0x1 cmd: 0x00000a00} <-- VIEWPORT_DIMS
|
||||
* 44b 0x04000000 <-- (Width_from_glViewport << 16) | x
|
||||
* 44c 0x03000000 <-- (Height_from_glViewport << 16) | (win_height - height - y)
|
||||
*
|
||||
*/
|
||||
|
||||
nouveauCalcViewport(ctx);
|
||||
}
|
||||
|
||||
static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far)
|
||||
{
|
||||
nouveauCalcViewport(ctx);
|
||||
}
|
||||
|
||||
static void nouveauUpdateProjectionMatrix(GLcontext *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static void nouveauUpdateModelviewMatrix(GLcontext *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static void nouveauDDUpdateHWState(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
int new_state = nmesa->new_state;
|
||||
|
||||
if ( new_state || nmesa->new_render_state & _NEW_TEXTURE )
|
||||
{
|
||||
nmesa->new_state = 0;
|
||||
|
||||
/* Update the various parts of the context's state.
|
||||
*/
|
||||
/*
|
||||
if ( new_state & NOUVEAU_NEW_ALPHA )
|
||||
nouveauUpdateAlphaMode( ctx );
|
||||
|
||||
if ( new_state & NOUVEAU_NEW_DEPTH )
|
||||
nouveauUpdateZMode( ctx );
|
||||
|
||||
if ( new_state & NOUVEAU_NEW_FOG )
|
||||
nouveauUpdateFogAttrib( ctx );
|
||||
|
||||
if ( new_state & NOUVEAU_NEW_CLIP )
|
||||
nouveauUpdateClipping( ctx );
|
||||
|
||||
if ( new_state & NOUVEAU_NEW_CULL )
|
||||
nouveauUpdateCull( ctx );
|
||||
|
||||
if ( new_state & NOUVEAU_NEW_MASKS )
|
||||
nouveauUpdateMasks( ctx );
|
||||
|
||||
if ( new_state & NOUVEAU_NEW_WINDOW )
|
||||
nouveauUpdateWindow( ctx );
|
||||
|
||||
if ( nmesa->new_render_state & _NEW_TEXTURE ) {
|
||||
nouveauUpdateTextureState( ctx );
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if ( new_state & _NEW_PROJECTION ) {
|
||||
nmesa->hw_func.UpdateProjectionMatrix(ctx);
|
||||
}
|
||||
if ( new_state & _NEW_MODELVIEW ) {
|
||||
nmesa->hw_func.UpdateModelviewMatrix(ctx);
|
||||
}
|
||||
|
||||
_swrast_InvalidateState( ctx, new_state );
|
||||
_swsetup_InvalidateState( ctx, new_state );
|
||||
_vbo_InvalidateState( ctx, new_state );
|
||||
_tnl_InvalidateState( ctx, new_state );
|
||||
NOUVEAU_CONTEXT(ctx)->new_render_state |= new_state;
|
||||
}
|
||||
|
||||
/* Initialize the context's hardware state. */
|
||||
void nouveauDDInitState(nouveauContextPtr nmesa)
|
||||
{
|
||||
uint32_t type = nmesa->screen->card->type;
|
||||
switch(type)
|
||||
{
|
||||
case NV_04:
|
||||
case NV_05:
|
||||
nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
|
||||
break;
|
||||
case NV_10:
|
||||
case NV_11:
|
||||
case NV_17:
|
||||
nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
|
||||
break;
|
||||
case NV_20:
|
||||
nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
|
||||
break;
|
||||
case NV_30:
|
||||
case NV_40:
|
||||
case NV_44:
|
||||
nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
|
||||
break;
|
||||
case NV_50:
|
||||
nv50InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
nouveau_state_cache_init(nmesa);
|
||||
}
|
||||
|
||||
/* Initialize the driver's state functions */
|
||||
void nouveauDDInitStateFuncs(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
ctx->Driver.UpdateState = nouveauDDInvalidateState;
|
||||
|
||||
ctx->Driver.ClearIndex = NULL;
|
||||
ctx->Driver.ClearColor = NULL; //nouveauDDClearColor;
|
||||
ctx->Driver.ClearStencil = NULL; //nouveauDDClearStencil;
|
||||
ctx->Driver.DrawBuffer = NULL; //nouveauDDDrawBuffer;
|
||||
ctx->Driver.ReadBuffer = NULL; //nouveauDDReadBuffer;
|
||||
|
||||
ctx->Driver.IndexMask = NULL;
|
||||
ctx->Driver.ColorMask = NULL; //nouveauDDColorMask;
|
||||
ctx->Driver.AlphaFunc = NULL; //nouveauDDAlphaFunc;
|
||||
ctx->Driver.BlendEquationSeparate = NULL; //nouveauDDBlendEquationSeparate;
|
||||
ctx->Driver.BlendFuncSeparate = NULL; //nouveauDDBlendFuncSeparate;
|
||||
ctx->Driver.ClearDepth = NULL; //nouveauDDClearDepth;
|
||||
ctx->Driver.CullFace = NULL; //nouveauDDCullFace;
|
||||
ctx->Driver.FrontFace = NULL; //nouveauDDFrontFace;
|
||||
ctx->Driver.DepthFunc = NULL; //nouveauDDDepthFunc;
|
||||
ctx->Driver.DepthMask = NULL; //nouveauDDDepthMask;
|
||||
ctx->Driver.Enable = NULL; //nouveauDDEnable;
|
||||
ctx->Driver.Fogfv = NULL; //nouveauDDFogfv;
|
||||
ctx->Driver.Hint = NULL;
|
||||
ctx->Driver.Lightfv = NULL;
|
||||
ctx->Driver.LightModelfv = NULL; //nouveauDDLightModelfv;
|
||||
ctx->Driver.LogicOpcode = NULL; //nouveauDDLogicOpCode;
|
||||
ctx->Driver.PolygonMode = NULL;
|
||||
ctx->Driver.PolygonStipple = NULL; //nouveauDDPolygonStipple;
|
||||
ctx->Driver.RenderMode = NULL; //nouveauDDRenderMode;
|
||||
ctx->Driver.Scissor = NULL; //nouveauDDScissor;
|
||||
ctx->Driver.ShadeModel = NULL; //nouveauDDShadeModel;
|
||||
ctx->Driver.StencilFuncSeparate = NULL; //nouveauDDStencilFuncSeparate;
|
||||
ctx->Driver.StencilMaskSeparate = NULL; //nouveauDDStencilMaskSeparate;
|
||||
ctx->Driver.StencilOpSeparate = NULL; //nouveauDDStencilOpSeparate;
|
||||
|
||||
ctx->Driver.DepthRange = nouveauDepthRange;
|
||||
ctx->Driver.Viewport = nouveauViewport;
|
||||
|
||||
/* Pixel path fallbacks.
|
||||
*/
|
||||
ctx->Driver.Accum = _swrast_Accum;
|
||||
ctx->Driver.Bitmap = _swrast_Bitmap;
|
||||
ctx->Driver.CopyPixels = _swrast_CopyPixels;
|
||||
ctx->Driver.DrawPixels = _swrast_DrawPixels;
|
||||
ctx->Driver.ReadPixels = _swrast_ReadPixels;
|
||||
|
||||
/* Swrast hooks for imaging extensions:
|
||||
*/
|
||||
ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
|
||||
ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
|
||||
ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
|
||||
ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
|
||||
|
||||
/* Matrix updates */
|
||||
nmesa->hw_func.UpdateProjectionMatrix = nouveauUpdateProjectionMatrix;
|
||||
nmesa->hw_func.UpdateModelviewMatrix = nouveauUpdateModelviewMatrix;
|
||||
}
|
||||
|
||||
#define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a
|
||||
|
||||
void nouveauInitState(GLcontext *ctx)
|
||||
{
|
||||
/*
|
||||
* Mesa should do this for us:
|
||||
*/
|
||||
|
||||
STATE_INIT(AlphaFunc)( ctx,
|
||||
ctx->Color.AlphaFunc,
|
||||
ctx->Color.AlphaRef);
|
||||
|
||||
STATE_INIT(BlendColor)( ctx,
|
||||
ctx->Color.BlendColor );
|
||||
|
||||
STATE_INIT(BlendEquationSeparate)( ctx,
|
||||
ctx->Color.BlendEquationRGB,
|
||||
ctx->Color.BlendEquationA);
|
||||
|
||||
STATE_INIT(BlendFuncSeparate)( ctx,
|
||||
ctx->Color.BlendSrcRGB,
|
||||
ctx->Color.BlendDstRGB,
|
||||
ctx->Color.BlendSrcA,
|
||||
ctx->Color.BlendDstA);
|
||||
|
||||
STATE_INIT(ClearColor)( ctx, ctx->Color.ClearColor);
|
||||
STATE_INIT(ClearDepth)( ctx, ctx->Depth.Clear);
|
||||
STATE_INIT(ClearStencil)( ctx, ctx->Stencil.Clear);
|
||||
|
||||
STATE_INIT(ColorMask)( ctx,
|
||||
ctx->Color.ColorMask[RCOMP],
|
||||
ctx->Color.ColorMask[GCOMP],
|
||||
ctx->Color.ColorMask[BCOMP],
|
||||
ctx->Color.ColorMask[ACOMP]);
|
||||
|
||||
STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode );
|
||||
STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func );
|
||||
STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask );
|
||||
STATE_INIT(DepthRange)( ctx, ctx->Viewport.Near, ctx->Viewport.Far );
|
||||
|
||||
STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
|
||||
STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled );
|
||||
STATE_INIT(Enable)( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
|
||||
STATE_INIT(Enable)( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
|
||||
STATE_INIT(Enable)( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
|
||||
STATE_INIT(Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
|
||||
STATE_INIT(Enable)( ctx, GL_DITHER, ctx->Color.DitherFlag );
|
||||
STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled );
|
||||
STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled );
|
||||
STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
|
||||
STATE_INIT(Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag );
|
||||
STATE_INIT(Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag );
|
||||
STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
|
||||
STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine);
|
||||
STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint);
|
||||
STATE_INIT(Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag );
|
||||
STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
|
||||
STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
|
||||
STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
|
||||
STATE_INIT(Enable)( ctx, GL_TEXTURE_1D, GL_FALSE );
|
||||
STATE_INIT(Enable)( ctx, GL_TEXTURE_2D, GL_FALSE );
|
||||
STATE_INIT(Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
|
||||
STATE_INIT(Enable)( ctx, GL_TEXTURE_3D, GL_FALSE );
|
||||
STATE_INIT(Enable)( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
|
||||
|
||||
STATE_INIT(Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color );
|
||||
STATE_INIT(Fogfv)( ctx, GL_FOG_MODE, 0 );
|
||||
STATE_INIT(Fogfv)( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
|
||||
STATE_INIT(Fogfv)( ctx, GL_FOG_START, &ctx->Fog.Start );
|
||||
STATE_INIT(Fogfv)( ctx, GL_FOG_END, &ctx->Fog.End );
|
||||
|
||||
STATE_INIT(FrontFace)( ctx, ctx->Polygon.FrontFace );
|
||||
|
||||
{
|
||||
GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
|
||||
STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
|
||||
}
|
||||
|
||||
STATE_INIT(LineStipple)( ctx, ctx->Line.StippleFactor, ctx->Line.StipplePattern );
|
||||
STATE_INIT(LineWidth)( ctx, ctx->Line.Width );
|
||||
STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp );
|
||||
STATE_INIT(PointSize)( ctx, ctx->Point.Size );
|
||||
STATE_INIT(PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode );
|
||||
STATE_INIT(PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode );
|
||||
STATE_INIT(PolygonOffset)( ctx,
|
||||
ctx->Polygon.OffsetFactor,
|
||||
ctx->Polygon.OffsetUnits );
|
||||
STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple );
|
||||
STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel );
|
||||
STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT,
|
||||
ctx->Stencil.Function[0],
|
||||
ctx->Stencil.Ref[0],
|
||||
ctx->Stencil.ValueMask[0] );
|
||||
STATE_INIT(StencilFuncSeparate)( ctx, GL_BACK,
|
||||
ctx->Stencil.Function[1],
|
||||
ctx->Stencil.Ref[1],
|
||||
ctx->Stencil.ValueMask[1] );
|
||||
STATE_INIT(StencilMaskSeparate)( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
|
||||
STATE_INIT(StencilMaskSeparate)( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
|
||||
STATE_INIT(StencilOpSeparate)( ctx, GL_FRONT,
|
||||
ctx->Stencil.FailFunc[0],
|
||||
ctx->Stencil.ZFailFunc[0],
|
||||
ctx->Stencil.ZPassFunc[0]);
|
||||
STATE_INIT(StencilOpSeparate)( ctx, GL_BACK,
|
||||
ctx->Stencil.FailFunc[1],
|
||||
ctx->Stencil.ZFailFunc[1],
|
||||
ctx->Stencil.ZPassFunc[1]);
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Jeremy Kolb
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef __NOUVEAU_STATE_H__
|
||||
#define __NOUVEAU_STATE_H__
|
||||
|
||||
#include "nouveau_context.h"
|
||||
|
||||
extern void nouveauDDInitState(nouveauContextPtr nmesa);
|
||||
extern void nouveauDDInitStateFuncs(GLcontext *ctx);
|
||||
|
||||
extern void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
|
||||
extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
|
||||
extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
|
||||
extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
|
||||
extern void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
|
||||
|
||||
extern void nouveauInitState(GLcontext *ctx);
|
||||
|
||||
/*
|
||||
extern void nouveauDDUpdateState(GLcontext *ctx);
|
||||
extern void nouveauDDUpdateHWState(GLcontext *ctx);
|
||||
|
||||
extern void nouveauEmitHwStateLocked(nouveauContextPtr nmesa);
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
|
||||
#include "nouveau_state_cache.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_fifo.h"
|
||||
|
||||
#define BEGIN_RING_NOFLUSH(subchannel,tag,size) do { \
|
||||
if (nmesa->fifo.free <= (size)) \
|
||||
WAIT_RING(nmesa,(size)); \
|
||||
OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \
|
||||
nmesa->fifo.free -= ((size) + 1); \
|
||||
}while(0)
|
||||
|
||||
// flush all the dirty state
|
||||
void nouveau_state_cache_flush(nouveauContextPtr nmesa)
|
||||
{
|
||||
int i=0;
|
||||
int run=0;
|
||||
|
||||
// fast-path no state changes
|
||||
if (!nmesa->state_cache.dirty)
|
||||
return;
|
||||
nmesa->state_cache.dirty=0;
|
||||
|
||||
do
|
||||
{
|
||||
// jump to a dirty state
|
||||
while((nmesa->state_cache.hdirty[i/NOUVEAU_STATE_CACHE_HIER_SIZE]==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES))
|
||||
i=(i&~(NOUVEAU_STATE_CACHE_HIER_SIZE-1))+NOUVEAU_STATE_CACHE_HIER_SIZE;
|
||||
while((nmesa->state_cache.atoms[i].dirty==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES))
|
||||
i++;
|
||||
|
||||
// figure out a run of dirty values
|
||||
run=0;
|
||||
while((nmesa->state_cache.atoms[i+run].dirty)&&(i+run<NOUVEAU_STATE_CACHE_ENTRIES))
|
||||
run++;
|
||||
|
||||
// output everything as a single run
|
||||
if (run>0) {
|
||||
int j;
|
||||
|
||||
BEGIN_RING_NOFLUSH(NvSub3D, i*4, run);
|
||||
for(j=0;j<run;j++)
|
||||
{
|
||||
OUT_RING(nmesa->state_cache.atoms[i+j].value);
|
||||
nmesa->state_cache.atoms[i+j].dirty=0;
|
||||
if ((i+j)%NOUVEAU_STATE_CACHE_HIER_SIZE==0)
|
||||
nmesa->state_cache.hdirty[(i+j)/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0;
|
||||
}
|
||||
i+=run;
|
||||
}
|
||||
}
|
||||
while(i<NOUVEAU_STATE_CACHE_ENTRIES);
|
||||
nmesa->state_cache.hdirty[NOUVEAU_STATE_CACHE_HIER_SIZE/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0;
|
||||
}
|
||||
|
||||
|
||||
// inits the state cache
|
||||
void nouveau_state_cache_init(nouveauContextPtr nmesa)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<NOUVEAU_STATE_CACHE_ENTRIES;i++)
|
||||
{
|
||||
nmesa->state_cache.atoms[i].dirty=0;
|
||||
nmesa->state_cache.atoms[i].value=0xDEADBEEF; // nvidia cards like beef
|
||||
}
|
||||
nmesa->state_cache.dirty=0;
|
||||
}
|
||||
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
#ifndef __NOUVEAU_STATE_CACHE_H__
|
||||
#define __NOUVEAU_STATE_CACHE_H__
|
||||
|
||||
#include "mtypes.h"
|
||||
|
||||
#define NOUVEAU_STATE_CACHE_ENTRIES 2048
|
||||
// size of a dirty requests block
|
||||
// you can play with that and tune the value to increase/decrease performance
|
||||
// but keep it a power of 2 !
|
||||
#define NOUVEAU_STATE_CACHE_HIER_SIZE 32
|
||||
|
||||
typedef struct nouveau_state_atom_t{
|
||||
uint32_t value;
|
||||
uint32_t dirty;
|
||||
}nouveau_state_atom;
|
||||
|
||||
typedef struct nouveau_state_cache_t{
|
||||
nouveau_state_atom atoms[NOUVEAU_STATE_CACHE_ENTRIES];
|
||||
uint32_t current_pos;
|
||||
// hierarchical dirty flags
|
||||
uint8_t hdirty[NOUVEAU_STATE_CACHE_ENTRIES/NOUVEAU_STATE_CACHE_HIER_SIZE];
|
||||
// master dirty flag
|
||||
uint8_t dirty;
|
||||
}nouveau_state_cache;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/* Common software TCL code */
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_swtcl.h"
|
||||
#include "nv10_swtcl.h"
|
||||
#include "nouveau_span.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
/* Common tri functions */
|
||||
|
||||
/* The fallbacks */
|
||||
void nouveau_fallback_tri(struct nouveau_context *nmesa,
|
||||
nouveauVertex *v0,
|
||||
nouveauVertex *v1,
|
||||
nouveauVertex *v2)
|
||||
{
|
||||
GLcontext *ctx = nmesa->glCtx;
|
||||
SWvertex v[3];
|
||||
_swsetup_Translate(ctx, v0, &v[0]);
|
||||
_swsetup_Translate(ctx, v1, &v[1]);
|
||||
_swsetup_Translate(ctx, v2, &v[2]);
|
||||
_swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
|
||||
}
|
||||
|
||||
|
||||
void nouveau_fallback_line(struct nouveau_context *nmesa,
|
||||
nouveauVertex *v0,
|
||||
nouveauVertex *v1)
|
||||
{
|
||||
GLcontext *ctx = nmesa->glCtx;
|
||||
SWvertex v[2];
|
||||
_swsetup_Translate(ctx, v0, &v[0]);
|
||||
_swsetup_Translate(ctx, v1, &v[1]);
|
||||
_swrast_Line(ctx, &v[0], &v[1]);
|
||||
}
|
||||
|
||||
|
||||
void nouveau_fallback_point(struct nouveau_context *nmesa,
|
||||
nouveauVertex *v0)
|
||||
{
|
||||
GLcontext *ctx = nmesa->glCtx;
|
||||
SWvertex v[1];
|
||||
_swsetup_Translate(ctx, v0, &v[0]);
|
||||
_swrast_Point(ctx, &v[0]);
|
||||
}
|
||||
|
||||
void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode)
|
||||
{
|
||||
GLcontext *ctx = nmesa->glCtx;
|
||||
GLuint oldfallback = nmesa->Fallback;
|
||||
|
||||
if (mode) {
|
||||
nmesa->Fallback |= bit;
|
||||
if (oldfallback == 0) {
|
||||
if (nmesa->screen->card->type<NV_10) {
|
||||
//nv04FinishPrimitive(nmesa);
|
||||
} else {
|
||||
//nv10FinishPrimitive(nmesa);
|
||||
}
|
||||
|
||||
_swsetup_Wakeup(ctx);
|
||||
nmesa->render_index = ~0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nmesa->Fallback &= ~bit;
|
||||
if (oldfallback == bit) {
|
||||
_swrast_flush( ctx );
|
||||
|
||||
if (nmesa->screen->card->type<NV_10) {
|
||||
nv04TriInitFunctions(ctx);
|
||||
} else {
|
||||
nv10TriInitFunctions(ctx);
|
||||
}
|
||||
|
||||
_tnl_invalidate_vertex_state( ctx, ~0 );
|
||||
_tnl_invalidate_vertices( ctx, ~0 );
|
||||
_tnl_install_attrs( ctx,
|
||||
nmesa->vertex_attrs,
|
||||
nmesa->vertex_attr_count,
|
||||
nmesa->viewport.m, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nouveauRunPipeline( GLcontext *ctx )
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (nmesa->new_state) {
|
||||
nmesa->new_render_state |= nmesa->new_state;
|
||||
}
|
||||
|
||||
_tnl_run_pipeline( ctx );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_SWTCL_H__
|
||||
#define __NOUVEAU_SWTCL_H__
|
||||
|
||||
#include "nouveau_context.h"
|
||||
|
||||
extern void nouveau_fallback_tri(struct nouveau_context *nmesa,
|
||||
nouveauVertex *v0,
|
||||
nouveauVertex *v1,
|
||||
nouveauVertex *v2);
|
||||
|
||||
extern void nouveau_fallback_line(struct nouveau_context *nmesa,
|
||||
nouveauVertex *v0,
|
||||
nouveauVertex *v1);
|
||||
|
||||
extern void nouveau_fallback_point(struct nouveau_context *nmesa,
|
||||
nouveauVertex *v0);
|
||||
|
||||
extern void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode);
|
||||
|
||||
extern void nouveauRunPipeline( GLcontext *ctx );
|
||||
|
||||
extern void nouveauTriInitFunctions( GLcontext *ctx );
|
||||
|
||||
|
||||
#endif /* __NOUVEAU_SWTCL_H__ */
|
||||
|
||||
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Ben Skeggs.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "vblank.h" /* for DO_USLEEP */
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_mem.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_sync.h"
|
||||
|
||||
#define NOTIFIER(__v) \
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \
|
||||
volatile uint32_t *__v = (void*)nmesa->fifo.notifier_block + \
|
||||
notifier->offset
|
||||
|
||||
struct drm_nouveau_notifierobj_alloc *
|
||||
nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
struct drm_nouveau_notifierobj_alloc *notifier;
|
||||
int ret;
|
||||
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
return NULL;
|
||||
#endif
|
||||
notifier = CALLOC_STRUCT(drm_nouveau_notifierobj_alloc);
|
||||
if (!notifier)
|
||||
return NULL;
|
||||
|
||||
notifier->channel = nmesa->fifo.drm.channel;
|
||||
notifier->handle = handle;
|
||||
notifier->count = count;
|
||||
ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
|
||||
notifier, sizeof(*notifier));
|
||||
if (ret) {
|
||||
MESSAGE("Failed to create notifier 0x%08x: %d\n", handle, ret);
|
||||
FREE(notifier);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return notifier;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_notifier_destroy(GLcontext *ctx,
|
||||
struct drm_nouveau_notifierobj_alloc *notifier)
|
||||
{
|
||||
/*XXX: free notifier object.. */
|
||||
FREE(notifier);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_notifier_reset(GLcontext *ctx,
|
||||
struct drm_nouveau_notifierobj_alloc *notifier,
|
||||
GLuint id)
|
||||
{
|
||||
NOTIFIER(n);
|
||||
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
return;
|
||||
#endif
|
||||
|
||||
n[NV_NOTIFY_TIME_0 /4] = 0x00000000;
|
||||
n[NV_NOTIFY_TIME_1 /4] = 0x00000000;
|
||||
n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000;
|
||||
n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS <<
|
||||
NV_NOTIFY_STATE_STATUS_SHIFT);
|
||||
}
|
||||
|
||||
GLuint
|
||||
nouveau_notifier_status(GLcontext *ctx,
|
||||
struct drm_nouveau_notifierobj_alloc *notifier,
|
||||
GLuint id)
|
||||
{
|
||||
NOTIFIER(n);
|
||||
|
||||
return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT;
|
||||
}
|
||||
|
||||
GLuint
|
||||
nouveau_notifier_return_val(GLcontext *ctx,
|
||||
struct drm_nouveau_notifierobj_alloc *notifier,
|
||||
GLuint id)
|
||||
{
|
||||
NOTIFIER(n);
|
||||
|
||||
return n[NV_NOTIFY_RETURN_VALUE/4];
|
||||
}
|
||||
|
||||
GLboolean
|
||||
nouveau_notifier_wait_status(GLcontext *ctx,
|
||||
struct drm_nouveau_notifierobj_alloc *notifier,
|
||||
GLuint id, GLuint status, GLuint timeout)
|
||||
{
|
||||
NOTIFIER(n);
|
||||
unsigned int time = 0;
|
||||
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
return GL_TRUE;
|
||||
#endif
|
||||
|
||||
while (time <= timeout) {
|
||||
if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) {
|
||||
MESSAGE("Notifier returned error: 0x%04x\n",
|
||||
n[NV_NOTIFY_STATE/4] &
|
||||
NV_NOTIFY_STATE_ERROR_CODE_MASK);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (((n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_STATUS_MASK) >>
|
||||
NV_NOTIFY_STATE_STATUS_SHIFT) == status)
|
||||
return GL_TRUE;
|
||||
|
||||
if (timeout) {
|
||||
DO_USLEEP(1);
|
||||
time++;
|
||||
}
|
||||
}
|
||||
|
||||
MESSAGE("Notifier timed out\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_notifier_wait_nop(GLcontext *ctx,
|
||||
struct drm_nouveau_notifierobj_alloc *notifier,
|
||||
GLuint subc)
|
||||
{
|
||||
NOTIFIER(n);
|
||||
GLboolean ret;
|
||||
|
||||
nouveau_notifier_reset(ctx, notifier, 0);
|
||||
|
||||
BEGIN_RING_SIZE(subc, NV_NOTIFY, 1);
|
||||
OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY);
|
||||
BEGIN_RING_SIZE(subc, NV_NOP, 1);
|
||||
OUT_RING (0);
|
||||
FIRE_RING();
|
||||
|
||||
ret = nouveau_notifier_wait_status(ctx, notifier, 0,
|
||||
NV_NOTIFY_STATE_STATUS_COMPLETED,
|
||||
0 /* no timeout */);
|
||||
if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n");
|
||||
}
|
||||
|
||||
GLboolean nouveauSyncInitFuncs(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
#ifdef NOUVEAU_RING_DEBUG
|
||||
return GL_TRUE;
|
||||
#endif
|
||||
|
||||
nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1);
|
||||
if (!nmesa->syncNotifier) {
|
||||
MESSAGE("Failed to create channel sync notifier\n");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
/* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D
|
||||
* object classes
|
||||
*/
|
||||
BEGIN_RING_CACHE(NvSub3D, 0x180, 1);
|
||||
OUT_RING_CACHE (NvSyncNotify);
|
||||
BEGIN_RING_SIZE(NvSubMemFormat,
|
||||
NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
|
||||
OUT_RING (NvSyncNotify);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Ben Skeggs.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NOUVEAU_SYNC_H__
|
||||
#define __NOUVEAU_SYNC_H__
|
||||
|
||||
#define NV_NOTIFIER_SIZE 32
|
||||
#define NV_NOTIFY_TIME_0 0x00000000
|
||||
#define NV_NOTIFY_TIME_1 0x00000004
|
||||
#define NV_NOTIFY_RETURN_VALUE 0x00000008
|
||||
#define NV_NOTIFY_STATE 0x0000000C
|
||||
#define NV_NOTIFY_STATE_STATUS_MASK 0xFF000000
|
||||
#define NV_NOTIFY_STATE_STATUS_SHIFT 24
|
||||
#define NV_NOTIFY_STATE_STATUS_COMPLETED 0x00
|
||||
#define NV_NOTIFY_STATE_STATUS_IN_PROCESS 0x01
|
||||
#define NV_NOTIFY_STATE_ERROR_CODE_MASK 0x0000FFFF
|
||||
#define NV_NOTIFY_STATE_ERROR_CODE_SHIFT 0
|
||||
|
||||
/* Methods that (hopefully) all objects have */
|
||||
#define NV_NOP 0x00000100
|
||||
#define NV_NOTIFY 0x00000104
|
||||
#define NV_NOTIFY_STYLE_WRITE_ONLY 0
|
||||
|
||||
extern struct drm_nouveau_notifierobj_alloc *
|
||||
nouveau_notifier_new(GLcontext *, GLuint handle, GLuint count);
|
||||
extern void
|
||||
nouveau_notifier_destroy(GLcontext *, struct drm_nouveau_notifierobj_alloc *);
|
||||
extern void
|
||||
nouveau_notifier_reset(GLcontext *, struct drm_nouveau_notifierobj_alloc *,
|
||||
GLuint id);
|
||||
extern GLuint
|
||||
nouveau_notifier_status(GLcontext *, struct drm_nouveau_notifierobj_alloc *,
|
||||
GLuint id);
|
||||
extern GLuint
|
||||
nouveau_notifier_return_val(GLcontext *, struct drm_nouveau_notifierobj_alloc *,
|
||||
GLuint id);
|
||||
extern GLboolean
|
||||
nouveau_notifier_wait_status(GLcontext *, struct drm_nouveau_notifierobj_alloc *,
|
||||
GLuint id, GLuint status, GLuint timeout);
|
||||
extern void
|
||||
nouveau_notifier_wait_nop(GLcontext *ctx, struct drm_nouveau_notifierobj_alloc *,
|
||||
GLuint subc);
|
||||
|
||||
extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx);
|
||||
#endif
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "nouveau_tex.h"
|
||||
|
||||
// XXX needs some love
|
||||
void nouveauTexInitFunctions( struct dd_function_table *functions )
|
||||
{
|
||||
/*
|
||||
functions->TexEnv = nouveauTexEnv;
|
||||
functions->ChooseTextureFormat = nouveauChooseTextureFormat;
|
||||
functions->TexImage1D = nouveauTexImage1D;
|
||||
functions->TexSubImage1D = nouveauTexSubImage1D;
|
||||
functions->TexImage2D = nouveauTexImage2D;
|
||||
functions->TexSubImage2D = nouveauTexSubImage2D;
|
||||
functions->TexParameter = nouveauTexParameter;
|
||||
functions->BindTexture = nouveauBindTexture;
|
||||
functions->NewTextureObject = nouveauNewTextureObject;
|
||||
functions->DeleteTexture = nouveauDeleteTexture;
|
||||
functions->IsTextureResident = driIsTextureResident;
|
||||
|
||||
driInitTextureFormats();
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef __NOUVEAU_TEX_H__
|
||||
#define __NOUVEAU_TEX_H__
|
||||
|
||||
#include <errno.h>
|
||||
#include "mtypes.h"
|
||||
#include "macros.h"
|
||||
#include "dd.h"
|
||||
|
||||
extern void nouveauTexInitFunctions( struct dd_function_table *functions );
|
||||
|
||||
#endif /* __NOUVEAU_TEX_H__ */
|
||||
|
|
@ -1,540 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2007 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "nouveau_context.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_msg.h"
|
||||
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
|
||||
static uint32_t nv04_compare_func(GLuint f)
|
||||
{
|
||||
switch ( f ) {
|
||||
case GL_NEVER: return 1;
|
||||
case GL_LESS: return 2;
|
||||
case GL_EQUAL: return 3;
|
||||
case GL_LEQUAL: return 4;
|
||||
case GL_GREATER: return 5;
|
||||
case GL_NOTEQUAL: return 6;
|
||||
case GL_GEQUAL: return 7;
|
||||
case GL_ALWAYS: return 8;
|
||||
}
|
||||
WARN_ONCE("Unable to find the function\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t nv04_blend_func(GLuint f)
|
||||
{
|
||||
switch ( f ) {
|
||||
case GL_ZERO: return 0x1;
|
||||
case GL_ONE: return 0x2;
|
||||
case GL_SRC_COLOR: return 0x3;
|
||||
case GL_ONE_MINUS_SRC_COLOR: return 0x4;
|
||||
case GL_SRC_ALPHA: return 0x5;
|
||||
case GL_ONE_MINUS_SRC_ALPHA: return 0x6;
|
||||
case GL_DST_ALPHA: return 0x7;
|
||||
case GL_ONE_MINUS_DST_ALPHA: return 0x8;
|
||||
case GL_DST_COLOR: return 0x9;
|
||||
case GL_ONE_MINUS_DST_COLOR: return 0xA;
|
||||
case GL_SRC_ALPHA_SATURATE: return 0xB;
|
||||
}
|
||||
WARN_ONCE("Unable to find the function 0x%x\n",f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nv04_emit_control(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
uint32_t control,cull;
|
||||
GLubyte alpha_ref;
|
||||
|
||||
CLAMPED_FLOAT_TO_UBYTE(alpha_ref, ctx->Color.AlphaRef);
|
||||
control=alpha_ref;
|
||||
control|=(nv04_compare_func(ctx->Color.AlphaFunc)<<8);
|
||||
control|=(ctx->Color.AlphaEnabled<<12);
|
||||
control|=(1<<13);
|
||||
control|=(ctx->Depth.Test<<14);
|
||||
control|=(nv04_compare_func(ctx->Depth.Func)<<16);
|
||||
if ((ctx->Polygon.CullFlag)&&(ctx->Polygon.CullFaceMode!=GL_FRONT_AND_BACK))
|
||||
{
|
||||
if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_FRONT))
|
||||
cull=2;
|
||||
if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_BACK))
|
||||
cull=3;
|
||||
if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_FRONT))
|
||||
cull=3;
|
||||
if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_BACK))
|
||||
cull=2;
|
||||
}
|
||||
else
|
||||
if (ctx->Polygon.CullFaceMode==GL_FRONT_AND_BACK)
|
||||
cull=0;
|
||||
else
|
||||
cull=1;
|
||||
control|=(cull<<20);
|
||||
control|=(ctx->Color.DitherFlag<<22);
|
||||
if ((ctx->Depth.Test)&&(ctx->Depth.Mask))
|
||||
control|=(1<<24);
|
||||
|
||||
control|=(1<<30); // integer zbuffer format
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
|
||||
OUT_RING_CACHE(control);
|
||||
}
|
||||
|
||||
static void nv04_emit_blend(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
uint32_t blend;
|
||||
|
||||
blend=0x4; // texture MODULATE_ALPHA
|
||||
blend|=0x20; // alpha is MSB
|
||||
switch(ctx->Light.ShadeModel) {
|
||||
case GL_SMOOTH:blend|=(1<<6);break;
|
||||
case GL_FLAT: blend|=(2<<6);break;
|
||||
default:break;
|
||||
}
|
||||
if (ctx->Hint.PerspectiveCorrection!=GL_FASTEST)
|
||||
blend|=(1<<8);
|
||||
blend|=(ctx->Fog.Enabled<<16);
|
||||
blend|=(ctx->Color.BlendEnabled<<20);
|
||||
blend|=(nv04_blend_func(ctx->Color.BlendSrcRGB)<<24);
|
||||
blend|=(nv04_blend_func(ctx->Color.BlendDstRGB)<<28);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
|
||||
OUT_RING_CACHE(blend);
|
||||
}
|
||||
|
||||
static void nv04_emit_fog_color(GLcontext *ctx)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte c[4];
|
||||
c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] );
|
||||
c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] );
|
||||
c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
|
||||
c[3] = FLOAT_TO_UBYTE( ctx->Fog.Color[3] );
|
||||
BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR, 1);
|
||||
OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3]));
|
||||
}
|
||||
|
||||
static void nv04AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
|
||||
{
|
||||
nv04_emit_control(ctx);
|
||||
}
|
||||
|
||||
static void nv04BlendColor(GLcontext *ctx, const GLfloat color[4])
|
||||
{
|
||||
nv04_emit_blend(ctx);
|
||||
}
|
||||
|
||||
static void nv04BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
|
||||
{
|
||||
nv04_emit_blend(ctx);
|
||||
}
|
||||
|
||||
|
||||
static void nv04BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
|
||||
GLenum sfactorA, GLenum dfactorA)
|
||||
{
|
||||
nv04_emit_blend(ctx);
|
||||
}
|
||||
|
||||
static void nv04Clear(GLcontext *ctx, GLbitfield mask)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04ClearColor(GLcontext *ctx, const GLfloat color[4])
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04ClearDepth(GLcontext *ctx, GLclampd d)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04ClearStencil(GLcontext *ctx, GLint s)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
|
||||
GLboolean bmask, GLboolean amask )
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
|
||||
{
|
||||
/* TODO I need love */
|
||||
}
|
||||
|
||||
static void nv04CullFace(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
nv04_emit_control(ctx);
|
||||
}
|
||||
|
||||
static void nv04FrontFace(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04DepthFunc(GLcontext *ctx, GLenum func)
|
||||
{
|
||||
nv04_emit_control(ctx);
|
||||
}
|
||||
|
||||
static void nv04DepthMask(GLcontext *ctx, GLboolean flag)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/** Specify the current buffer for writing */
|
||||
//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
|
||||
/** Specify the buffers for writing for fragment programs*/
|
||||
//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
|
||||
|
||||
static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
{
|
||||
switch(cap)
|
||||
{
|
||||
case GL_ALPHA_TEST:
|
||||
nv04_emit_control(ctx);
|
||||
break;
|
||||
// case GL_AUTO_NORMAL:
|
||||
case GL_BLEND:
|
||||
nv04_emit_blend(ctx);
|
||||
break;
|
||||
// case GL_CLIP_PLANE0:
|
||||
// case GL_CLIP_PLANE1:
|
||||
// case GL_CLIP_PLANE2:
|
||||
// case GL_CLIP_PLANE3:
|
||||
// case GL_CLIP_PLANE4:
|
||||
// case GL_CLIP_PLANE5:
|
||||
// case GL_COLOR_LOGIC_OP:
|
||||
// case GL_COLOR_MATERIAL:
|
||||
// case GL_COLOR_SUM_EXT:
|
||||
// case GL_COLOR_TABLE:
|
||||
// case GL_CONVOLUTION_1D:
|
||||
// case GL_CONVOLUTION_2D:
|
||||
case GL_CULL_FACE:
|
||||
nv04_emit_control(ctx);
|
||||
break;
|
||||
case GL_DEPTH_TEST:
|
||||
nv04_emit_control(ctx);
|
||||
break;
|
||||
case GL_DITHER:
|
||||
nv04_emit_control(ctx);
|
||||
break;
|
||||
case GL_FOG:
|
||||
nv04_emit_blend(ctx);
|
||||
nv04_emit_fog_color(ctx);
|
||||
break;
|
||||
// case GL_HISTOGRAM:
|
||||
// case GL_INDEX_LOGIC_OP:
|
||||
// case GL_LIGHT0:
|
||||
// case GL_LIGHT1:
|
||||
// case GL_LIGHT2:
|
||||
// case GL_LIGHT3:
|
||||
// case GL_LIGHT4:
|
||||
// case GL_LIGHT5:
|
||||
// case GL_LIGHT6:
|
||||
// case GL_LIGHT7:
|
||||
// case GL_LIGHTING:
|
||||
// case GL_LINE_SMOOTH:
|
||||
// case GL_LINE_STIPPLE:
|
||||
// case GL_MAP1_COLOR_4:
|
||||
// case GL_MAP1_INDEX:
|
||||
// case GL_MAP1_NORMAL:
|
||||
// case GL_MAP1_TEXTURE_COORD_1:
|
||||
// case GL_MAP1_TEXTURE_COORD_2:
|
||||
// case GL_MAP1_TEXTURE_COORD_3:
|
||||
// case GL_MAP1_TEXTURE_COORD_4:
|
||||
// case GL_MAP1_VERTEX_3:
|
||||
// case GL_MAP1_VERTEX_4:
|
||||
// case GL_MAP2_COLOR_4:
|
||||
// case GL_MAP2_INDEX:
|
||||
// case GL_MAP2_NORMAL:
|
||||
// case GL_MAP2_TEXTURE_COORD_1:
|
||||
// case GL_MAP2_TEXTURE_COORD_2:
|
||||
// case GL_MAP2_TEXTURE_COORD_3:
|
||||
// case GL_MAP2_TEXTURE_COORD_4:
|
||||
// case GL_MAP2_VERTEX_3:
|
||||
// case GL_MAP2_VERTEX_4:
|
||||
// case GL_MINMAX:
|
||||
// case GL_NORMALIZE:
|
||||
// case GL_POINT_SMOOTH:
|
||||
// case GL_POLYGON_OFFSET_POINT:
|
||||
// case GL_POLYGON_OFFSET_LINE:
|
||||
// case GL_POLYGON_OFFSET_FILL:
|
||||
// case GL_POLYGON_SMOOTH:
|
||||
// case GL_POLYGON_STIPPLE:
|
||||
// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
|
||||
// case GL_POST_CONVOLUTION_COLOR_TABLE:
|
||||
// case GL_RESCALE_NORMAL:
|
||||
// case GL_SCISSOR_TEST:
|
||||
// case GL_SEPARABLE_2D:
|
||||
// case GL_STENCIL_TEST:
|
||||
// case GL_TEXTURE_GEN_Q:
|
||||
// case GL_TEXTURE_GEN_R:
|
||||
// case GL_TEXTURE_GEN_S:
|
||||
// case GL_TEXTURE_GEN_T:
|
||||
// case GL_TEXTURE_1D:
|
||||
// case GL_TEXTURE_2D:
|
||||
// case GL_TEXTURE_3D:
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||
{
|
||||
nv04_emit_blend(ctx);
|
||||
nv04_emit_fog_color(ctx);
|
||||
}
|
||||
|
||||
static void nv04Hint(GLcontext *ctx, GLenum target, GLenum mode)
|
||||
{
|
||||
switch(target)
|
||||
{
|
||||
case GL_PERSPECTIVE_CORRECTION_HINT:nv04_emit_blend(ctx);break;
|
||||
default:break;
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
|
||||
{
|
||||
/* TODO not even in your dreams */
|
||||
}
|
||||
|
||||
static void nv04LineWidth(GLcontext *ctx, GLfloat width)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04LogicOpcode(GLcontext *ctx, GLenum opcode)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04PointSize(GLcontext *ctx, GLfloat size)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void nv04PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/** Set the scale and units used to calculate depth values */
|
||||
static void nv04PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/** Set the polygon stippling pattern */
|
||||
static void nv04PolygonStipple(GLcontext *ctx, const GLubyte *mask )
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Specifies the current buffer for reading */
|
||||
void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
|
||||
/** Set rasterization mode */
|
||||
void (*RenderMode)(GLcontext *ctx, GLenum mode );
|
||||
|
||||
/** Define the scissor box */
|
||||
static void nv04Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/** Select flat or smooth shading */
|
||||
static void nv04ShadeModel(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
nv04_emit_blend(ctx);
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilFunc */
|
||||
static void nv04StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
|
||||
GLint ref, GLuint mask)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilMask */
|
||||
static void nv04StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilOp */
|
||||
static void nv04StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
|
||||
GLenum zfail, GLenum zpass)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/** Control the generation of texture coordinates */
|
||||
void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
|
||||
const GLfloat *params);
|
||||
/** Set texture environment parameters */
|
||||
void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
|
||||
const GLfloat *param);
|
||||
/** Set texture parameters */
|
||||
void (*TexParameter)(GLcontext *ctx, GLenum target,
|
||||
struct gl_texture_object *texObj,
|
||||
GLenum pname, const GLfloat *params);
|
||||
|
||||
/* Update anything that depends on the window position/size */
|
||||
static void nv04WindowMoved(nouveauContextPtr nmesa)
|
||||
{
|
||||
}
|
||||
|
||||
/* Initialise any card-specific non-GL related state */
|
||||
static GLboolean nv04InitCard(nouveauContextPtr nmesa)
|
||||
{
|
||||
nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
|
||||
nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf3D, NvCtxSurf3D);
|
||||
|
||||
BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3);
|
||||
OUT_RING(NvDmaFB);
|
||||
OUT_RING(NvDmaFB);
|
||||
OUT_RING(NvDmaFB);
|
||||
BEGIN_RING_SIZE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_SURFACE, 1);
|
||||
OUT_RING(NvCtxSurf3D);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Update buffer offset/pitch/format */
|
||||
static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color,
|
||||
nouveau_renderbuffer_t **color,
|
||||
nouveau_renderbuffer_t *depth)
|
||||
{
|
||||
GLuint x, y, w, h;
|
||||
uint32_t depth_pitch=(depth?depth->pitch:0+15)&~15+16;
|
||||
if (depth_pitch<256) depth_pitch=256;
|
||||
|
||||
w = color[0]->mesa.Width;
|
||||
h = color[0]->mesa.Height;
|
||||
x = nmesa->drawX;
|
||||
y = nmesa->drawY;
|
||||
|
||||
BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
|
||||
if (color[0]->mesa._ActualFormat == GL_RGBA8)
|
||||
OUT_RING(0x108/*A8R8G8B8*/);
|
||||
else
|
||||
OUT_RING(0x103/*R5G6B5*/);
|
||||
|
||||
/* FIXME pitches have to be aligned ! */
|
||||
BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
|
||||
OUT_RING(color[0]->pitch|(depth_pitch<<16));
|
||||
OUT_RING(color[0]->offset);
|
||||
if (depth) {
|
||||
BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
|
||||
OUT_RING(depth->offset);
|
||||
}
|
||||
|
||||
// BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2);
|
||||
// OUT_RING((w<<16)|x);
|
||||
// OUT_RING((h<<16)|y);
|
||||
|
||||
|
||||
/* FIXME not sure... */
|
||||
/* BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_SIZE, 1);
|
||||
OUT_RING((h<<16)|w);*/
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
func->AlphaFunc = nv04AlphaFunc;
|
||||
func->BlendColor = nv04BlendColor;
|
||||
func->BlendEquationSeparate = nv04BlendEquationSeparate;
|
||||
func->BlendFuncSeparate = nv04BlendFuncSeparate;
|
||||
func->Clear = nv04Clear;
|
||||
func->ClearColor = nv04ClearColor;
|
||||
func->ClearDepth = nv04ClearDepth;
|
||||
func->ClearStencil = nv04ClearStencil;
|
||||
func->ClipPlane = nv04ClipPlane;
|
||||
func->ColorMask = nv04ColorMask;
|
||||
func->ColorMaterial = nv04ColorMaterial;
|
||||
func->CullFace = nv04CullFace;
|
||||
func->FrontFace = nv04FrontFace;
|
||||
func->DepthFunc = nv04DepthFunc;
|
||||
func->DepthMask = nv04DepthMask;
|
||||
func->DepthRange = nv04DepthRange;
|
||||
func->Enable = nv04Enable;
|
||||
func->Fogfv = nv04Fogfv;
|
||||
func->Hint = nv04Hint;
|
||||
/* func->Lightfv = nv04Lightfv;*/
|
||||
/* func->LightModelfv = nv04LightModelfv; */
|
||||
func->LineStipple = nv04LineStipple; /* Not for NV04 */
|
||||
func->LineWidth = nv04LineWidth;
|
||||
func->LogicOpcode = nv04LogicOpcode;
|
||||
func->PointParameterfv = nv04PointParameterfv;
|
||||
func->PointSize = nv04PointSize;
|
||||
func->PolygonMode = nv04PolygonMode;
|
||||
func->PolygonOffset = nv04PolygonOffset;
|
||||
func->PolygonStipple = nv04PolygonStipple; /* Not for NV04 */
|
||||
/* func->ReadBuffer = nv04ReadBuffer;*/
|
||||
/* func->RenderMode = nv04RenderMode;*/
|
||||
func->Scissor = nv04Scissor;
|
||||
func->ShadeModel = nv04ShadeModel;
|
||||
func->StencilFuncSeparate = nv04StencilFuncSeparate;
|
||||
func->StencilMaskSeparate = nv04StencilMaskSeparate;
|
||||
func->StencilOpSeparate = nv04StencilOpSeparate;
|
||||
/* func->TexGen = nv04TexGen;*/
|
||||
/* func->TexParameter = nv04TexParameter;*/
|
||||
/* func->TextureMatrix = nv04TextureMatrix;*/
|
||||
|
||||
nmesa->hw_func.InitCard = nv04InitCard;
|
||||
nmesa->hw_func.BindBuffers = nv04BindBuffers;
|
||||
nmesa->hw_func.WindowMoved = nv04WindowMoved;
|
||||
}
|
||||
|
|
@ -1,619 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 Stephane Marchesin. All Rights Reserved.
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
|
||||
*/
|
||||
|
||||
/* Software TCL for NV04, NV05, NV06 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "context.h"
|
||||
#include "mtypes.h"
|
||||
#include "macros.h"
|
||||
#include "colormac.h"
|
||||
#include "enums.h"
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "tnl/t_context.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "nouveau_swtcl.h"
|
||||
#include "nv04_swtcl.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_span.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_tex.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_object.h"
|
||||
|
||||
static void nv04RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
|
||||
static void nv04RenderPrimitive( GLcontext *ctx, GLenum prim );
|
||||
static void nv04ResetLineStipple( GLcontext *ctx );
|
||||
|
||||
|
||||
static INLINE void nv04_2triangles(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3,nouveauVertex* v4,nouveauVertex* v5)
|
||||
{
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49);
|
||||
OUT_RINGp(v0,8);
|
||||
OUT_RINGp(v1,8);
|
||||
OUT_RINGp(v2,8);
|
||||
OUT_RINGp(v3,8);
|
||||
OUT_RINGp(v4,8);
|
||||
OUT_RINGp(v5,8);
|
||||
OUT_RING(0xFEDCBA);
|
||||
}
|
||||
|
||||
static INLINE void nv04_1triangle(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2)
|
||||
{
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25);
|
||||
OUT_RINGp(v0,8);
|
||||
OUT_RINGp(v1,8);
|
||||
OUT_RINGp(v2,8);
|
||||
OUT_RING(0xFED);
|
||||
}
|
||||
|
||||
static INLINE void nv04_1quad(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3)
|
||||
{
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33);
|
||||
OUT_RINGp(v0,8);
|
||||
OUT_RINGp(v1,8);
|
||||
OUT_RINGp(v2,8);
|
||||
OUT_RINGp(v3,8);
|
||||
OUT_RING(0xFECEDC);
|
||||
}
|
||||
|
||||
static INLINE void nv04_render_points(GLcontext *ctx,GLuint first,GLuint last)
|
||||
{
|
||||
WARN_ONCE("Unimplemented\n");
|
||||
}
|
||||
|
||||
static INLINE void nv04_render_line(GLcontext *ctx,GLuint v1,GLuint v2)
|
||||
{
|
||||
WARN_ONCE("Unimplemented\n");
|
||||
}
|
||||
|
||||
static INLINE void nv04_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
|
||||
nv04_1triangle(nmesa,
|
||||
(nouveauVertex*)(vertptr+v1*vertsize),
|
||||
(nouveauVertex*)(vertptr+v2*vertsize),
|
||||
(nouveauVertex*)(vertptr+v3*vertsize)
|
||||
);
|
||||
}
|
||||
|
||||
static INLINE void nv04_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
|
||||
nv04_1quad(nmesa,
|
||||
(nouveauVertex*)(vertptr+v1*vertsize),
|
||||
(nouveauVertex*)(vertptr+v2*vertsize),
|
||||
(nouveauVertex*)(vertptr+v3*vertsize),
|
||||
(nouveauVertex*)(vertptr+v4*vertsize)
|
||||
);
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Render unclipped begin/end objects */
|
||||
/**********************************************************************/
|
||||
|
||||
static void nv04_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
// erm
|
||||
}
|
||||
|
||||
static void nv04_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
// umm
|
||||
}
|
||||
|
||||
static void nv04_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
// yeah
|
||||
}
|
||||
|
||||
static void nv04_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
// right
|
||||
}
|
||||
|
||||
static void nv04_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
int i;
|
||||
|
||||
for(i=start;i<count-5;i+=6)
|
||||
nv04_2triangles(nmesa,
|
||||
(nouveauVertex*)(vertptr+(i+0)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+1)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+2)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+3)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+4)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+5)*vertsize)
|
||||
);
|
||||
if (i!=count)
|
||||
{
|
||||
nv04_1triangle(nmesa,
|
||||
(nouveauVertex*)(vertptr+(i+0)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+1)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+2)*vertsize)
|
||||
);
|
||||
i+=3;
|
||||
}
|
||||
if (i!=count)
|
||||
printf("oops\n");
|
||||
}
|
||||
|
||||
static void nv04_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC};
|
||||
int i,j;
|
||||
|
||||
for(i=start;i<count;i+=14)
|
||||
{
|
||||
int numvert=MIN2(16,count-i);
|
||||
int numtri=numvert-2;
|
||||
if (numvert<3)
|
||||
break;
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),numvert*8);
|
||||
for(j=0;j<numvert;j++)
|
||||
OUT_RINGp((nouveauVertex*)(vertptr+(i+j)*vertsize),8);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
|
||||
for(j=0;j<numtri/2;j++)
|
||||
OUT_RING(striptbl[j]);
|
||||
if (numtri%2)
|
||||
OUT_RING(striptbl[numtri/2]&0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0};
|
||||
int i,j;
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8);
|
||||
OUT_RINGp((nouveauVertex*)(vertptr+start*vertsize),8);
|
||||
|
||||
for(i=start+1;i<count;i+=14)
|
||||
{
|
||||
int numvert=MIN2(15,count-i);
|
||||
int numtri=numvert-1;
|
||||
if (numvert<3)
|
||||
break;
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1),numvert*8);
|
||||
|
||||
for(j=0;j<numvert;j++)
|
||||
OUT_RINGp((nouveauVertex*)(vertptr+(i+j)*vertsize),8);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
|
||||
for(j=0;j<numtri/2;j++)
|
||||
OUT_RING(fantbl[j]);
|
||||
if (numtri%2)
|
||||
OUT_RING(fantbl[numtri/2]&0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
int i;
|
||||
|
||||
for(i=start;i<count;i+=4)
|
||||
nv04_1quad(nmesa,
|
||||
(nouveauVertex*)(vertptr+(i+0)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+1)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+2)*vertsize),
|
||||
(nouveauVertex*)(vertptr+(i+3)*vertsize)
|
||||
);
|
||||
}
|
||||
|
||||
static void nv04_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void (*nv04_render_tab_verts[GL_POLYGON+2])(GLcontext *,
|
||||
GLuint,
|
||||
GLuint,
|
||||
GLuint) =
|
||||
{
|
||||
nv04_render_points_verts,
|
||||
nv04_render_lines_verts,
|
||||
nv04_render_line_loop_verts,
|
||||
nv04_render_line_strip_verts,
|
||||
nv04_render_triangles_verts,
|
||||
nv04_render_tri_strip_verts,
|
||||
nv04_render_tri_fan_verts,
|
||||
nv04_render_quads_verts,
|
||||
nv04_render_tri_strip_verts, //nv04_render_quad_strip_verts
|
||||
nv04_render_tri_fan_verts, //nv04_render_poly_verts
|
||||
nv04_render_noop_verts,
|
||||
};
|
||||
|
||||
|
||||
static void nv04_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
// erm
|
||||
}
|
||||
|
||||
static void nv04_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
// umm
|
||||
}
|
||||
|
||||
static void nv04_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
// yeah
|
||||
}
|
||||
|
||||
static void nv04_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
// right
|
||||
}
|
||||
|
||||
static void nv04_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
|
||||
int i;
|
||||
|
||||
for(i=start;i<count-5;i+=6)
|
||||
nv04_2triangles(nmesa,
|
||||
(nouveauVertex*)(vertptr+elt[i+0]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+1]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+2]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+3]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+4]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+5]*vertsize)
|
||||
);
|
||||
if (i!=count)
|
||||
{
|
||||
nv04_1triangle(nmesa,
|
||||
(nouveauVertex*)(vertptr+elt[i+0]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+1]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+2]*vertsize)
|
||||
);
|
||||
i+=3;
|
||||
}
|
||||
if (i!=count)
|
||||
printf("oops\n");
|
||||
}
|
||||
|
||||
static void nv04_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC};
|
||||
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
|
||||
int i,j;
|
||||
|
||||
for(i=start;i<count;i+=14)
|
||||
{
|
||||
int numvert=MIN2(16,count-i);
|
||||
int numtri=numvert-2;
|
||||
if (numvert<3)
|
||||
break;
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),numvert*8);
|
||||
for(j=0;j<numvert;j++)
|
||||
OUT_RINGp((nouveauVertex*)(vertptr+elt[i+j]*vertsize),8);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
|
||||
for(j=0;j<numtri/2;j++)
|
||||
OUT_RING(striptbl[j]);
|
||||
if (numtri%2)
|
||||
OUT_RING(striptbl[numtri/2]&0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0};
|
||||
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
|
||||
int i,j;
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8);
|
||||
OUT_RINGp((nouveauVertex*)(vertptr+elt[start]*vertsize),8);
|
||||
|
||||
for(i=start+1;i<count;i+=14)
|
||||
{
|
||||
int numvert=MIN2(15,count-i);
|
||||
int numtri=numvert-2;
|
||||
if (numvert<3)
|
||||
break;
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1),numvert*8);
|
||||
|
||||
for(j=0;j<numvert;j++)
|
||||
OUT_RINGp((nouveauVertex*)(vertptr+elt[i+j]*vertsize),8);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_DRAW|NONINC_METHOD,(numtri+1)/2);
|
||||
for(j=0;j<numtri/2;j++)
|
||||
OUT_RING(fantbl[j]);
|
||||
if (numtri%2)
|
||||
OUT_RING(fantbl[numtri/2]&0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte *vertptr = (GLubyte *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
|
||||
int i;
|
||||
|
||||
for(i=start;i<count;i+=4)
|
||||
nv04_1quad(nmesa,
|
||||
(nouveauVertex*)(vertptr+elt[i+0]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+1]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+2]*vertsize),
|
||||
(nouveauVertex*)(vertptr+elt[i+3]*vertsize)
|
||||
);
|
||||
}
|
||||
|
||||
static void nv04_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void (*nv04_render_tab_elts[GL_POLYGON+2])(GLcontext *,
|
||||
GLuint,
|
||||
GLuint,
|
||||
GLuint) =
|
||||
{
|
||||
nv04_render_points_elts,
|
||||
nv04_render_lines_elts,
|
||||
nv04_render_line_loop_elts,
|
||||
nv04_render_line_strip_elts,
|
||||
nv04_render_triangles_elts,
|
||||
nv04_render_tri_strip_elts,
|
||||
nv04_render_tri_fan_elts,
|
||||
nv04_render_quads_elts,
|
||||
nv04_render_tri_strip_elts, // nv04_render_quad_strip_elts,
|
||||
nv04_render_tri_fan_elts, // nv04_render_poly_elts,
|
||||
nv04_render_noop_elts,
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Choose render functions */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
#define EMIT_ATTR( ATTR, STYLE ) \
|
||||
do { \
|
||||
nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \
|
||||
nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \
|
||||
nmesa->vertex_attr_count++; \
|
||||
} while (0)
|
||||
|
||||
#define EMIT_PAD( N ) \
|
||||
do { \
|
||||
nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = 0; \
|
||||
nmesa->vertex_attrs[nmesa->vertex_attr_count].format = EMIT_PAD; \
|
||||
nmesa->vertex_attrs[nmesa->vertex_attr_count].offset = (N); \
|
||||
nmesa->vertex_attr_count++; \
|
||||
} while (0)
|
||||
|
||||
static void nv04_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj)
|
||||
{
|
||||
}
|
||||
|
||||
static void nv04_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n)
|
||||
{
|
||||
}
|
||||
|
||||
static void nv04ChooseRenderState(GLcontext *ctx)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
|
||||
tnl->Driver.Render.PrimTabVerts = nv04_render_tab_verts;
|
||||
tnl->Driver.Render.PrimTabElts = nv04_render_tab_elts;
|
||||
tnl->Driver.Render.ClippedLine = nv04_render_clipped_line;
|
||||
tnl->Driver.Render.ClippedPolygon = nv04_render_clipped_poly;
|
||||
tnl->Driver.Render.Points = nv04_render_points;
|
||||
tnl->Driver.Render.Line = nv04_render_line;
|
||||
tnl->Driver.Render.Triangle = nv04_render_triangle;
|
||||
tnl->Driver.Render.Quad = nv04_render_quad;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static INLINE void nv04OutputVertexFormat(struct nouveau_context* nmesa)
|
||||
{
|
||||
GLcontext* ctx=nmesa->glCtx;
|
||||
DECLARE_RENDERINPUTS(index);
|
||||
|
||||
/*
|
||||
* Tell t_vertex about the vertex format
|
||||
*/
|
||||
nmesa->vertex_attr_count = 0;
|
||||
RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
|
||||
|
||||
// SX SY SZ INVW
|
||||
// FIXME : we use W instead of INVW, but since W=1 it doesn't matter
|
||||
if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_POS))
|
||||
EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_4F_VIEWPORT);
|
||||
else
|
||||
EMIT_PAD(4*sizeof(float));
|
||||
|
||||
// COLOR
|
||||
if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR0))
|
||||
EMIT_ATTR(_TNL_ATTRIB_COLOR0,EMIT_4UB_4F_ABGR);
|
||||
else
|
||||
EMIT_PAD(4);
|
||||
|
||||
// SPECULAR
|
||||
if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR1))
|
||||
EMIT_ATTR(_TNL_ATTRIB_COLOR1,EMIT_4UB_4F_ABGR);
|
||||
else
|
||||
EMIT_PAD(4);
|
||||
|
||||
// TEXTURE
|
||||
if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_TEX0))
|
||||
EMIT_ATTR(_TNL_ATTRIB_TEX0,EMIT_2F);
|
||||
else
|
||||
EMIT_PAD(2*sizeof(float));
|
||||
|
||||
nmesa->vertex_size=_tnl_install_attrs( ctx,
|
||||
nmesa->vertex_attrs,
|
||||
nmesa->vertex_attr_count,
|
||||
nmesa->viewport.m, 0 );
|
||||
}
|
||||
|
||||
|
||||
static void nv04ChooseVertexState( GLcontext *ctx )
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
DECLARE_RENDERINPUTS(index);
|
||||
|
||||
RENDERINPUTS_COPY(index, tnl->render_inputs_bitset);
|
||||
if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset))
|
||||
{
|
||||
RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index);
|
||||
nv04OutputVertexFormat(nmesa);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* High level hooks for t_vb_render.c */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
static void nv04RenderStart(GLcontext *ctx)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (nmesa->new_state) {
|
||||
nmesa->new_render_state |= nmesa->new_state;
|
||||
}
|
||||
|
||||
if (nmesa->new_render_state) {
|
||||
nv04ChooseVertexState(ctx);
|
||||
nv04ChooseRenderState(ctx);
|
||||
nmesa->new_render_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04RenderFinish(GLcontext *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* System to flush dma and emit state changes based on the rasterized
|
||||
* primitive.
|
||||
*/
|
||||
void nv04RasterPrimitive(GLcontext *ctx,
|
||||
GLenum glprim,
|
||||
GLuint hwprim)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
assert (!nmesa->new_state);
|
||||
|
||||
if (hwprim != nmesa->current_primitive)
|
||||
{
|
||||
nmesa->current_primitive=hwprim;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static const GLuint hw_prim[GL_POLYGON+1] = {
|
||||
GL_POINTS+1,
|
||||
GL_LINES+1,
|
||||
GL_LINE_STRIP+1,
|
||||
GL_LINE_LOOP+1,
|
||||
GL_TRIANGLES+1,
|
||||
GL_TRIANGLE_STRIP+1,
|
||||
GL_TRIANGLE_FAN+1,
|
||||
GL_QUADS+1,
|
||||
GL_QUAD_STRIP+1,
|
||||
GL_POLYGON+1
|
||||
};
|
||||
|
||||
/* Callback for mesa:
|
||||
*/
|
||||
static void nv04RenderPrimitive( GLcontext *ctx, GLuint prim )
|
||||
{
|
||||
nv04RasterPrimitive( ctx, prim, hw_prim[prim] );
|
||||
}
|
||||
|
||||
static void nv04ResetLineStipple( GLcontext *ctx )
|
||||
{
|
||||
/* FIXME do something here */
|
||||
WARN_ONCE("Unimplemented nv04ResetLineStipple\n");
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Initialization. */
|
||||
/**********************************************************************/
|
||||
|
||||
void nv04TriInitFunctions(GLcontext *ctx)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
|
||||
tnl->Driver.RunPipeline = nouveauRunPipeline;
|
||||
tnl->Driver.Render.Start = nv04RenderStart;
|
||||
tnl->Driver.Render.Finish = nv04RenderFinish;
|
||||
tnl->Driver.Render.PrimitiveNotify = nv04RenderPrimitive;
|
||||
tnl->Driver.Render.ResetLineStipple = nv04ResetLineStipple;
|
||||
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
|
||||
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
|
||||
tnl->Driver.Render.Interp = _tnl_interp;
|
||||
|
||||
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 32 );
|
||||
|
||||
nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef __NV04_SWTCL_H__
|
||||
#define __NV04_SWTCL_H__
|
||||
|
||||
#include "mtypes.h"
|
||||
|
||||
extern void nv04Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
|
||||
extern void nv04FinishPrimitive(struct nouveau_context *nmesa);
|
||||
extern void nv04TriInitFunctions(GLcontext *ctx);
|
||||
#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode )
|
||||
|
||||
#endif /* __NV04_SWTCL_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,714 +0,0 @@
|
|||
/*
|
||||
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
|
||||
* Copyright 2006 Stephane Marchesin. All Rights Reserved.
|
||||
*
|
||||
* 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, sub license,
|
||||
* 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
|
||||
*/
|
||||
|
||||
/* Software TCL for NV10, NV20, NV30, NV40, NV50 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "context.h"
|
||||
#include "mtypes.h"
|
||||
#include "macros.h"
|
||||
#include "colormac.h"
|
||||
#include "enums.h"
|
||||
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "tnl/t_context.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "nouveau_swtcl.h"
|
||||
#include "nv10_swtcl.h"
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_span.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_tex.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_object.h"
|
||||
|
||||
static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
|
||||
static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim );
|
||||
static void nv10ResetLineStipple( GLcontext *ctx );
|
||||
|
||||
static const int default_attr_size[8]={3,3,3,4,3,1,4,4};
|
||||
|
||||
/* Mesa requires us to put pos attribute as the first attribute of the
|
||||
* vertex, but on NV10 it is the last attribute.
|
||||
* To fix that we put the pos attribute first, and we swap the pos
|
||||
* attribute before sending it to the card.
|
||||
* Speed cost of the swap seems negligeable
|
||||
*/
|
||||
#if 0
|
||||
/* old stuff where pos attribute isn't put first for mesa.
|
||||
* Usefull for speed comparaison
|
||||
*/
|
||||
#define INV_VERT(i) i
|
||||
#define OUT_RING_VERTp(nmesa, ptr,sz, vertex_size) OUT_RINGp(ptr,sz)
|
||||
#define OUT_RING_VERT(nmesa, ptr, vertex_size) OUT_RINGp(ptr,vertex_size)
|
||||
#else
|
||||
|
||||
#define INV_VERT(i) (i==0?7:i-1)
|
||||
|
||||
#define OUT_RING_VERT_RAW(ptr,vertex_size) do{ \
|
||||
/* if the vertex size is not null, we have at least pos attribute */ \
|
||||
OUT_RINGp((GLfloat *)(ptr) + default_attr_size[_TNL_ATTRIB_POS], (vertex_size) - default_attr_size[_TNL_ATTRIB_POS]); \
|
||||
OUT_RINGp((GLfloat *)(ptr), default_attr_size[_TNL_ATTRIB_POS]); \
|
||||
}while(0)
|
||||
|
||||
#define OUT_RING_VERT(nmesa,ptr,vertex_size) do{ \
|
||||
if (nmesa->screen->card->type>=NV_20) \
|
||||
OUT_RINGp(ptr, vertex_size); \
|
||||
else \
|
||||
OUT_RING_VERT_RAW(ptr, vertex_size); \
|
||||
}while(0)
|
||||
|
||||
|
||||
#define OUT_RING_VERTp(nmesa, ptr,sz, vertex_size) do{ \
|
||||
int nb_vert; \
|
||||
if (nmesa->screen->card->type>=NV_20) \
|
||||
OUT_RINGp(ptr, sz); \
|
||||
else \
|
||||
for (nb_vert = 0; nb_vert < (sz)/(vertex_size); nb_vert++) { \
|
||||
OUT_RING_VERT_RAW((GLfloat*)(ptr)+nb_vert*(vertex_size), vertex_size); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static INLINE void nv10StartPrimitive(struct nouveau_context* nmesa,GLuint primitive,GLuint size)
|
||||
{
|
||||
if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17))
|
||||
BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1);
|
||||
else if (nmesa->screen->card->type==NV_20)
|
||||
BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1);
|
||||
else
|
||||
BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
|
||||
OUT_RING(primitive);
|
||||
|
||||
if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17))
|
||||
BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA|NONINC_METHOD,size);
|
||||
else if (nmesa->screen->card->type==NV_20)
|
||||
BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size);
|
||||
else
|
||||
BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size);
|
||||
}
|
||||
|
||||
void nv10FinishPrimitive(struct nouveau_context *nmesa)
|
||||
{
|
||||
if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17))
|
||||
BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1);
|
||||
else if (nmesa->screen->card->type==NV_20)
|
||||
BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1);
|
||||
else
|
||||
BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1);
|
||||
OUT_RING(0x0);
|
||||
FIRE_RING();
|
||||
}
|
||||
|
||||
|
||||
static INLINE void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size)
|
||||
{
|
||||
/* make sure there's enough room. if not, wait */
|
||||
if (RING_AVAILABLE()<size)
|
||||
{
|
||||
WAIT_RING(nmesa,size);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Render unclipped begin/end objects */
|
||||
/**********************************************************************/
|
||||
|
||||
static INLINE void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLfloat *vertptr = (GLfloat *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
GLuint size_dword = vertsize*(count-start);
|
||||
|
||||
nv10ExtendPrimitive(nmesa, size_dword);
|
||||
nv10StartPrimitive(nmesa,prim+1,size_dword);
|
||||
OUT_RING_VERTp(nmesa, (nouveauVertex*)(vertptr+(start*vertsize)),size_dword, vertsize);
|
||||
nv10FinishPrimitive(nmesa);
|
||||
}
|
||||
|
||||
static void nv10_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POINTS);
|
||||
}
|
||||
|
||||
static void nv10_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINES);
|
||||
}
|
||||
|
||||
static void nv10_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_STRIP);
|
||||
}
|
||||
|
||||
static void nv10_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_LOOP);
|
||||
}
|
||||
|
||||
static void nv10_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLES);
|
||||
}
|
||||
|
||||
static void nv10_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
static void nv10_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_FAN);
|
||||
}
|
||||
|
||||
static void nv10_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUADS);
|
||||
}
|
||||
|
||||
static void nv10_render_quad_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUAD_STRIP);
|
||||
}
|
||||
|
||||
static void nv10_render_poly_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POLYGON);
|
||||
}
|
||||
|
||||
static void nv10_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void (*nv10_render_tab_verts[GL_POLYGON+2])(GLcontext *,
|
||||
GLuint,
|
||||
GLuint,
|
||||
GLuint) =
|
||||
{
|
||||
nv10_render_points_verts,
|
||||
nv10_render_lines_verts,
|
||||
nv10_render_line_loop_verts,
|
||||
nv10_render_line_strip_verts,
|
||||
nv10_render_triangles_verts,
|
||||
nv10_render_tri_strip_verts,
|
||||
nv10_render_tri_fan_verts,
|
||||
nv10_render_quads_verts,
|
||||
nv10_render_quad_strip_verts,
|
||||
nv10_render_poly_verts,
|
||||
nv10_render_noop_verts,
|
||||
};
|
||||
|
||||
|
||||
static INLINE void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLfloat *vertptr = (GLfloat *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
GLuint size_dword = vertsize*(count-start);
|
||||
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;
|
||||
GLuint j;
|
||||
|
||||
nv10ExtendPrimitive(nmesa, size_dword);
|
||||
nv10StartPrimitive(nmesa,prim+1,size_dword);
|
||||
for (j=start; j<count; j++ ) {
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(elt[j]*vertsize)),vertsize);
|
||||
}
|
||||
nv10FinishPrimitive(nmesa);
|
||||
}
|
||||
|
||||
static void nv10_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POINTS);
|
||||
}
|
||||
|
||||
static void nv10_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINES);
|
||||
}
|
||||
|
||||
static void nv10_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_STRIP);
|
||||
}
|
||||
|
||||
static void nv10_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_LOOP);
|
||||
}
|
||||
|
||||
static void nv10_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLES);
|
||||
}
|
||||
|
||||
static void nv10_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
static void nv10_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_FAN);
|
||||
}
|
||||
|
||||
static void nv10_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUADS);
|
||||
}
|
||||
|
||||
static void nv10_render_quad_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUAD_STRIP);
|
||||
}
|
||||
|
||||
static void nv10_render_poly_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POLYGON);
|
||||
}
|
||||
|
||||
static void nv10_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags)
|
||||
{
|
||||
}
|
||||
|
||||
static void (*nv10_render_tab_elts[GL_POLYGON+2])(GLcontext *,
|
||||
GLuint,
|
||||
GLuint,
|
||||
GLuint) =
|
||||
{
|
||||
nv10_render_points_elts,
|
||||
nv10_render_lines_elts,
|
||||
nv10_render_line_loop_elts,
|
||||
nv10_render_line_strip_elts,
|
||||
nv10_render_triangles_elts,
|
||||
nv10_render_tri_strip_elts,
|
||||
nv10_render_tri_fan_elts,
|
||||
nv10_render_quads_elts,
|
||||
nv10_render_quad_strip_elts,
|
||||
nv10_render_poly_elts,
|
||||
nv10_render_noop_elts,
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Choose render functions */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
#define EMIT_ATTR( ATTR, STYLE ) \
|
||||
do { \
|
||||
nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \
|
||||
nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \
|
||||
nmesa->vertex_attr_count++; \
|
||||
} while (0)
|
||||
|
||||
static INLINE void nv10_render_point(GLcontext *ctx, GLfloat *vertptr)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
GLuint size_dword = vertsize;
|
||||
|
||||
nv10ExtendPrimitive(nmesa, size_dword);
|
||||
nv10StartPrimitive(nmesa,GL_POINTS+1,size_dword);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr),vertsize);
|
||||
nv10FinishPrimitive(nmesa);
|
||||
}
|
||||
|
||||
static INLINE void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last)
|
||||
{
|
||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLfloat *vertptr = (GLfloat *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
GLuint i;
|
||||
|
||||
if (VB->Elts) {
|
||||
for (i = first; i < last; i++)
|
||||
if (VB->ClipMask[VB->Elts[i]] == 0)
|
||||
nv10_render_point(ctx, vertptr + (VB->Elts[i]*vertsize));
|
||||
}
|
||||
else {
|
||||
for (i = first; i < last; i++)
|
||||
if (VB->ClipMask[i] == 0)
|
||||
nv10_render_point(ctx, vertptr + (i*vertsize));
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLfloat *vertptr = (GLfloat *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
GLuint size_dword = vertsize*2;
|
||||
|
||||
nv10ExtendPrimitive(nmesa, size_dword);
|
||||
nv10StartPrimitive(nmesa,GL_LINES+1,size_dword);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
|
||||
nv10FinishPrimitive(nmesa);
|
||||
}
|
||||
|
||||
static INLINE void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLfloat *vertptr = (GLfloat *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
GLuint size_dword = vertsize*3;
|
||||
|
||||
nv10ExtendPrimitive(nmesa, size_dword);
|
||||
nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v3*vertsize)),vertsize);
|
||||
nv10FinishPrimitive(nmesa);
|
||||
}
|
||||
|
||||
static INLINE void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLfloat *vertptr = (GLfloat *)nmesa->verts;
|
||||
GLuint vertsize = nmesa->vertex_size;
|
||||
GLuint size_dword = vertsize*4;
|
||||
|
||||
nv10ExtendPrimitive(nmesa, size_dword);
|
||||
nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v1*vertsize)),vertsize);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v2*vertsize)),vertsize);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v3*vertsize)),vertsize);
|
||||
OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr+(v4*vertsize)),vertsize);
|
||||
nv10FinishPrimitive(nmesa);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void nv10ChooseRenderState(GLcontext *ctx)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts;
|
||||
tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts;
|
||||
tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
|
||||
tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
|
||||
tnl->Driver.Render.Points = nv10_render_points;
|
||||
tnl->Driver.Render.Line = nv10_render_line;
|
||||
tnl->Driver.Render.Triangle = nv10_render_triangle;
|
||||
tnl->Driver.Render.Quad = nv10_render_quad;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static INLINE void nv10OutputVertexFormat(struct nouveau_context* nmesa)
|
||||
{
|
||||
GLcontext* ctx=nmesa->glCtx;
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
DECLARE_RENDERINPUTS(index);
|
||||
struct vertex_buffer *VB = &tnl->vb;
|
||||
int attr_size[16];
|
||||
const int nv10_vtx_attribs[8]={
|
||||
_TNL_ATTRIB_FOG, _TNL_ATTRIB_WEIGHT,
|
||||
_TNL_ATTRIB_NORMAL, _TNL_ATTRIB_TEX1,
|
||||
_TNL_ATTRIB_TEX0, _TNL_ATTRIB_COLOR1,
|
||||
_TNL_ATTRIB_COLOR0, _TNL_ATTRIB_POS
|
||||
};
|
||||
int i;
|
||||
int slots=0;
|
||||
int total_size=0;
|
||||
|
||||
nmesa->vertex_attr_count = 0;
|
||||
RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
|
||||
|
||||
/*
|
||||
* Determine attribute sizes
|
||||
*/
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
if (RENDERINPUTS_TEST(index, i))
|
||||
attr_size[i]=default_attr_size[i];
|
||||
else
|
||||
attr_size[i]=0;
|
||||
}
|
||||
for(i=8;i<16;i++)
|
||||
{
|
||||
if (RENDERINPUTS_TEST(index, i))
|
||||
attr_size[i]=VB->TexCoordPtr[i-8]->size;
|
||||
else
|
||||
attr_size[i]=0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell t_vertex about the vertex format
|
||||
*/
|
||||
if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) {
|
||||
for(i=0;i<8;i++) {
|
||||
int j = nv10_vtx_attribs[INV_VERT(i)];
|
||||
if (RENDERINPUTS_TEST(index, j)) {
|
||||
switch(attr_size[j])
|
||||
{
|
||||
case 1:
|
||||
EMIT_ATTR(j,EMIT_1F);
|
||||
break;
|
||||
case 2:
|
||||
EMIT_ATTR(j,EMIT_2F);
|
||||
break;
|
||||
case 3:
|
||||
EMIT_ATTR(j,EMIT_3F);
|
||||
break;
|
||||
case 4:
|
||||
EMIT_ATTR(j,EMIT_4F);
|
||||
break;
|
||||
}
|
||||
total_size+=attr_size[j];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(i=0;i<16;i++)
|
||||
{
|
||||
if (RENDERINPUTS_TEST(index, i))
|
||||
{
|
||||
slots=i+1;
|
||||
switch(attr_size[i])
|
||||
{
|
||||
case 1:
|
||||
EMIT_ATTR(i,EMIT_1F);
|
||||
break;
|
||||
case 2:
|
||||
EMIT_ATTR(i,EMIT_2F);
|
||||
break;
|
||||
case 3:
|
||||
EMIT_ATTR(i,EMIT_3F);
|
||||
break;
|
||||
case 4:
|
||||
EMIT_ATTR(i,EMIT_4F);
|
||||
break;
|
||||
}
|
||||
if (i==_TNL_ATTRIB_COLOR0)
|
||||
nmesa->color_offset=total_size;
|
||||
if (i==_TNL_ATTRIB_COLOR1)
|
||||
nmesa->specular_offset=total_size;
|
||||
total_size+=attr_size[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nmesa->vertex_size=_tnl_install_attrs( ctx,
|
||||
nmesa->vertex_attrs,
|
||||
nmesa->vertex_attr_count,
|
||||
NULL, 0 );
|
||||
/* OUT_RINGp wants size in DWORDS */
|
||||
nmesa->vertex_size = nmesa->vertex_size / 4;
|
||||
assert(nmesa->vertex_size==total_size);
|
||||
|
||||
/*
|
||||
* Tell the hardware about the vertex format
|
||||
*/
|
||||
if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) {
|
||||
int total_stride = 0;
|
||||
|
||||
#define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2
|
||||
|
||||
for(i=0;i<8;i++) {
|
||||
int j = nv10_vtx_attribs[i];
|
||||
int size;
|
||||
int stride = attr_size[j] << 2;
|
||||
if (j==_TNL_ATTRIB_POS) {
|
||||
stride += total_stride;
|
||||
}
|
||||
size = attr_size[j] << 4;
|
||||
size |= stride << 8;
|
||||
size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT;
|
||||
BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR((7-i)),1);
|
||||
OUT_RING_CACHE(size);
|
||||
total_stride += stride;
|
||||
}
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1);
|
||||
OUT_RING_CACHE(0);
|
||||
} else if (nmesa->screen->card->type==NV_20) {
|
||||
for(i=0;i<16;i++)
|
||||
{
|
||||
int size=attr_size[i];
|
||||
BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1);
|
||||
OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
|
||||
}
|
||||
} else {
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1);
|
||||
OUT_RING(0);
|
||||
BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR8_TX0,slots);
|
||||
for(i=0;i<slots;i++)
|
||||
{
|
||||
int size=attr_size[i];
|
||||
OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10));
|
||||
}
|
||||
// FIXME this is probably not needed
|
||||
BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
|
||||
OUT_RING(0);
|
||||
BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
|
||||
OUT_RING(0);
|
||||
BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0,1);
|
||||
OUT_RING(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void nv10ChooseVertexState( GLcontext *ctx )
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
DECLARE_RENDERINPUTS(index);
|
||||
|
||||
RENDERINPUTS_COPY(index, tnl->render_inputs_bitset);
|
||||
if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset))
|
||||
{
|
||||
RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index);
|
||||
nv10OutputVertexFormat(nmesa);
|
||||
}
|
||||
|
||||
if (nmesa->screen->card->type == NV_30) {
|
||||
nouveauShader *fp;
|
||||
|
||||
if (ctx->FragmentProgram.Enabled) {
|
||||
fp = (nouveauShader *) ctx->FragmentProgram.Current;
|
||||
nvsUpdateShader(ctx, fp);
|
||||
} else
|
||||
nvsUpdateShader(ctx, nmesa->passthrough_fp);
|
||||
}
|
||||
|
||||
if (nmesa->screen->card->type >= NV_40) {
|
||||
/* Ensure passthrough shader is being used, and mvp matrix
|
||||
* is up to date
|
||||
*/
|
||||
nvsUpdateShader(ctx, nmesa->passthrough_vp);
|
||||
|
||||
/* Update texenv shader / user fragprog */
|
||||
nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* High level hooks for t_vb_render.c */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
static void nv10RenderStart(GLcontext *ctx)
|
||||
{
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (nmesa->new_state) {
|
||||
nmesa->new_render_state |= nmesa->new_state;
|
||||
}
|
||||
|
||||
if (nmesa->new_render_state) {
|
||||
nv10ChooseVertexState(ctx);
|
||||
nv10ChooseRenderState(ctx);
|
||||
nmesa->new_render_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void nv10RenderFinish(GLcontext *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* System to flush dma and emit state changes based on the rasterized
|
||||
* primitive.
|
||||
*/
|
||||
void nv10RasterPrimitive(GLcontext *ctx,
|
||||
GLenum glprim,
|
||||
GLuint hwprim)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
assert (!nmesa->new_state);
|
||||
|
||||
if (hwprim != nmesa->current_primitive)
|
||||
{
|
||||
nmesa->current_primitive=hwprim;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static const GLuint hw_prim[GL_POLYGON+1] = {
|
||||
GL_POINTS+1,
|
||||
GL_LINES+1,
|
||||
GL_LINE_STRIP+1,
|
||||
GL_LINE_LOOP+1,
|
||||
GL_TRIANGLES+1,
|
||||
GL_TRIANGLE_STRIP+1,
|
||||
GL_TRIANGLE_FAN+1,
|
||||
GL_QUADS+1,
|
||||
GL_QUAD_STRIP+1,
|
||||
GL_POLYGON+1
|
||||
};
|
||||
|
||||
/* Callback for mesa:
|
||||
*/
|
||||
static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim )
|
||||
{
|
||||
nv10RasterPrimitive( ctx, prim, hw_prim[prim] );
|
||||
}
|
||||
|
||||
static void nv10ResetLineStipple( GLcontext *ctx )
|
||||
{
|
||||
/* FIXME do something here */
|
||||
WARN_ONCE("Unimplemented nv10ResetLineStipple\n");
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* Initialization. */
|
||||
/**********************************************************************/
|
||||
|
||||
void nv10TriInitFunctions(GLcontext *ctx)
|
||||
{
|
||||
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||
|
||||
tnl->Driver.RunPipeline = nouveauRunPipeline;
|
||||
tnl->Driver.Render.Start = nv10RenderStart;
|
||||
tnl->Driver.Render.Finish = nv10RenderFinish;
|
||||
tnl->Driver.Render.PrimitiveNotify = nv10RenderPrimitive;
|
||||
tnl->Driver.Render.ResetLineStipple = nv10ResetLineStipple;
|
||||
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
|
||||
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
|
||||
tnl->Driver.Render.Interp = _tnl_interp;
|
||||
|
||||
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
|
||||
64 * sizeof(GLfloat) );
|
||||
|
||||
nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Stephane Marchesin
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef __NV10_SWTCL_H__
|
||||
#define __NV10_SWTCL_H__
|
||||
|
||||
#include "mtypes.h"
|
||||
|
||||
extern void nv10Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
|
||||
extern void nv10FinishPrimitive(struct nouveau_context *nmesa);
|
||||
extern void nv10TriInitFunctions(GLcontext *ctx);
|
||||
#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode )
|
||||
|
||||
#endif /* __NV10_SWTCL_H__ */
|
||||
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
/* NV20_TCL_PRIMITIVE_3D_0x0B00 */
|
||||
#define NV20_VP_INST_0B00 0x00000000 /* always 0? */
|
||||
#define NV20_VP_INST0_KNOWN 0
|
||||
|
||||
/* NV20_TCL_PRIMITIVE_3D_0x0B04 */
|
||||
#define NV20_VP_INST_SCA_OPCODE_SHIFT 25
|
||||
#define NV20_VP_INST_SCA_OPCODE_MASK (0x0F << 25)
|
||||
#define NV20_VP_INST_OPCODE_RCP 0x2
|
||||
#define NV20_VP_INST_OPCODE_RCC 0x3
|
||||
#define NV20_VP_INST_OPCODE_RSQ 0x4
|
||||
#define NV20_VP_INST_OPCODE_EXP 0x5
|
||||
#define NV20_VP_INST_OPCODE_LOG 0x6
|
||||
#define NV20_VP_INST_OPCODE_LIT 0x7
|
||||
#define NV20_VP_INST_VEC_OPCODE_SHIFT 21
|
||||
#define NV20_VP_INST_VEC_OPCODE_MASK (0x0F << 21)
|
||||
#define NV20_VP_INST_OPCODE_NOP 0x0 /* guess */
|
||||
#define NV20_VP_INST_OPCODE_MOV 0x1
|
||||
#define NV20_VP_INST_OPCODE_MUL 0x2
|
||||
#define NV20_VP_INST_OPCODE_ADD 0x3
|
||||
#define NV20_VP_INST_OPCODE_MAD 0x4
|
||||
#define NV20_VP_INST_OPCODE_DP3 0x5
|
||||
#define NV20_VP_INST_OPCODE_DPH 0x6
|
||||
#define NV20_VP_INST_OPCODE_DP4 0x7
|
||||
#define NV20_VP_INST_OPCODE_DST 0x8
|
||||
#define NV20_VP_INST_OPCODE_MIN 0x9
|
||||
#define NV20_VP_INST_OPCODE_MAX 0xA
|
||||
#define NV20_VP_INST_OPCODE_SLT 0xB
|
||||
#define NV20_VP_INST_OPCODE_SGE 0xC
|
||||
#define NV20_VP_INST_OPCODE_ARL 0xD
|
||||
#define NV20_VP_INST_CONST_SRC_SHIFT 13
|
||||
#define NV20_VP_INST_CONST_SRC_MASK (0xFF << 13)
|
||||
#define NV20_VP_INST_INPUT_SRC_SHIFT 9
|
||||
#define NV20_VP_INST_INPUT_SRC_MASK (0xF << 9) /* guess */
|
||||
#define NV20_VP_INST_INPUT_SRC_POS 0
|
||||
#define NV20_VP_INST_INPUT_SRC_COL0 3
|
||||
#define NV20_VP_INST_INPUT_SRC_COL1 4
|
||||
#define NV20_VP_INST_INPUT_SRC_TC(n) (9+n)
|
||||
#define NV20_VP_INST_SRC0H_SHIFT 0
|
||||
#define NV20_VP_INST_SRC0H_MASK (0x1FF << 0)
|
||||
#define NV20_VP_INST1_KNOWN ( \
|
||||
NV20_VP_INST_OPCODE_MASK | \
|
||||
NV20_VP_INST_CONST_SRC_MASK | \
|
||||
NV20_VP_INST_INPUT_SRC_MASK | \
|
||||
NV20_VP_INST_SRC0H_MASK \
|
||||
)
|
||||
|
||||
/* NV20_TCL_PRIMITIVE_3D_0x0B08 */
|
||||
#define NV20_VP_INST_SRC0L_SHIFT 26
|
||||
#define NV20_VP_INST_SRC0L_MASK (0x3F <<26)
|
||||
#define NV20_VP_INST_SRC1_SHIFT 11
|
||||
#define NV20_VP_INST_SRC1_MASK (0x7FFF<<11)
|
||||
#define NV20_VP_INST_SRC2H_SHIFT 0
|
||||
#define NV20_VP_INST_SRC2H_MASK (0x7FF << 0)
|
||||
|
||||
/* NV20_TCL_PRIMITIVE_3D_0x0B0C */
|
||||
#define NV20_VP_INST_SRC2L_SHIFT 28
|
||||
#define NV20_VP_INST_SRC2L_MASK (0x0F <<28)
|
||||
#define NV20_VP_INST_VTEMP_WRITEMASK_SHIFT 24
|
||||
#define NV20_VP_INST_VTEMP_WRITEMASK_MASK (0x0F <<24)
|
||||
# define NV20_VP_INST_TEMP_WRITEMASK_X (1<<27)
|
||||
# define NV20_VP_INST_TEMP_WRITEMASK_Y (1<<26)
|
||||
# define NV20_VP_INST_TEMP_WRITEMASK_Z (1<<25)
|
||||
# define NV20_VP_INST_TEMP_WRITEMASK_W (1<<24)
|
||||
#define NV20_VP_INST_DEST_TEMP_ID_SHIFT 20
|
||||
#define NV20_VP_INST_DEST_TEMP_ID_MASK (0x0F <<20)
|
||||
#define NV20_VP_INST_STEMP_WRITEMASK_SHIFT 16
|
||||
#define NV20_VP_INST_STEMP_WRITEMASK_MASK (0x0F <<16)
|
||||
# define NV20_VP_INST_STEMP_WRITEMASK_X (1<<19)
|
||||
# define NV20_VP_INST_STEMP_WRITEMASK_Y (1<<18)
|
||||
# define NV20_VP_INST_STEMP_WRITEMASK_Z (1<<17)
|
||||
# define NV20_VP_INST_STEMP_WRITEMASK_W (1<<16)
|
||||
#define NV20_VP_INST_DEST_WRITEMASK_SHIFT 12
|
||||
#define NV20_VP_INST_DEST_WRITEMASK_MASK (0x0F <<12)
|
||||
# define NV20_VP_INST_DEST_WRITEMASK_X (1<<15)
|
||||
# define NV20_VP_INST_DEST_WRITEMASK_Y (1<<14)
|
||||
# define NV20_VP_INST_DEST_WRITEMASK_Z (1<<13)
|
||||
# define NV20_VP_INST_DEST_WRITEMASK_W (1<<12)
|
||||
#define NV20_VP_INST_DEST_SHIFT 3
|
||||
#define NV20_VP_INST_DEST_MASK (0xF << 3) /* guess */
|
||||
#define NV20_VP_INST_DEST_POS 0
|
||||
#define NV20_VP_INST_DEST_COL0 3
|
||||
#define NV20_VP_INST_DEST_COL1 4
|
||||
#define NV20_VP_INST_DEST_TC(n) (9+n)
|
||||
#define NV20_VP_INST_INDEX_CONST (1<<1)
|
||||
#define NV20_VP_INST3_KNOWN ( \
|
||||
NV20_VP_INST_SRC2L_MASK | \
|
||||
NV20_VP_INST_TEMP_WRITEMASK_MASK | \
|
||||
NV20_VP_INST_DEST_TEMP_ID_MASK | \
|
||||
NV20_VP_INST_STEMP_WRITEMASK_MASK | \
|
||||
NV20_VP_INST_DEST_WRITEMASK_MASK | \
|
||||
NV20_VP_INST_DEST_MASK | \
|
||||
NV20_VP_INST_INDEX_CONST \
|
||||
)
|
||||
|
||||
/* Useful to split the source selection regs into their pieces */
|
||||
#define NV20_VP_SRC0_HIGH_SHIFT 6
|
||||
#define NV20_VP_SRC0_HIGH_MASK 0x00007FC0
|
||||
#define NV20_VP_SRC0_LOW_MASK 0x0000003F
|
||||
#define NV20_VP_SRC2_HIGH_SHIFT 4
|
||||
#define NV20_VP_SRC2_HIGH_MASK 0x00007FF0
|
||||
#define NV20_VP_SRC2_LOW_MASK 0x0000000F
|
||||
|
||||
#define NV20_VP_SRC_REG_NEGATE (1<<14)
|
||||
#define NV20_VP_SRC_REG_SWZ_X_SHIFT 12
|
||||
#define NV20_VP_SRC_REG_SWZ_X_MASK (0x03 <<12)
|
||||
#define NV20_VP_SRC_REG_SWZ_Y_SHIFT 10
|
||||
#define NV20_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10)
|
||||
#define NV20_VP_SRC_REG_SWZ_Z_SHIFT 8
|
||||
#define NV20_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8)
|
||||
#define NV20_VP_SRC_REG_SWZ_W_SHIFT 6
|
||||
#define NV20_VP_SRC_REG_SWZ_W_MASK (0x03 << 6)
|
||||
#define NV20_VP_SRC_REG_SWZ_ALL_SHIFT 6
|
||||
#define NV20_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6)
|
||||
#define NV20_VP_SRC_REG_TEMP_ID_SHIFT 2
|
||||
#define NV20_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0)
|
||||
#define NV20_VP_SRC_REG_TYPE_SHIFT 0
|
||||
#define NV20_VP_SRC_REG_TYPE_MASK (0x03 << 0)
|
||||
#define NV20_VP_SRC_REG_TYPE_TEMP 1
|
||||
#define NV20_VP_SRC_REG_TYPE_INPUT 2
|
||||
#define NV20_VP_SRC_REG_TYPE_CONST 3 /* guess */
|
||||
|
||||
|
|
@ -1,824 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Nouveau
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "nouveau_context.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_reg.h"
|
||||
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
|
||||
static void nv20AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte ubRef;
|
||||
CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2);
|
||||
OUT_RING_CACHE(func);
|
||||
OUT_RING_CACHE(ubRef);
|
||||
}
|
||||
|
||||
static void nv20BlendColor(GLcontext *ctx, const GLfloat color[4])
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte cf[4];
|
||||
|
||||
CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]);
|
||||
CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]);
|
||||
CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]);
|
||||
CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_COLOR, 1);
|
||||
OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0]));
|
||||
}
|
||||
|
||||
static void nv20BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1);
|
||||
OUT_RING_CACHE((modeA<<16) | modeRGB);
|
||||
}
|
||||
|
||||
|
||||
static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
|
||||
GLenum sfactorA, GLenum dfactorA)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2);
|
||||
OUT_RING_CACHE((sfactorA<<16) | sfactorRGB);
|
||||
OUT_RING_CACHE((dfactorA<<16) | dfactorRGB);
|
||||
}
|
||||
|
||||
static void nv20Clear(GLcontext *ctx, GLbitfield mask)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLuint hw_bufs = 0;
|
||||
|
||||
if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT))
|
||||
hw_bufs |= 0xf0;
|
||||
if (mask & (BUFFER_BIT_DEPTH))
|
||||
hw_bufs |= 0x03;
|
||||
|
||||
if (hw_bufs) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1);
|
||||
OUT_RING_CACHE(hw_bufs);
|
||||
}
|
||||
}
|
||||
|
||||
static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4])
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte c[4];
|
||||
UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1);
|
||||
OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2]));
|
||||
}
|
||||
|
||||
static void nv20ClearDepth(GLcontext *ctx, GLclampd d)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8));
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
|
||||
OUT_RING_CACHE(nmesa->clear_value);
|
||||
}
|
||||
|
||||
/* we're don't support indexed buffers
|
||||
void (*ClearIndex)(GLcontext *ctx, GLuint index)
|
||||
*/
|
||||
|
||||
static void nv20ClearStencil(GLcontext *ctx, GLint s)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF));
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1);
|
||||
OUT_RING_CACHE(nmesa->clear_value);
|
||||
}
|
||||
|
||||
static void nv20ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
|
||||
OUT_RING_CACHEf(equation[0]);
|
||||
OUT_RING_CACHEf(equation[1]);
|
||||
OUT_RING_CACHEf(equation[2]);
|
||||
OUT_RING_CACHEf(equation[3]);
|
||||
}
|
||||
|
||||
static void nv20ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
|
||||
GLboolean bmask, GLboolean amask )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_MASK, 1);
|
||||
OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0));
|
||||
}
|
||||
|
||||
static void nv20ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
|
||||
{
|
||||
// TODO I need love
|
||||
}
|
||||
|
||||
static void nv20CullFace(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
|
||||
static void nv20FrontFace(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
|
||||
static void nv20DepthFunc(GLcontext *ctx, GLenum func)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
|
||||
OUT_RING_CACHE(func);
|
||||
}
|
||||
|
||||
static void nv20DepthMask(GLcontext *ctx, GLboolean flag)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
|
||||
OUT_RING_CACHE(flag);
|
||||
}
|
||||
|
||||
static void nv20DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
|
||||
OUT_RING_CACHEf(nearval);
|
||||
OUT_RING_CACHEf(farval);
|
||||
}
|
||||
|
||||
/** Specify the current buffer for writing */
|
||||
//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
|
||||
/** Specify the buffers for writing for fragment programs*/
|
||||
//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
|
||||
|
||||
static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
switch(cap)
|
||||
{
|
||||
case GL_ALPHA_TEST:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_AUTO_NORMAL:
|
||||
case GL_BLEND:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_CLIP_PLANE0:
|
||||
case GL_CLIP_PLANE1:
|
||||
case GL_CLIP_PLANE2:
|
||||
case GL_CLIP_PLANE3:
|
||||
case GL_CLIP_PLANE4:
|
||||
case GL_CLIP_PLANE5:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_COLOR_LOGIC_OP:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_COLOR_MATERIAL:
|
||||
// case GL_COLOR_SUM_EXT:
|
||||
// case GL_COLOR_TABLE:
|
||||
// case GL_CONVOLUTION_1D:
|
||||
// case GL_CONVOLUTION_2D:
|
||||
case GL_CULL_FACE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_DEPTH_TEST:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_DITHER:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_FOG:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_HISTOGRAM:
|
||||
// case GL_INDEX_LOGIC_OP:
|
||||
case GL_LIGHT0:
|
||||
case GL_LIGHT1:
|
||||
case GL_LIGHT2:
|
||||
case GL_LIGHT3:
|
||||
case GL_LIGHT4:
|
||||
case GL_LIGHT5:
|
||||
case GL_LIGHT6:
|
||||
case GL_LIGHT7:
|
||||
{
|
||||
uint32_t mask=0x11<<(2*(cap-GL_LIGHT0));
|
||||
nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state));
|
||||
if (nmesa->lighting_enabled)
|
||||
{
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
|
||||
OUT_RING_CACHE(nmesa->enabled_lights);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GL_LIGHTING:
|
||||
nmesa->lighting_enabled=state;
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1);
|
||||
if (nmesa->lighting_enabled)
|
||||
OUT_RING_CACHE(nmesa->enabled_lights);
|
||||
else
|
||||
OUT_RING_CACHE(0x0);
|
||||
break;
|
||||
case GL_LINE_SMOOTH:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_LINE_STIPPLE:
|
||||
// case GL_MAP1_COLOR_4:
|
||||
// case GL_MAP1_INDEX:
|
||||
// case GL_MAP1_NORMAL:
|
||||
// case GL_MAP1_TEXTURE_COORD_1:
|
||||
// case GL_MAP1_TEXTURE_COORD_2:
|
||||
// case GL_MAP1_TEXTURE_COORD_3:
|
||||
// case GL_MAP1_TEXTURE_COORD_4:
|
||||
// case GL_MAP1_VERTEX_3:
|
||||
// case GL_MAP1_VERTEX_4:
|
||||
// case GL_MAP2_COLOR_4:
|
||||
// case GL_MAP2_INDEX:
|
||||
// case GL_MAP2_NORMAL:
|
||||
// case GL_MAP2_TEXTURE_COORD_1:
|
||||
// case GL_MAP2_TEXTURE_COORD_2:
|
||||
// case GL_MAP2_TEXTURE_COORD_3:
|
||||
// case GL_MAP2_TEXTURE_COORD_4:
|
||||
// case GL_MAP2_VERTEX_3:
|
||||
// case GL_MAP2_VERTEX_4:
|
||||
// case GL_MINMAX:
|
||||
case GL_NORMALIZE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_POINT_SMOOTH:
|
||||
case GL_POLYGON_OFFSET_POINT:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_POLYGON_OFFSET_LINE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_POLYGON_OFFSET_FILL:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_POLYGON_SMOOTH:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_POLYGON_STIPPLE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
|
||||
// case GL_POST_CONVOLUTION_COLOR_TABLE:
|
||||
// case GL_RESCALE_NORMAL:
|
||||
case GL_SCISSOR_TEST:
|
||||
/* No enable bit, nv20Scissor will adjust to max range */
|
||||
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
||||
ctx->Scissor.Width, ctx->Scissor.Height);
|
||||
break;
|
||||
// case GL_SEPARABLE_2D:
|
||||
case GL_STENCIL_TEST:
|
||||
// TODO BACK and FRONT ?
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_TEXTURE_GEN_Q:
|
||||
// case GL_TEXTURE_GEN_R:
|
||||
// case GL_TEXTURE_GEN_S:
|
||||
// case GL_TEXTURE_GEN_T:
|
||||
// case GL_TEXTURE_1D:
|
||||
// case GL_TEXTURE_2D:
|
||||
// case GL_TEXTURE_3D:
|
||||
}
|
||||
}
|
||||
|
||||
static void nv20Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
switch(pname)
|
||||
{
|
||||
case GL_FOG_MODE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_MODE, 1);
|
||||
//OUT_RING_CACHE (params);
|
||||
break;
|
||||
/* TODO: unsure about the rest.*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode)
|
||||
{
|
||||
// TODO I need love (fog and line_smooth hints)
|
||||
}
|
||||
|
||||
// void (*IndexMask)(GLcontext *ctx, GLuint mask);
|
||||
|
||||
enum {
|
||||
SPOTLIGHT_NO_UPDATE,
|
||||
SPOTLIGHT_UPDATE_EXPONENT,
|
||||
SPOTLIGHT_UPDATE_DIRECTION,
|
||||
SPOTLIGHT_UPDATE_ALL
|
||||
};
|
||||
|
||||
static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLint p = light - GL_LIGHT0;
|
||||
struct gl_light *l = &ctx->Light.Light[p];
|
||||
int spotlight_update = SPOTLIGHT_NO_UPDATE;
|
||||
|
||||
/* not sure where the fourth param value goes...*/
|
||||
switch(pname)
|
||||
{
|
||||
case GL_AMBIENT:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3);
|
||||
OUT_RING_CACHEf(params[0]);
|
||||
OUT_RING_CACHEf(params[1]);
|
||||
OUT_RING_CACHEf(params[2]);
|
||||
break;
|
||||
case GL_DIFFUSE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3);
|
||||
OUT_RING_CACHEf(params[0]);
|
||||
OUT_RING_CACHEf(params[1]);
|
||||
OUT_RING_CACHEf(params[2]);
|
||||
break;
|
||||
case GL_SPECULAR:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3);
|
||||
OUT_RING_CACHEf(params[0]);
|
||||
OUT_RING_CACHEf(params[1]);
|
||||
OUT_RING_CACHEf(params[2]);
|
||||
break;
|
||||
case GL_POSITION:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3);
|
||||
OUT_RING_CACHEf(params[0]);
|
||||
OUT_RING_CACHEf(params[1]);
|
||||
OUT_RING_CACHEf(params[2]);
|
||||
break;
|
||||
case GL_SPOT_DIRECTION:
|
||||
spotlight_update = SPOTLIGHT_UPDATE_DIRECTION;
|
||||
break;
|
||||
case GL_SPOT_EXPONENT:
|
||||
spotlight_update = SPOTLIGHT_UPDATE_EXPONENT;
|
||||
break;
|
||||
case GL_SPOT_CUTOFF:
|
||||
spotlight_update = SPOTLIGHT_UPDATE_ALL;
|
||||
break;
|
||||
case GL_CONSTANT_ATTENUATION:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1);
|
||||
OUT_RING_CACHEf(*params);
|
||||
break;
|
||||
case GL_LINEAR_ATTENUATION:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1);
|
||||
OUT_RING_CACHEf(*params);
|
||||
break;
|
||||
case GL_QUADRATIC_ATTENUATION:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1);
|
||||
OUT_RING_CACHEf(*params);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(spotlight_update) {
|
||||
case SPOTLIGHT_UPDATE_DIRECTION:
|
||||
{
|
||||
GLfloat x,y,z;
|
||||
GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
|
||||
x = spot_light_coef_a * l->_NormDirection[0];
|
||||
y = spot_light_coef_a * l->_NormDirection[1];
|
||||
z = spot_light_coef_a * l->_NormDirection[2];
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3);
|
||||
OUT_RING_CACHEf(x);
|
||||
OUT_RING_CACHEf(y);
|
||||
OUT_RING_CACHEf(z);
|
||||
}
|
||||
break;
|
||||
case SPOTLIGHT_UPDATE_EXPONENT:
|
||||
{
|
||||
GLfloat cc,lc,qc;
|
||||
cc = 1.0; /* FIXME: These need to be correctly computed */
|
||||
lc = 0.0;
|
||||
qc = 2.0;
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3);
|
||||
OUT_RING_CACHEf(cc);
|
||||
OUT_RING_CACHEf(lc);
|
||||
OUT_RING_CACHEf(qc);
|
||||
}
|
||||
break;
|
||||
case SPOTLIGHT_UPDATE_ALL:
|
||||
{
|
||||
GLfloat cc,lc,qc, x,y,z, c;
|
||||
GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0);
|
||||
cc = 1.0; /* FIXME: These need to be correctly computed */
|
||||
lc = 0.0;
|
||||
qc = 2.0;
|
||||
x = spot_light_coef_a * l->_NormDirection[0];
|
||||
y = spot_light_coef_a * l->_NormDirection[1];
|
||||
z = spot_light_coef_a * l->_NormDirection[2];
|
||||
c = spot_light_coef_a + 1.0;
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7);
|
||||
OUT_RING_CACHEf(cc);
|
||||
OUT_RING_CACHEf(lc);
|
||||
OUT_RING_CACHEf(qc);
|
||||
OUT_RING_CACHEf(x);
|
||||
OUT_RING_CACHEf(y);
|
||||
OUT_RING_CACHEf(z);
|
||||
OUT_RING_CACHEf(c);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Set the lighting model parameters */
|
||||
static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
|
||||
|
||||
|
||||
static void nv20LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
|
||||
{
|
||||
/* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
|
||||
OUT_RING_CACHE((pattern << 16) | factor);*/
|
||||
}
|
||||
|
||||
static void nv20LineWidth(GLcontext *ctx, GLfloat width)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
|
||||
OUT_RING_CACHEf(width);
|
||||
}
|
||||
|
||||
static void nv20LogicOpcode(GLcontext *ctx, GLenum opcode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1);
|
||||
OUT_RING_CACHE(opcode);
|
||||
}
|
||||
|
||||
static void nv20PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||
{
|
||||
/*TODO: not sure what goes here. */
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
}
|
||||
|
||||
/** Specify the diameter of rasterized points */
|
||||
static void nv20PointSize(GLcontext *ctx, GLfloat size)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
|
||||
OUT_RING_CACHEf(size);
|
||||
}
|
||||
|
||||
/** Select a polygon rasterization mode */
|
||||
static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
}
|
||||
|
||||
/** Set the scale and units used to calculate depth values */
|
||||
static void nv20PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2);
|
||||
OUT_RING_CACHEf(factor);
|
||||
OUT_RING_CACHEf(units);
|
||||
}
|
||||
|
||||
/** Set the polygon stippling pattern */
|
||||
static void nv20PolygonStipple(GLcontext *ctx, const GLubyte *mask )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
|
||||
OUT_RING_CACHEp(mask, 32);
|
||||
}
|
||||
|
||||
/* Specifies the current buffer for reading */
|
||||
void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
|
||||
/** Set rasterization mode */
|
||||
void (*RenderMode)(GLcontext *ctx, GLenum mode );
|
||||
|
||||
/** Define the scissor box */
|
||||
static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
/* There's no scissor enable bit, so adjust the scissor to cover the
|
||||
* maximum draw buffer bounds
|
||||
*/
|
||||
if (!ctx->Scissor.Enabled) {
|
||||
x = y = 0;
|
||||
w = h = 4095;
|
||||
} else {
|
||||
x += nmesa->drawX;
|
||||
y += nmesa->drawY;
|
||||
}
|
||||
|
||||
/*BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 1);
|
||||
OUT_RING_CACHE((w << 16) | x );
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1, 1);
|
||||
OUT_RING_CACHE((h << 16) | y );*/
|
||||
|
||||
}
|
||||
|
||||
/** Select flat or smooth shading */
|
||||
static void nv20ShadeModel(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilFunc */
|
||||
static void nv20StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
|
||||
GLint ref, GLuint mask)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3);
|
||||
OUT_RING_CACHE(func);
|
||||
OUT_RING_CACHE(ref);
|
||||
OUT_RING_CACHE(mask);
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilMask */
|
||||
static void nv20StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK, 1);
|
||||
OUT_RING_CACHE(mask);
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilOp */
|
||||
static void nv20StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
|
||||
GLenum zfail, GLenum zpass)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1);
|
||||
OUT_RING_CACHE(fail);
|
||||
OUT_RING_CACHE(zfail);
|
||||
OUT_RING_CACHE(zpass);
|
||||
}
|
||||
|
||||
/** Control the generation of texture coordinates */
|
||||
void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
|
||||
const GLfloat *params);
|
||||
/** Set texture environment parameters */
|
||||
void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
|
||||
const GLfloat *param);
|
||||
/** Set texture parameters */
|
||||
void (*TexParameter)(GLcontext *ctx, GLenum target,
|
||||
struct gl_texture_object *texObj,
|
||||
GLenum pname, const GLfloat *params);
|
||||
|
||||
static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
|
||||
/*XXX: This SHOULD work.*/
|
||||
OUT_RING_CACHEp(mat->m, 16);
|
||||
}
|
||||
|
||||
/* Update anything that depends on the window position/size */
|
||||
static void nv20WindowMoved(nouveauContextPtr nmesa)
|
||||
{
|
||||
GLcontext *ctx = nmesa->glCtx;
|
||||
GLfloat *v = nmesa->viewport.m;
|
||||
GLuint w = ctx->Viewport.Width;
|
||||
GLuint h = ctx->Viewport.Height;
|
||||
GLuint x = ctx->Viewport.X + nmesa->drawX;
|
||||
GLuint y = ctx->Viewport.Y + nmesa->drawY;
|
||||
int i;
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2);
|
||||
OUT_RING_CACHE((w << 16) | x);
|
||||
OUT_RING_CACHE((h << 16) | y);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1);
|
||||
OUT_RING(0);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D,
|
||||
NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1);
|
||||
OUT_RING_CACHE((4095 << 16) | 0);
|
||||
BEGIN_RING_CACHE(NvSub3D,
|
||||
NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1);
|
||||
OUT_RING_CACHE((4095 << 16) | 0);
|
||||
for (i=1; i<8; i++) {
|
||||
BEGIN_RING_CACHE(NvSub3D,
|
||||
NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1);
|
||||
OUT_RING_CACHE(0);
|
||||
BEGIN_RING_CACHE(NvSub3D,
|
||||
NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1);
|
||||
OUT_RING_CACHE(0);
|
||||
}
|
||||
|
||||
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
||||
ctx->Scissor.Width, ctx->Scissor.Height);
|
||||
|
||||
/* TODO: recalc viewport scale coefs */
|
||||
}
|
||||
|
||||
/* Initialise any card-specific non-GL related state */
|
||||
static GLboolean nv20InitCard(nouveauContextPtr nmesa)
|
||||
{
|
||||
nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT1, 2);
|
||||
OUT_RING(NvDmaFB); /* 184 dma_object1 */
|
||||
OUT_RING(NvDmaFB); /* 188 dma_object2 */
|
||||
BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT3, 2);
|
||||
OUT_RING(NvDmaFB); /* 194 dma_object3 */
|
||||
OUT_RING(NvDmaFB); /* 198 dma_object4 */
|
||||
BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
|
||||
OUT_RING(NvDmaFB); /* 1a8 dma_object8 */
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3);
|
||||
OUT_RINGf(0.0);
|
||||
OUT_RINGf(0.0);
|
||||
OUT_RINGf(1.0);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x1e6c, 1);
|
||||
OUT_RING(0x0db6);
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x0290, 1);
|
||||
OUT_RING(0x00100001);
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x09fc, 1);
|
||||
OUT_RING(0);
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1);
|
||||
OUT_RING(1);
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x09f8, 1);
|
||||
OUT_RING(4);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x17ec, 3);
|
||||
OUT_RINGf(0.0);
|
||||
OUT_RINGf(1.0);
|
||||
OUT_RINGf(0.0);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1);
|
||||
OUT_RING(3);
|
||||
|
||||
/* FIXME: More dma objects to setup ? */
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1);
|
||||
OUT_RING(0);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x120, 3);
|
||||
OUT_RING(0);
|
||||
OUT_RING(1);
|
||||
OUT_RING(2);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Update buffer offset/pitch/format */
|
||||
static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color,
|
||||
nouveau_renderbuffer_t **color,
|
||||
nouveau_renderbuffer_t *depth)
|
||||
{
|
||||
GLuint x, y, w, h;
|
||||
GLuint pitch, format, depth_pitch;
|
||||
|
||||
w = color[0]->mesa.Width;
|
||||
h = color[0]->mesa.Height;
|
||||
x = nmesa->drawX;
|
||||
y = nmesa->drawY;
|
||||
|
||||
if (num_color != 1)
|
||||
return GL_FALSE;
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6);
|
||||
OUT_RING_CACHE((w << 16) | x);
|
||||
OUT_RING_CACHE((h << 16) | y);
|
||||
depth_pitch = (depth ? depth->pitch : color[0]->pitch);
|
||||
pitch = (depth_pitch<<16) | color[0]->pitch;
|
||||
format = 0x128;
|
||||
if (color[0]->mesa._ActualFormat != GL_RGBA8) {
|
||||
format = 0x123; /* R5G6B5 color buffer */
|
||||
}
|
||||
OUT_RING_CACHE(format);
|
||||
OUT_RING_CACHE(pitch);
|
||||
OUT_RING_CACHE(color[0]->offset);
|
||||
OUT_RING_CACHE(depth ? depth->offset : color[0]->offset);
|
||||
|
||||
if (depth) {
|
||||
BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 2);
|
||||
/* TODO: use a different buffer */
|
||||
OUT_RING(depth->pitch);
|
||||
OUT_RING(depth->offset);
|
||||
}
|
||||
|
||||
/* Always set to bottom left of buffer */
|
||||
/*BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4);
|
||||
OUT_RING_CACHEf (0.0);
|
||||
OUT_RING_CACHEf ((GLfloat) h);
|
||||
OUT_RING_CACHEf (0.0);
|
||||
OUT_RING_CACHEf (0.0);*/
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
func->AlphaFunc = nv20AlphaFunc;
|
||||
func->BlendColor = nv20BlendColor;
|
||||
func->BlendEquationSeparate = nv20BlendEquationSeparate;
|
||||
func->BlendFuncSeparate = nv20BlendFuncSeparate;
|
||||
func->Clear = nv20Clear;
|
||||
func->ClearColor = nv20ClearColor;
|
||||
func->ClearDepth = nv20ClearDepth;
|
||||
func->ClearStencil = nv20ClearStencil;
|
||||
func->ClipPlane = nv20ClipPlane;
|
||||
func->ColorMask = nv20ColorMask;
|
||||
func->ColorMaterial = nv20ColorMaterial;
|
||||
func->CullFace = nv20CullFace;
|
||||
func->FrontFace = nv20FrontFace;
|
||||
func->DepthFunc = nv20DepthFunc;
|
||||
func->DepthMask = nv20DepthMask;
|
||||
func->DepthRange = nv20DepthRange;
|
||||
func->Enable = nv20Enable;
|
||||
func->Fogfv = nv20Fogfv;
|
||||
func->Hint = nv20Hint;
|
||||
func->Lightfv = nv20Lightfv;
|
||||
/* func->LightModelfv = nv20LightModelfv; */
|
||||
func->LineStipple = nv20LineStipple;
|
||||
func->LineWidth = nv20LineWidth;
|
||||
func->LogicOpcode = nv20LogicOpcode;
|
||||
func->PointParameterfv = nv20PointParameterfv;
|
||||
func->PointSize = nv20PointSize;
|
||||
func->PolygonMode = nv20PolygonMode;
|
||||
func->PolygonOffset = nv20PolygonOffset;
|
||||
func->PolygonStipple = nv20PolygonStipple;
|
||||
/* func->ReadBuffer = nv20ReadBuffer;*/
|
||||
/* func->RenderMode = nv20RenderMode;*/
|
||||
func->Scissor = nv20Scissor;
|
||||
func->ShadeModel = nv20ShadeModel;
|
||||
func->StencilFuncSeparate = nv20StencilFuncSeparate;
|
||||
func->StencilMaskSeparate = nv20StencilMaskSeparate;
|
||||
func->StencilOpSeparate = nv20StencilOpSeparate;
|
||||
/* func->TexGen = nv20TexGen;*/
|
||||
/* func->TexParameter = nv20TexParameter;*/
|
||||
func->TextureMatrix = nv20TextureMatrix;
|
||||
|
||||
nmesa->hw_func.InitCard = nv20InitCard;
|
||||
nmesa->hw_func.BindBuffers = nv20BindBuffers;
|
||||
nmesa->hw_func.WindowMoved = nv20WindowMoved;
|
||||
}
|
||||
|
||||
|
|
@ -1,447 +0,0 @@
|
|||
#include "nouveau_context.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_reg.h"
|
||||
|
||||
#include "nouveau_shader.h"
|
||||
#include "nv20_shader.h"
|
||||
|
||||
unsigned int NVVP_TX_VOP_COUNT = 16;
|
||||
unsigned int NVVP_TX_NVS_OP_COUNT = 16;
|
||||
struct _op_xlat NVVP_TX_VOP[32];
|
||||
struct _op_xlat NVVP_TX_SOP[32];
|
||||
|
||||
nvsSwzComp NV20VP_TX_SWIZZLE[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
|
||||
|
||||
/*****************************************************************************
|
||||
* Support routines
|
||||
*/
|
||||
static void
|
||||
NV20VPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
int i;
|
||||
|
||||
/* XXX: missing a way to say what insn we're uploading from, and possible
|
||||
* the program start position (if NV20 has one) */
|
||||
for (i=0; i<nvs->program_size; i+=4) {
|
||||
BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4);
|
||||
OUT_RING(nvs->program[i + 0]);
|
||||
OUT_RING(nvs->program[i + 1]);
|
||||
OUT_RING(nvs->program[i + 2]);
|
||||
OUT_RING(nvs->program[i + 3]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV20VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
/* Worth checking if the value *actually* changed? Mesa doesn't tell us this
|
||||
* as far as I know..
|
||||
*/
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 1);
|
||||
OUT_RING (id);
|
||||
BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X, 4);
|
||||
OUT_RINGf(nvs->params[id].source_val[0]);
|
||||
OUT_RINGf(nvs->params[id].source_val[1]);
|
||||
OUT_RINGf(nvs->params[id].source_val[2]);
|
||||
OUT_RINGf(nvs->params[id].source_val[3]);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Assembly routines
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* Disassembly routines
|
||||
*/
|
||||
void
|
||||
NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz)
|
||||
{
|
||||
swz[NVS_SWZ_X] = NV20VP_TX_SWIZZLE[(hwswz & 0xC0) >> 6];
|
||||
swz[NVS_SWZ_Y] = NV20VP_TX_SWIZZLE[(hwswz & 0x30) >> 4];
|
||||
swz[NVS_SWZ_Z] = NV20VP_TX_SWIZZLE[(hwswz & 0x0C) >> 2];
|
||||
swz[NVS_SWZ_W] = NV20VP_TX_SWIZZLE[(hwswz & 0x03) >> 0];
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPHasMergedInst(nvsFunc * shader)
|
||||
{
|
||||
if (shader->GetOpcodeHW(shader, 0) != NV20_VP_INST_OPCODE_NOP &&
|
||||
shader->GetOpcodeHW(shader, 1) != NV20_VP_INST_OPCODE_NOP)
|
||||
printf
|
||||
("\n\n*****both opcode fields have values - PLEASE REPORT*****\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPIsLastInst(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[3] & (1 << 0)) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPGetOffsetNext(nvsFunc * shader)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
static struct _op_xlat *
|
||||
NV20VPGetOPTXRec(nvsFunc * shader, int merged)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
int op;
|
||||
|
||||
if (shader->GetOpcodeSlot(shader, merged)) {
|
||||
opr = NVVP_TX_SOP;
|
||||
op = shader->GetOpcodeHW(shader, 1);
|
||||
if (op >= NVVP_TX_NVS_OP_COUNT)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
opr = NVVP_TX_VOP;
|
||||
op = shader->GetOpcodeHW(shader, 0);
|
||||
if (op >= NVVP_TX_VOP_COUNT)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (opr[op].SOP == NVS_OP_UNKNOWN)
|
||||
return NULL;
|
||||
return &opr[op];
|
||||
}
|
||||
|
||||
static struct _op_xlat *
|
||||
NV20VPGetOPTXFromSOP(nvsOpcode sop, int *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<NVVP_TX_VOP_COUNT;i++) {
|
||||
if (NVVP_TX_VOP[i].SOP == sop) {
|
||||
if (id) *id = 0;
|
||||
return &NVVP_TX_VOP[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<NVVP_TX_NVS_OP_COUNT;i++) {
|
||||
if (NVVP_TX_SOP[i].SOP == sop) {
|
||||
if (id) *id = 1;
|
||||
return &NVVP_TX_SOP[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPGetOpcodeSlot(nvsFunc * shader, int merged)
|
||||
{
|
||||
if (shader->HasMergedInst(shader))
|
||||
return merged;
|
||||
if (shader->GetOpcodeHW(shader, 0) == NV20_VP_INST_OPCODE_NOP)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nvsOpcode
|
||||
NV20VPGetOpcode(nvsFunc * shader, int merged)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr)
|
||||
return NVS_OP_UNKNOWN;
|
||||
|
||||
return opr->SOP;
|
||||
}
|
||||
|
||||
static nvsOpcode
|
||||
NV20VPGetOpcodeHW(nvsFunc * shader, int slot)
|
||||
{
|
||||
if (slot)
|
||||
return (shader->inst[1] & NV20_VP_INST_SCA_OPCODE_MASK)
|
||||
>> NV20_VP_INST_SCA_OPCODE_SHIFT;
|
||||
return (shader->inst[1] & NV20_VP_INST_VEC_OPCODE_MASK)
|
||||
>> NV20_VP_INST_VEC_OPCODE_SHIFT;
|
||||
}
|
||||
|
||||
static nvsRegFile
|
||||
NV20VPGetDestFile(nvsFunc * shader, int merged)
|
||||
{
|
||||
switch (shader->GetOpcode(shader, merged)) {
|
||||
case NVS_OP_ARL:
|
||||
return NVS_FILE_ADDRESS;
|
||||
default:
|
||||
/*FIXME: This probably isn't correct.. */
|
||||
if ((shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK) == 0)
|
||||
return NVS_FILE_TEMP;
|
||||
return NVS_FILE_RESULT;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV20VPGetDestID(nvsFunc * shader, int merged)
|
||||
{
|
||||
int id;
|
||||
|
||||
switch (shader->GetDestFile(shader, merged)) {
|
||||
case NVS_FILE_RESULT:
|
||||
id = ((shader->inst[3] & NV20_VP_INST_DEST_MASK)
|
||||
>> NV20_VP_INST_DEST_SHIFT);
|
||||
switch (id) {
|
||||
case NV20_VP_INST_DEST_POS : return NVS_FR_POSITION;
|
||||
case NV20_VP_INST_DEST_COL0 : return NVS_FR_COL0;
|
||||
case NV20_VP_INST_DEST_COL1 : return NVS_FR_COL1;
|
||||
case NV20_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
|
||||
case NV20_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
|
||||
case NV20_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
|
||||
case NV20_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
case NVS_FILE_ADDRESS:
|
||||
return 0;
|
||||
case NVS_FILE_TEMP:
|
||||
id = ((shader->inst[3] & NV20_VP_INST_DEST_TEMP_ID_MASK)
|
||||
>> NV20_VP_INST_DEST_TEMP_ID_SHIFT);
|
||||
return id;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV20VPGetDestMask(nvsFunc * shader, int merged)
|
||||
{
|
||||
int hwmask, mask = 0;
|
||||
|
||||
/* Special handling for ARL - hardware only supports a
|
||||
* 1-component address reg
|
||||
*/
|
||||
if (shader->GetOpcode(shader, merged) == NVS_OP_ARL)
|
||||
return SMASK_X;
|
||||
|
||||
if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT)
|
||||
hwmask = (shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK)
|
||||
>> NV20_VP_INST_DEST_WRITEMASK_SHIFT;
|
||||
else if (shader->GetOpcodeSlot(shader, merged))
|
||||
hwmask = (shader->inst[3] & NV20_VP_INST_STEMP_WRITEMASK_MASK)
|
||||
>> NV20_VP_INST_STEMP_WRITEMASK_SHIFT;
|
||||
else
|
||||
hwmask = (shader->inst[3] & NV20_VP_INST_VTEMP_WRITEMASK_MASK)
|
||||
>> NV20_VP_INST_VTEMP_WRITEMASK_SHIFT;
|
||||
|
||||
if (hwmask & (1 << 3)) mask |= SMASK_X;
|
||||
if (hwmask & (1 << 2)) mask |= SMASK_Y;
|
||||
if (hwmask & (1 << 1)) mask |= SMASK_Z;
|
||||
if (hwmask & (1 << 0)) mask |= SMASK_W;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV20VPGetSourceHW(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
unsigned int src;
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr)
|
||||
return -1;
|
||||
|
||||
switch (opr->srcpos[pos]) {
|
||||
case 0:
|
||||
src = ((shader->inst[1] & NV20_VP_INST_SRC0H_MASK)
|
||||
>> NV20_VP_INST_SRC0H_SHIFT)
|
||||
<< NV20_VP_SRC0_HIGH_SHIFT;
|
||||
src |= ((shader->inst[2] & NV20_VP_INST_SRC0L_MASK)
|
||||
>> NV20_VP_INST_SRC0L_SHIFT);
|
||||
break;
|
||||
case 1:
|
||||
src = ((shader->inst[2] & NV20_VP_INST_SRC1_MASK)
|
||||
>> NV20_VP_INST_SRC1_SHIFT);
|
||||
break;
|
||||
case 2:
|
||||
src = ((shader->inst[2] & NV20_VP_INST_SRC2H_MASK)
|
||||
>> NV20_VP_INST_SRC2H_SHIFT)
|
||||
<< NV20_VP_SRC2_HIGH_SHIFT;
|
||||
src |= ((shader->inst[3] & NV20_VP_INST_SRC2L_MASK)
|
||||
>> NV20_VP_INST_SRC2L_SHIFT);
|
||||
break;
|
||||
default:
|
||||
src = -1;
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
static nvsRegFile
|
||||
NV20VPGetSourceFile(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
unsigned int src;
|
||||
struct _op_xlat *opr;
|
||||
int file;
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr || opr->srcpos[pos] == -1)
|
||||
return -1;
|
||||
|
||||
switch (opr->srcpos[pos]) {
|
||||
case SPOS_ADDRESS:
|
||||
return NVS_FILE_ADDRESS;
|
||||
default:
|
||||
src = NV20VPGetSourceHW(shader, merged, pos);
|
||||
file = (src & NV20_VP_SRC_REG_TYPE_MASK) >> NV20_VP_SRC_REG_TYPE_SHIFT;
|
||||
|
||||
switch (file) {
|
||||
case NV20_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP;
|
||||
case NV20_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
|
||||
case NV20_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST;
|
||||
default:
|
||||
return NVS_FILE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPGetSourceID(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
switch (shader->GetSourceFile(shader, merged, pos)) {
|
||||
case NVS_FILE_TEMP:
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
return ((src & NV20_VP_SRC_REG_TEMP_ID_MASK) >>
|
||||
NV20_VP_SRC_REG_TEMP_ID_SHIFT);
|
||||
case NVS_FILE_CONST:
|
||||
return ((shader->inst[1] & NV20_VP_INST_CONST_SRC_MASK)
|
||||
>> NV20_VP_INST_CONST_SRC_SHIFT);
|
||||
case NVS_FILE_ATTRIB:
|
||||
src = ((shader->inst[1] & NV20_VP_INST_INPUT_SRC_MASK)
|
||||
>> NV20_VP_INST_INPUT_SRC_SHIFT);
|
||||
switch (src) {
|
||||
case NV20_VP_INST_INPUT_SRC_POS : return NVS_FR_POSITION;
|
||||
case NV20_VP_INST_INPUT_SRC_COL0 : return NVS_FR_COL0;
|
||||
case NV20_VP_INST_INPUT_SRC_COL1 : return NVS_FR_COL1;
|
||||
case NV20_VP_INST_INPUT_SRC_TC(0): return NVS_FR_TEXCOORD0;
|
||||
case NV20_VP_INST_INPUT_SRC_TC(1): return NVS_FR_TEXCOORD1;
|
||||
case NV20_VP_INST_INPUT_SRC_TC(2): return NVS_FR_TEXCOORD2;
|
||||
case NV20_VP_INST_INPUT_SRC_TC(3): return NVS_FR_TEXCOORD3;
|
||||
default:
|
||||
return NVS_FR_UNKNOWN;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPGetSourceNegate(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
|
||||
return ((src & NV20_VP_SRC_REG_NEGATE) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPGetSourceAbs(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
/* NV20 can't do ABS on sources? Appears to be emulated with
|
||||
* MAX reg, reg, -reg
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
NV20VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
|
||||
{
|
||||
unsigned int src;
|
||||
int swzbits;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
swzbits =
|
||||
(src & NV20_VP_SRC_REG_SWZ_ALL_MASK) >> NV20_VP_SRC_REG_SWZ_ALL_SHIFT;
|
||||
return NV20VPTXSwizzle(swzbits, swz);
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
/* I don't think NV20 can index into attribs, at least no GL
|
||||
* extension is exposed that will allow it.
|
||||
*/
|
||||
if (shader->GetSourceFile(shader, merged, pos) != NVS_FILE_CONST)
|
||||
return 0;
|
||||
if (shader->inst[3] & NV20_VP_INST_INDEX_CONST)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
NV20VPGetAddressRegID(nvsFunc * shader)
|
||||
{
|
||||
/* Only 1 address reg */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nvsSwzComp
|
||||
NV20VPGetAddressRegSwizzle(nvsFunc * shader)
|
||||
{
|
||||
/* Only A0.x available */
|
||||
return NVS_SWZ_X;
|
||||
}
|
||||
|
||||
void
|
||||
NV20VPInitShaderFuncs(nvsFunc * shader)
|
||||
{
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ADD, NVS_OP_ADD, 0, 2, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DPH, NVS_OP_DPH, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DST, NVS_OP_DST, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ARL, NVS_OP_ARL, 0, -1, -1);
|
||||
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCP, NVS_OP_RCP, 2, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCC, NVS_OP_RCC, 2, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RSQ, NVS_OP_RSQ, 2, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_EXP, NVS_OP_EXP, 2, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LOG, NVS_OP_LOG, 2, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LIT, NVS_OP_LIT, 2, -1, -1);
|
||||
|
||||
shader->UploadToHW = NV20VPUploadToHW;
|
||||
shader->UpdateConst = NV20VPUpdateConst;
|
||||
|
||||
shader->GetOPTXRec = NV20VPGetOPTXRec;
|
||||
shader->GetOPTXFromSOP = NV20VPGetOPTXFromSOP;
|
||||
|
||||
shader->HasMergedInst = NV20VPHasMergedInst;
|
||||
shader->IsLastInst = NV20VPIsLastInst;
|
||||
shader->GetOffsetNext = NV20VPGetOffsetNext;
|
||||
shader->GetOpcodeSlot = NV20VPGetOpcodeSlot;
|
||||
shader->GetOpcode = NV20VPGetOpcode;
|
||||
shader->GetOpcodeHW = NV20VPGetOpcodeHW;
|
||||
shader->GetDestFile = NV20VPGetDestFile;
|
||||
shader->GetDestID = NV20VPGetDestID;
|
||||
shader->GetDestMask = NV20VPGetDestMask;
|
||||
shader->GetSourceHW = NV20VPGetSourceHW;
|
||||
shader->GetSourceFile = NV20VPGetSourceFile;
|
||||
shader->GetSourceID = NV20VPGetSourceID;
|
||||
shader->GetSourceNegate = NV20VPGetSourceNegate;
|
||||
shader->GetSourceAbs = NV20VPGetSourceAbs;
|
||||
shader->GetSourceSwizzle = NV20VPGetSourceSwizzle;
|
||||
shader->GetSourceIndexed = NV20VPGetSourceIndexed;
|
||||
shader->GetRelAddressRegID = NV20VPGetAddressRegID;
|
||||
shader->GetRelAddressSwizzle = NV20VPGetAddressRegSwizzle;
|
||||
}
|
||||
|
|
@ -1,742 +0,0 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "glheader.h"
|
||||
#include "macros.h"
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_shader.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nouveau_bufferobj.h"
|
||||
#include "nv30_shader.h"
|
||||
|
||||
unsigned int NVFP_TX_AOP_COUNT = 64;
|
||||
struct _op_xlat NVFP_TX_AOP[64];
|
||||
|
||||
/*******************************************************************************
|
||||
* Support routines
|
||||
*/
|
||||
|
||||
static void
|
||||
NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
nvsCardPriv *priv = &nvs->card_priv;
|
||||
uint32_t offset;
|
||||
|
||||
if (!nvs->program_buffer)
|
||||
nvs->program_buffer = ctx->Driver.NewBufferObject(ctx, 0,
|
||||
GL_ARRAY_BUFFER_ARB);
|
||||
|
||||
/* Should use STATIC_DRAW_ARB if shader doesn't use changable params */
|
||||
nouveau_bo_init_storage(ctx, NOUVEAU_BO_VRAM_OK,
|
||||
nvs->program_size * sizeof(uint32_t),
|
||||
(const GLvoid *)nvs->program,
|
||||
GL_DYNAMIC_DRAW_ARB,
|
||||
nvs->program_buffer, 1);
|
||||
|
||||
offset = nouveau_bo_gpu_ref(ctx, nvs->program_buffer);
|
||||
|
||||
/* Not using state cache here, updated programs at the same address don't
|
||||
* seem to take effect unless the ACTIVE_PROGRAM method is called again.
|
||||
* HW caches the program somewhere?
|
||||
*/
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
|
||||
OUT_RING (offset | 1);
|
||||
if (nmesa->screen->card->type == NV_30) {
|
||||
BEGIN_RING_SIZE(NvSub3D,
|
||||
0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1);
|
||||
OUT_RING ((priv->NV30FP.uses_kil << 7));
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x1450, 1);
|
||||
OUT_RING (priv->NV30FP.num_regs << 16);
|
||||
} else {
|
||||
BEGIN_RING_SIZE(NvSub3D,
|
||||
0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1);
|
||||
OUT_RING ((priv->NV30FP.uses_kil << 7) |
|
||||
(priv->NV30FP.num_regs << 24));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
|
||||
{
|
||||
uint32_t *new = nvs->params[id].source_val ?
|
||||
(uint32_t*)nvs->params[id].source_val : (uint32_t*)nvs->params[id].val;
|
||||
uint32_t *current;
|
||||
int i;
|
||||
|
||||
for (i=0; i<nvs->params[id].hw_index_cnt; i++) {
|
||||
current = nvs->program + nvs->params[id].hw_index[i];
|
||||
COPY_4V(current, new);
|
||||
}
|
||||
nvs->on_hardware = 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Assembly helpers
|
||||
*/
|
||||
static struct _op_xlat *
|
||||
NV30FPGetOPTXFromSOP(nvsOpcode op, int *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<NVFP_TX_AOP_COUNT; i++) {
|
||||
if (NVFP_TX_AOP[i].SOP == op) {
|
||||
if (id) *id = 0;
|
||||
return &NVFP_TX_AOP[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPSupportsOpcode(nvsFunc *shader, nvsOpcode op)
|
||||
{
|
||||
if (shader->GetOPTXFromSOP(op, NULL))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot)
|
||||
{
|
||||
if (opcode == NV30_FP_OP_OPCODE_KIL)
|
||||
shader->card_priv->NV30FP.uses_kil = GL_TRUE;
|
||||
shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK;
|
||||
shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetCCUpdate(nvsFunc *shader)
|
||||
{
|
||||
shader->inst[0] |= NV30_FP_OP_COND_WRITE_ENABLE;
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg,
|
||||
nvsSwzComp *swz)
|
||||
{
|
||||
nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
|
||||
unsigned int hwcond;
|
||||
|
||||
/* cond masking is always enabled */
|
||||
if (!on) {
|
||||
cond = NVS_COND_TR;
|
||||
reg = 0;
|
||||
swz = default_swz;
|
||||
}
|
||||
|
||||
switch (cond) {
|
||||
case NVS_COND_TR: hwcond = NV30_FP_OP_COND_TR; break;
|
||||
case NVS_COND_FL: hwcond = NV30_FP_OP_COND_FL; break;
|
||||
case NVS_COND_LT: hwcond = NV30_FP_OP_COND_LT; break;
|
||||
case NVS_COND_GT: hwcond = NV30_FP_OP_COND_GT; break;
|
||||
case NVS_COND_LE: hwcond = NV30_FP_OP_COND_LE; break;
|
||||
case NVS_COND_GE: hwcond = NV30_FP_OP_COND_GE; break;
|
||||
case NVS_COND_EQ: hwcond = NV30_FP_OP_COND_EQ; break;
|
||||
case NVS_COND_NE: hwcond = NV30_FP_OP_COND_NE; break;
|
||||
default:
|
||||
WARN_ONCE("unknown fp condmask=%d\n", cond);
|
||||
hwcond = NV30_FP_OP_COND_TR;
|
||||
break;
|
||||
}
|
||||
|
||||
shader->inst[1] &= ~NV30_FP_OP_COND_MASK;
|
||||
shader->inst[1] |= (hwcond << NV30_FP_OP_COND_SHIFT);
|
||||
|
||||
shader->inst[1] &= ~NV30_FP_OP_COND_SWZ_ALL_MASK;
|
||||
shader->inst[1] |= (swz[NVS_SWZ_X] << NV30_FP_OP_COND_SWZ_X_SHIFT);
|
||||
shader->inst[1] |= (swz[NVS_SWZ_Y] << NV30_FP_OP_COND_SWZ_Y_SHIFT);
|
||||
shader->inst[1] |= (swz[NVS_SWZ_Z] << NV30_FP_OP_COND_SWZ_Z_SHIFT);
|
||||
shader->inst[1] |= (swz[NVS_SWZ_W] << NV30_FP_OP_COND_SWZ_W_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetHighReg(nvsFunc *shader, int id)
|
||||
{
|
||||
if (shader->card_priv->NV30FP.num_regs < (id+1)) {
|
||||
if (id == 0)
|
||||
id = 1; /* necessary? */
|
||||
shader->card_priv->NV30FP.num_regs = (id+1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot)
|
||||
{
|
||||
unsigned int hwreg;
|
||||
|
||||
if (mask & SMASK_X) shader->inst[0] |= NV30_FP_OP_OUT_X;
|
||||
if (mask & SMASK_Y) shader->inst[0] |= NV30_FP_OP_OUT_Y;
|
||||
if (mask & SMASK_Z) shader->inst[0] |= NV30_FP_OP_OUT_Z;
|
||||
if (mask & SMASK_W) shader->inst[0] |= NV30_FP_OP_OUT_W;
|
||||
|
||||
if (reg->file == NVS_FILE_RESULT) {
|
||||
hwreg = 0; /* FIXME: this is only fragment.color */
|
||||
/* This is *not* correct, I have no idea what it is either */
|
||||
shader->inst[0] |= NV30_FP_OP_UNK0_7;
|
||||
} else {
|
||||
shader->inst[0] &= ~NV30_FP_OP_UNK0_7;
|
||||
hwreg = reg->index;
|
||||
}
|
||||
NV30FPSetHighReg(shader, hwreg);
|
||||
shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT;
|
||||
shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos)
|
||||
{
|
||||
unsigned int hwsrc = 0;
|
||||
|
||||
switch (reg->file) {
|
||||
case NVS_FILE_TEMP:
|
||||
hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT);
|
||||
hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT);
|
||||
NV30FPSetHighReg(shader, reg->index);
|
||||
break;
|
||||
case NVS_FILE_ATTRIB:
|
||||
{
|
||||
unsigned int hwin;
|
||||
|
||||
switch (reg->index) {
|
||||
case NVS_FR_POSITION : hwin = NV30_FP_OP_INPUT_SRC_POSITION; break;
|
||||
case NVS_FR_COL0 : hwin = NV30_FP_OP_INPUT_SRC_COL0; break;
|
||||
case NVS_FR_COL1 : hwin = NV30_FP_OP_INPUT_SRC_COL1; break;
|
||||
case NVS_FR_FOGCOORD : hwin = NV30_FP_OP_INPUT_SRC_FOGC; break;
|
||||
case NVS_FR_TEXCOORD0: hwin = NV30_FP_OP_INPUT_SRC_TC(0); break;
|
||||
case NVS_FR_TEXCOORD1: hwin = NV30_FP_OP_INPUT_SRC_TC(1); break;
|
||||
case NVS_FR_TEXCOORD2: hwin = NV30_FP_OP_INPUT_SRC_TC(2); break;
|
||||
case NVS_FR_TEXCOORD3: hwin = NV30_FP_OP_INPUT_SRC_TC(3); break;
|
||||
case NVS_FR_TEXCOORD4: hwin = NV30_FP_OP_INPUT_SRC_TC(4); break;
|
||||
case NVS_FR_TEXCOORD5: hwin = NV30_FP_OP_INPUT_SRC_TC(5); break;
|
||||
case NVS_FR_TEXCOORD6: hwin = NV30_FP_OP_INPUT_SRC_TC(6); break;
|
||||
case NVS_FR_TEXCOORD7: hwin = NV30_FP_OP_INPUT_SRC_TC(7); break;
|
||||
default:
|
||||
WARN_ONCE("unknown fp input %d\n", reg->index);
|
||||
hwin = NV30_FP_OP_INPUT_SRC_COL0;
|
||||
break;
|
||||
}
|
||||
shader->inst[0] &= ~NV30_FP_OP_INPUT_SRC_MASK;
|
||||
shader->inst[0] |= (hwin << NV30_FP_OP_INPUT_SRC_SHIFT);
|
||||
hwsrc |= (hwin << NV30_FP_REG_SRC_SHIFT);
|
||||
}
|
||||
hwsrc |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT);
|
||||
break;
|
||||
case NVS_FILE_CONST:
|
||||
/* consts are inlined after the inst */
|
||||
hwsrc |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (reg->negate)
|
||||
hwsrc |= NV30_FP_REG_NEGATE;
|
||||
if (reg->abs)
|
||||
shader->inst[1] |= (1 << (29+pos));
|
||||
hwsrc |= (reg->swizzle[NVS_SWZ_X] << NV30_FP_REG_SWZ_X_SHIFT);
|
||||
hwsrc |= (reg->swizzle[NVS_SWZ_Y] << NV30_FP_REG_SWZ_Y_SHIFT);
|
||||
hwsrc |= (reg->swizzle[NVS_SWZ_Z] << NV30_FP_REG_SWZ_Z_SHIFT);
|
||||
hwsrc |= (reg->swizzle[NVS_SWZ_W] << NV30_FP_REG_SWZ_W_SHIFT);
|
||||
|
||||
shader->inst[pos+1] &= ~NV30_FP_REG_ALL_MASK;
|
||||
shader->inst[pos+1] |= hwsrc;
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetTexImageUnit(nvsFunc *shader, int unit)
|
||||
{
|
||||
shader->inst[0] &= ~NV30_FP_OP_TEX_UNIT_SHIFT;
|
||||
shader->inst[0] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetSaturate(nvsFunc *shader)
|
||||
{
|
||||
shader->inst[0] |= NV30_FP_OP_OUT_SAT;
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPInitInstruction(nvsFunc *shader)
|
||||
{
|
||||
unsigned int hwsrc;
|
||||
|
||||
shader->inst[0] = 0;
|
||||
|
||||
hwsrc = (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) |
|
||||
(NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) |
|
||||
(NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) |
|
||||
(NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) |
|
||||
(NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT);
|
||||
shader->inst[1] = hwsrc;
|
||||
shader->inst[2] = hwsrc;
|
||||
shader->inst[3] = hwsrc;
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPSetLastInst(nvsFunc *shader)
|
||||
{
|
||||
shader->inst[0] |= 1;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Disassembly helpers
|
||||
*/
|
||||
static struct _op_xlat *
|
||||
NV30FPGetOPTXRec(nvsFunc * shader, int merged)
|
||||
{
|
||||
int op;
|
||||
|
||||
op = shader->GetOpcodeHW(shader, 0);
|
||||
if (op > NVFP_TX_AOP_COUNT)
|
||||
return NULL;
|
||||
if (NVFP_TX_AOP[op].SOP == NVS_OP_UNKNOWN)
|
||||
return NULL;
|
||||
return &NVFP_TX_AOP[op];
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPHasMergedInst(nvsFunc * shader)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPIsLastInst(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[0] & NV30_FP_OP_PROGRAM_END) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetOffsetNext(nvsFunc * shader)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (shader->GetSourceFile(shader, 0, i) == NVS_FILE_CONST)
|
||||
return 8;
|
||||
return 4;
|
||||
}
|
||||
|
||||
static nvsOpcode
|
||||
NV30FPGetOpcode(nvsFunc * shader, int merged)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr)
|
||||
return NVS_OP_UNKNOWN;
|
||||
|
||||
return opr->SOP;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV30FPGetOpcodeHW(nvsFunc * shader, int slot)
|
||||
{
|
||||
int op;
|
||||
|
||||
op = (shader->inst[0] & NV30_FP_OP_OPCODE_MASK) >> NV30_FP_OP_OPCODE_SHIFT;
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
static nvsRegFile
|
||||
NV30FPGetDestFile(nvsFunc * shader, int merged)
|
||||
{
|
||||
/* Result regs overlap temporary regs */
|
||||
return NVS_FILE_TEMP;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV30FPGetDestID(nvsFunc * shader, int merged)
|
||||
{
|
||||
int id;
|
||||
|
||||
switch (shader->GetDestFile(shader, merged)) {
|
||||
case NVS_FILE_TEMP:
|
||||
id = ((shader->inst[0] & NV30_FP_OP_OUT_REG_MASK)
|
||||
>> NV30_FP_OP_OUT_REG_SHIFT);
|
||||
return id;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV30FPGetDestMask(nvsFunc * shader, int merged)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
|
||||
if (shader->inst[0] & NV30_FP_OP_OUT_X) mask |= SMASK_X;
|
||||
if (shader->inst[0] & NV30_FP_OP_OUT_Y) mask |= SMASK_Y;
|
||||
if (shader->inst[0] & NV30_FP_OP_OUT_Z) mask |= SMASK_Z;
|
||||
if (shader->inst[0] & NV30_FP_OP_OUT_W) mask |= SMASK_W;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV30FPGetSourceHW(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr || opr->srcpos[pos] == -1)
|
||||
return -1;
|
||||
|
||||
return shader->inst[opr->srcpos[pos] + 1];
|
||||
}
|
||||
|
||||
static nvsRegFile
|
||||
NV30FPGetSourceFile(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
unsigned int src;
|
||||
struct _op_xlat *opr;
|
||||
int file;
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr || opr->srcpos[pos] == -1)
|
||||
return NVS_FILE_UNKNOWN;
|
||||
|
||||
switch (opr->srcpos[pos]) {
|
||||
case SPOS_ADDRESS: return NVS_FILE_ADDRESS;
|
||||
default:
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
file = (src & NV30_FP_REG_TYPE_MASK) >> NV30_FP_REG_TYPE_SHIFT;
|
||||
|
||||
switch (file) {
|
||||
case NV30_FP_REG_TYPE_TEMP : return NVS_FILE_TEMP;
|
||||
case NV30_FP_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
|
||||
case NV30_FP_REG_TYPE_CONST: return NVS_FILE_CONST;
|
||||
default:
|
||||
return NVS_FILE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetSourceID(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
switch (shader->GetSourceFile(shader, merged, pos)) {
|
||||
case NVS_FILE_ATTRIB:
|
||||
switch ((shader->inst[0] & NV30_FP_OP_INPUT_SRC_MASK)
|
||||
>> NV30_FP_OP_INPUT_SRC_SHIFT) {
|
||||
case NV30_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION;
|
||||
case NV30_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0;
|
||||
case NV30_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1;
|
||||
case NV30_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD;
|
||||
case NV30_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0;
|
||||
case NV30_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1;
|
||||
case NV30_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2;
|
||||
case NV30_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3;
|
||||
case NV30_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4;
|
||||
case NV30_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5;
|
||||
case NV30_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6;
|
||||
case NV30_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case NVS_FILE_TEMP:
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
return ((src & NV30_FP_REG_SRC_MASK) >> NV30_FP_REG_SRC_SHIFT);
|
||||
}
|
||||
case NVS_FILE_CONST: /* inlined into fragprog */
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetTexImageUnit(nvsFunc *shader)
|
||||
{
|
||||
return ((shader->inst[0] & NV30_FP_OP_TEX_UNIT_MASK)
|
||||
>> NV30_FP_OP_TEX_UNIT_SHIFT);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetSourceNegate(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
|
||||
if (src == -1)
|
||||
return -1;
|
||||
return ((src & NV30_FP_REG_NEGATE) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetSourceAbs(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
static unsigned int abspos[3] = {
|
||||
NV30_FP_OP_OUT_ABS,
|
||||
(1 << 30), /* guess */
|
||||
(1 << 31) /* guess */
|
||||
};
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr || opr->srcpos[pos] == -1)
|
||||
return -1;
|
||||
|
||||
return ((shader->inst[1] & abspos[opr->srcpos[pos]]) ? 1 : 0);
|
||||
}
|
||||
|
||||
nvsSwzComp NV30FP_TX_SWIZZLE[4] = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
|
||||
|
||||
static void
|
||||
NV30FPTXSwizzle(int hwswz, nvsSwzComp *swz)
|
||||
{
|
||||
swz[NVS_SWZ_W] = NV30FP_TX_SWIZZLE[(hwswz & 0xC0) >> 6];
|
||||
swz[NVS_SWZ_Z] = NV30FP_TX_SWIZZLE[(hwswz & 0x30) >> 4];
|
||||
swz[NVS_SWZ_Y] = NV30FP_TX_SWIZZLE[(hwswz & 0x0C) >> 2];
|
||||
swz[NVS_SWZ_X] = NV30FP_TX_SWIZZLE[(hwswz & 0x03) >> 0];
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
|
||||
{
|
||||
unsigned int src;
|
||||
int swzbits;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
swzbits = (src & NV30_FP_REG_SWZ_ALL_MASK) >> NV30_FP_REG_SWZ_ALL_SHIFT;
|
||||
NV30FPTXSwizzle(swzbits, swz);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
switch (shader->GetSourceFile(shader, merged, pos)) {
|
||||
case NVS_FILE_ATTRIB:
|
||||
return ((shader->inst[3] & NV30_FP_OP_INDEX_INPUT) ? 1 : 0);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPGetSourceConstVal(nvsFunc * shader, int merged, int pos, float *val)
|
||||
{
|
||||
val[0] = *(float *) &(shader->inst[4]);
|
||||
val[1] = *(float *) &(shader->inst[5]);
|
||||
val[2] = *(float *) &(shader->inst[6]);
|
||||
val[3] = *(float *) &(shader->inst[7]);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetSourceScale(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
/*FIXME: is this per-source, only for a specific source, or all sources??*/
|
||||
return (1 << ((shader->inst[2] & NV30_FP_OP_SRC_SCALE_MASK)
|
||||
>> NV30_FP_OP_SRC_SCALE_SHIFT));
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetAddressRegID(nvsFunc * shader)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nvsSwzComp
|
||||
NV30FPGetAddressRegSwizzle(nvsFunc * shader)
|
||||
{
|
||||
return NVS_SWZ_X;
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPSupportsConditional(nvsFunc * shader)
|
||||
{
|
||||
/*FIXME: Is this true of all ops? */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetConditionUpdate(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[0] & NV30_FP_OP_COND_WRITE_ENABLE) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetConditionTest(nvsFunc * shader)
|
||||
{
|
||||
/*FIXME: always? */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static nvsCond
|
||||
NV30FPGetCondition(nvsFunc * shader)
|
||||
{
|
||||
int cond;
|
||||
|
||||
cond = ((shader->inst[1] & NV30_FP_OP_COND_MASK)
|
||||
>> NV30_FP_OP_COND_SHIFT);
|
||||
|
||||
switch (cond) {
|
||||
case NV30_FP_OP_COND_FL: return NVS_COND_FL;
|
||||
case NV30_FP_OP_COND_LT: return NVS_COND_LT;
|
||||
case NV30_FP_OP_COND_EQ: return NVS_COND_EQ;
|
||||
case NV30_FP_OP_COND_LE: return NVS_COND_LE;
|
||||
case NV30_FP_OP_COND_GT: return NVS_COND_GT;
|
||||
case NV30_FP_OP_COND_NE: return NVS_COND_NE;
|
||||
case NV30_FP_OP_COND_GE: return NVS_COND_GE;
|
||||
case NV30_FP_OP_COND_TR: return NVS_COND_TR;
|
||||
default:
|
||||
return NVS_COND_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV30FPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
|
||||
{
|
||||
int swzbits;
|
||||
|
||||
swzbits = (shader->inst[1] & NV30_FP_OP_COND_SWZ_ALL_MASK)
|
||||
>> NV30_FP_OP_COND_SWZ_ALL_SHIFT;
|
||||
NV30FPTXSwizzle(swzbits, swz);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetCondRegID(nvsFunc * shader)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nvsPrecision
|
||||
NV30FPGetPrecision(nvsFunc * shader)
|
||||
{
|
||||
int p;
|
||||
|
||||
p = (shader->inst[0] & NV30_FP_OP_PRECISION_MASK)
|
||||
>> NV30_FP_OP_PRECISION_SHIFT;
|
||||
|
||||
switch (p) {
|
||||
case NV30_FP_PRECISION_FP32: return NVS_PREC_FLOAT32;
|
||||
case NV30_FP_PRECISION_FP16: return NVS_PREC_FLOAT16;
|
||||
case NV30_FP_PRECISION_FX12: return NVS_PREC_FIXED12;
|
||||
default:
|
||||
return NVS_PREC_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV30FPGetSaturate(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[0] & NV30_FP_OP_OUT_SAT) ? 1 : 0);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Init
|
||||
*/
|
||||
void
|
||||
NV30FPInitShaderFuncs(nvsFunc * shader)
|
||||
{
|
||||
/* These are probably bogus, I made them up... */
|
||||
shader->MaxInst = 1024;
|
||||
shader->MaxAttrib = 16;
|
||||
shader->MaxTemp = 32;
|
||||
shader->MaxAddress = 1;
|
||||
shader->MaxConst = 256;
|
||||
shader->caps = SCAP_SRC_ABS;
|
||||
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_ADD, NVS_OP_ADD, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DST, NVS_OP_DST, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FRC, NVS_OP_FRC, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FLR, NVS_OP_FLR, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TEX, NVS_OP_TEX, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXD, NVS_OP_TXD, 0, 1, 2);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXP, NVS_OP_TXP, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXB, NVS_OP_TXB, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SEQ, NVS_OP_SEQ, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGT, NVS_OP_SGT, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLE, NVS_OP_SLE, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SNE, NVS_OP_SNE, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RCP, NVS_OP_RCP, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LG2, NVS_OP_LG2, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_EX2, NVS_OP_EX2, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_COS, NVS_OP_COS, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SIN, NVS_OP_SIN, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDX, NVS_OP_DDX, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDY, NVS_OP_DDY, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_KIL, NVS_OP_KIL, -1, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4B, NVS_OP_PK4B, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4B, NVS_OP_UP4B, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2H, NVS_OP_PK2H, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2H, NVS_OP_UP2H, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4UB, NVS_OP_PK4UB, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4UB, NVS_OP_UP4UB, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2US, NVS_OP_PK2US, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2US, NVS_OP_UP2US, 0, -1, -1);
|
||||
/*FIXME: Haven't confirmed the source positions for the below opcodes */
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LIT, NVS_OP_LIT, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LRP, NVS_OP_LRP, 0, 1, 2);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_POW, NVS_OP_POW, 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RSQ, NVS_OP_RSQ, 0, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RFL, NVS_OP_RFL, 0, 1, -1);
|
||||
|
||||
shader->GetOPTXRec = NV30FPGetOPTXRec;
|
||||
shader->GetOPTXFromSOP = NV30FPGetOPTXFromSOP;
|
||||
|
||||
shader->UploadToHW = NV30FPUploadToHW;
|
||||
shader->UpdateConst = NV30FPUpdateConst;
|
||||
|
||||
shader->InitInstruction = NV30FPInitInstruction;
|
||||
shader->SupportsOpcode = NV30FPSupportsOpcode;
|
||||
shader->SetOpcode = NV30FPSetOpcode;
|
||||
shader->SetCCUpdate = NV30FPSetCCUpdate;
|
||||
shader->SetCondition = NV30FPSetCondition;
|
||||
shader->SetResult = NV30FPSetResult;
|
||||
shader->SetSource = NV30FPSetSource;
|
||||
shader->SetTexImageUnit = NV30FPSetTexImageUnit;
|
||||
shader->SetSaturate = NV30FPSetSaturate;
|
||||
shader->SetLastInst = NV30FPSetLastInst;
|
||||
|
||||
shader->HasMergedInst = NV30FPHasMergedInst;
|
||||
shader->IsLastInst = NV30FPIsLastInst;
|
||||
shader->GetOffsetNext = NV30FPGetOffsetNext;
|
||||
shader->GetOpcode = NV30FPGetOpcode;
|
||||
shader->GetOpcodeHW = NV30FPGetOpcodeHW;
|
||||
shader->GetDestFile = NV30FPGetDestFile;
|
||||
shader->GetDestID = NV30FPGetDestID;
|
||||
shader->GetDestMask = NV30FPGetDestMask;
|
||||
shader->GetSourceHW = NV30FPGetSourceHW;
|
||||
shader->GetSourceFile = NV30FPGetSourceFile;
|
||||
shader->GetSourceID = NV30FPGetSourceID;
|
||||
shader->GetTexImageUnit = NV30FPGetTexImageUnit;
|
||||
shader->GetSourceNegate = NV30FPGetSourceNegate;
|
||||
shader->GetSourceAbs = NV30FPGetSourceAbs;
|
||||
shader->GetSourceSwizzle = NV30FPGetSourceSwizzle;
|
||||
shader->GetSourceIndexed = NV30FPGetSourceIndexed;
|
||||
shader->GetSourceConstVal = NV30FPGetSourceConstVal;
|
||||
shader->GetSourceScale = NV30FPGetSourceScale;
|
||||
shader->GetRelAddressRegID = NV30FPGetAddressRegID;
|
||||
shader->GetRelAddressSwizzle = NV30FPGetAddressRegSwizzle;
|
||||
shader->GetPrecision = NV30FPGetPrecision;
|
||||
shader->GetSaturate = NV30FPGetSaturate;
|
||||
shader->SupportsConditional = NV30FPSupportsConditional;
|
||||
shader->GetConditionUpdate = NV30FPGetConditionUpdate;
|
||||
shader->GetConditionTest = NV30FPGetConditionTest;
|
||||
shader->GetCondition = NV30FPGetCondition;
|
||||
shader->GetCondRegSwizzle = NV30FPGetCondRegSwizzle;
|
||||
shader->GetCondRegID = NV30FPGetCondRegID;
|
||||
}
|
||||
|
|
@ -1,379 +0,0 @@
|
|||
#ifndef __NV30_SHADER_H__
|
||||
#define __NV30_SHADER_H__
|
||||
|
||||
/* Vertex programs instruction set
|
||||
*
|
||||
* 128bit opcodes, split into 4 32-bit ones for ease of use.
|
||||
*
|
||||
* Non-native instructions
|
||||
* ABS - MOV + NV40_VP_INST0_DEST_ABS
|
||||
* POW - EX2 + MUL + LG2
|
||||
* SUB - ADD, second source negated
|
||||
* SWZ - MOV
|
||||
* XPD -
|
||||
*
|
||||
* Register access
|
||||
* - Only one INPUT can be accessed per-instruction (move extras into TEMPs)
|
||||
* - Only one CONST can be accessed per-instruction (move extras into TEMPs)
|
||||
*
|
||||
* Relative Addressing
|
||||
* According to the value returned for MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
|
||||
* there are only two address registers available. The destination in the ARL
|
||||
* instruction is set to TEMP <n> (The temp isn't actually written).
|
||||
*
|
||||
* When using vanilla ARB_v_p, the proprietary driver will squish both the available
|
||||
* ADDRESS regs into the first hardware reg in the X and Y components.
|
||||
*
|
||||
* To use an address reg as an index into consts, the CONST_SRC is set to
|
||||
* (const_base + offset) and INDEX_CONST is set.
|
||||
*
|
||||
* To access the second address reg use ADDR_REG_SELECT_1. A particular component
|
||||
* of the address regs is selected with ADDR_SWZ.
|
||||
*
|
||||
* Only one address register can be accessed per instruction.
|
||||
*
|
||||
* Conditional execution (see NV_vertex_program{2,3} for details)
|
||||
* Conditional execution of an instruction is enabled by setting COND_TEST_ENABLE, and
|
||||
* selecting the condition which will allow the test to pass with COND_{FL,LT,...}.
|
||||
* It is possible to swizzle the values in the condition register, which allows for
|
||||
* testing against an individual component.
|
||||
*
|
||||
* Branching
|
||||
* The BRA/CAL instructions seem to follow a slightly different opcode layout. The
|
||||
* destination instruction ID (IADDR) overlaps a source field. Instruction ID's seem to
|
||||
* be numbered based on the UPLOAD_FROM_ID FIFO command, and is incremented automatically
|
||||
* on each UPLOAD_INST FIFO command.
|
||||
*
|
||||
* Conditional branching is achieved by using the condition tests described above.
|
||||
* There doesn't appear to be dedicated looping instructions, but this can be done
|
||||
* using a temp reg + conditional branching.
|
||||
*
|
||||
* Subroutines may be uploaded before the main program itself, but the first executed
|
||||
* instruction is determined by the PROGRAM_START_ID FIFO command.
|
||||
*
|
||||
*/
|
||||
|
||||
/* DWORD 0 */
|
||||
#define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
|
||||
#define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */
|
||||
#define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */
|
||||
#define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */
|
||||
#define NV30_VP_INST_OUT_RESULT (1 << 20)
|
||||
#define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16
|
||||
#define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16)
|
||||
#define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15)
|
||||
#define NV30_VP_INST_COND_TEST_ENABLE (1<<14)
|
||||
#define NV30_VP_INST_COND_SHIFT 11
|
||||
#define NV30_VP_INST_COND_MASK (0x07 << 11)
|
||||
# define NV30_VP_INST_COND_FL 0 /* guess */
|
||||
# define NV30_VP_INST_COND_LT 1
|
||||
# define NV30_VP_INST_COND_EQ 2
|
||||
# define NV30_VP_INST_COND_LE 3
|
||||
# define NV30_VP_INST_COND_GT 4
|
||||
# define NV30_VP_INST_COND_NE 5
|
||||
# define NV30_VP_INST_COND_GE 6
|
||||
# define NV30_VP_INST_COND_TR 7 /* guess */
|
||||
#define NV30_VP_INST_COND_SWZ_X_SHIFT 9
|
||||
#define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9)
|
||||
#define NV30_VP_INST_COND_SWZ_Y_SHIFT 7
|
||||
#define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7)
|
||||
#define NV30_VP_INST_COND_SWZ_Z_SHIFT 5
|
||||
#define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5)
|
||||
#define NV30_VP_INST_COND_SWZ_W_SHIFT 3
|
||||
#define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3)
|
||||
#define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3
|
||||
#define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3)
|
||||
#define NV30_VP_INST_ADDR_SWZ_SHIFT 1
|
||||
#define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1)
|
||||
#define NV30_VP_INST_SCA_OPCODEH_SHIFT 0
|
||||
#define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0)
|
||||
|
||||
/* DWORD 1 */
|
||||
#define NV30_VP_INST_SCA_OPCODEL_SHIFT 28
|
||||
#define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28)
|
||||
# define NV30_VP_INST_OP_NOP 0x00
|
||||
# define NV30_VP_INST_OP_RCP 0x02
|
||||
# define NV30_VP_INST_OP_RCC 0x03
|
||||
# define NV30_VP_INST_OP_RSQ 0x04
|
||||
# define NV30_VP_INST_OP_EXP 0x05
|
||||
# define NV30_VP_INST_OP_LOG 0x06
|
||||
# define NV30_VP_INST_OP_LIT 0x07
|
||||
# define NV30_VP_INST_OP_BRA 0x09
|
||||
# define NV30_VP_INST_OP_CAL 0x0B
|
||||
# define NV30_VP_INST_OP_RET 0x0C
|
||||
# define NV30_VP_INST_OP_LG2 0x0D
|
||||
# define NV30_VP_INST_OP_EX2 0x0E
|
||||
# define NV30_VP_INST_OP_SIN 0x0F
|
||||
# define NV30_VP_INST_OP_COS 0x10
|
||||
#define NV30_VP_INST_VEC_OPCODE_SHIFT 23
|
||||
#define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23)
|
||||
# define NV30_VP_INST_OP_NOPV 0x00
|
||||
# define NV30_VP_INST_OP_MOV 0x01
|
||||
# define NV30_VP_INST_OP_MUL 0x02
|
||||
# define NV30_VP_INST_OP_ADD 0x03
|
||||
# define NV30_VP_INST_OP_MAD 0x04
|
||||
# define NV30_VP_INST_OP_DP3 0x05
|
||||
# define NV30_VP_INST_OP_DP4 0x07
|
||||
# define NV30_VP_INST_OP_DPH 0x06
|
||||
# define NV30_VP_INST_OP_DST 0x08
|
||||
# define NV30_VP_INST_OP_MIN 0x09
|
||||
# define NV30_VP_INST_OP_MAX 0x0A
|
||||
# define NV30_VP_INST_OP_SLT 0x0B
|
||||
# define NV30_VP_INST_OP_SGE 0x0C
|
||||
# define NV30_VP_INST_OP_ARL 0x0D
|
||||
# define NV30_VP_INST_OP_FRC 0x0E
|
||||
# define NV30_VP_INST_OP_FLR 0x0F
|
||||
# define NV30_VP_INST_OP_SEQ 0x10
|
||||
# define NV30_VP_INST_OP_SFL 0x11
|
||||
# define NV30_VP_INST_OP_SGT 0x12
|
||||
# define NV30_VP_INST_OP_SLE 0x13
|
||||
# define NV30_VP_INST_OP_SNE 0x14
|
||||
# define NV30_VP_INST_OP_STR 0x15
|
||||
# define NV30_VP_INST_OP_SSG 0x16
|
||||
# define NV30_VP_INST_OP_ARR 0x17
|
||||
# define NV30_VP_INST_OP_ARA 0x18
|
||||
#define NV30_VP_INST_CONST_SRC_SHIFT 14
|
||||
#define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14)
|
||||
#define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/
|
||||
#define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/
|
||||
# define NV30_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */
|
||||
# define NV30_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */
|
||||
# define NV30_VP_INST_IN_NORMAL 2
|
||||
# define NV30_VP_INST_IN_COL0 3 /* Should probably confirm them all though */
|
||||
# define NV30_VP_INST_IN_COL1 4
|
||||
# define NV30_VP_INST_IN_FOGC 5
|
||||
# define NV30_VP_INST_IN_TC0 8
|
||||
# define NV30_VP_INST_IN_TC(n) (8+n)
|
||||
#define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/
|
||||
#define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/
|
||||
|
||||
/* DWORD 2 */
|
||||
#define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/
|
||||
#define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /*NV20*/
|
||||
#define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/
|
||||
#define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/
|
||||
#define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/
|
||||
#define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /*NV20*/
|
||||
#define NV30_VP_INST_IADDR_SHIFT 2
|
||||
#define NV30_VP_INST_IADDR_MASK (0xFF << 2) /* guess */
|
||||
|
||||
/* DWORD 3 */
|
||||
#define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/
|
||||
#define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/
|
||||
#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24
|
||||
#define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24)
|
||||
#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20
|
||||
#define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20)
|
||||
#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16
|
||||
#define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16)
|
||||
#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/
|
||||
#define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/
|
||||
#define NV30_VP_INST_DEST_ID_SHIFT 2
|
||||
#define NV30_VP_INST_DEST_ID_MASK (0x0F << 2)
|
||||
# define NV30_VP_INST_DEST_POS 0
|
||||
# define NV30_VP_INST_DEST_COL0 3
|
||||
# define NV30_VP_INST_DEST_COL1 4
|
||||
# define NV30_VP_INST_DEST_TC(n) (8+n)
|
||||
|
||||
/* Source-register definition - matches NV20 exactly */
|
||||
#define NV30_VP_SRC_REG_NEGATE (1<<14)
|
||||
#define NV30_VP_SRC_REG_SWZ_X_SHIFT 12
|
||||
#define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12)
|
||||
#define NV30_VP_SRC_REG_SWZ_Y_SHIFT 10
|
||||
#define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10)
|
||||
#define NV30_VP_SRC_REG_SWZ_Z_SHIFT 8
|
||||
#define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8)
|
||||
#define NV30_VP_SRC_REG_SWZ_W_SHIFT 6
|
||||
#define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6)
|
||||
#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6
|
||||
#define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6)
|
||||
#define NV30_VP_SRC_REG_TEMP_ID_SHIFT 2
|
||||
#define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0)
|
||||
#define NV30_VP_SRC_REG_TYPE_SHIFT 0
|
||||
#define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0)
|
||||
#define NV30_VP_SRC_REG_TYPE_TEMP 1
|
||||
#define NV30_VP_SRC_REG_TYPE_INPUT 2
|
||||
#define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */
|
||||
|
||||
/*
|
||||
* Each fragment program opcode appears to be comprised of 4 32-bit values.
|
||||
*
|
||||
* 0 - Opcode, output reg/mask, ATTRIB source
|
||||
* 1 - Source 0
|
||||
* 2 - Source 1
|
||||
* 3 - Source 2
|
||||
*
|
||||
* There appears to be no special difference between result regs and temp regs.
|
||||
* result.color == R0.xyzw
|
||||
* result.depth == R1.z
|
||||
* When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0
|
||||
* otherwise it is set to 1.
|
||||
*
|
||||
* Constants are inserted directly after the instruction that uses them.
|
||||
*
|
||||
* It appears that it's not possible to use two input registers in one
|
||||
* instruction as the input sourcing is done in the instruction dword
|
||||
* and not the source selection dwords. As such instructions such as:
|
||||
*
|
||||
* ADD result.color, fragment.color, fragment.texcoord[0];
|
||||
*
|
||||
* must be split into two MOV's and then an ADD (nvidia does this) but
|
||||
* I'm not sure why it's not just one MOV and then source the second input
|
||||
* in the ADD instruction..
|
||||
*
|
||||
* Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
|
||||
* negation requires multiplication with a const.
|
||||
*
|
||||
* Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE
|
||||
* The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO
|
||||
* is implemented simply by not writing to the relevant components of the destination.
|
||||
*
|
||||
* Conditional execution
|
||||
* TODO
|
||||
*
|
||||
* Non-native instructions:
|
||||
* LIT
|
||||
* LRP - MAD+MAD
|
||||
* SUB - ADD, negate second source
|
||||
* RSQ - LG2 + EX2
|
||||
* POW - LG2 + MUL + EX2
|
||||
* SCS - COS + SIN
|
||||
* XPD
|
||||
*/
|
||||
|
||||
//== Opcode / Destination selection ==
|
||||
#define NV30_FP_OP_PROGRAM_END (1 << 0)
|
||||
#define NV30_FP_OP_OUT_REG_SHIFT 1
|
||||
#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */
|
||||
/* Needs to be set when writing outputs to get expected result.. */
|
||||
#define NV30_FP_OP_UNK0_7 (1 << 7)
|
||||
#define NV30_FP_OP_COND_WRITE_ENABLE (1 << 8)
|
||||
#define NV30_FP_OP_OUTMASK_SHIFT 9
|
||||
#define NV30_FP_OP_OUTMASK_MASK (0xF << 9)
|
||||
# define NV30_FP_OP_OUT_X (1<<9)
|
||||
# define NV30_FP_OP_OUT_Y (1<<10)
|
||||
# define NV30_FP_OP_OUT_Z (1<<11)
|
||||
# define NV30_FP_OP_OUT_W (1<<12)
|
||||
/* Uncertain about these, especially the input_src values.. it's possible that
|
||||
* they can be dynamically changed.
|
||||
*/
|
||||
#define NV30_FP_OP_INPUT_SRC_SHIFT 13
|
||||
#define NV30_FP_OP_INPUT_SRC_MASK (15 << 13)
|
||||
# define NV30_FP_OP_INPUT_SRC_POSITION 0x0
|
||||
# define NV30_FP_OP_INPUT_SRC_COL0 0x1
|
||||
# define NV30_FP_OP_INPUT_SRC_COL1 0x2
|
||||
# define NV30_FP_OP_INPUT_SRC_FOGC 0x3
|
||||
# define NV30_FP_OP_INPUT_SRC_TC0 0x4
|
||||
# define NV30_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
|
||||
#define NV30_FP_OP_TEX_UNIT_SHIFT 17
|
||||
#define NV30_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */
|
||||
#define NV30_FP_OP_PRECISION_SHIFT 22
|
||||
#define NV30_FP_OP_PRECISION_MASK (3 << 22)
|
||||
# define NV30_FP_PRECISION_FP32 0
|
||||
# define NV30_FP_PRECISION_FP16 1
|
||||
# define NV30_FP_PRECISION_FX12 2
|
||||
#define NV30_FP_OP_OPCODE_SHIFT 24
|
||||
#define NV30_FP_OP_OPCODE_MASK (0x3F << 24)
|
||||
# define NV30_FP_OP_OPCODE_NOP 0x00
|
||||
# define NV30_FP_OP_OPCODE_MOV 0x01
|
||||
# define NV30_FP_OP_OPCODE_MUL 0x02
|
||||
# define NV30_FP_OP_OPCODE_ADD 0x03
|
||||
# define NV30_FP_OP_OPCODE_MAD 0x04
|
||||
# define NV30_FP_OP_OPCODE_DP3 0x05
|
||||
# define NV30_FP_OP_OPCODE_DP4 0x06
|
||||
# define NV30_FP_OP_OPCODE_DST 0x07
|
||||
# define NV30_FP_OP_OPCODE_MIN 0x08
|
||||
# define NV30_FP_OP_OPCODE_MAX 0x09
|
||||
# define NV30_FP_OP_OPCODE_SLT 0x0A
|
||||
# define NV30_FP_OP_OPCODE_SGE 0x0B
|
||||
# define NV30_FP_OP_OPCODE_SLE 0x0C
|
||||
# define NV30_FP_OP_OPCODE_SGT 0x0D
|
||||
# define NV30_FP_OP_OPCODE_SNE 0x0E
|
||||
# define NV30_FP_OP_OPCODE_SEQ 0x0F
|
||||
# define NV30_FP_OP_OPCODE_FRC 0x10
|
||||
# define NV30_FP_OP_OPCODE_FLR 0x11
|
||||
# define NV30_FP_OP_OPCODE_KIL 0x12
|
||||
# define NV30_FP_OP_OPCODE_PK4B 0x13
|
||||
# define NV30_FP_OP_OPCODE_UP4B 0x14
|
||||
# define NV30_FP_OP_OPCODE_DDX 0x15 /* can only write XY */
|
||||
# define NV30_FP_OP_OPCODE_DDY 0x16 /* can only write XY */
|
||||
# define NV30_FP_OP_OPCODE_TEX 0x17
|
||||
# define NV30_FP_OP_OPCODE_TXP 0x18
|
||||
# define NV30_FP_OP_OPCODE_TXD 0x19
|
||||
# define NV30_FP_OP_OPCODE_RCP 0x1A
|
||||
# define NV30_FP_OP_OPCODE_RSQ 0x1B
|
||||
# define NV30_FP_OP_OPCODE_EX2 0x1C
|
||||
# define NV30_FP_OP_OPCODE_LG2 0x1D
|
||||
# define NV30_FP_OP_OPCODE_LIT 0x1E
|
||||
# define NV30_FP_OP_OPCODE_LRP 0x1F
|
||||
# define NV30_FP_OP_OPCODE_COS 0x22
|
||||
# define NV30_FP_OP_OPCODE_SIN 0x23
|
||||
# define NV30_FP_OP_OPCODE_PK2H 0x24
|
||||
# define NV30_FP_OP_OPCODE_UP2H 0x25
|
||||
# define NV30_FP_OP_OPCODE_POW 0x26
|
||||
# define NV30_FP_OP_OPCODE_PK4UB 0x27
|
||||
# define NV30_FP_OP_OPCODE_UP4UB 0x28
|
||||
# define NV30_FP_OP_OPCODE_PK2US 0x29
|
||||
# define NV30_FP_OP_OPCODE_UP2US 0x2A
|
||||
# define NV30_FP_OP_OPCODE_DP2A 0x2E
|
||||
# define NV30_FP_OP_OPCODE_TXB 0x31
|
||||
# define NV30_FP_OP_OPCODE_RFL 0x36
|
||||
#define NV30_FP_OP_OUT_SAT (1 << 31)
|
||||
|
||||
/* high order bits of SRC0 */
|
||||
#define NV30_FP_OP_OUT_ABS (1 << 29)
|
||||
#define NV30_FP_OP_COND_SWZ_W_SHIFT 27
|
||||
#define NV30_FP_OP_COND_SWZ_W_MASK (3 << 27)
|
||||
#define NV30_FP_OP_COND_SWZ_Z_SHIFT 25
|
||||
#define NV30_FP_OP_COND_SWZ_Z_MASK (3 << 25)
|
||||
#define NV30_FP_OP_COND_SWZ_Y_SHIFT 23
|
||||
#define NV30_FP_OP_COND_SWZ_Y_MASK (3 << 23)
|
||||
#define NV30_FP_OP_COND_SWZ_X_SHIFT 21
|
||||
#define NV30_FP_OP_COND_SWZ_X_MASK (3 << 21)
|
||||
#define NV30_FP_OP_COND_SWZ_ALL_SHIFT 21
|
||||
#define NV30_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
|
||||
#define NV30_FP_OP_COND_SHIFT 18
|
||||
#define NV30_FP_OP_COND_MASK (0x07 << 18)
|
||||
# define NV30_FP_OP_COND_FL 0
|
||||
# define NV30_FP_OP_COND_LT 1
|
||||
# define NV30_FP_OP_COND_EQ 2
|
||||
# define NV30_FP_OP_COND_LE 3
|
||||
# define NV30_FP_OP_COND_GT 4
|
||||
# define NV30_FP_OP_COND_NE 5
|
||||
# define NV30_FP_OP_COND_GE 6
|
||||
# define NV30_FP_OP_COND_TR 7
|
||||
|
||||
/* high order bits of SRC1 */
|
||||
#define NV30_FP_OP_SRC_SCALE_SHIFT 28
|
||||
#define NV30_FP_OP_SRC_SCALE_MASK (3 << 28)
|
||||
|
||||
/* high order bits of SRC2 */
|
||||
#define NV30_FP_OP_INDEX_INPUT (1 << 30)
|
||||
|
||||
//== Register selection ==
|
||||
#define NV30_FP_REG_ALL_MASK (0x1FFFF<<0)
|
||||
#define NV30_FP_REG_TYPE_SHIFT 0
|
||||
#define NV30_FP_REG_TYPE_MASK (3 << 0)
|
||||
# define NV30_FP_REG_TYPE_TEMP 0
|
||||
# define NV30_FP_REG_TYPE_INPUT 1
|
||||
# define NV30_FP_REG_TYPE_CONST 2
|
||||
#define NV30_FP_REG_SRC_SHIFT 2 /* uncertain */
|
||||
#define NV30_FP_REG_SRC_MASK (31 << 2)
|
||||
#define NV30_FP_REG_UNK_0 (1 << 8)
|
||||
#define NV30_FP_REG_SWZ_ALL_SHIFT 9
|
||||
#define NV30_FP_REG_SWZ_ALL_MASK (255 << 9)
|
||||
#define NV30_FP_REG_SWZ_X_SHIFT 9
|
||||
#define NV30_FP_REG_SWZ_X_MASK (3 << 9)
|
||||
#define NV30_FP_REG_SWZ_Y_SHIFT 11
|
||||
#define NV30_FP_REG_SWZ_Y_MASK (3 << 11)
|
||||
#define NV30_FP_REG_SWZ_Z_SHIFT 13
|
||||
#define NV30_FP_REG_SWZ_Z_MASK (3 << 13)
|
||||
#define NV30_FP_REG_SWZ_W_SHIFT 15
|
||||
#define NV30_FP_REG_SWZ_W_MASK (3 << 15)
|
||||
# define NV30_FP_SWIZZLE_X 0
|
||||
# define NV30_FP_SWIZZLE_Y 1
|
||||
# define NV30_FP_SWIZZLE_Z 2
|
||||
# define NV30_FP_SWIZZLE_W 3
|
||||
#define NV30_FP_REG_NEGATE (1 << 17)
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,367 +0,0 @@
|
|||
#include "nouveau_context.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_reg.h"
|
||||
|
||||
#include "nouveau_shader.h"
|
||||
#include "nv30_shader.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Support routines
|
||||
*/
|
||||
static void
|
||||
NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
int i;
|
||||
|
||||
/* We can do better here and keep more than one VP on the hardware, and
|
||||
* switch between them with PROGRAM_START_ID..
|
||||
*/
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID, 1);
|
||||
OUT_RING(0);
|
||||
for (i=0; i<nvs->program_size; i+=4) {
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4);
|
||||
OUT_RING(nvs->program[i + 0]);
|
||||
OUT_RING(nvs->program[i + 1]);
|
||||
OUT_RING(nvs->program[i + 2]);
|
||||
OUT_RING(nvs->program[i + 3]);
|
||||
}
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1);
|
||||
OUT_RING(0);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2);
|
||||
OUT_RING(nvs->card_priv.NV30VP.vp_in_reg);
|
||||
OUT_RING(nvs->card_priv.NV30VP.vp_out_reg);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1);
|
||||
OUT_RING_CACHE (nvs->card_priv.NV30VP.clip_enables);
|
||||
}
|
||||
|
||||
static void
|
||||
NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLfloat *val;
|
||||
|
||||
val = nvs->params[id].source_val ?
|
||||
nvs->params[id].source_val : nvs->params[id].val;
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 5);
|
||||
OUT_RING (id);
|
||||
OUT_RINGp(val, 4);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Assembly routines
|
||||
*/
|
||||
static void
|
||||
NV30VPSetBranchTarget(nvsFunc *shader, int addr)
|
||||
{
|
||||
shader->inst[2] &= ~NV30_VP_INST_IADDR_MASK;
|
||||
shader->inst[2] |= (addr << NV30_VP_INST_IADDR_SHIFT);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Disassembly routines
|
||||
*/
|
||||
static unsigned int
|
||||
NV30VPGetOpcodeHW(nvsFunc * shader, int slot)
|
||||
{
|
||||
int op;
|
||||
|
||||
if (slot) {
|
||||
op = (shader->inst[1] & NV30_VP_INST_SCA_OPCODEL_MASK)
|
||||
>> NV30_VP_INST_SCA_OPCODEL_SHIFT;
|
||||
op |= ((shader->inst[0] & NV30_VP_INST_SCA_OPCODEH_MASK)
|
||||
>> NV30_VP_INST_SCA_OPCODEH_SHIFT) << 4;
|
||||
}
|
||||
else {
|
||||
op = (shader->inst[1] & NV30_VP_INST_VEC_OPCODE_MASK)
|
||||
>> NV30_VP_INST_VEC_OPCODE_SHIFT;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
static nvsRegFile
|
||||
NV30VPGetDestFile(nvsFunc * shader, int merged)
|
||||
{
|
||||
switch (shader->GetOpcode(shader, merged)) {
|
||||
case NVS_OP_ARL:
|
||||
case NVS_OP_ARR:
|
||||
case NVS_OP_ARA:
|
||||
return NVS_FILE_ADDRESS;
|
||||
default:
|
||||
/*FIXME: This probably isn't correct.. */
|
||||
if ((shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK) != 0)
|
||||
return NVS_FILE_RESULT;
|
||||
if ((shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK) != 0)
|
||||
return NVS_FILE_RESULT;
|
||||
return NVS_FILE_TEMP;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV30VPGetDestID(nvsFunc * shader, int merged)
|
||||
{
|
||||
int id;
|
||||
|
||||
switch (shader->GetDestFile(shader, merged)) {
|
||||
case NVS_FILE_RESULT:
|
||||
id = ((shader->inst[3] & NV30_VP_INST_DEST_ID_MASK)
|
||||
>> NV30_VP_INST_DEST_ID_SHIFT);
|
||||
switch (id) {
|
||||
case NV30_VP_INST_DEST_POS : return NVS_FR_POSITION;
|
||||
case NV30_VP_INST_DEST_COL0 : return NVS_FR_COL0;
|
||||
case NV30_VP_INST_DEST_COL1 : return NVS_FR_COL1;
|
||||
case NV30_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
|
||||
case NV30_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
|
||||
case NV30_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
|
||||
case NV30_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
|
||||
case NV30_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4;
|
||||
case NV30_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5;
|
||||
case NV30_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6;
|
||||
case NV30_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
case NVS_FILE_ADDRESS:
|
||||
case NVS_FILE_TEMP:
|
||||
return (shader->inst[0] & NV30_VP_INST_DEST_TEMP_ID_MASK)
|
||||
>> NV30_VP_INST_DEST_TEMP_ID_SHIFT;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV30VPGetDestMask(nvsFunc * shader, int merged)
|
||||
{
|
||||
int hwmask, mask = 0;
|
||||
|
||||
if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT)
|
||||
if (shader->GetOpcodeSlot(shader, merged))
|
||||
hwmask = (shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK)
|
||||
>> NV30_VP_INST_SDEST_WRITEMASK_SHIFT;
|
||||
else
|
||||
hwmask = (shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK)
|
||||
>> NV30_VP_INST_VDEST_WRITEMASK_SHIFT;
|
||||
else if (shader->GetOpcodeSlot(shader, merged))
|
||||
hwmask = (shader->inst[3] & NV30_VP_INST_STEMP_WRITEMASK_MASK)
|
||||
>> NV30_VP_INST_STEMP_WRITEMASK_SHIFT;
|
||||
else
|
||||
hwmask = (shader->inst[3] & NV30_VP_INST_VTEMP_WRITEMASK_MASK)
|
||||
>> NV30_VP_INST_VTEMP_WRITEMASK_SHIFT;
|
||||
|
||||
if (hwmask & (1 << 3)) mask |= SMASK_X;
|
||||
if (hwmask & (1 << 2)) mask |= SMASK_Y;
|
||||
if (hwmask & (1 << 1)) mask |= SMASK_Z;
|
||||
if (hwmask & (1 << 0)) mask |= SMASK_W;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static int
|
||||
NV30VPGetSourceID(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
switch (shader->GetSourceFile(shader, merged, pos)) {
|
||||
case NVS_FILE_TEMP:
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
return ((src & NV30_VP_SRC_REG_TEMP_ID_MASK) >>
|
||||
NV30_VP_SRC_REG_TEMP_ID_SHIFT);
|
||||
case NVS_FILE_CONST:
|
||||
return ((shader->inst[1] & NV30_VP_INST_CONST_SRC_MASK)
|
||||
>> NV30_VP_INST_CONST_SRC_SHIFT);
|
||||
case NVS_FILE_ATTRIB:
|
||||
src = ((shader->inst[1] & NV30_VP_INST_INPUT_SRC_MASK)
|
||||
>> NV30_VP_INST_INPUT_SRC_SHIFT);
|
||||
switch (src) {
|
||||
case NV30_VP_INST_IN_POS : return NVS_FR_POSITION;
|
||||
case NV30_VP_INST_IN_COL0 : return NVS_FR_COL0;
|
||||
case NV30_VP_INST_IN_COL1 : return NVS_FR_COL1;
|
||||
case NV30_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0;
|
||||
case NV30_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1;
|
||||
case NV30_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2;
|
||||
case NV30_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3;
|
||||
case NV30_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4;
|
||||
case NV30_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5;
|
||||
case NV30_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6;
|
||||
case NV30_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7;
|
||||
default:
|
||||
return NVS_FR_UNKNOWN;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV30VPGetSourceAbs(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
static unsigned int abspos[3] = {
|
||||
NV30_VP_INST_SRC0_ABS,
|
||||
NV30_VP_INST_SRC1_ABS,
|
||||
NV30_VP_INST_SRC2_ABS,
|
||||
};
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr || opr->srcpos[pos] == -1 || opr->srcpos[pos] > 2)
|
||||
return 0;
|
||||
|
||||
return ((shader->inst[0] & abspos[opr->srcpos[pos]]) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30VPGetRelAddressRegID(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[0] & NV30_VP_INST_ADDR_REG_SELECT_1) ? 1 : 0);
|
||||
}
|
||||
|
||||
static nvsSwzComp
|
||||
NV30VPGetRelAddressSwizzle(nvsFunc * shader)
|
||||
{
|
||||
nvsSwzComp swz;
|
||||
|
||||
swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV30_VP_INST_ADDR_SWZ_MASK)
|
||||
>> NV30_VP_INST_ADDR_SWZ_SHIFT];
|
||||
return swz;
|
||||
}
|
||||
|
||||
static int
|
||||
NV30VPSupportsConditional(nvsFunc * shader)
|
||||
{
|
||||
/*FIXME: Is this true of all ops? */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
NV30VPGetConditionUpdate(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[0] & NV30_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30VPGetConditionTest(nvsFunc * shader)
|
||||
{
|
||||
int op;
|
||||
|
||||
/* The condition test is unconditionally enabled on some
|
||||
* instructions. ie: the condition test bit does *NOT* have
|
||||
* to be set.
|
||||
*
|
||||
* FIXME: check other relevant ops for this situation.
|
||||
*/
|
||||
op = shader->GetOpcodeHW(shader, 1);
|
||||
switch (op) {
|
||||
case NV30_VP_INST_OP_BRA:
|
||||
return 1;
|
||||
default:
|
||||
return ((shader->inst[0] & NV30_VP_INST_COND_TEST_ENABLE) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
static nvsCond
|
||||
NV30VPGetCondition(nvsFunc * shader)
|
||||
{
|
||||
int cond;
|
||||
|
||||
cond = ((shader->inst[0] & NV30_VP_INST_COND_MASK)
|
||||
>> NV30_VP_INST_COND_SHIFT);
|
||||
|
||||
switch (cond) {
|
||||
case NV30_VP_INST_COND_FL: return NVS_COND_FL;
|
||||
case NV30_VP_INST_COND_LT: return NVS_COND_LT;
|
||||
case NV30_VP_INST_COND_EQ: return NVS_COND_EQ;
|
||||
case NV30_VP_INST_COND_LE: return NVS_COND_LE;
|
||||
case NV30_VP_INST_COND_GT: return NVS_COND_GT;
|
||||
case NV30_VP_INST_COND_NE: return NVS_COND_NE;
|
||||
case NV30_VP_INST_COND_GE: return NVS_COND_GE;
|
||||
case NV30_VP_INST_COND_TR: return NVS_COND_TR;
|
||||
default:
|
||||
return NVS_COND_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV30VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
|
||||
{
|
||||
int swzbits;
|
||||
|
||||
swzbits = (shader->inst[0] & NV30_VP_INST_COND_SWZ_ALL_MASK)
|
||||
>> NV30_VP_INST_COND_SWZ_ALL_SHIFT;
|
||||
NV20VPTXSwizzle(swzbits, swz);
|
||||
}
|
||||
|
||||
static int
|
||||
NV30VPGetCondRegID(nvsFunc * shader)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
NV30VPGetBranch(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[2] & NV30_VP_INST_IADDR_MASK)
|
||||
>> NV30_VP_INST_IADDR_SHIFT);
|
||||
}
|
||||
|
||||
void
|
||||
NV30VPInitShaderFuncs(nvsFunc * shader)
|
||||
{
|
||||
/* Inherit NV20 code, a lot of it is the same */
|
||||
NV20VPInitShaderFuncs(shader);
|
||||
|
||||
/* Increase max valid opcode ID, and add new instructions */
|
||||
NVVP_TX_VOP_COUNT = NVVP_TX_NVS_OP_COUNT = 32;
|
||||
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FRC, NVS_OP_FRC, 0, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FLR, NVS_OP_FLR, 0, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SEQ, NVS_OP_SEQ, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SFL, NVS_OP_SFL, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SGT, NVS_OP_SGT, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SLE, NVS_OP_SLE, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SNE, NVS_OP_SNE, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_STR, NVS_OP_STR, 0, 1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SSG, NVS_OP_SSG, 0, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARR, NVS_OP_ARR, 0, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARA, NVS_OP_ARA, 3, -1, -1);
|
||||
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_BRA, NVS_OP_BRA, -1, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_CAL, NVS_OP_CAL, -1, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_RET, NVS_OP_RET, -1, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_LG2, NVS_OP_LG2, 2, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_EX2, NVS_OP_EX2, 2, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_SIN, NVS_OP_SIN, 2, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_COS, NVS_OP_COS, 2, -1, -1);
|
||||
|
||||
shader->UploadToHW = NV30VPUploadToHW;
|
||||
shader->UpdateConst = NV30VPUpdateConst;
|
||||
|
||||
shader->GetOpcodeHW = NV30VPGetOpcodeHW;
|
||||
|
||||
shader->GetDestFile = NV30VPGetDestFile;
|
||||
shader->GetDestID = NV30VPGetDestID;
|
||||
shader->GetDestMask = NV30VPGetDestMask;
|
||||
|
||||
shader->GetSourceID = NV30VPGetSourceID;
|
||||
shader->GetSourceAbs = NV30VPGetSourceAbs;
|
||||
|
||||
shader->GetRelAddressRegID = NV30VPGetRelAddressRegID;
|
||||
shader->GetRelAddressSwizzle = NV30VPGetRelAddressSwizzle;
|
||||
|
||||
shader->SupportsConditional = NV30VPSupportsConditional;
|
||||
shader->GetConditionUpdate = NV30VPGetConditionUpdate;
|
||||
shader->GetConditionTest = NV30VPGetConditionTest;
|
||||
shader->GetCondition = NV30VPGetCondition;
|
||||
shader->GetCondRegSwizzle = NV30VPGetCondRegSwizzle;
|
||||
shader->GetCondRegID = NV30VPGetCondRegID;
|
||||
|
||||
shader->GetBranch = NV30VPGetBranch;
|
||||
shader->SetBranchTarget = NV30VPSetBranchTarget;
|
||||
}
|
||||
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
#include "nouveau_shader.h"
|
||||
#include "nv40_shader.h"
|
||||
|
||||
/* branching ops */
|
||||
unsigned int NVFP_TX_BOP_COUNT = 5;
|
||||
struct _op_xlat NVFP_TX_BOP[64];
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Assembly routines
|
||||
* - These extend the NV30 routines, which are almost identical. NV40
|
||||
* just has branching hacked into the instruction set.
|
||||
*/
|
||||
static int
|
||||
NV40FPSupportsResultScale(nvsFunc *shader, nvsScale scale)
|
||||
{
|
||||
switch (scale) {
|
||||
case NVS_SCALE_1X:
|
||||
case NVS_SCALE_2X:
|
||||
case NVS_SCALE_4X:
|
||||
case NVS_SCALE_8X:
|
||||
case NVS_SCALE_INV_2X:
|
||||
case NVS_SCALE_INV_4X:
|
||||
case NVS_SCALE_INV_8X:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV40FPSetResultScale(nvsFunc *shader, nvsScale scale)
|
||||
{
|
||||
shader->inst[2] &= ~NV40_FP_OP_DST_SCALE_MASK;
|
||||
shader->inst[2] |= ((unsigned int)scale << NV40_FP_OP_DST_SCALE_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV40FPSetBranchTarget(nvsFunc *shader, int addr)
|
||||
{
|
||||
shader->inst[2] &= ~NV40_FP_OP_IADDR_MASK;
|
||||
shader->inst[2] |= (addr << NV40_FP_OP_IADDR_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV40FPSetBranchElse(nvsFunc *shader, int addr)
|
||||
{
|
||||
shader->inst[2] &= ~NV40_FP_OP_ELSE_ID_MASK;
|
||||
shader->inst[2] |= (addr << NV40_FP_OP_ELSE_ID_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV40FPSetBranchEnd(nvsFunc *shader, int addr)
|
||||
{
|
||||
shader->inst[3] &= ~NV40_FP_OP_END_ID_MASK;
|
||||
shader->inst[3] |= (addr << NV40_FP_OP_END_ID_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV40FPSetLoopParams(nvsFunc *shader, int count, int initial, int increment)
|
||||
{
|
||||
shader->inst[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK |
|
||||
NV40_FP_OP_LOOP_INDEX_MASK |
|
||||
NV40_FP_OP_LOOP_INCR_MASK);
|
||||
shader->inst[2] |= ((count << NV40_FP_OP_LOOP_COUNT_SHIFT) |
|
||||
(initial << NV40_FP_OP_LOOP_INDEX_SHIFT) |
|
||||
(increment << NV40_FP_OP_LOOP_INCR_SHIFT));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Disassembly routines
|
||||
*/
|
||||
static struct _op_xlat *
|
||||
NV40FPGetOPTXRec(nvsFunc * shader, int merged)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
int op;
|
||||
|
||||
op = shader->GetOpcodeHW(shader, 0);
|
||||
if (shader->inst[2] & NV40_FP_OP_OPCODE_IS_BRANCH) {
|
||||
opr = NVFP_TX_BOP;
|
||||
op &= ~NV40_FP_OP_OPCODE_IS_BRANCH;
|
||||
if (op > NVFP_TX_BOP_COUNT)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
opr = NVFP_TX_AOP;
|
||||
if (op > NVFP_TX_AOP_COUNT)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (opr[op].SOP == NVS_OP_UNKNOWN)
|
||||
return NULL;
|
||||
return &opr[op];
|
||||
}
|
||||
|
||||
static int
|
||||
NV40FPGetSourceID(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
switch (shader->GetSourceFile(shader, merged, pos)) {
|
||||
case NVS_FILE_ATTRIB:
|
||||
switch ((shader->inst[0] & NV40_FP_OP_INPUT_SRC_MASK)
|
||||
>> NV40_FP_OP_INPUT_SRC_SHIFT) {
|
||||
case NV40_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION;
|
||||
case NV40_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0;
|
||||
case NV40_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1;
|
||||
case NV40_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD;
|
||||
case NV40_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0;
|
||||
case NV40_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1;
|
||||
case NV40_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2;
|
||||
case NV40_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3;
|
||||
case NV40_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4;
|
||||
case NV40_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5;
|
||||
case NV40_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6;
|
||||
case NV40_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7;
|
||||
case NV40_FP_OP_INPUT_SRC_FACING : return NVS_FR_FACING;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case NVS_FILE_TEMP:
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
return ((src & NV40_FP_REG_SRC_MASK) >> NV40_FP_REG_SRC_SHIFT);
|
||||
}
|
||||
case NVS_FILE_CONST: /* inlined into fragprog */
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV40FPGetBranch(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[2] & NV40_FP_OP_IADDR_MASK)
|
||||
>> NV40_FP_OP_IADDR_SHIFT);;
|
||||
}
|
||||
|
||||
static int
|
||||
NV40FPGetBranchElse(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[2] & NV40_FP_OP_ELSE_ID_MASK)
|
||||
>> NV40_FP_OP_ELSE_ID_SHIFT);
|
||||
}
|
||||
|
||||
static int
|
||||
NV40FPGetBranchEnd(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[3] & NV40_FP_OP_END_ID_MASK)
|
||||
>> NV40_FP_OP_END_ID_SHIFT);
|
||||
}
|
||||
|
||||
static int
|
||||
NV40FPGetLoopCount(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[2] & NV40_FP_OP_LOOP_COUNT_MASK)
|
||||
>> NV40_FP_OP_LOOP_COUNT_SHIFT);
|
||||
}
|
||||
|
||||
static int
|
||||
NV40FPGetLoopInitial(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[2] & NV40_FP_OP_LOOP_INDEX_MASK)
|
||||
>> NV40_FP_OP_LOOP_INDEX_SHIFT);
|
||||
}
|
||||
|
||||
static int
|
||||
NV40FPGetLoopIncrement(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[2] & NV40_FP_OP_LOOP_INCR_MASK)
|
||||
>> NV40_FP_OP_LOOP_INCR_SHIFT);
|
||||
}
|
||||
|
||||
void
|
||||
NV40FPInitShaderFuncs(nvsFunc * shader)
|
||||
{
|
||||
/* Inherit NV30 FP code, it's mostly the same */
|
||||
NV30FPInitShaderFuncs(shader);
|
||||
|
||||
/* Kill off opcodes seen on NV30, but not seen on NV40 - need to find
|
||||
* out if these actually work or not.
|
||||
*
|
||||
* update: either LIT/RSQ don't work on nv40, or I generate bad code for
|
||||
* them. haven't tested the others yet
|
||||
*/
|
||||
MOD_OPCODE(NVFP_TX_AOP, 0x1B, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RSQ */
|
||||
MOD_OPCODE(NVFP_TX_AOP, 0x1E, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LIT */
|
||||
MOD_OPCODE(NVFP_TX_AOP, 0x1F, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LRP */
|
||||
MOD_OPCODE(NVFP_TX_AOP, 0x26, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 POW */
|
||||
MOD_OPCODE(NVFP_TX_AOP, 0x36, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RFL */
|
||||
|
||||
/* Extra opcodes supported on NV40 */
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DIV , NVS_OP_DIV , 0, 1, -1);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DP2A , NVS_OP_DP2A, 0, 1, 2);
|
||||
MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_TXL , NVS_OP_TXL , 0, -1, -1);
|
||||
|
||||
MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_BRK , NVS_OP_BRK , -1, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_CAL , NVS_OP_CAL , -1, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_IF , NVS_OP_IF , -1, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_LOOP, NVS_OP_LOOP, -1, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_REP , NVS_OP_REP , -1, -1, -1);
|
||||
MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_RET , NVS_OP_RET , -1, -1, -1);
|
||||
|
||||
shader->SupportsResultScale = NV40FPSupportsResultScale;
|
||||
shader->SetResultScale = NV40FPSetResultScale;
|
||||
|
||||
/* fragment.facing */
|
||||
shader->GetSourceID = NV40FPGetSourceID;
|
||||
|
||||
/* branching */
|
||||
shader->GetOPTXRec = NV40FPGetOPTXRec;
|
||||
shader->GetBranch = NV40FPGetBranch;
|
||||
shader->GetBranchElse = NV40FPGetBranchElse;
|
||||
shader->GetBranchEnd = NV40FPGetBranchEnd;
|
||||
shader->GetLoopCount = NV40FPGetLoopCount;
|
||||
shader->GetLoopInitial = NV40FPGetLoopInitial;
|
||||
shader->GetLoopIncrement = NV40FPGetLoopIncrement;
|
||||
shader->SetBranchTarget = NV40FPSetBranchTarget;
|
||||
shader->SetBranchElse = NV40FPSetBranchElse;
|
||||
shader->SetBranchEnd = NV40FPSetBranchEnd;
|
||||
shader->SetLoopParams = NV40FPSetLoopParams;
|
||||
}
|
||||
|
|
@ -1,467 +0,0 @@
|
|||
#ifndef __NV40_SHADER_H__
|
||||
#define __NV40_SHADER_H__
|
||||
|
||||
/* Vertex programs instruction set
|
||||
*
|
||||
* The NV40 instruction set is very similar to NV30. Most fields are in
|
||||
* a slightly different position in the instruction however.
|
||||
*
|
||||
* Merged instructions
|
||||
* In some cases it is possible to put two instructions into one opcode
|
||||
* slot. The rules for when this is OK is not entirely clear to me yet.
|
||||
*
|
||||
* There are separate writemasks and dest temp register fields for each
|
||||
* grouping of instructions. There is however only one field with the
|
||||
* ID of a result register. Writing to temp/result regs is selected by
|
||||
* setting VEC_RESULT/SCA_RESULT.
|
||||
*
|
||||
* Temporary registers
|
||||
* The source/dest temp register fields have been extended by 1 bit, to
|
||||
* give a total of 32 temporary registers.
|
||||
*
|
||||
* Relative Addressing
|
||||
* NV40 can use an address register to index into vertex attribute regs.
|
||||
* This is done by putting the offset value into INPUT_SRC and setting
|
||||
* the INDEX_INPUT flag.
|
||||
*
|
||||
* Conditional execution (see NV_vertex_program{2,3} for details)
|
||||
* There is a second condition code register on NV40, it's use is enabled
|
||||
* by setting the COND_REG_SELECT_1 flag.
|
||||
*
|
||||
* Texture lookup
|
||||
* TODO
|
||||
*/
|
||||
|
||||
/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */
|
||||
#define NV40_VP_INST_VEC_RESULT (1 << 30)
|
||||
/* uncertain.. */
|
||||
#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29)
|
||||
/* use address reg as index into attribs */
|
||||
#define NV40_VP_INST_INDEX_INPUT (1 << 27)
|
||||
#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25)
|
||||
#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
|
||||
#define NV40_VP_INST_SRC2_ABS (1 << 23)
|
||||
#define NV40_VP_INST_SRC1_ABS (1 << 22)
|
||||
#define NV40_VP_INST_SRC0_ABS (1 << 21)
|
||||
#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT 15
|
||||
#define NV40_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 15)
|
||||
#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13)
|
||||
#define NV40_VP_INST_COND_SHIFT 10
|
||||
#define NV40_VP_INST_COND_MASK (0x7 << 10)
|
||||
# define NV40_VP_INST_COND_FL 0
|
||||
# define NV40_VP_INST_COND_LT 1
|
||||
# define NV40_VP_INST_COND_EQ 2
|
||||
# define NV40_VP_INST_COND_LE 3
|
||||
# define NV40_VP_INST_COND_GT 4
|
||||
# define NV40_VP_INST_COND_NE 5
|
||||
# define NV40_VP_INST_COND_GE 6
|
||||
# define NV40_VP_INST_COND_TR 7
|
||||
#define NV40_VP_INST_COND_SWZ_X_SHIFT 8
|
||||
#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8)
|
||||
#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6
|
||||
#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6)
|
||||
#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4
|
||||
#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4)
|
||||
#define NV40_VP_INST_COND_SWZ_W_SHIFT 2
|
||||
#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2)
|
||||
#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2
|
||||
#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2)
|
||||
#define NV40_VP_INST_ADDR_SWZ_SHIFT 0
|
||||
#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0)
|
||||
#define NV40_VP_INST0_KNOWN ( \
|
||||
NV40_VP_INST_INDEX_INPUT | \
|
||||
NV40_VP_INST_COND_REG_SELECT_1 | \
|
||||
NV40_VP_INST_ADDR_REG_SELECT_1 | \
|
||||
NV40_VP_INST_SRC2_ABS | \
|
||||
NV40_VP_INST_SRC1_ABS | \
|
||||
NV40_VP_INST_SRC0_ABS | \
|
||||
NV40_VP_INST_VEC_DEST_TEMP_MASK | \
|
||||
NV40_VP_INST_COND_TEST_ENABLE | \
|
||||
NV40_VP_INST_COND_MASK | \
|
||||
NV40_VP_INST_COND_SWZ_ALL_MASK | \
|
||||
NV40_VP_INST_ADDR_SWZ_MASK)
|
||||
|
||||
/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */
|
||||
#define NV40_VP_INST_VEC_OPCODE_SHIFT 22
|
||||
#define NV40_VP_INST_VEC_OPCODE_MASK (0x1F << 22)
|
||||
# define NV40_VP_INST_OP_NOP 0x00
|
||||
# define NV40_VP_INST_OP_MOV 0x01
|
||||
# define NV40_VP_INST_OP_MUL 0x02
|
||||
# define NV40_VP_INST_OP_ADD 0x03
|
||||
# define NV40_VP_INST_OP_MAD 0x04
|
||||
# define NV40_VP_INST_OP_DP3 0x05
|
||||
# define NV40_VP_INST_OP_DP4 0x07
|
||||
# define NV40_VP_INST_OP_DPH 0x06
|
||||
# define NV40_VP_INST_OP_DST 0x08
|
||||
# define NV40_VP_INST_OP_MIN 0x09
|
||||
# define NV40_VP_INST_OP_MAX 0x0A
|
||||
# define NV40_VP_INST_OP_SLT 0x0B
|
||||
# define NV40_VP_INST_OP_SGE 0x0C
|
||||
# define NV40_VP_INST_OP_ARL 0x0D
|
||||
# define NV40_VP_INST_OP_FRC 0x0E
|
||||
# define NV40_VP_INST_OP_FLR 0x0F
|
||||
# define NV40_VP_INST_OP_SEQ 0x10
|
||||
# define NV40_VP_INST_OP_SFL 0x11
|
||||
# define NV40_VP_INST_OP_SGT 0x12
|
||||
# define NV40_VP_INST_OP_SLE 0x13
|
||||
# define NV40_VP_INST_OP_SNE 0x14
|
||||
# define NV40_VP_INST_OP_STR 0x15
|
||||
# define NV40_VP_INST_OP_SSG 0x16
|
||||
# define NV40_VP_INST_OP_ARR 0x17
|
||||
# define NV40_VP_INST_OP_ARA 0x18
|
||||
# define NV40_VP_INST_OP_TXWHAT 0x19
|
||||
#define NV40_VP_INST_SCA_OPCODE_SHIFT 27
|
||||
#define NV40_VP_INST_SCA_OPCODE_MASK (0x1F << 27)
|
||||
# define NV40_VP_INST_OP_RCP 0x02
|
||||
# define NV40_VP_INST_OP_RCC 0x03
|
||||
# define NV40_VP_INST_OP_RSQ 0x04
|
||||
# define NV40_VP_INST_OP_EXP 0x05
|
||||
# define NV40_VP_INST_OP_LOG 0x06
|
||||
# define NV40_VP_INST_OP_LIT 0x07
|
||||
# define NV40_VP_INST_OP_BRA 0x09
|
||||
# define NV40_VP_INST_OP_CAL 0x0B
|
||||
# define NV40_VP_INST_OP_RET 0x0C
|
||||
# define NV40_VP_INST_OP_LG2 0x0D
|
||||
# define NV40_VP_INST_OP_EX2 0x0E
|
||||
# define NV40_VP_INST_OP_SIN 0x0F
|
||||
# define NV40_VP_INST_OP_COS 0x10
|
||||
# define NV40_VP_INST_OP_PUSHA 0x13
|
||||
# define NV40_VP_INST_OP_POPA 0x14
|
||||
#define NV40_VP_INST_CONST_SRC_SHIFT 12
|
||||
#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12)
|
||||
#define NV40_VP_INST_INPUT_SRC_SHIFT 8
|
||||
#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8)
|
||||
# define NV40_VP_INST_IN_POS 0
|
||||
# define NV40_VP_INST_IN_WEIGHT 1
|
||||
# define NV40_VP_INST_IN_NORMAL 2
|
||||
# define NV40_VP_INST_IN_COL0 3
|
||||
# define NV40_VP_INST_IN_COL1 4
|
||||
# define NV40_VP_INST_IN_FOGC 5
|
||||
# define NV40_VP_INST_IN_TC0 8
|
||||
# define NV40_VP_INST_IN_TC(n) (8+n)
|
||||
#define NV40_VP_INST_SRC0H_SHIFT 0
|
||||
#define NV40_VP_INST_SRC0H_MASK (0xFF << 0)
|
||||
#define NV40_VP_INST1_KNOWN ( \
|
||||
NV40_VP_INST_VEC_OPCODE_MASK | \
|
||||
NV40_VP_INST_SCA_OPCODE_MASK | \
|
||||
NV40_VP_INST_CONST_SRC_MASK | \
|
||||
NV40_VP_INST_INPUT_SRC_MASK | \
|
||||
NV40_VP_INST_SRC0H_MASK \
|
||||
)
|
||||
|
||||
/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */
|
||||
#define NV40_VP_INST_SRC0L_SHIFT 23
|
||||
#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23)
|
||||
#define NV40_VP_INST_SRC1_SHIFT 6
|
||||
#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6)
|
||||
#define NV40_VP_INST_SRC2H_SHIFT 0
|
||||
#define NV40_VP_INST_SRC2H_MASK (0x3F << 0)
|
||||
#define NV40_VP_INST_IADDRH_SHIFT 0
|
||||
#define NV40_VP_INST_IADDRH_MASK (0x1F << 0)
|
||||
|
||||
/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */
|
||||
#define NV40_VP_INST_IADDRL_SHIFT 29
|
||||
#define NV40_VP_INST_IADDRL_MASK (7 << 29)
|
||||
#define NV40_VP_INST_SRC2L_SHIFT 21
|
||||
#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21)
|
||||
#define NV40_VP_INST_SCA_WRITEMASK_SHIFT 17
|
||||
#define NV40_VP_INST_SCA_WRITEMASK_MASK (0xF << 17)
|
||||
# define NV40_VP_INST_SCA_WRITEMASK_X (1 << 20)
|
||||
# define NV40_VP_INST_SCA_WRITEMASK_Y (1 << 19)
|
||||
# define NV40_VP_INST_SCA_WRITEMASK_Z (1 << 18)
|
||||
# define NV40_VP_INST_SCA_WRITEMASK_W (1 << 17)
|
||||
#define NV40_VP_INST_VEC_WRITEMASK_SHIFT 13
|
||||
#define NV40_VP_INST_VEC_WRITEMASK_MASK (0xF << 13)
|
||||
# define NV40_VP_INST_VEC_WRITEMASK_X (1 << 16)
|
||||
# define NV40_VP_INST_VEC_WRITEMASK_Y (1 << 15)
|
||||
# define NV40_VP_INST_VEC_WRITEMASK_Z (1 << 14)
|
||||
# define NV40_VP_INST_VEC_WRITEMASK_W (1 << 13)
|
||||
#define NV40_VP_INST_SCA_RESULT (1 << 12)
|
||||
#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT 7
|
||||
#define NV40_VP_INST_SCA_DEST_TEMP_MASK (0x1F << 7)
|
||||
#define NV40_VP_INST_DEST_SHIFT 2
|
||||
#define NV40_VP_INST_DEST_MASK (31 << 2)
|
||||
# define NV40_VP_INST_DEST_POS 0
|
||||
# define NV40_VP_INST_DEST_COL0 1
|
||||
# define NV40_VP_INST_DEST_COL1 2
|
||||
# define NV40_VP_INST_DEST_BFC0 3
|
||||
# define NV40_VP_INST_DEST_BFC1 4
|
||||
# define NV40_VP_INST_DEST_FOGC 5
|
||||
# define NV40_VP_INST_DEST_PSZ 6
|
||||
# define NV40_VP_INST_DEST_TC0 7
|
||||
# define NV40_VP_INST_DEST_TC(n) (7+n)
|
||||
# define NV40_VP_INST_DEST_TEMP 0x1F
|
||||
#define NV40_VP_INST_INDEX_CONST (1 << 1)
|
||||
#define NV40_VP_INST_LAST (1 << 0)
|
||||
#define NV40_VP_INST3_KNOWN ( \
|
||||
NV40_VP_INST_SRC2L_MASK |\
|
||||
NV40_VP_INST_SCA_WRITEMASK_MASK |\
|
||||
NV40_VP_INST_VEC_WRITEMASK_MASK |\
|
||||
NV40_VP_INST_SCA_DEST_TEMP_MASK |\
|
||||
NV40_VP_INST_DEST_MASK |\
|
||||
NV40_VP_INST_INDEX_CONST)
|
||||
|
||||
/* Useful to split the source selection regs into their pieces */
|
||||
#define NV40_VP_SRC0_HIGH_SHIFT 9
|
||||
#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00
|
||||
#define NV40_VP_SRC0_LOW_MASK 0x000001FF
|
||||
#define NV40_VP_SRC2_HIGH_SHIFT 11
|
||||
#define NV40_VP_SRC2_HIGH_MASK 0x0001F800
|
||||
#define NV40_VP_SRC2_LOW_MASK 0x000007FF
|
||||
|
||||
/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */
|
||||
#define NV40_VP_SRC_NEGATE (1 << 16)
|
||||
#define NV40_VP_SRC_SWZ_X_SHIFT 14
|
||||
#define NV40_VP_SRC_SWZ_X_MASK (3 << 14)
|
||||
#define NV40_VP_SRC_SWZ_Y_SHIFT 12
|
||||
#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12)
|
||||
#define NV40_VP_SRC_SWZ_Z_SHIFT 10
|
||||
#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10)
|
||||
#define NV40_VP_SRC_SWZ_W_SHIFT 8
|
||||
#define NV40_VP_SRC_SWZ_W_MASK (3 << 8)
|
||||
#define NV40_VP_SRC_SWZ_ALL_SHIFT 8
|
||||
#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8)
|
||||
#define NV40_VP_SRC_TEMP_SRC_SHIFT 2
|
||||
#define NV40_VP_SRC_TEMP_SRC_MASK (0x1F << 2)
|
||||
#define NV40_VP_SRC_REG_TYPE_SHIFT 0
|
||||
#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0)
|
||||
# define NV40_VP_SRC_REG_TYPE_UNK0 0
|
||||
# define NV40_VP_SRC_REG_TYPE_TEMP 1
|
||||
# define NV40_VP_SRC_REG_TYPE_INPUT 2
|
||||
# define NV40_VP_SRC_REG_TYPE_CONST 3
|
||||
|
||||
|
||||
/*
|
||||
* Each fragment program opcode appears to be comprised of 4 32-bit values.
|
||||
*
|
||||
* 0 - Opcode, output reg/mask, ATTRIB source
|
||||
* 1 - Source 0
|
||||
* 2 - Source 1
|
||||
* 3 - Source 2
|
||||
*
|
||||
* There appears to be no special difference between result regs and temp regs.
|
||||
* result.color == R0.xyzw
|
||||
* result.depth == R1.z
|
||||
* When the fragprog contains instructions to write depth,
|
||||
* NV30_TCL_PRIMITIVE_3D_UNK1D78=0 otherwise it is set to 1.
|
||||
*
|
||||
* Constants are inserted directly after the instruction that uses them.
|
||||
*
|
||||
* It appears that it's not possible to use two input registers in one
|
||||
* instruction as the input sourcing is done in the instruction dword
|
||||
* and not the source selection dwords. As such instructions such as:
|
||||
*
|
||||
* ADD result.color, fragment.color, fragment.texcoord[0];
|
||||
*
|
||||
* must be split into two MOV's and then an ADD (nvidia does this) but
|
||||
* I'm not sure why it's not just one MOV and then source the second input
|
||||
* in the ADD instruction..
|
||||
*
|
||||
* Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
|
||||
* negation requires multiplication with a const.
|
||||
*
|
||||
* Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO and
|
||||
* SWIZZLE_ONE.
|
||||
*
|
||||
* The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as
|
||||
* SWIZZLE_ZERO is implemented simply by not writing to the relevant components
|
||||
* of the destination.
|
||||
*
|
||||
* Looping
|
||||
* Loops appear to be fairly expensive on NV40 at least, the proprietary
|
||||
* driver goes to a lot of effort to avoid using the native looping
|
||||
* instructions. If the total number of *executed* instructions between
|
||||
* REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop.
|
||||
* The maximum loop count is 255.
|
||||
*
|
||||
* Conditional execution
|
||||
* TODO
|
||||
*
|
||||
* Non-native instructions:
|
||||
* LIT
|
||||
* LRP - MAD+MAD
|
||||
* SUB - ADD, negate second source
|
||||
* RSQ - LG2 + EX2
|
||||
* POW - LG2 + MUL + EX2
|
||||
* SCS - COS + SIN
|
||||
* XPD
|
||||
* DP2 - MUL + ADD
|
||||
* NRM
|
||||
*/
|
||||
|
||||
//== Opcode / Destination selection ==
|
||||
#define NV40_FP_OP_PROGRAM_END (1 << 0)
|
||||
#define NV40_FP_OP_OUT_REG_SHIFT 1
|
||||
#define NV40_FP_OP_OUT_REG_MASK (31 << 1)
|
||||
/* Needs to be set when writing outputs to get expected result.. */
|
||||
#define NV40_FP_OP_UNK0_7 (1 << 7)
|
||||
#define NV40_FP_OP_COND_WRITE_ENABLE (1 << 8)
|
||||
#define NV40_FP_OP_OUTMASK_SHIFT 9
|
||||
#define NV40_FP_OP_OUTMASK_MASK (0xF << 9)
|
||||
# define NV40_FP_OP_OUT_X (1 << 9)
|
||||
# define NV40_FP_OP_OUT_Y (1 <<10)
|
||||
# define NV40_FP_OP_OUT_Z (1 <<11)
|
||||
# define NV40_FP_OP_OUT_W (1 <<12)
|
||||
/* Uncertain about these, especially the input_src values.. it's possible that
|
||||
* they can be dynamically changed.
|
||||
*/
|
||||
#define NV40_FP_OP_INPUT_SRC_SHIFT 13
|
||||
#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13)
|
||||
# define NV40_FP_OP_INPUT_SRC_POSITION 0x0
|
||||
# define NV40_FP_OP_INPUT_SRC_COL0 0x1
|
||||
# define NV40_FP_OP_INPUT_SRC_COL1 0x2
|
||||
# define NV40_FP_OP_INPUT_SRC_FOGC 0x3
|
||||
# define NV40_FP_OP_INPUT_SRC_TC0 0x4
|
||||
# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
|
||||
# define NV40_FP_OP_INPUT_SRC_FACING 0xE
|
||||
#define NV40_FP_OP_TEX_UNIT_SHIFT 17
|
||||
#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17)
|
||||
#define NV40_FP_OP_PRECISION_SHIFT 22
|
||||
#define NV40_FP_OP_PRECISION_MASK (3 << 22)
|
||||
# define NV40_FP_PRECISION_FP32 0
|
||||
# define NV40_FP_PRECISION_FP16 1
|
||||
# define NV40_FP_PRECISION_FX12 2
|
||||
#define NV40_FP_OP_OPCODE_SHIFT 24
|
||||
#define NV40_FP_OP_OPCODE_MASK (0x3F << 24)
|
||||
# define NV40_FP_OP_OPCODE_NOP 0x00
|
||||
# define NV40_FP_OP_OPCODE_MOV 0x01
|
||||
# define NV40_FP_OP_OPCODE_MUL 0x02
|
||||
# define NV40_FP_OP_OPCODE_ADD 0x03
|
||||
# define NV40_FP_OP_OPCODE_MAD 0x04
|
||||
# define NV40_FP_OP_OPCODE_DP3 0x05
|
||||
# define NV40_FP_OP_OPCODE_DP4 0x06
|
||||
# define NV40_FP_OP_OPCODE_DST 0x07
|
||||
# define NV40_FP_OP_OPCODE_MIN 0x08
|
||||
# define NV40_FP_OP_OPCODE_MAX 0x09
|
||||
# define NV40_FP_OP_OPCODE_SLT 0x0A
|
||||
# define NV40_FP_OP_OPCODE_SGE 0x0B
|
||||
# define NV40_FP_OP_OPCODE_SLE 0x0C
|
||||
# define NV40_FP_OP_OPCODE_SGT 0x0D
|
||||
# define NV40_FP_OP_OPCODE_SNE 0x0E
|
||||
# define NV40_FP_OP_OPCODE_SEQ 0x0F
|
||||
# define NV40_FP_OP_OPCODE_FRC 0x10
|
||||
# define NV40_FP_OP_OPCODE_FLR 0x11
|
||||
# define NV40_FP_OP_OPCODE_KIL 0x12
|
||||
# define NV40_FP_OP_OPCODE_PK4B 0x13
|
||||
# define NV40_FP_OP_OPCODE_UP4B 0x14
|
||||
/* DDX/DDY can only write to XY */
|
||||
# define NV40_FP_OP_OPCODE_DDX 0x15
|
||||
# define NV40_FP_OP_OPCODE_DDY 0x16
|
||||
# define NV40_FP_OP_OPCODE_TEX 0x17
|
||||
# define NV40_FP_OP_OPCODE_TXP 0x18
|
||||
# define NV40_FP_OP_OPCODE_TXD 0x19
|
||||
# define NV40_FP_OP_OPCODE_RCP 0x1A
|
||||
# define NV40_FP_OP_OPCODE_EX2 0x1C
|
||||
# define NV40_FP_OP_OPCODE_LG2 0x1D
|
||||
# define NV40_FP_OP_OPCODE_COS 0x22
|
||||
# define NV40_FP_OP_OPCODE_SIN 0x23
|
||||
# define NV40_FP_OP_OPCODE_PK2H 0x24
|
||||
# define NV40_FP_OP_OPCODE_UP2H 0x25
|
||||
# define NV40_FP_OP_OPCODE_PK4UB 0x27
|
||||
# define NV40_FP_OP_OPCODE_UP4UB 0x28
|
||||
# define NV40_FP_OP_OPCODE_PK2US 0x29
|
||||
# define NV40_FP_OP_OPCODE_UP2US 0x2A
|
||||
# define NV40_FP_OP_OPCODE_DP2A 0x2E
|
||||
# define NV40_FP_OP_OPCODE_TXL 0x2F
|
||||
# define NV40_FP_OP_OPCODE_TXB 0x31
|
||||
# define NV40_FP_OP_OPCODE_DIV 0x3A
|
||||
/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/
|
||||
# define NV40_FP_OP_BRA_OPCODE_BRK 0x0
|
||||
# define NV40_FP_OP_BRA_OPCODE_CAL 0x1
|
||||
# define NV40_FP_OP_BRA_OPCODE_IF 0x2
|
||||
# define NV40_FP_OP_BRA_OPCODE_LOOP 0x3
|
||||
# define NV40_FP_OP_BRA_OPCODE_REP 0x4
|
||||
# define NV40_FP_OP_BRA_OPCODE_RET 0x5
|
||||
#define NV40_FP_OP_OUT_SAT (1 << 31)
|
||||
|
||||
/* high order bits of SRC0 */
|
||||
#define NV40_FP_OP_OUT_ABS (1 << 29)
|
||||
#define NV40_FP_OP_COND_SWZ_W_SHIFT 27
|
||||
#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27)
|
||||
#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25
|
||||
#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25)
|
||||
#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23
|
||||
#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23)
|
||||
#define NV40_FP_OP_COND_SWZ_X_SHIFT 21
|
||||
#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21)
|
||||
#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21
|
||||
#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
|
||||
#define NV40_FP_OP_COND_SHIFT 18
|
||||
#define NV40_FP_OP_COND_MASK (0x07 << 18)
|
||||
# define NV40_FP_OP_COND_FL 0
|
||||
# define NV40_FP_OP_COND_LT 1
|
||||
# define NV40_FP_OP_COND_EQ 2
|
||||
# define NV40_FP_OP_COND_LE 3
|
||||
# define NV40_FP_OP_COND_GT 4
|
||||
# define NV40_FP_OP_COND_NE 5
|
||||
# define NV40_FP_OP_COND_GE 6
|
||||
# define NV40_FP_OP_COND_TR 7
|
||||
|
||||
/* high order bits of SRC1 */
|
||||
#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31)
|
||||
#define NV40_FP_OP_DST_SCALE_SHIFT 28
|
||||
#define NV40_FP_OP_DST_SCALE_MASK (3 << 28)
|
||||
|
||||
/* SRC1 LOOP */
|
||||
#define NV40_FP_OP_LOOP_INCR_SHIFT 19
|
||||
#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19)
|
||||
#define NV40_FP_OP_LOOP_INDEX_SHIFT 10
|
||||
#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10)
|
||||
#define NV40_FP_OP_LOOP_COUNT_SHIFT 2
|
||||
#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)
|
||||
|
||||
/* SRC1 IF */
|
||||
#define NV40_FP_OP_ELSE_ID_SHIFT 2
|
||||
#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2)
|
||||
|
||||
/* SRC1 CAL */
|
||||
#define NV40_FP_OP_IADDR_SHIFT 2
|
||||
#define NV40_FP_OP_IADDR_MASK (0xFF << 2)
|
||||
|
||||
/* SRC1 REP
|
||||
* I have no idea why there are 3 count values here.. but they
|
||||
* have always been filled with the same value in my tests so
|
||||
* far..
|
||||
*/
|
||||
#define NV40_FP_OP_REP_COUNT1_SHIFT 2
|
||||
#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2)
|
||||
#define NV40_FP_OP_REP_COUNT2_SHIFT 10
|
||||
#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10)
|
||||
#define NV40_FP_OP_REP_COUNT3_SHIFT 19
|
||||
#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)
|
||||
|
||||
/* SRC2 REP/IF */
|
||||
#define NV40_FP_OP_END_ID_SHIFT 2
|
||||
#define NV40_FP_OP_END_ID_MASK (0xFF << 2)
|
||||
|
||||
// SRC2 high-order
|
||||
#define NV40_FP_OP_INDEX_INPUT (1 << 30)
|
||||
#define NV40_FP_OP_ADDR_INDEX_SHIFT 19
|
||||
#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19)
|
||||
|
||||
//== Register selection ==
|
||||
#define NV40_FP_REG_TYPE_SHIFT 0
|
||||
#define NV40_FP_REG_TYPE_MASK (3 << 0)
|
||||
# define NV40_FP_REG_TYPE_TEMP 0
|
||||
# define NV40_FP_REG_TYPE_INPUT 1
|
||||
# define NV40_FP_REG_TYPE_CONST 2
|
||||
#define NV40_FP_REG_SRC_SHIFT 2
|
||||
#define NV40_FP_REG_SRC_MASK (31 << 2)
|
||||
#define NV40_FP_REG_UNK_0 (1 << 8)
|
||||
#define NV40_FP_REG_SWZ_ALL_SHIFT 9
|
||||
#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9)
|
||||
#define NV40_FP_REG_SWZ_X_SHIFT 9
|
||||
#define NV40_FP_REG_SWZ_X_MASK (3 << 9)
|
||||
#define NV40_FP_REG_SWZ_Y_SHIFT 11
|
||||
#define NV40_FP_REG_SWZ_Y_MASK (3 << 11)
|
||||
#define NV40_FP_REG_SWZ_Z_SHIFT 13
|
||||
#define NV40_FP_REG_SWZ_Z_MASK (3 << 13)
|
||||
#define NV40_FP_REG_SWZ_W_SHIFT 15
|
||||
#define NV40_FP_REG_SWZ_W_MASK (3 << 15)
|
||||
# define NV40_FP_SWIZZLE_X 0
|
||||
# define NV40_FP_SWIZZLE_Y 1
|
||||
# define NV40_FP_SWIZZLE_Z 2
|
||||
# define NV40_FP_SWIZZLE_W 3
|
||||
#define NV40_FP_REG_NEGATE (1 << 17)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,778 +0,0 @@
|
|||
#include "nouveau_shader.h"
|
||||
#include "nouveau_msg.h"
|
||||
#include "nv40_shader.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Assembly routines
|
||||
*/
|
||||
static int
|
||||
NV40VPSupportsOpcode(nvsFunc * shader, nvsOpcode op)
|
||||
{
|
||||
if (shader->GetOPTXFromSOP(op, NULL))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot)
|
||||
{
|
||||
if (slot) {
|
||||
shader->inst[1] &= ~NV40_VP_INST_SCA_OPCODE_MASK;
|
||||
shader->inst[1] |= (opcode << NV40_VP_INST_SCA_OPCODE_SHIFT);
|
||||
} else {
|
||||
shader->inst[1] &= ~NV40_VP_INST_VEC_OPCODE_MASK;
|
||||
shader->inst[1] |= (opcode << NV40_VP_INST_VEC_OPCODE_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPSetCCUpdate(nvsFunc *shader)
|
||||
{
|
||||
shader->inst[0] |= NV40_VP_INST_COND_UPDATE_ENABLE;
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg,
|
||||
nvsSwzComp *swizzle)
|
||||
{
|
||||
unsigned int hwcond;
|
||||
|
||||
if (on ) shader->inst[0] |= NV40_VP_INST_COND_TEST_ENABLE;
|
||||
else shader->inst[0] &= ~NV40_VP_INST_COND_TEST_ENABLE;
|
||||
if (reg) shader->inst[0] |= NV40_VP_INST_COND_REG_SELECT_1;
|
||||
else shader->inst[0] &= ~NV40_VP_INST_COND_REG_SELECT_1;
|
||||
|
||||
switch (cond) {
|
||||
case NVS_COND_TR: hwcond = NV40_VP_INST_COND_TR; break;
|
||||
case NVS_COND_FL: hwcond = NV40_VP_INST_COND_FL; break;
|
||||
case NVS_COND_LT: hwcond = NV40_VP_INST_COND_LT; break;
|
||||
case NVS_COND_GT: hwcond = NV40_VP_INST_COND_GT; break;
|
||||
case NVS_COND_NE: hwcond = NV40_VP_INST_COND_NE; break;
|
||||
case NVS_COND_EQ: hwcond = NV40_VP_INST_COND_EQ; break;
|
||||
case NVS_COND_GE: hwcond = NV40_VP_INST_COND_GE; break;
|
||||
case NVS_COND_LE: hwcond = NV40_VP_INST_COND_LE; break;
|
||||
default:
|
||||
WARN_ONCE("unknown vp cond %d\n", cond);
|
||||
hwcond = NV40_VP_INST_COND_TR;
|
||||
break;
|
||||
}
|
||||
shader->inst[0] &= ~NV40_VP_INST_COND_MASK;
|
||||
shader->inst[0] |= (hwcond << NV40_VP_INST_COND_SHIFT);
|
||||
|
||||
shader->inst[0] &= ~NV40_VP_INST_COND_SWZ_ALL_MASK;
|
||||
shader->inst[0] |= (swizzle[NVS_SWZ_X] << NV40_VP_INST_COND_SWZ_X_SHIFT);
|
||||
shader->inst[0] |= (swizzle[NVS_SWZ_Y] << NV40_VP_INST_COND_SWZ_Y_SHIFT);
|
||||
shader->inst[0] |= (swizzle[NVS_SWZ_Z] << NV40_VP_INST_COND_SWZ_Z_SHIFT);
|
||||
shader->inst[0] |= (swizzle[NVS_SWZ_W] << NV40_VP_INST_COND_SWZ_W_SHIFT);
|
||||
}
|
||||
|
||||
/* these just exist here until nouveau_reg.h has them. */
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0 (1<<0)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1 (1<<1)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0 (1<<2)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1 (1<<3)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC (1<<4)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ (1<<5)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0 (1<<6)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1 (1<<7)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2 (1<<8)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3 (1<<9)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4 (1<<10)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5 (1<<11)
|
||||
#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 (1<<14)
|
||||
|
||||
static unsigned int
|
||||
NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result,
|
||||
unsigned int *mask_ret)
|
||||
{
|
||||
unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg;
|
||||
unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables;
|
||||
|
||||
*mask_ret = 0xf;
|
||||
|
||||
switch (result) {
|
||||
case NVS_FR_POSITION:
|
||||
/* out_reg POS implied */
|
||||
return NV40_VP_INST_DEST_POS;
|
||||
case NVS_FR_COL0:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0;
|
||||
return NV40_VP_INST_DEST_COL0;
|
||||
case NVS_FR_COL1:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1;
|
||||
return NV40_VP_INST_DEST_COL1;
|
||||
case NVS_FR_BFC0:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0;
|
||||
return NV40_VP_INST_DEST_BFC0;
|
||||
case NVS_FR_BFC1:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1;
|
||||
return NV40_VP_INST_DEST_BFC1;
|
||||
case NVS_FR_FOGCOORD:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC;
|
||||
*mask_ret = 0x8;
|
||||
return NV40_VP_INST_DEST_FOGC;
|
||||
case NVS_FR_CLIP0:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0;
|
||||
(*clip_en) |= 0x00000002;
|
||||
*mask_ret = 0x4;
|
||||
return NV40_VP_INST_DEST_FOGC;
|
||||
case NVS_FR_CLIP1:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1;
|
||||
(*clip_en) |= 0x00000020;
|
||||
*mask_ret = 0x2;
|
||||
return NV40_VP_INST_DEST_FOGC;
|
||||
case NVS_FR_CLIP2:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2;
|
||||
(*clip_en) |= 0x00000200;
|
||||
*mask_ret = 0x1;
|
||||
return NV40_VP_INST_DEST_FOGC;
|
||||
case NVS_FR_POINTSZ:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ;
|
||||
*mask_ret = 0x8;
|
||||
return NV40_VP_INST_DEST_PSZ;
|
||||
case NVS_FR_CLIP3:
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3;
|
||||
(*clip_en) |= 0x00002000;
|
||||
*mask_ret = 0x4;
|
||||
return NV40_VP_INST_DEST_PSZ;
|
||||
case NVS_FR_CLIP4:
|
||||
(*clip_en) |= 0x00020000;
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4;
|
||||
*mask_ret = 0x2;
|
||||
return NV40_VP_INST_DEST_PSZ;
|
||||
case NVS_FR_CLIP5:
|
||||
(*clip_en) |= 0x00200000;
|
||||
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5;
|
||||
*mask_ret = 0x1;
|
||||
return NV40_VP_INST_DEST_PSZ;
|
||||
case NVS_FR_TEXCOORD0:
|
||||
case NVS_FR_TEXCOORD1:
|
||||
case NVS_FR_TEXCOORD2:
|
||||
case NVS_FR_TEXCOORD3:
|
||||
case NVS_FR_TEXCOORD4:
|
||||
case NVS_FR_TEXCOORD5:
|
||||
case NVS_FR_TEXCOORD6:
|
||||
case NVS_FR_TEXCOORD7:
|
||||
{
|
||||
int unit = result - NVS_FR_TEXCOORD0;
|
||||
(*out_reg) |= (NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 << unit);
|
||||
return NV40_VP_INST_DEST_TC(unit);
|
||||
}
|
||||
default:
|
||||
WARN_ONCE("unknown vp output %d\n", result);
|
||||
return NV40_VP_INST_DEST_POS;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask,
|
||||
int slot)
|
||||
{
|
||||
unsigned int hwmask = 0;
|
||||
|
||||
if (mask & SMASK_X) hwmask |= (1 << 3);
|
||||
if (mask & SMASK_Y) hwmask |= (1 << 2);
|
||||
if (mask & SMASK_Z) hwmask |= (1 << 1);
|
||||
if (mask & SMASK_W) hwmask |= (1 << 0);
|
||||
|
||||
if (dest->file == NVS_FILE_RESULT) {
|
||||
unsigned int valid_mask;
|
||||
int hwidx;
|
||||
|
||||
hwidx = NV40VPTranslateResultReg(shader, dest->index, &valid_mask);
|
||||
if (hwmask & ~valid_mask)
|
||||
WARN_ONCE("writing invalid components of result reg\n");
|
||||
hwmask &= valid_mask;
|
||||
|
||||
shader->inst[3] &= ~NV40_VP_INST_DEST_MASK;
|
||||
shader->inst[3] |= (hwidx << NV40_VP_INST_DEST_SHIFT);
|
||||
|
||||
if (slot) shader->inst[3] |= NV40_VP_INST_SCA_RESULT;
|
||||
else shader->inst[0] |= NV40_VP_INST_VEC_RESULT;
|
||||
} else {
|
||||
/* NVS_FILE_TEMP || NVS_FILE_ADDRESS */
|
||||
if (slot) {
|
||||
shader->inst[3] &= ~NV40_VP_INST_SCA_RESULT;
|
||||
shader->inst[3] &= ~NV40_VP_INST_SCA_DEST_TEMP_MASK;
|
||||
shader->inst[3] |= (dest->index << NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
|
||||
} else {
|
||||
shader->inst[0] &= ~NV40_VP_INST_VEC_RESULT;
|
||||
shader->inst[0] &= ~(NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20));
|
||||
shader->inst[0] |= (dest->index << NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
if (slot) {
|
||||
shader->inst[3] &= ~NV40_VP_INST_SCA_WRITEMASK_MASK;
|
||||
shader->inst[3] |= (hwmask << NV40_VP_INST_SCA_WRITEMASK_SHIFT);
|
||||
} else {
|
||||
shader->inst[3] &= ~NV40_VP_INST_VEC_WRITEMASK_MASK;
|
||||
shader->inst[3] |= (hwmask << NV40_VP_INST_VEC_WRITEMASK_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPInsertSource(nvsFunc *shader, unsigned int hw, int pos)
|
||||
{
|
||||
switch (pos) {
|
||||
case 0:
|
||||
shader->inst[1] &= ~NV40_VP_INST_SRC0H_MASK;
|
||||
shader->inst[2] &= ~NV40_VP_INST_SRC0L_MASK;
|
||||
shader->inst[1] |= ((hw & NV40_VP_SRC0_HIGH_MASK) >>
|
||||
NV40_VP_SRC0_HIGH_SHIFT)
|
||||
<< NV40_VP_INST_SRC0H_SHIFT;
|
||||
shader->inst[2] |= (hw & NV40_VP_SRC0_LOW_MASK)
|
||||
<< NV40_VP_INST_SRC0L_SHIFT;
|
||||
break;
|
||||
case 1:
|
||||
shader->inst[2] &= ~NV40_VP_INST_SRC1_MASK;
|
||||
shader->inst[2] |= hw
|
||||
<< NV40_VP_INST_SRC1_SHIFT;
|
||||
break;
|
||||
case 2:
|
||||
shader->inst[2] &= ~NV40_VP_INST_SRC2H_MASK;
|
||||
shader->inst[3] &= ~NV40_VP_INST_SRC2L_MASK;
|
||||
shader->inst[2] |= ((hw & NV40_VP_SRC2_HIGH_MASK) >>
|
||||
NV40_VP_SRC2_HIGH_SHIFT)
|
||||
<< NV40_VP_INST_SRC2H_SHIFT;
|
||||
shader->inst[3] |= (hw & NV40_VP_SRC2_LOW_MASK)
|
||||
<< NV40_VP_INST_SRC2L_SHIFT;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos)
|
||||
{
|
||||
unsigned int hw = 0;
|
||||
|
||||
switch (src->file) {
|
||||
case NVS_FILE_ADDRESS:
|
||||
break;
|
||||
case NVS_FILE_ATTRIB:
|
||||
hw |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT);
|
||||
|
||||
shader->inst[1] &= ~NV40_VP_INST_INPUT_SRC_MASK;
|
||||
shader->inst[1] |= (src->index << NV40_VP_INST_INPUT_SRC_SHIFT);
|
||||
shader->card_priv->NV30VP.vp_in_reg |= (1 << src->index);
|
||||
if (src->indexed) {
|
||||
shader->inst[0] |= NV40_VP_INST_INDEX_INPUT;
|
||||
if (src->addr_reg)
|
||||
shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1;
|
||||
else
|
||||
shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1;
|
||||
shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_SHIFT;
|
||||
shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT);
|
||||
} else
|
||||
shader->inst[0] &= ~NV40_VP_INST_INDEX_INPUT;
|
||||
break;
|
||||
case NVS_FILE_CONST:
|
||||
hw |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT);
|
||||
|
||||
shader->inst[1] &= ~NV40_VP_INST_CONST_SRC_MASK;
|
||||
shader->inst[1] |= (src->index << NV40_VP_INST_CONST_SRC_SHIFT);
|
||||
if (src->indexed) {
|
||||
shader->inst[3] |= NV40_VP_INST_INDEX_CONST;
|
||||
if (src->addr_reg)
|
||||
shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1;
|
||||
else
|
||||
shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1;
|
||||
shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_MASK;
|
||||
shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT);
|
||||
} else
|
||||
shader->inst[3] &= ~NV40_VP_INST_INDEX_CONST;
|
||||
break;
|
||||
case NVS_FILE_TEMP:
|
||||
hw |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT);
|
||||
hw |= (src->index << NV40_VP_SRC_TEMP_SRC_SHIFT);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unknown source file %d\n", src->file);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (src->file != NVS_FILE_ADDRESS) {
|
||||
if (src->negate)
|
||||
hw |= NV40_VP_SRC_NEGATE;
|
||||
if (src->abs)
|
||||
shader->inst[0] |= (1 << (21 + pos));
|
||||
else
|
||||
shader->inst[0] &= ~(1 << (21 + pos));
|
||||
hw |= (src->swizzle[0] << NV40_VP_SRC_SWZ_X_SHIFT);
|
||||
hw |= (src->swizzle[1] << NV40_VP_SRC_SWZ_Y_SHIFT);
|
||||
hw |= (src->swizzle[2] << NV40_VP_SRC_SWZ_Z_SHIFT);
|
||||
hw |= (src->swizzle[3] << NV40_VP_SRC_SWZ_W_SHIFT);
|
||||
|
||||
NV40VPInsertSource(shader, hw, pos);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPSetBranchTarget(nvsFunc *shader, int addr)
|
||||
{
|
||||
shader->inst[2] &= ~NV40_VP_INST_IADDRH_MASK;
|
||||
shader->inst[2] |= ((addr & 0xf8) >> 3) << NV40_VP_INST_IADDRH_SHIFT;
|
||||
shader->inst[3] &= ~NV40_VP_INST_IADDRL_MASK;
|
||||
shader->inst[3] |= ((addr & 0x07) << NV40_VP_INST_IADDRL_SHIFT);
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPInitInstruction(nvsFunc *shader)
|
||||
{
|
||||
unsigned int hwsrc = 0;
|
||||
|
||||
shader->inst[0] = /*NV40_VP_INST_VEC_RESULT | */
|
||||
NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20);
|
||||
shader->inst[1] = 0;
|
||||
shader->inst[2] = 0;
|
||||
shader->inst[3] = NV40_VP_INST_SCA_RESULT |
|
||||
NV40_VP_INST_SCA_DEST_TEMP_MASK |
|
||||
NV40_VP_INST_DEST_MASK;
|
||||
|
||||
hwsrc = (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT) |
|
||||
(NVS_SWZ_X << NV40_VP_SRC_SWZ_X_SHIFT) |
|
||||
(NVS_SWZ_Y << NV40_VP_SRC_SWZ_Y_SHIFT) |
|
||||
(NVS_SWZ_Z << NV40_VP_SRC_SWZ_Z_SHIFT) |
|
||||
(NVS_SWZ_W << NV40_VP_SRC_SWZ_W_SHIFT);
|
||||
NV40VPInsertSource(shader, hwsrc, 0);
|
||||
NV40VPInsertSource(shader, hwsrc, 1);
|
||||
NV40VPInsertSource(shader, hwsrc, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPSetLastInst(nvsFunc *shader)
|
||||
{
|
||||
shader->inst[3] |= 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Disassembly routines
|
||||
*/
|
||||
static int
|
||||
NV40VPHasMergedInst(nvsFunc * shader)
|
||||
{
|
||||
if (shader->GetOpcodeHW(shader, 0) != NV40_VP_INST_OP_NOP &&
|
||||
shader->GetOpcodeHW(shader, 1) != NV40_VP_INST_OP_NOP)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV40VPGetOpcodeHW(nvsFunc * shader, int slot)
|
||||
{
|
||||
int op;
|
||||
|
||||
if (slot)
|
||||
op = (shader->inst[1] & NV40_VP_INST_SCA_OPCODE_MASK)
|
||||
>> NV40_VP_INST_SCA_OPCODE_SHIFT;
|
||||
else
|
||||
op = (shader->inst[1] & NV40_VP_INST_VEC_OPCODE_MASK)
|
||||
>> NV40_VP_INST_VEC_OPCODE_SHIFT;
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
static nvsRegFile
|
||||
NV40VPGetDestFile(nvsFunc * shader, int merged)
|
||||
{
|
||||
nvsOpcode op;
|
||||
|
||||
op = shader->GetOpcode(shader, merged);
|
||||
switch (op) {
|
||||
case NVS_OP_ARL:
|
||||
case NVS_OP_ARR:
|
||||
case NVS_OP_ARA:
|
||||
case NVS_OP_POPA:
|
||||
return NVS_FILE_ADDRESS;
|
||||
default:
|
||||
if (shader->GetOpcodeSlot(shader, merged)) {
|
||||
if (shader->inst[3] & NV40_VP_INST_SCA_RESULT)
|
||||
return NVS_FILE_RESULT;
|
||||
}
|
||||
else {
|
||||
if (shader->inst[0] & NV40_VP_INST_VEC_RESULT)
|
||||
return NVS_FILE_RESULT;
|
||||
}
|
||||
return NVS_FILE_TEMP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV40VPGetDestID(nvsFunc * shader, int merged)
|
||||
{
|
||||
int id;
|
||||
|
||||
switch (shader->GetDestFile(shader, merged)) {
|
||||
case NVS_FILE_RESULT:
|
||||
id = ((shader->inst[3] & NV40_VP_INST_DEST_MASK)
|
||||
>> NV40_VP_INST_DEST_SHIFT);
|
||||
switch (id) {
|
||||
case NV40_VP_INST_DEST_POS : return NVS_FR_POSITION;
|
||||
case NV40_VP_INST_DEST_COL0: return NVS_FR_COL0;
|
||||
case NV40_VP_INST_DEST_COL1: return NVS_FR_COL1;
|
||||
case NV40_VP_INST_DEST_BFC0: return NVS_FR_BFC0;
|
||||
case NV40_VP_INST_DEST_BFC1: return NVS_FR_BFC1;
|
||||
case NV40_VP_INST_DEST_FOGC: {
|
||||
int mask = shader->GetDestMask(shader, merged);
|
||||
switch (mask) {
|
||||
case SMASK_X: return NVS_FR_FOGCOORD;
|
||||
case SMASK_Y: return NVS_FR_CLIP0;
|
||||
case SMASK_Z: return NVS_FR_CLIP1;
|
||||
case SMASK_W: return NVS_FR_CLIP2;
|
||||
default:
|
||||
printf("more than 1 mask component set in FOGC writemask!\n");
|
||||
return NVS_FR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
case NV40_VP_INST_DEST_PSZ:
|
||||
{
|
||||
int mask = shader->GetDestMask(shader, merged);
|
||||
switch (mask) {
|
||||
case SMASK_X: return NVS_FR_POINTSZ;
|
||||
case SMASK_Y: return NVS_FR_CLIP3;
|
||||
case SMASK_Z: return NVS_FR_CLIP4;
|
||||
case SMASK_W: return NVS_FR_CLIP5;
|
||||
default:
|
||||
printf("more than 1 mask component set in PSZ writemask!\n");
|
||||
return NVS_FR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
case NV40_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
|
||||
case NV40_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
|
||||
case NV40_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
|
||||
case NV40_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
|
||||
case NV40_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4;
|
||||
case NV40_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5;
|
||||
case NV40_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6;
|
||||
case NV40_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
case NVS_FILE_ADDRESS:
|
||||
/* Instructions that write address regs are encoded as if
|
||||
* they would write temps.
|
||||
*/
|
||||
case NVS_FILE_TEMP:
|
||||
if (shader->GetOpcodeSlot(shader, merged))
|
||||
id = ((shader->inst[3] & NV40_VP_INST_SCA_DEST_TEMP_MASK)
|
||||
>> NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
|
||||
else
|
||||
id = ((shader->inst[0] & NV40_VP_INST_VEC_DEST_TEMP_MASK)
|
||||
>> NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
|
||||
return id;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV40VPGetDestMask(nvsFunc * shader, int merged)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
|
||||
if (shader->GetOpcodeSlot(shader, merged)) {
|
||||
if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_X) mask |= SMASK_X;
|
||||
if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Y) mask |= SMASK_Y;
|
||||
if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Z) mask |= SMASK_Z;
|
||||
if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_W) mask |= SMASK_W;
|
||||
} else {
|
||||
if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_X) mask |= SMASK_X;
|
||||
if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Y) mask |= SMASK_Y;
|
||||
if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Z) mask |= SMASK_Z;
|
||||
if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_W) mask |= SMASK_W;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
NV40VPGetSourceHW(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
struct _op_xlat *opr;
|
||||
unsigned int src;
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr)
|
||||
return -1;
|
||||
|
||||
switch (opr->srcpos[pos]) {
|
||||
case 0:
|
||||
src = ((shader->inst[1] & NV40_VP_INST_SRC0H_MASK)
|
||||
>> NV40_VP_INST_SRC0H_SHIFT)
|
||||
<< NV40_VP_SRC0_HIGH_SHIFT;
|
||||
src |= ((shader->inst[2] & NV40_VP_INST_SRC0L_MASK)
|
||||
>> NV40_VP_INST_SRC0L_SHIFT);
|
||||
break;
|
||||
case 1:
|
||||
src = ((shader->inst[2] & NV40_VP_INST_SRC1_MASK)
|
||||
>> NV40_VP_INST_SRC1_SHIFT);
|
||||
break;
|
||||
case 2:
|
||||
src = ((shader->inst[2] & NV40_VP_INST_SRC2H_MASK)
|
||||
>> NV40_VP_INST_SRC2H_SHIFT)
|
||||
<< NV40_VP_SRC2_HIGH_SHIFT;
|
||||
src |= ((shader->inst[3] & NV40_VP_INST_SRC2L_MASK)
|
||||
>> NV40_VP_INST_SRC2L_SHIFT);
|
||||
break;
|
||||
default:
|
||||
src = -1;
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
static nvsRegFile
|
||||
NV40VPGetSourceFile(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
unsigned int src;
|
||||
struct _op_xlat *opr;
|
||||
int file;
|
||||
|
||||
opr = shader->GetOPTXRec(shader, merged);
|
||||
if (!opr || opr->srcpos[pos] == -1)
|
||||
return -1;
|
||||
|
||||
switch (opr->srcpos[pos]) {
|
||||
case SPOS_ADDRESS: return NVS_FILE_ADDRESS;
|
||||
default:
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
file = (src & NV40_VP_SRC_REG_TYPE_MASK) >> NV40_VP_SRC_REG_TYPE_SHIFT;
|
||||
|
||||
switch (file) {
|
||||
case NV40_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP;
|
||||
case NV40_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
|
||||
case NV40_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST;
|
||||
default:
|
||||
return NVS_FILE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV40VPGetSourceID(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
switch (shader->GetSourceFile(shader, merged, pos)) {
|
||||
case NVS_FILE_ATTRIB:
|
||||
switch ((shader->inst[1] & NV40_VP_INST_INPUT_SRC_MASK)
|
||||
>> NV40_VP_INST_INPUT_SRC_SHIFT) {
|
||||
case NV40_VP_INST_IN_POS: return NVS_FR_POSITION;
|
||||
case NV40_VP_INST_IN_WEIGHT: return NVS_FR_WEIGHT;
|
||||
case NV40_VP_INST_IN_NORMAL: return NVS_FR_NORMAL;
|
||||
case NV40_VP_INST_IN_COL0: return NVS_FR_COL0;
|
||||
case NV40_VP_INST_IN_COL1: return NVS_FR_COL1;
|
||||
case NV40_VP_INST_IN_FOGC: return NVS_FR_FOGCOORD;
|
||||
case NV40_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0;
|
||||
case NV40_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1;
|
||||
case NV40_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2;
|
||||
case NV40_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3;
|
||||
case NV40_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4;
|
||||
case NV40_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5;
|
||||
case NV40_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6;
|
||||
case NV40_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case NVS_FILE_CONST:
|
||||
return ((shader->inst[1] & NV40_VP_INST_CONST_SRC_MASK)
|
||||
>> NV40_VP_INST_CONST_SRC_SHIFT);
|
||||
case NVS_FILE_TEMP:
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
return ((src & NV40_VP_SRC_TEMP_SRC_MASK) >>
|
||||
NV40_VP_SRC_TEMP_SRC_SHIFT);
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
NV40VPGetSourceNegate(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
unsigned int src;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
|
||||
if (src == -1)
|
||||
return -1;
|
||||
return ((src & NV40_VP_SRC_NEGATE) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
|
||||
{
|
||||
unsigned int src;
|
||||
int swzbits;
|
||||
|
||||
src = shader->GetSourceHW(shader, merged, pos);
|
||||
swzbits = (src & NV40_VP_SRC_SWZ_ALL_MASK) >> NV40_VP_SRC_SWZ_ALL_SHIFT;
|
||||
NV20VPTXSwizzle(swzbits, swz);
|
||||
}
|
||||
|
||||
static int
|
||||
NV40VPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
|
||||
{
|
||||
switch (shader->GetSourceFile(shader, merged, pos)) {
|
||||
case NVS_FILE_ATTRIB:
|
||||
return ((shader->inst[0] & NV40_VP_INST_INDEX_INPUT) ? 1 : 0);
|
||||
case NVS_FILE_CONST:
|
||||
return ((shader->inst[3] & NV40_VP_INST_INDEX_CONST) ? 1 : 0);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static nvsSwzComp
|
||||
NV40VPGetAddressRegSwizzle(nvsFunc * shader)
|
||||
{
|
||||
nvsSwzComp swz;
|
||||
|
||||
swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV40_VP_INST_ADDR_SWZ_MASK)
|
||||
>> NV40_VP_INST_ADDR_SWZ_SHIFT];
|
||||
return swz;
|
||||
}
|
||||
|
||||
static int
|
||||
NV40VPSupportsConditional(nvsFunc * shader)
|
||||
{
|
||||
/*FIXME: Is this true of all ops? */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
NV40VPGetConditionUpdate(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[0] & NV40_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV40VPGetConditionTest(nvsFunc * shader)
|
||||
{
|
||||
int op;
|
||||
|
||||
/* The condition test is unconditionally enabled on some
|
||||
* instructions. ie: the condition test bit does *NOT* have
|
||||
* to be set.
|
||||
*
|
||||
* FIXME: check other relevant ops for this situation.
|
||||
*/
|
||||
op = shader->GetOpcodeHW(shader, 1);
|
||||
switch (op) {
|
||||
case NV40_VP_INST_OP_BRA:
|
||||
return 1;
|
||||
default:
|
||||
return ((shader->inst[0] & NV40_VP_INST_COND_TEST_ENABLE) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
static nvsCond
|
||||
NV40VPGetCondition(nvsFunc * shader)
|
||||
{
|
||||
int cond;
|
||||
|
||||
cond = ((shader->inst[0] & NV40_VP_INST_COND_MASK)
|
||||
>> NV40_VP_INST_COND_SHIFT);
|
||||
|
||||
switch (cond) {
|
||||
case NV40_VP_INST_COND_FL: return NVS_COND_FL;
|
||||
case NV40_VP_INST_COND_LT: return NVS_COND_LT;
|
||||
case NV40_VP_INST_COND_EQ: return NVS_COND_EQ;
|
||||
case NV40_VP_INST_COND_LE: return NVS_COND_LE;
|
||||
case NV40_VP_INST_COND_GT: return NVS_COND_GT;
|
||||
case NV40_VP_INST_COND_NE: return NVS_COND_NE;
|
||||
case NV40_VP_INST_COND_GE: return NVS_COND_GE;
|
||||
case NV40_VP_INST_COND_TR: return NVS_COND_TR;
|
||||
default:
|
||||
return NVS_COND_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
NV40VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
|
||||
{
|
||||
int swzbits;
|
||||
|
||||
swzbits = (shader->inst[0] & NV40_VP_INST_COND_SWZ_ALL_MASK)
|
||||
>> NV40_VP_INST_COND_SWZ_ALL_SHIFT;
|
||||
NV20VPTXSwizzle(swzbits, swz);
|
||||
}
|
||||
|
||||
static int
|
||||
NV40VPGetCondRegID(nvsFunc * shader)
|
||||
{
|
||||
return ((shader->inst[0] & NV40_VP_INST_COND_REG_SELECT_1) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
NV40VPGetBranch(nvsFunc * shader)
|
||||
{
|
||||
int addr;
|
||||
|
||||
addr = ((shader->inst[2] & NV40_VP_INST_IADDRH_MASK)
|
||||
>> NV40_VP_INST_IADDRH_SHIFT) << 3;
|
||||
addr |= ((shader->inst[3] & NV40_VP_INST_IADDRL_MASK)
|
||||
>> NV40_VP_INST_IADDRL_SHIFT);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
NV40VPInitShaderFuncs(nvsFunc * shader)
|
||||
{
|
||||
/* Inherit NV30 VP code, we share some of it */
|
||||
NV30VPInitShaderFuncs(shader);
|
||||
|
||||
/* Limits */
|
||||
shader->MaxInst = 4096;
|
||||
shader->MaxAttrib = 16;
|
||||
shader->MaxTemp = 32;
|
||||
shader->MaxAddress = 2;
|
||||
shader->MaxConst = 256;
|
||||
shader->caps = SCAP_SRC_ABS;
|
||||
|
||||
/* Add extra opcodes for NV40+ */
|
||||
// MOD_OPCODE(NVVP_TX_VOP, NV40_VP_INST_OP_TXWHAT, NVS_OP_TEX , 0, 4, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_PUSHA, NVS_OP_PUSHA, 3, -1, -1);
|
||||
MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_POPA , NVS_OP_POPA , -1, -1, -1);
|
||||
|
||||
shader->InitInstruction = NV40VPInitInstruction;
|
||||
shader->SupportsOpcode = NV40VPSupportsOpcode;
|
||||
shader->SetOpcode = NV40VPSetOpcode;
|
||||
shader->SetCCUpdate = NV40VPSetCCUpdate;
|
||||
shader->SetCondition = NV40VPSetCondition;
|
||||
shader->SetResult = NV40VPSetResult;
|
||||
shader->SetSource = NV40VPSetSource;
|
||||
shader->SetLastInst = NV40VPSetLastInst;
|
||||
shader->SetBranchTarget = NV40VPSetBranchTarget;
|
||||
|
||||
shader->HasMergedInst = NV40VPHasMergedInst;
|
||||
shader->GetOpcodeHW = NV40VPGetOpcodeHW;
|
||||
|
||||
shader->GetDestFile = NV40VPGetDestFile;
|
||||
shader->GetDestID = NV40VPGetDestID;
|
||||
shader->GetDestMask = NV40VPGetDestMask;
|
||||
|
||||
shader->GetSourceHW = NV40VPGetSourceHW;
|
||||
shader->GetSourceFile = NV40VPGetSourceFile;
|
||||
shader->GetSourceID = NV40VPGetSourceID;
|
||||
shader->GetSourceNegate = NV40VPGetSourceNegate;
|
||||
shader->GetSourceSwizzle = NV40VPGetSourceSwizzle;
|
||||
shader->GetSourceIndexed = NV40VPGetSourceIndexed;
|
||||
|
||||
shader->GetRelAddressSwizzle = NV40VPGetAddressRegSwizzle;
|
||||
|
||||
shader->SupportsConditional = NV40VPSupportsConditional;
|
||||
shader->GetConditionUpdate = NV40VPGetConditionUpdate;
|
||||
shader->GetConditionTest = NV40VPGetConditionTest;
|
||||
shader->GetCondition = NV40VPGetCondition;
|
||||
shader->GetCondRegSwizzle = NV40VPGetCondRegSwizzle;
|
||||
shader->GetCondRegID = NV40VPGetCondRegID;
|
||||
|
||||
shader->GetBranch = NV40VPGetBranch;
|
||||
}
|
||||
|
|
@ -1,641 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
Copyright 2006 Nouveau
|
||||
All Rights Reserved.
|
||||
|
||||
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
|
||||
on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 "nouveau_context.h"
|
||||
#include "nouveau_object.h"
|
||||
#include "nouveau_fifo.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_state.h"
|
||||
|
||||
#include "tnl/t_pipeline.h"
|
||||
|
||||
#include "mtypes.h"
|
||||
#include "colormac.h"
|
||||
|
||||
static void nv50AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLubyte ubRef;
|
||||
CLAMPED_FLOAT_TO_UBYTE(ubRef, ref);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF, 2);
|
||||
OUT_RING_CACHE(ubRef);
|
||||
OUT_RING_CACHE(func);
|
||||
}
|
||||
|
||||
static void nv50BlendColor(GLcontext *ctx, const GLfloat color[4])
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_R, 4);
|
||||
OUT_RING_CACHEf(color[0]);
|
||||
OUT_RING_CACHEf(color[1]);
|
||||
OUT_RING_CACHEf(color[2]);
|
||||
OUT_RING_CACHEf(color[3]);
|
||||
}
|
||||
|
||||
static void nv50BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_RGB, 1);
|
||||
OUT_RING_CACHE(modeRGB);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_ALPHA, 1);
|
||||
OUT_RING_CACHE(modeA);
|
||||
}
|
||||
|
||||
|
||||
static void nv50BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
|
||||
GLenum sfactorA, GLenum dfactorA)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_RGB, 2);
|
||||
OUT_RING_CACHE(sfactorRGB); /* FIXME, sometimes has |0x4000 */
|
||||
OUT_RING_CACHE(dfactorRGB); /* FIXME, sometimes has |0x4000 */
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_ALPHA, 2);
|
||||
OUT_RING_CACHE(sfactorA); /* FIXME, sometimes has |0x4000 */
|
||||
OUT_RING_CACHE(dfactorA); /* FIXME, sometimes has |0x4000 */
|
||||
}
|
||||
|
||||
static void nv50Clear(GLcontext *ctx, GLbitfield mask)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
GLuint hw_bufs = 0;
|
||||
|
||||
if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT))
|
||||
hw_bufs |= 0x3c;
|
||||
if (mask & (BUFFER_BIT_STENCIL))
|
||||
hw_bufs |= 0x02;
|
||||
if (mask & (BUFFER_BIT_DEPTH))
|
||||
hw_bufs |= 0x01;
|
||||
|
||||
if (hw_bufs) {
|
||||
BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_BUFFERS, 1);
|
||||
OUT_RING(hw_bufs);
|
||||
}
|
||||
}
|
||||
|
||||
static void nv50ClearColor(GLcontext *ctx, const GLfloat color[4])
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_R, 4);
|
||||
OUT_RING_CACHEf(color[0]);
|
||||
OUT_RING_CACHEf(color[1]);
|
||||
OUT_RING_CACHEf(color[2]);
|
||||
OUT_RING_CACHEf(color[3]);
|
||||
}
|
||||
|
||||
static void nv50ClearDepth(GLcontext *ctx, GLclampd d)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_DEPTH, 1);
|
||||
OUT_RING_CACHEf(d);
|
||||
}
|
||||
|
||||
/* we're don't support indexed buffers
|
||||
void (*ClearIndex)(GLcontext *ctx, GLuint index)
|
||||
*/
|
||||
|
||||
static void nv50ClearStencil(GLcontext *ctx, GLint s)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_STENCIL, 1);
|
||||
OUT_RING_CACHE(s);
|
||||
}
|
||||
|
||||
static void nv50ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
|
||||
{
|
||||
/* Only using shaders */
|
||||
}
|
||||
|
||||
static void nv50ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
|
||||
GLboolean bmask, GLboolean amask )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
int i;
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_COLOR_MASK(0), 8);
|
||||
for (i=0; i<8; i++) {
|
||||
OUT_RING_CACHE(((amask && 0x01) << 12) | ((bmask && 0x01) << 8) | ((gmask && 0x01)<< 4) | ((rmask && 0x01) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
static void nv50ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
|
||||
{
|
||||
// TODO I need love
|
||||
}
|
||||
|
||||
static void nv50CullFace(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
|
||||
static void nv50FrontFace(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_FRONT_FACE, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
|
||||
static void nv50DepthFunc(GLcontext *ctx, GLenum func)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1);
|
||||
OUT_RING_CACHE(func);
|
||||
}
|
||||
|
||||
static void nv50DepthMask(GLcontext *ctx, GLboolean flag)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1);
|
||||
OUT_RING_CACHE(flag);
|
||||
}
|
||||
|
||||
static void nv50DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2);
|
||||
OUT_RING_CACHEf(nearval);
|
||||
OUT_RING_CACHEf(farval);
|
||||
}
|
||||
|
||||
/** Specify the current buffer for writing */
|
||||
//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
|
||||
/** Specify the buffers for writing for fragment programs*/
|
||||
//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
|
||||
|
||||
static void nv50Enable(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
switch(cap)
|
||||
{
|
||||
case GL_ALPHA_TEST:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_AUTO_NORMAL:
|
||||
// case GL_BLEND:
|
||||
// case GL_CLIP_PLANE0:
|
||||
// case GL_CLIP_PLANE1:
|
||||
// case GL_CLIP_PLANE2:
|
||||
// case GL_CLIP_PLANE3:
|
||||
// case GL_CLIP_PLANE4:
|
||||
// case GL_CLIP_PLANE5:
|
||||
case GL_COLOR_LOGIC_OP:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_COLOR_MATERIAL:
|
||||
// case GL_COLOR_SUM_EXT:
|
||||
// case GL_COLOR_TABLE:
|
||||
// case GL_CONVOLUTION_1D:
|
||||
// case GL_CONVOLUTION_2D:
|
||||
case GL_CULL_FACE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_DEPTH_TEST:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_DITHER:
|
||||
// case GL_FOG:
|
||||
// case GL_HISTOGRAM:
|
||||
// case GL_INDEX_LOGIC_OP:
|
||||
// case GL_LIGHT0:
|
||||
// case GL_LIGHT1:
|
||||
// case GL_LIGHT2:
|
||||
// case GL_LIGHT3:
|
||||
// case GL_LIGHT4:
|
||||
// case GL_LIGHT5:
|
||||
// case GL_LIGHT6:
|
||||
// case GL_LIGHT7:
|
||||
// case GL_LIGHTING:
|
||||
case GL_LINE_SMOOTH:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_LINE_STIPPLE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_MAP1_COLOR_4:
|
||||
// case GL_MAP1_INDEX:
|
||||
// case GL_MAP1_NORMAL:
|
||||
// case GL_MAP1_TEXTURE_COORD_1:
|
||||
// case GL_MAP1_TEXTURE_COORD_2:
|
||||
// case GL_MAP1_TEXTURE_COORD_3:
|
||||
// case GL_MAP1_TEXTURE_COORD_4:
|
||||
// case GL_MAP1_VERTEX_3:
|
||||
// case GL_MAP1_VERTEX_4:
|
||||
// case GL_MAP2_COLOR_4:
|
||||
// case GL_MAP2_INDEX:
|
||||
// case GL_MAP2_NORMAL:
|
||||
// case GL_MAP2_TEXTURE_COORD_1:
|
||||
// case GL_MAP2_TEXTURE_COORD_2:
|
||||
// case GL_MAP2_TEXTURE_COORD_3:
|
||||
// case GL_MAP2_TEXTURE_COORD_4:
|
||||
// case GL_MAP2_VERTEX_3:
|
||||
// case GL_MAP2_VERTEX_4:
|
||||
// case GL_MINMAX:
|
||||
// case GL_NORMALIZE:
|
||||
// case GL_POINT_SMOOTH:
|
||||
case GL_POLYGON_OFFSET_POINT:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_POLYGON_OFFSET_LINE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_POLYGON_OFFSET_FILL:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_POLYGON_SMOOTH:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
case GL_POLYGON_STIPPLE:
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
|
||||
// case GL_POST_CONVOLUTION_COLOR_TABLE:
|
||||
// case GL_RESCALE_NORMAL:
|
||||
case GL_SCISSOR_TEST:
|
||||
/* No enable bit, nv50Scissor will adjust to max range */
|
||||
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
||||
ctx->Scissor.Width, ctx->Scissor.Height);
|
||||
break;
|
||||
// case GL_SEPARABLE_2D:
|
||||
case GL_STENCIL_TEST:
|
||||
// TODO BACK and FRONT ?
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1);
|
||||
OUT_RING_CACHE(state);
|
||||
break;
|
||||
// case GL_TEXTURE_GEN_Q:
|
||||
// case GL_TEXTURE_GEN_R:
|
||||
// case GL_TEXTURE_GEN_S:
|
||||
// case GL_TEXTURE_GEN_T:
|
||||
// case GL_TEXTURE_1D:
|
||||
// case GL_TEXTURE_2D:
|
||||
// case GL_TEXTURE_3D:
|
||||
}
|
||||
}
|
||||
|
||||
static void nv50Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||
{
|
||||
/* Only using shaders */
|
||||
}
|
||||
|
||||
static void nv50Hint(GLcontext *ctx, GLenum target, GLenum mode)
|
||||
{
|
||||
// TODO I need love (fog and line_smooth hints)
|
||||
}
|
||||
|
||||
// void (*IndexMask)(GLcontext *ctx, GLuint mask);
|
||||
|
||||
static void nv50Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params )
|
||||
{
|
||||
/* Only with shaders */
|
||||
}
|
||||
|
||||
/** Set the lighting model parameters */
|
||||
void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params);
|
||||
|
||||
|
||||
static void nv50LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1);
|
||||
OUT_RING_CACHE((pattern << 8) | factor);
|
||||
}
|
||||
|
||||
static void nv50LineWidth(GLcontext *ctx, GLfloat width)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_WIDTH, 1);
|
||||
OUT_RING_CACHEf(width);
|
||||
}
|
||||
|
||||
static void nv50LogicOpcode(GLcontext *ctx, GLenum opcode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_OP, 1);
|
||||
OUT_RING_CACHE(opcode);
|
||||
}
|
||||
|
||||
static void nv50PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||
{
|
||||
/*TODO: not sure what goes here. */
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
}
|
||||
|
||||
/** Specify the diameter of rasterized points */
|
||||
static void nv50PointSize(GLcontext *ctx, GLfloat size)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POINT_SIZE, 1);
|
||||
OUT_RING_CACHEf(size);
|
||||
}
|
||||
|
||||
/** Select a polygon rasterization mode */
|
||||
static void nv50PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
}
|
||||
|
||||
/** Set the scale and units used to calculate depth values */
|
||||
static void nv50PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 1);
|
||||
OUT_RING_CACHEf(factor);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS, 1);
|
||||
OUT_RING_CACHEf(units);
|
||||
}
|
||||
|
||||
/** Set the polygon stippling pattern */
|
||||
static void nv50PolygonStipple(GLcontext *ctx, const GLubyte *mask )
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32);
|
||||
OUT_RING_CACHEp(mask, 32);
|
||||
}
|
||||
|
||||
/* Specifies the current buffer for reading */
|
||||
void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
|
||||
/** Set rasterization mode */
|
||||
void (*RenderMode)(GLcontext *ctx, GLenum mode );
|
||||
|
||||
/** Define the scissor box */
|
||||
static void nv50Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
/* There's no scissor enable bit, so adjust the scissor to cover the
|
||||
* maximum draw buffer bounds
|
||||
*/
|
||||
if (!ctx->Scissor.Enabled) {
|
||||
x = y = 0;
|
||||
w = h = 8191;
|
||||
} else {
|
||||
x += nmesa->drawX;
|
||||
y += nmesa->drawY;
|
||||
}
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
|
||||
OUT_RING_CACHE(((w) << 16) | x);
|
||||
OUT_RING_CACHE(((h) << 16) | y);
|
||||
}
|
||||
|
||||
/** Select flat or smooth shading */
|
||||
static void nv50ShadeModel(GLcontext *ctx, GLenum mode)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SHADE_MODEL, 1);
|
||||
OUT_RING_CACHE(mode);
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilFunc */
|
||||
static void nv50StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
|
||||
GLint ref, GLuint mask)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 1);
|
||||
OUT_RING_CACHE(func);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF, 1);
|
||||
OUT_RING_CACHE(ref);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK, 1);
|
||||
OUT_RING_CACHE(mask);
|
||||
}
|
||||
if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 2);
|
||||
OUT_RING_CACHE(func);
|
||||
OUT_RING_CACHE(ref);
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK, 1);
|
||||
OUT_RING_CACHE(mask);
|
||||
}
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilMask */
|
||||
static void nv50StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1);
|
||||
OUT_RING_CACHE(mask);
|
||||
}
|
||||
if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1);
|
||||
OUT_RING_CACHE(mask);
|
||||
}
|
||||
}
|
||||
|
||||
/** OpenGL 2.0 two-sided StencilOp */
|
||||
static void nv50StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
|
||||
GLenum zfail, GLenum zpass)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3);
|
||||
OUT_RING_CACHE(fail);
|
||||
OUT_RING_CACHE(zfail);
|
||||
OUT_RING_CACHE(zpass);
|
||||
}
|
||||
if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
|
||||
BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3);
|
||||
OUT_RING_CACHE(fail);
|
||||
OUT_RING_CACHE(zfail);
|
||||
OUT_RING_CACHE(zpass);
|
||||
}
|
||||
}
|
||||
|
||||
/** Control the generation of texture coordinates */
|
||||
void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
|
||||
const GLfloat *params);
|
||||
/** Set texture environment parameters */
|
||||
void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
|
||||
const GLfloat *param);
|
||||
/** Set texture parameters */
|
||||
void (*TexParameter)(GLcontext *ctx, GLenum target,
|
||||
struct gl_texture_object *texObj,
|
||||
GLenum pname, const GLfloat *params);
|
||||
|
||||
static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
|
||||
{
|
||||
/* Only with shaders */
|
||||
}
|
||||
|
||||
static void nv50WindowMoved(nouveauContextPtr nmesa)
|
||||
{
|
||||
GLcontext *ctx = nmesa->glCtx;
|
||||
GLfloat *v = nmesa->viewport.m;
|
||||
GLuint w = ctx->Viewport.Width;
|
||||
GLuint h = ctx->Viewport.Height;
|
||||
GLuint x = ctx->Viewport.X + nmesa->drawX;
|
||||
GLuint y = ctx->Viewport.Y + nmesa->drawY;
|
||||
int i;
|
||||
|
||||
BEGIN_RING_CACHE(NvSub3D,
|
||||
NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2);
|
||||
OUT_RING_CACHE((8191 << 16) | 0);
|
||||
OUT_RING_CACHE((8191 << 16) | 0);
|
||||
for (i=1; i<8; i++) {
|
||||
BEGIN_RING_CACHE(NvSub3D,
|
||||
NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2);
|
||||
OUT_RING_CACHE(0);
|
||||
OUT_RING_CACHE(0);
|
||||
}
|
||||
|
||||
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
||||
ctx->Scissor.Width, ctx->Scissor.Height);
|
||||
}
|
||||
|
||||
static GLboolean nv50InitCard(nouveauContextPtr nmesa)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x1558, 1);
|
||||
OUT_RING(1);
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_1(0), 8);
|
||||
for (i=0; i<8; i++) {
|
||||
OUT_RING(NvDmaFB);
|
||||
}
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_0(0), 12);
|
||||
for (i=0; i<12; i++) {
|
||||
OUT_RING(NvDmaFB);
|
||||
}
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x121c, 1);
|
||||
OUT_RING(1);
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x0200 + (i*0x20), 5);
|
||||
for (j=0; j<5; j++) {
|
||||
OUT_RING(0);
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_RING_SIZE(NvSub3D, 0x0fe0, 5);
|
||||
OUT_RING(0);
|
||||
OUT_RING(0);
|
||||
OUT_RING(0x16);
|
||||
OUT_RING(0);
|
||||
OUT_RING(0);
|
||||
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static GLboolean
|
||||
nv50BindBuffers(nouveauContextPtr nmesa, int num_color,
|
||||
nouveau_renderbuffer_t **color, nouveau_renderbuffer_t *depth)
|
||||
{
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
|
||||
{
|
||||
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
|
||||
|
||||
func->AlphaFunc = nv50AlphaFunc;
|
||||
func->BlendColor = nv50BlendColor;
|
||||
func->BlendEquationSeparate = nv50BlendEquationSeparate;
|
||||
func->BlendFuncSeparate = nv50BlendFuncSeparate;
|
||||
func->Clear = nv50Clear;
|
||||
func->ClearColor = nv50ClearColor;
|
||||
func->ClearDepth = nv50ClearDepth;
|
||||
func->ClearStencil = nv50ClearStencil;
|
||||
func->ClipPlane = nv50ClipPlane;
|
||||
func->ColorMask = nv50ColorMask;
|
||||
func->ColorMaterial = nv50ColorMaterial;
|
||||
func->CullFace = nv50CullFace;
|
||||
func->FrontFace = nv50FrontFace;
|
||||
func->DepthFunc = nv50DepthFunc;
|
||||
func->DepthMask = nv50DepthMask;
|
||||
func->DepthRange = nv50DepthRange;
|
||||
func->Enable = nv50Enable;
|
||||
func->Fogfv = nv50Fogfv;
|
||||
func->Hint = nv50Hint;
|
||||
func->Lightfv = nv50Lightfv;
|
||||
/* func->LightModelfv = nv50LightModelfv; */
|
||||
func->LineStipple = nv50LineStipple;
|
||||
func->LineWidth = nv50LineWidth;
|
||||
func->LogicOpcode = nv50LogicOpcode;
|
||||
func->PointParameterfv = nv50PointParameterfv;
|
||||
func->PointSize = nv50PointSize;
|
||||
func->PolygonMode = nv50PolygonMode;
|
||||
func->PolygonOffset = nv50PolygonOffset;
|
||||
func->PolygonStipple = nv50PolygonStipple;
|
||||
/* func->ReadBuffer = nv50ReadBuffer; */
|
||||
/* func->RenderMode = nv50RenderMode; */
|
||||
func->Scissor = nv50Scissor;
|
||||
func->ShadeModel = nv50ShadeModel;
|
||||
func->StencilFuncSeparate = nv50StencilFuncSeparate;
|
||||
func->StencilMaskSeparate = nv50StencilMaskSeparate;
|
||||
func->StencilOpSeparate = nv50StencilOpSeparate;
|
||||
/* func->TexGen = nv50TexGen; */
|
||||
/* func->TexParameter = nv50TexParameter; */
|
||||
func->TextureMatrix = nv50TextureMatrix;
|
||||
|
||||
nmesa->hw_func.InitCard = nv50InitCard;
|
||||
nmesa->hw_func.BindBuffers = nv50BindBuffers;
|
||||
nmesa->hw_func.WindowMoved = nv50WindowMoved;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue