mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-22 09:40:40 +02:00
Some work on buffer handling, most likely not entirely correct and
incomplete. But, it works well enough that windows can be
moved/resized.
This commit is contained in:
parent
3867bc9780
commit
4cfb762c3e
19 changed files with 779 additions and 145 deletions
|
|
@ -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
src/mesa/drivers/dri/nouveau/nouveau_buffers.c
Normal file
331
src/mesa/drivers/dri/nouveau/nouveau_buffers.c
Normal file
|
|
@ -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
src/mesa/drivers/dri/nouveau/nouveau_buffers.h
Normal file
41
src/mesa/drivers/dri/nouveau/nouveau_buffers.h
Normal file
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
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, newNOUVEAUCtx->vblank_flags, &newNOUVEAUCtx->vblank_seq );
|
||||
newNOUVEAUCtx->driDrawable = driDrawPriv;
|
||||
driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
|
||||
nmesa->driDrawable = driDrawPriv;
|
||||
|
||||
_mesa_make_current( newNOUVEAUCtx->glCtx,
|
||||
(GLframebuffer *) driDrawPriv->driverPrivate,
|
||||
(GLframebuffer *) driReadPriv->driverPrivate );
|
||||
_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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
fb = _mesa_create_framebuffer(mesaVis);
|
||||
if (!fb)
|
||||
return GL_FALSE;
|
||||
|
||||
/* back color renderbuffer */
|
||||
/* 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) {
|
||||
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);
|
||||
nrb = nouveau_renderbuffer_new(GL_RGBA, NULL,
|
||||
0, 0,
|
||||
driDrawPriv);
|
||||
nouveauSpanSetFunctions(nrb, mesaVis);
|
||||
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
_mesa_add_soft_renderbuffers(fb,
|
||||
GL_FALSE, /* color */
|
||||
swDepth,
|
||||
swStencil,
|
||||
swAccum,
|
||||
swAlpha,
|
||||
GL_FALSE /* aux */);
|
||||
driDrawPriv->driverPrivate = (void *) fb;
|
||||
|
||||
return (driDrawPriv->driverPrivate != NULL);
|
||||
}
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -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] );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
void nv30InitStateFuncs(struct dd_function_table *func)
|
||||
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…
Add table
Reference in a new issue