瀏覽代碼

Some work on buffer handling, most likely not entirely correct and

    incomplete. But, it works well enough that windows can be
    moved/resized.
tags/pre-merge-glsl-compiler-1
Ben Skeggs 19 年之前
父節點
當前提交
4cfb762c3e

+ 1
- 0
src/mesa/drivers/dri/nouveau/Makefile 查看文件

@@ -8,6 +8,7 @@ LIBNAME = nouveau_dri.so
MINIGLX_SOURCES =

DRIVER_SOURCES = \
nouveau_buffers.c \
nouveau_card.c \
nouveau_context.c \
nouveau_driver.c \

+ 331
- 0
src/mesa/drivers/dri/nouveau/nouveau_buffers.c 查看文件

@@ -0,0 +1,331 @@
#include "utils.h"
#include "framebuffer.h"
#include "renderbuffer.h"
#include "fbobject.h"

#include "nouveau_context.h"
#include "nouveau_buffers.h"

void
nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
drm_nouveau_mem_free_t memf;

if (mem->map)
drmUnmap(mem->map, mem->size);
memf.flags = mem->type;
memf.region_offset = mem->offset;
drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, sizeof(memf));
FREE(mem);
}

nouveau_mem *
nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
drm_nouveau_mem_alloc_t mema;
nouveau_mem *mem;
int ret;

mem = CALLOC(sizeof(nouveau_mem));
if (!mem)
return NULL;

mema.flags = mem->type = type;
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.region_offset;

if (type & NOUVEAU_MEM_MAPPED)
ret = drmMap(nmesa->driFd, mem->offset, 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);

if (mem->type & NOUVEAU_MEM_FB)
return (uint32_t)mem->offset - nmesa->vram_phys;
else if (mem->type & NOUVEAU_MEM_AGP)
return (uint32_t)mem->offset - nmesa->agp_phys;
else
return 0xDEADF00D;
}

static GLboolean
nouveau_renderbuffer_pixelformat(nouveau_renderbuffer *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_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 *nrb = (nouveau_renderbuffer*)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 (!nrb->map && (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;
return GL_TRUE;
}

static void
nouveau_renderbuffer_delete(struct gl_renderbuffer *rb)
{
GET_CURRENT_CONTEXT(ctx);
nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb;

if (nrb->mem)
nouveau_mem_free(ctx, nrb->mem);
FREE(nrb);
}

nouveau_renderbuffer *
nouveau_renderbuffer_new(GLenum internalFormat, GLvoid *map,
GLuint offset, GLuint pitch,
__DRIdrawablePrivate *dPriv)
{
nouveau_renderbuffer *nrb;

nrb = CALLOC_STRUCT(nouveau_renderbuffer_t);
if (nrb) {
_mesa_init_renderbuffer(&nrb->mesa, 0);

nouveau_renderbuffer_pixelformat(nrb, internalFormat);

nrb->mesa.AllocStorage = nouveau_renderbuffer_storage;
nrb->mesa.Delete = nouveau_renderbuffer_delete;

nrb->dPriv = dPriv;
nrb->offset = offset;
nrb->pitch = pitch;
nrb->map = map;
}

return nrb;
}

void
nouveau_window_moved(GLcontext *ctx)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);

/* 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 *color[MAX_DRAW_BUFFERS];
nouveau_renderbuffer *depth;

_mesa_update_framebuffer(ctx);
_mesa_update_draw_buffer_bounds(ctx);

color[0] = (nouveau_renderbuffer *)fb->_ColorDrawBuffers[0][0];
depth = (nouveau_renderbuffer *)fb->_DepthBuffer;

if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth))
return GL_FALSE;
nouveau_window_moved(ctx);

return GL_TRUE;
}

nouveau_renderbuffer *
nouveau_current_draw_buffer(GLcontext *ctx)
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
nouveau_renderbuffer *nrb;

if (!fb)
return NULL;

if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT)
nrb = (nouveau_renderbuffer *)
fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
else if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT)
nrb = (nouveau_renderbuffer *)
fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
else
nrb = NULL;
return nrb;
}

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 *nrb;

nrb = CALLOC_STRUCT(nouveau_renderbuffer_t);
if (nrb) {
_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)
{
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->NewFramebuffer = nouveauNewFramebuffer;
func->NewRenderbuffer = nouveauNewRenderbuffer;
func->BindFramebuffer = nouveauBindFramebuffer;
func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer;
func->RenderTexture = nouveauRenderTexture;
func->FinishRenderTexture = nouveauFinishRenderTexture;
}


+ 41
- 0
src/mesa/drivers/dri/nouveau/nouveau_buffers.h 查看文件

@@ -0,0 +1,41 @@
#ifndef __NOUVEAU_BUFFERS_H__
#define __NOUVEAU_BUFFERS_H__

#include <stdint.h>
#include "mtypes.h"
#include "utils.h"
#include "renderbuffer.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 *ctx, int type,
GLuint size, GLuint align);
extern void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem);
extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem);

typedef struct nouveau_renderbuffer_t {
struct gl_renderbuffer mesa; /* must be first! */
__DRIdrawablePrivate *dPriv;

nouveau_mem *mem;
void * map;

int cpp;
uint32_t offset;
uint32_t pitch;
} nouveau_renderbuffer;

extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat,
GLvoid *map, GLuint offset, GLuint pitch, __DRIdrawablePrivate *dPriv);
extern void nouveau_window_moved(GLcontext *ctx);
extern GLboolean nouveau_build_framebuffer(GLcontext *, struct gl_framebuffer *);
extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *ctx);

extern void nouveauInitBufferFuncs(struct dd_function_table *func);

#endif

+ 68
- 11
src/mesa/drivers/dri/nouveau/nouveau_context.c 查看文件

@@ -32,6 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "array_cache/acache.h"
#include "framebuffer.h"

#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
@@ -47,6 +48,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "nouveau_fifo.h"
#include "nouveau_tex.h"
#include "nouveau_msg.h"
#include "nouveau_reg.h"
#include "nv10_swtcl.h"

#include "vblank.h"
@@ -96,10 +98,17 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
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_AGP_PHYSICAL,
&nmesa->agp_phys))
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)
*/
@@ -169,6 +178,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
break;
}

nmesa->hw_func.InitCard(nmesa);
nouveauInitState(ctx);

driContextPriv->driverPrivate = (void *)nmesa;
@@ -208,17 +218,26 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driReadPriv )
{
if ( driContextPriv ) {
GET_CURRENT_CONTEXT(ctx);
nouveauContextPtr oldNOUVEAUCtx = ctx ? NOUVEAU_CONTEXT(ctx) : NULL;
nouveauContextPtr newNOUVEAUCtx = (nouveauContextPtr) driContextPriv->driverPrivate;

driDrawableInitVBlank(driDrawPriv, newNOUVEAUCtx->vblank_flags, &newNOUVEAUCtx->vblank_seq );
newNOUVEAUCtx->driDrawable = driDrawPriv;

_mesa_make_current( newNOUVEAUCtx->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate );

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;

driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
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 );
}
@@ -234,8 +253,46 @@ GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
return GL_TRUE;
}

static void nouveauDoSwapBuffers(nouveauContextPtr nmesa,
__DRIdrawablePrivate *dPriv)
{
struct gl_framebuffer *fb;
nouveau_renderbuffer *src, *dst;

fb = (struct gl_framebuffer *)dPriv->driverPrivate;
dst = (nouveau_renderbuffer*)
fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
src = (nouveau_renderbuffer*)
fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;

#ifdef ALLOW_MULTI_SUBCHANNEL
/* Ignore this.. it's a hack to test double-buffering, and not how
* SwapBuffers should look :)
*/
BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4);
OUT_RING (6); /* X8R8G8B8 */
OUT_RING ((dst->pitch << 16) | src->pitch);
OUT_RING (src->offset);
OUT_RING (dst->offset);

BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3);
OUT_RING ((0 << 16) | 0); /* src point */
OUT_RING ((0 << 16) | 0); /* dst point */
OUT_RING ((fb->Height << 16) | fb->Width); /* width/height */
#endif
}

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,

+ 20
- 0
src/mesa/drivers/dri/nouveau/nouveau_context.h 查看文件

@@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "nouveau_screen.h"
#include "nouveau_state_cache.h"
#include "nouveau_buffers.h"
#include "nouveau_shader.h"

#include "xmlconfig.h"
@@ -75,6 +76,17 @@ typedef void (*nouveau_line_func)( struct nouveau_context*,
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 **color,
nouveau_renderbuffer *depth);
/* Update anything that depends on the window position/size */
void (*WindowMoved)(struct nouveau_context *);
} nouveau_hw_func;

typedef struct nouveau_context {
/* Mesa context */
GLcontext *glCtx;
@@ -85,6 +97,13 @@ typedef struct nouveau_context {
/* The read-only regs */
volatile unsigned char* mmio;

/* Physical addresses of AGP/VRAM apertures */
uint64_t vram_phys;
uint64_t agp_phys;

/* 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;
@@ -132,6 +151,7 @@ typedef struct nouveau_context {
__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;

+ 29
- 0
src/mesa/drivers/dri/nouveau/nouveau_driver.c 查看文件

@@ -36,6 +36,35 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "utils.h"

/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */
GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa,
unsigned int param,
uint64_t* value)
{
drm_nouveau_getparam_t 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)
{
drm_nouveau_setparam_t 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,

+ 4
- 1
src/mesa/drivers/dri/nouveau/nouveau_driver.h 查看文件

@@ -33,7 +33,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#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__ */


+ 18
- 0
src/mesa/drivers/dri/nouveau/nouveau_lock.c 查看文件

@@ -29,6 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "nouveau_lock.h"

#include "drirenderbuffer.h"
#include "framebuffer.h"


/* Update the hardware state. This is called if another context has
@@ -57,6 +58,23 @@ void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags )
*/
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;


+ 20
- 3
src/mesa/drivers/dri/nouveau/nouveau_object.c 查看文件

@@ -1,6 +1,7 @@

#include "nouveau_fifo.h"
#include "nouveau_object.h"
#include "nouveau_reg.h"


static GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier)
@@ -51,14 +52,30 @@ void nouveauObjectInit(nouveauContextPtr nmesa)
return;
#endif

nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0);
nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
/* We need to know vram size.. */
#if 0
nouveauCreateDmaObject( nmesa, NvDmaFB,
0, (256*1024*1024),
0 /*NV_DMA_TARGET_FB*/, 0 /*NV_DMA_ACCESS_RW*/);

nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d,
0, 0, 0, 0);
nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D,
0, 0, 0, 0);
nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT,
NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0);

#ifdef ALLOW_MULTI_SUBCHANNEL
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, NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D, 1);
OUT_RING(NvCtxSurf2D);
#endif

nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);
}



+ 8
- 1
src/mesa/drivers/dri/nouveau/nouveau_object.h 查看文件

@@ -3,14 +3,21 @@

#include "nouveau_context.h"

#define ALLOW_MULTI_SUBCHANNEL

void nouveauObjectInit(nouveauContextPtr nmesa);

enum DMAObjects {
Nv3D = 0x80000019,
NvDmaFB = 0xD0FB0001
NvCtxSurf2D = 0x80000020,
NvImageBlit = 0x80000021,
NvDmaFB = 0xD0FB0001,
NvDmaAGP = 0xD0AA0001
};

enum DMASubchannel {
NvSubCtxSurf2D = 0,
NvSubImageBlit = 1,
NvSub3D = 7,
};


+ 56
- 72
src/mesa/drivers/dri/nouveau/nouveau_screen.c 查看文件

@@ -120,86 +120,69 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv,
GLboolean isPixmap)
{
nouveauScreenPtr screen = (nouveauScreenPtr) driScrnPriv->private;
nouveau_renderbuffer *nrb;
struct gl_framebuffer *fb;
const GLboolean swAccum = mesaVis->accumRedBits > 0;
const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24;

if (isPixmap) {
if (isPixmap)
return GL_FALSE; /* not implemented */
}
else {
const GLboolean swDepth = GL_FALSE;
const GLboolean swAlpha = GL_FALSE;
const GLboolean swAccum = mesaVis->accumRedBits > 0;
const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24;
struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);

/* front color renderbuffer */
{
driRenderbuffer *frontRb
= driNewRenderbuffer(GL_RGBA,
driScrnPriv->pFB + screen->frontOffset,
screen->fbFormat,
screen->frontOffset, screen->frontPitch,
driDrawPriv);
nouveauSpanSetFunctions(frontRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
}

/* back color renderbuffer */
if (mesaVis->doubleBufferMode) {
driRenderbuffer *backRb
= driNewRenderbuffer(GL_RGBA,
driScrnPriv->pFB + screen->backOffset,
screen->fbFormat,
screen->backOffset, screen->backPitch,
driDrawPriv);
nouveauSpanSetFunctions(backRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
}
fb = _mesa_create_framebuffer(mesaVis);
if (!fb)
return GL_FALSE;

/* depth renderbuffer */
if (mesaVis->depthBits == 16) {
driRenderbuffer *depthRb
= driNewRenderbuffer(GL_DEPTH_COMPONENT16,
driScrnPriv->pFB + screen->depthOffset,
screen->fbFormat,
screen->depthOffset, screen->depthPitch,
driDrawPriv);
nouveauSpanSetFunctions(depthRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
}
else if (mesaVis->depthBits == 24) {
driRenderbuffer *depthRb
= driNewRenderbuffer(GL_DEPTH_COMPONENT24,
driScrnPriv->pFB + screen->depthOffset,
screen->fbFormat,
screen->depthOffset, screen->depthPitch,
driDrawPriv);
nouveauSpanSetFunctions(depthRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
/* Front buffer */
nrb = nouveau_renderbuffer_new(GL_RGBA,
driScrnPriv->pFB + screen->frontOffset,
screen->frontOffset,
screen->frontPitch * 4,
driDrawPriv);
nouveauSpanSetFunctions(nrb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &nrb->mesa);

if (0 /* unified buffers if we choose to support them.. */) {
} else {
if (mesaVis->doubleBufferMode) {
nrb = nouveau_renderbuffer_new(GL_RGBA, NULL,
0, 0,
driDrawPriv);
nouveauSpanSetFunctions(nrb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa);
}

/* stencil renderbuffer */
if (mesaVis->stencilBits > 0 && !swStencil) {
driRenderbuffer *stencilRb
= driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
driScrnPriv->pFB + screen->depthOffset,
screen->fbFormat,
screen->depthOffset, screen->depthPitch,
driDrawPriv);
nouveauSpanSetFunctions(stencilRb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) {
nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT, NULL,
0, 0,
driDrawPriv);
nouveauSpanSetFunctions(nrb, mesaVis);
_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, NULL,
0, 0,
driDrawPriv);
nouveauSpanSetFunctions(nrb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa);
} else if (mesaVis->depthBits == 16) {
nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16, NULL,
0, 0,
driDrawPriv);
nouveauSpanSetFunctions(nrb, mesaVis);
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa);
}
}

_mesa_add_soft_renderbuffers(fb,
GL_FALSE, /* color */
swDepth,
swStencil,
swAccum,
swAlpha,
GL_FALSE /* aux */);
driDrawPriv->driverPrivate = (void *) fb;
_mesa_add_soft_renderbuffers(fb,
GL_FALSE, /* color */
GL_FALSE, /* depth */
swStencil,
swAccum,
GL_FALSE, /* alpha */
GL_FALSE /* aux */);

return (driDrawPriv->driverPrivate != NULL);
}
driDrawPriv->driverPrivate = (void *) fb;
return (driDrawPriv->driverPrivate != NULL);
}


@@ -363,7 +346,8 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc
*driver_modes = nouveauFillInModes(dri_priv->bpp,
(dri_priv->bpp == 16) ? 16 : 24,
(dri_priv->bpp == 16) ? 0 : 8,
(dri_priv->back_offset != dri_priv->depth_offset));
1
);

/* 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

+ 2
- 0
src/mesa/drivers/dri/nouveau/nouveau_shader.c 查看文件

@@ -132,6 +132,8 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs)
*/
nvs->func->UpdateConst(ctx, nvs, i);
} else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) {
if (!nvs->params[i].source_val) /* this is a workaround when consts aren't alloc'd from id=0.. */
continue;
/* update any changed state parameters */
if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val))
nvs->func->UpdateConst(ctx, nvs, i);

+ 2
- 0
src/mesa/drivers/dri/nouveau/nouveau_shader.h 查看文件

@@ -2,6 +2,7 @@
#define __SHADER_COMMON_H__

#include "mtypes.h"
#include "nouveau_buffers.h"

typedef struct _nvsFunc nvsFunc;

@@ -40,6 +41,7 @@ typedef struct _nouveauShader {
unsigned int program_alloc_size;
unsigned int program_start_id;
unsigned int program_current;
nouveau_mem *program_buffer;
unsigned int inputs_read;
unsigned int outputs_written;
int inst_count;

+ 5
- 9
src/mesa/drivers/dri/nouveau/nouveau_span.c 查看文件

@@ -109,14 +109,10 @@ void nouveauSpanInitFunctions( GLcontext *ctx )
* Plug in the Get/Put routines for the given driRenderbuffer.
*/
void
nouveauSpanSetFunctions(driRenderbuffer *drb, const GLvisual *vis)
nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis)
{
if (drb->Base.InternalFormat == GL_RGBA) {
if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
nouveauInitPointers_RGB565(&drb->Base);
}
else {
nouveauInitPointers_ARGB8888(&drb->Base);
}
}
if (nrb->mesa._ActualFormat == GL_RGBA8)
nouveauInitPointers_ARGB8888(&nrb->mesa);
else if (nrb->mesa._ActualFormat == GL_RGB5)
nouveauInitPointers_RGB565(&nrb->mesa);
}

+ 2
- 1
src/mesa/drivers/dri/nouveau/nouveau_span.h 查看文件

@@ -30,9 +30,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define __NOUVEAU_SPAN_H__

#include "drirenderbuffer.h"
#include "nouveau_buffers.h"

extern void nouveauSpanInitFunctions( GLcontext *ctx );
extern void nouveauSpanSetFunctions(driRenderbuffer *rb, const GLvisual *vis);
extern void nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis);

#endif /* __NOUVEAU_SPAN_H__ */


+ 23
- 19
src/mesa/drivers/dri/nouveau/nouveau_state.c 查看文件

@@ -59,20 +59,33 @@ static void nouveauCalcViewport(GLcontext *ctx)
/* Calculate the Viewport Matrix */
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
nouveau_renderbuffer *nrb;
const GLfloat *v = ctx->Viewport._WindowMap.m;
GLfloat *m = nmesa->viewport.m;
GLfloat xoffset, yoffset;
GLint h = 0;
if (nmesa->driDrawable)
h = nmesa->driDrawable->h + SUBPIXEL_Y;
nrb = nouveau_current_draw_buffer(ctx);
nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF;

if (nrb && nrb->map) {
/* Window */
xoffset = nrb->dPriv->x;
yoffset = nrb->dPriv->y;
} else {
/* Offscreen or back buffer */
xoffset = 0.0;
yoffset = 0.0;
}

m[MAT_SX] = v[MAT_SX];
m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X;
m[MAT_SY] = - v[MAT_SY];
m[MAT_TY] = - v[MAT_TY] + h;
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)
@@ -96,7 +109,7 @@ static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei
nouveauCalcViewport(ctx);
}

static void nouveauDepthRange(GLcontext *ctx)
static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far)
{
nouveauCalcViewport(ctx);
}
@@ -161,15 +174,15 @@ void nouveauDDInitState(nouveauContextPtr nmesa)
/* No TCL engines for these ones */
break;
case NV_10:
nv10InitStateFuncs(&nmesa->glCtx->Driver);
nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
break;
case NV_20:
nv20InitStateFuncs(&nmesa->glCtx->Driver);
nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
break;
case NV_30:
case NV_40:
case NV_50:
nv30InitStateFuncs(&nmesa->glCtx->Driver);
nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
break;
default:
break;
@@ -270,7 +283,6 @@ void nouveauInitState(GLcontext *ctx)
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 );
@@ -320,8 +332,6 @@ void nouveauInitState(GLcontext *ctx)
ctx->Polygon.OffsetFactor,
ctx->Polygon.OffsetUnits );
STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple );
STATE_INIT(Scissor)( ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height );
STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel );
STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT,
ctx->Stencil.Function[0],
@@ -341,10 +351,4 @@ void nouveauInitState(GLcontext *ctx)
ctx->Stencil.FailFunc[1],
ctx->Stencil.ZFailFunc[1],
ctx->Stencil.ZPassFunc[1]);

STATE_INIT(Viewport)( ctx,
ctx->Viewport.X, ctx->Viewport.Y,
ctx->Viewport.Width, ctx->Viewport.Height );

STATE_INIT(DrawBuffer)( ctx, ctx->Color.DrawBuffer[0] );
}

+ 3
- 3
src/mesa/drivers/dri/nouveau/nouveau_state.h 查看文件

@@ -32,9 +32,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
extern void nouveauDDInitState(nouveauContextPtr nmesa);
extern void nouveauDDInitStateFuncs(GLcontext *ctx);

extern void nv10InitStateFuncs(struct dd_function_table *func);
extern void nv20InitStateFuncs(struct dd_function_table *func);
extern void nv30InitStateFuncs(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 nouveauInitState(GLcontext *ctx);


+ 11
- 18
src/mesa/drivers/dri/nouveau/nv30_fragprog.c 查看文件

@@ -10,6 +10,7 @@
#include "nouveau_shader.h"
#include "nouveau_object.h"
#include "nouveau_msg.h"
#include "nouveau_buffers.h"
#include "nv30_shader.h"

unsigned int NVFP_TX_AOP_COUNT = 64;
@@ -19,31 +20,22 @@ struct _op_xlat NVFP_TX_AOP[64];
* Support routines
*/

/*XXX: bad bad bad bad */
static uint64_t fragprog_ofs;
static uint32_t *fragprog_buf = NULL;

static void
NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
drm_nouveau_mem_alloc_t mem;

if (!fragprog_buf) {
mem.flags = NOUVEAU_MEM_FB|NOUVEAU_MEM_MAPPED;
mem.size = nvs->program_size * sizeof(uint32_t);
mem.alignment = 0;
mem.region_offset = &fragprog_ofs;
if (drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, &mem,
sizeof(mem))) {
fprintf(stderr, "MEM_ALLOC fail\n");
return;
}
if (!nvs->program_buffer) {
nouveau_mem *fpbuf;

if (drmMap(nmesa->driFd, fragprog_ofs, mem.size, &fragprog_buf)) {
fprintf(stderr, "MEM_MAP fail\n");
fpbuf = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB|NOUVEAU_MEM_MAPPED,
nvs->program_size * sizeof(uint32_t), 0);
if (!fpbuf) {
fprintf(stderr, "fragprog vram alloc fail!\n");
return;
}
nvs->program_buffer = fpbuf;
}

/*XXX: should do a DMA.. and not copy over a possibly in-use program.. */
@@ -52,9 +44,10 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
* caches the program somewhere? so, maybe not so bad to just clobber the
* old program in vram..
*/
memcpy(fragprog_buf, nvs->program, nvs->program_size * sizeof(uint32_t));
memcpy(nvs->program_buffer->map, nvs->program,
nvs->program_size * sizeof(uint32_t));
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
OUT_RING(((uint32_t)fragprog_ofs-0xE0000000)|1);
OUT_RING(nouveau_mem_gpu_offset_get(ctx, nvs->program_buffer) | 1);
}

static void

+ 140
- 12
src/mesa/drivers/dri/nouveau/nv30_state.c 查看文件

@@ -304,10 +304,16 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
// case GL_POST_CONVOLUTION_COLOR_TABLE:
// case GL_RESCALE_NORMAL:
// case GL_SCISSOR_TEST:
case GL_SCISSOR_TEST:
/* No enable bit, nv30Scissor 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, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1);
OUT_RING_CACHE(state);
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1);
OUT_RING_CACHE(state);
break;
@@ -514,9 +520,26 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode );
static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
nouveau_renderbuffer *nrb;

/* Adjust offsets if drawing to a window */
nrb = nouveau_current_draw_buffer(ctx);
if (nrb && nrb->map) {
x += nrb->dPriv->x;
y += nrb->dPriv->y;
}

/* 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;
}

BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2);
OUT_RING_CACHE((w << 16) | x);
OUT_RING_CACHE((h << 16) | y);
OUT_RING_CACHE(((w) << 16) | x);
OUT_RING_CACHE(((h) << 16) | y);
}

/** Select flat or smooth shading */
@@ -602,18 +625,117 @@ static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
OUT_RING_CACHEp(mat->m, 16);
}

/** Set the viewport */
static void nv30Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
static void nv30WindowMoved(nouveauContextPtr nmesa)
{
/* TODO: Where do the VIEWPORT_XFRM_* regs come in? */
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
GLcontext *ctx = nmesa->glCtx;
nouveau_renderbuffer *nrb;
GLfloat *v = nmesa->viewport.m;
GLuint w = ctx->Viewport.Width;
GLuint h = ctx->Viewport.Height;
GLuint x = ctx->Viewport.X;
GLuint y = ctx->Viewport.Y;

/* Adjust offsets if drawing to a window */
nrb = nouveau_current_draw_buffer(ctx);
if (nrb && nrb->map) {
x += nrb->dPriv->x;
y += nrb->dPriv->y;
}

BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2);
OUT_RING_CACHE((w << 16) | x);
OUT_RING_CACHE((h << 16) | y);
}

void nv30InitStateFuncs(struct dd_function_table *func)
/* something to do with clears, possibly doesn't belong here */
BEGIN_RING_CACHE(NvSub3D,
NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2);
OUT_RING_CACHE(((w+x) << 16) | x);
OUT_RING_CACHE(((h+y) << 16) | y);
/* viewport transform */
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8);
OUT_RING_CACHEf (v[MAT_TX]);
OUT_RING_CACHEf (v[MAT_TY]);
OUT_RING_CACHEf (v[MAT_TZ]);
OUT_RING_CACHEf (0.0);
OUT_RING_CACHEf (v[MAT_SX]);
OUT_RING_CACHEf (v[MAT_SY]);
OUT_RING_CACHEf (v[MAT_SZ]);
OUT_RING_CACHEf (0.0);

ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height);
}

static GLboolean nv30InitCard(nouveauContextPtr nmesa)
{
/* Need some love.. */
return GL_FALSE;
}

static GLboolean nv40InitCard(nouveauContextPtr nmesa)
{
nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D);

BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2);
OUT_RING(NvDmaFB);
OUT_RING(NvDmaFB);
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
OUT_RING(NvDmaFB);
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2);
OUT_RING(NvDmaFB);
OUT_RING(NvDmaFB);
BEGIN_RING_SIZE(NvSub3D, 0x0220, 1);
OUT_RING(1);
BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2);
OUT_RING(0xedcba987);
OUT_RING(0x00000021);
BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1);
OUT_RING(0x03008000);

return GL_TRUE;
}

static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color,
nouveau_renderbuffer **color,
nouveau_renderbuffer *depth)
{
nouveau_renderbuffer *nrb;
GLuint x, y, w, h;

/* Adjust offsets if drawing to a window */
nrb = nouveau_current_draw_buffer(nmesa->glCtx);
w = nrb->mesa.Width;
h = nrb->mesa.Height;
if (nrb && nrb->map) {
x = nrb->dPriv->x;
y = nrb->dPriv->y;
} else {
x = 0;
y = 0;
}

if (num_color != 1)
return GL_FALSE;
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5);
OUT_RING (((w+x)<<16)|x);
OUT_RING (((h+y)<<16)|y);
OUT_RING (0x148);
OUT_RING (color[0]->pitch);
OUT_RING (color[0]->offset);

if (depth) {
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1);
OUT_RING (depth->offset);
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1);
OUT_RING (depth->pitch);
}

return GL_TRUE;
}

void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);

func->AlphaFunc = nv30AlphaFunc;
func->BlendColor = nv30BlendColor;
func->BlendEquationSeparate = nv30BlendEquationSeparate;
@@ -628,7 +750,6 @@ void nv30InitStateFuncs(struct dd_function_table *func)
func->FrontFace = nv30FrontFace;
func->DepthFunc = nv30DepthFunc;
func->DepthMask = nv30DepthMask;
func->DepthRange = nv30DepthRange;
func->Enable = nv30Enable;
func->Fogfv = nv30Fogfv;
func->Hint = nv30Hint;
@@ -656,6 +777,13 @@ void nv30InitStateFuncs(struct dd_function_table *func)
func->TexParameter = nv30TexParameter;
#endif
func->TextureMatrix = nv30TextureMatrix;
func->Viewport = nv30Viewport;


if (nmesa->screen->card->type >= NV_40)
nmesa->hw_func.InitCard = nv40InitCard;
else
nmesa->hw_func.InitCard = nv30InitCard;
nmesa->hw_func.BindBuffers = nv30BindBuffers;
nmesa->hw_func.WindowMoved = nv30WindowMoved;
}


Loading…
取消
儲存