diff options
Diffstat (limited to 'src/mesa/drivers/dri')
140 files changed, 4489 insertions, 2829 deletions
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index bd38e3be47c..18dbeba24a8 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -11,7 +11,8 @@ COMMON_GALLIUM_SOURCES = \ COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ ../../common/driverfuncs.c \ ../common/texmem.c \ - ../common/drirenderbuffer.c + ../common/drirenderbuffer.c \ + ../common/dri_metaops.c ifeq ($(WINDOW_SYSTEM),dri) WINOBJ= diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c new file mode 100644 index 00000000000..fe183c2e870 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_metaops.c @@ -0,0 +1,541 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#include "main/arrayobj.h" +#include "main/attrib.h" +#include "main/blend.h" +#include "main/bufferobj.h" +#include "main/buffers.h" +#include "main/depth.h" +#include "main/enable.h" +#include "main/matrix.h" +#include "main/macros.h" +#include "main/polygon.h" +#include "main/shaders.h" +#include "main/stencil.h" +#include "main/texstate.h" +#include "main/varray.h" +#include "main/viewport.h" +#include "shader/arbprogram.h" +#include "shader/program.h" +#include "dri_metaops.h" + +void +meta_set_passthrough_transform(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + meta->saved_vp_x = ctx->Viewport.X; + meta->saved_vp_y = ctx->Viewport.Y; + meta->saved_vp_width = ctx->Viewport.Width; + meta->saved_vp_height = ctx->Viewport.Height; + meta->saved_matrix_mode = ctx->Transform.MatrixMode; + + meta->internal_viewport_call = GL_TRUE; + _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); + meta->internal_viewport_call = GL_FALSE; + + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); + _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); + + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); +} + +void +meta_restore_transform(struct dri_metaops *meta) +{ + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PopMatrix(); + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PopMatrix(); + + _mesa_MatrixMode(meta->saved_matrix_mode); + + meta->internal_viewport_call = GL_TRUE; + _mesa_Viewport(meta->saved_vp_x, meta->saved_vp_y, + meta->saved_vp_width, meta->saved_vp_height); + meta->internal_viewport_call = GL_FALSE; +} + + +/** + * Set up a vertex program to pass through the position and first texcoord + * for pixel path. + */ +void +meta_set_passthrough_vertex_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + static const char *vp = + "!!ARBvp1.0\n" + "TEMP vertexClip;\n" + "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n" + "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n" + "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n" + "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n" + "MOV result.position, vertexClip;\n" + "MOV result.texcoord[0], vertex.texcoord[0];\n" + "MOV result.color, vertex.color;\n" + "END\n"; + + assert(meta->saved_vp == NULL); + + _mesa_reference_vertprog(ctx, &meta->saved_vp, + ctx->VertexProgram.Current); + if (meta->passthrough_vp == NULL) { + GLuint prog_name; + _mesa_GenPrograms(1, &prog_name); + _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name); + _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB, + GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(vp), (const GLubyte *)vp); + _mesa_reference_vertprog(ctx, &meta->passthrough_vp, + ctx->VertexProgram.Current); + _mesa_DeletePrograms(1, &prog_name); + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + meta->passthrough_vp); + ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, + &meta->passthrough_vp->Base); + + meta->saved_vp_enable = ctx->VertexProgram.Enabled; + _mesa_Enable(GL_VERTEX_PROGRAM_ARB); +} + +/** + * Restores the previous vertex program after + * meta_set_passthrough_vertex_program() + */ +void +meta_restore_vertex_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + meta->saved_vp); + _mesa_reference_vertprog(ctx, &meta->saved_vp, NULL); + ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, + &ctx->VertexProgram.Current->Base); + + if (!meta->saved_vp_enable) + _mesa_Disable(GL_VERTEX_PROGRAM_ARB); +} + +/** + * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the + * program object. + */ +void +meta_set_fragment_program(struct dri_metaops *meta, + struct gl_fragment_program **prog, + const char *prog_string) +{ + GLcontext *ctx = meta->ctx; + assert(meta->saved_fp == NULL); + + _mesa_reference_fragprog(ctx, &meta->saved_fp, + ctx->FragmentProgram.Current); + if (*prog == NULL) { + GLuint prog_name; + _mesa_GenPrograms(1, &prog_name); + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name); + _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, + GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(prog_string), (const GLubyte *)prog_string); + _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current); + /* Note that DeletePrograms unbinds the program on us */ + _mesa_DeletePrograms(1, &prog_name); + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog); + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base)); + + meta->saved_fp_enable = ctx->FragmentProgram.Enabled; + _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); +} + +/** + * Restores the previous fragment program after + * meta_set_fragment_program() + */ +void +meta_restore_fragment_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + meta->saved_fp); + _mesa_reference_fragprog(ctx, &meta->saved_fp, NULL); + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, + &ctx->FragmentProgram.Current->Base); + + if (!meta->saved_fp_enable) + _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); +} + +static const float default_texcoords[4][2] = { { 0.0, 0.0 }, + { 1.0, 0.0 }, + { 1.0, 1.0 }, + { 0.0, 1.0 } }; + +void +meta_set_default_texrect(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + struct gl_client_array *old_texcoord_array; + + meta->saved_active_texture = ctx->Texture.CurrentUnit; + if (meta->saved_array_vbo == NULL) { + _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, + ctx->Array.ArrayBufferObj); + } + + old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; + meta->saved_texcoord_type = old_texcoord_array->Type; + meta->saved_texcoord_size = old_texcoord_array->Size; + meta->saved_texcoord_stride = old_texcoord_array->Stride; + meta->saved_texcoord_enable = old_texcoord_array->Enabled; + meta->saved_texcoord_ptr = old_texcoord_array->Ptr; + _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, + old_texcoord_array->BufferObj); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0); + + if (meta->texcoord_vbo == NULL) { + GLuint vbo_name; + + _mesa_GenBuffersARB(1, &vbo_name); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), + default_texcoords, GL_STATIC_DRAW_ARB); + _mesa_reference_buffer_object(ctx, &meta->texcoord_vbo, + ctx->Array.ArrayBufferObj); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->texcoord_vbo->Name); + } + _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); + + _mesa_Enable(GL_TEXTURE_COORD_ARRAY); +} + +void +meta_restore_texcoords(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + /* Restore the old TexCoordPointer */ + if (meta->saved_texcoord_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->saved_texcoord_vbo->Name); + _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + + _mesa_TexCoordPointer(meta->saved_texcoord_size, + meta->saved_texcoord_type, + meta->saved_texcoord_stride, + meta->saved_texcoord_ptr); + if (!meta->saved_texcoord_enable) + _mesa_Disable(GL_TEXTURE_COORD_ARRAY); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0 + + meta->saved_active_texture); + + if (meta->saved_array_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->saved_array_vbo->Name); + _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + + +/** + * Perform glClear where mask contains only color, depth, and/or stencil. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering. The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ + +/** + * Per-context one-time init of things for intl_clear_tris(). + * Basically set up a private array object for vertex/color arrays. + */ +static void +meta_init_clear(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + struct gl_array_object *arraySave = NULL; + const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name; + const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name; + + /* create new array object */ + meta->clear.arrayObj = _mesa_new_array_object(ctx, ~0); + + /* save current array object, bind new one */ + _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj); + + /* one-time setup of vertex arrays (pos, color) */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), meta->clear.color); + _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), meta->clear.vertices); + _mesa_Enable(GL_COLOR_ARRAY); + _mesa_Enable(GL_VERTEX_ARRAY); + + /* restore original array object */ + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); + _mesa_reference_array_object(ctx, &arraySave, NULL); + + /* restore original buffer objects */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer); + _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer); +} + + + +/** + * Perform glClear where mask contains only color, depth, and/or stencil. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering. The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ +void +meta_clear_tris(struct dri_metaops *meta, GLbitfield mask) +{ + GLcontext *ctx = meta->ctx; + GLfloat dst_z; + struct gl_framebuffer *fb = ctx->DrawBuffer; + int i; + GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; + GLuint saved_shader_program = 0; + unsigned int saved_active_texture; + struct gl_array_object *arraySave = NULL; + + if (!meta->clear.arrayObj) + meta_init_clear(meta); + + assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | + BUFFER_BIT_STENCIL)) == 0); + + _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | + GL_DEPTH_BUFFER_BIT | + GL_ENABLE_BIT | + GL_POLYGON_BIT | + GL_STENCIL_BUFFER_BIT | + GL_TRANSFORM_BIT | + GL_CURRENT_BIT | + GL_VIEWPORT_BIT); + saved_active_texture = ctx->Texture.CurrentUnit; + + /* Disable existing GL state we don't want to apply to a clear. */ + _mesa_Disable(GL_ALPHA_TEST); + _mesa_Disable(GL_BLEND); + _mesa_Disable(GL_CULL_FACE); + _mesa_Disable(GL_FOG); + _mesa_Disable(GL_POLYGON_SMOOTH); + _mesa_Disable(GL_POLYGON_STIPPLE); + _mesa_Disable(GL_POLYGON_OFFSET_FILL); + _mesa_Disable(GL_LIGHTING); + _mesa_Disable(GL_CLIP_PLANE0); + _mesa_Disable(GL_CLIP_PLANE1); + _mesa_Disable(GL_CLIP_PLANE2); + _mesa_Disable(GL_CLIP_PLANE3); + _mesa_Disable(GL_CLIP_PLANE4); + _mesa_Disable(GL_CLIP_PLANE5); + _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { + saved_fp_enable = GL_TRUE; + _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); + } + if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { + saved_vp_enable = GL_TRUE; + _mesa_Disable(GL_VERTEX_PROGRAM_ARB); + } + if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { + saved_shader_program = ctx->Shader.CurrentProgram->Name; + _mesa_UseProgramObjectARB(0); + } + + if (ctx->Texture._EnabledUnits != 0) { + int i; + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + _mesa_ActiveTextureARB(GL_TEXTURE0 + i); + _mesa_Disable(GL_TEXTURE_1D); + _mesa_Disable(GL_TEXTURE_2D); + _mesa_Disable(GL_TEXTURE_3D); + if (ctx->Extensions.ARB_texture_cube_map) + _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); + if (ctx->Extensions.NV_texture_rectangle) + _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); + if (ctx->Extensions.MESA_texture_array) { + _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); + _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); + } + } + } + + /* save current array object, bind our private one */ + _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj); + + meta_set_passthrough_transform(meta); + + for (i = 0; i < 4; i++) { + COPY_4FV(meta->clear.color[i], ctx->Color.ClearColor); + } + + /* convert clear Z from [0,1] to NDC coord in [-1,1] */ + dst_z = -1.0 + 2.0 * ctx->Depth.Clear; + + /* The ClearDepth value is unaffected by DepthRange, so do a default + * mapping. + */ + _mesa_DepthRange(0.0, 1.0); + + /* Prepare the vertices, which are the same regardless of which buffer we're + * drawing to. + */ + meta->clear.vertices[0][0] = fb->_Xmin; + meta->clear.vertices[0][1] = fb->_Ymin; + meta->clear.vertices[0][2] = dst_z; + meta->clear.vertices[1][0] = fb->_Xmax; + meta->clear.vertices[1][1] = fb->_Ymin; + meta->clear.vertices[1][2] = dst_z; + meta->clear.vertices[2][0] = fb->_Xmax; + meta->clear.vertices[2][1] = fb->_Ymax; + meta->clear.vertices[2][2] = dst_z; + meta->clear.vertices[3][0] = fb->_Xmin; + meta->clear.vertices[3][1] = fb->_Ymax; + meta->clear.vertices[3][2] = dst_z; + + while (mask != 0) { + GLuint this_mask = 0; + GLuint color_bit; + + color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); + if (color_bit != 0) + this_mask |= (1 << (color_bit - 1)); + + /* Clear depth/stencil in the same pass as color. */ + this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); + + /* Select the current color buffer and use the color write mask if + * we have one, otherwise don't write any color channels. + */ + if (this_mask & BUFFER_BIT_FRONT_LEFT) + _mesa_DrawBuffer(GL_FRONT_LEFT); + else if (this_mask & BUFFER_BIT_BACK_LEFT) + _mesa_DrawBuffer(GL_BACK_LEFT); + else if (color_bit != 0) + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + + (color_bit - BUFFER_COLOR0 - 1)); + else + _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + /* Control writing of the depth clear value to depth. */ + if (this_mask & BUFFER_BIT_DEPTH) { + _mesa_DepthFunc(GL_ALWAYS); + _mesa_Enable(GL_DEPTH_TEST); + } else { + _mesa_Disable(GL_DEPTH_TEST); + _mesa_DepthMask(GL_FALSE); + } + + /* Control writing of the stencil clear value to stencil. */ + if (this_mask & BUFFER_BIT_STENCIL) { + _mesa_Enable(GL_STENCIL_TEST); + _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, + GL_REPLACE, GL_REPLACE, GL_REPLACE); + _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, + ctx->Stencil.Clear & 0x7fffffff, + ctx->Stencil.WriteMask[0]); + } else { + _mesa_Disable(GL_STENCIL_TEST); + } + + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + + mask &= ~this_mask; + } + + meta_restore_transform(meta); + + _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); + if (saved_fp_enable) + _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); + if (saved_vp_enable) + _mesa_Enable(GL_VERTEX_PROGRAM_ARB); + + if (saved_shader_program) + _mesa_UseProgramObjectARB(saved_shader_program); + + _mesa_PopAttrib(); + + /* restore current array object */ + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); + _mesa_reference_array_object(ctx, &arraySave, NULL); +} + +void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta) +{ + meta->ctx = ctx; +} + +void meta_destroy_metaops(struct dri_metaops *meta) +{ + if (meta->clear.arrayObj) + _mesa_delete_array_object(meta->ctx, meta->clear.arrayObj); + +} diff --git a/src/mesa/drivers/dri/common/dri_metaops.h b/src/mesa/drivers/dri/common/dri_metaops.h new file mode 100644 index 00000000000..bb4079d5353 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_metaops.h @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * 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 TUNGSTEN 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. + * + **************************************************************************/ +#ifndef DRI_METAOPS_H +#define DRI_METAOPS_H + +#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \ + BUFFER_BIT_FRONT_LEFT | \ + BUFFER_BIT_COLOR0 | \ + BUFFER_BIT_COLOR1 | \ + BUFFER_BIT_COLOR2 | \ + BUFFER_BIT_COLOR3 | \ + BUFFER_BIT_COLOR4 | \ + BUFFER_BIT_COLOR5 | \ + BUFFER_BIT_COLOR6 | \ + BUFFER_BIT_COLOR7) + +struct dri_meta_clear { + struct gl_array_object *arrayObj; + GLfloat vertices[4][3]; + GLfloat color[4][4]; +}; + +struct dri_metaops { + GLcontext *ctx; + GLboolean internal_viewport_call; + struct gl_fragment_program *bitmap_fp; + struct gl_vertex_program *passthrough_vp; + struct gl_buffer_object *texcoord_vbo; + + struct gl_fragment_program *saved_fp; + GLboolean saved_fp_enable; + struct gl_vertex_program *saved_vp; + GLboolean saved_vp_enable; + + struct gl_fragment_program *tex2d_fp; + + GLboolean saved_texcoord_enable; + struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; + GLenum saved_texcoord_type; + GLsizei saved_texcoord_size, saved_texcoord_stride; + const void *saved_texcoord_ptr; + int saved_active_texture; + + GLint saved_vp_x, saved_vp_y; + GLsizei saved_vp_width, saved_vp_height; + GLenum saved_matrix_mode; + + struct dri_meta_clear clear; +}; + + +void meta_set_passthrough_transform(struct dri_metaops *meta); + +void meta_restore_transform(struct dri_metaops *meta); + +void meta_set_passthrough_vertex_program(struct dri_metaops *meta); + +void meta_restore_vertex_program(struct dri_metaops *meta); + +void meta_set_fragment_program(struct dri_metaops *meta, + struct gl_fragment_program **prog, + const char *prog_string); + +void meta_restore_fragment_program(struct dri_metaops *meta); + +void meta_set_default_texrect(struct dri_metaops *meta); + +void meta_restore_texcoords(struct dri_metaops *meta); +void meta_clear_tris(struct dri_metaops *meta, GLbitfield mask); + +void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta); +void meta_destroy_metaops(struct dri_metaops *meta); +#endif + diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index ae0e61e515b..1d940603fa8 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -1,4 +1,3 @@ -/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.7 2003/04/28 17:01:25 dawes Exp $ */ /** * \file dri_util.c * DRI utility functions. @@ -122,6 +121,9 @@ static int driUnbindContext(__DRIcontext *pcp) pdp = pcp->driDrawablePriv; prp = pcp->driReadablePriv; + /* already unbound */ + if (!pdp && !prp) + return GL_TRUE; /* Let driver unbind drawable from context */ (*psp->DriverAPI.UnbindContext)(pcp); @@ -146,9 +148,10 @@ static int driUnbindContext(__DRIcontext *pcp) * window we can determine the last context bound to the window and * use that context's lock. (BrianP, 2-Dec-2000) */ + pcp->driDrawablePriv = pcp->driReadablePriv = NULL; + #if 0 /* Unbind the drawable */ - pcp->driDrawablePriv = NULL; pdp->driContextPriv = &psp->dummyContextPriv; #endif diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h index f5e35e41618..e308fd28311 100644 --- a/src/mesa/drivers/dri/common/extension_helper.h +++ b/src/mesa/drivers/dri/common/extension_helper.h @@ -406,9 +406,10 @@ static const char UniformMatrix4fvARB_names[] = ""; #endif -#if defined(need_GL_APPLE_vertex_array_object) +#if defined(need_GL_ARB_vertex_array_object) || defined(need_GL_APPLE_vertex_array_object) static const char DeleteVertexArraysAPPLE_names[] = "ip\0" /* Parameter signature */ + "glDeleteVertexArrays\0" "glDeleteVertexArraysAPPLE\0" ""; #endif @@ -941,6 +942,13 @@ static const char WeightivARB_names[] = ""; #endif +#if defined(need_GL_SGIX_instruments) +static const char PollInstrumentsSGIX_names[] = + "p\0" /* Parameter signature */ + "glPollInstrumentsSGIX\0" + ""; +#endif + #if defined(need_GL_SUN_global_alpha) static const char GlobalAlphaFactordSUN_names[] = "d\0" /* Parameter signature */ @@ -2114,6 +2122,13 @@ static const char Tangent3fvEXT_names[] = ""; #endif +#if defined(need_GL_ARB_vertex_array_object) +static const char GenVertexArrays_names[] = + "ip\0" /* Parameter signature */ + "glGenVertexArrays\0" + ""; +#endif + #if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) static const char BindFramebufferEXT_names[] = "ii\0" /* Parameter signature */ @@ -2340,10 +2355,10 @@ static const char GetCombinerStageParameterfvNV_names[] = ""; #endif -#if defined(need_GL_EXT_coordinate_frame) -static const char Binormal3fEXT_names[] = - "fff\0" /* Parameter signature */ - "glBinormal3fEXT\0" +#if defined(need_GL_ARB_vertex_array_object) +static const char BindVertexArray_names[] = + "i\0" /* Parameter signature */ + "glBindVertexArray\0" ""; #endif @@ -2773,10 +2788,10 @@ static const char Uniform4fARB_names[] = ""; #endif -#if defined(need_GL_IBM_multimode_draw_arrays) -static const char MultiModeDrawArraysIBM_names[] = - "pppii\0" /* Parameter signature */ - "glMultiModeDrawArraysIBM\0" +#if defined(need_GL_ARB_map_buffer_range) +static const char FlushMappedBufferRange_names[] = + "iii\0" /* Parameter signature */ + "glFlushMappedBufferRange\0" ""; #endif @@ -3403,10 +3418,11 @@ static const char GetProgramParameterdvNV_names[] = ""; #endif -#if defined(need_GL_SGIX_instruments) -static const char PollInstrumentsSGIX_names[] = - "p\0" /* Parameter signature */ - "glPollInstrumentsSGIX\0" +#if defined(need_GL_ARB_vertex_array_object) || defined(need_GL_APPLE_vertex_array_object) +static const char IsVertexArrayAPPLE_names[] = + "i\0" /* Parameter signature */ + "glIsVertexArray\0" + "glIsVertexArrayAPPLE\0" ""; #endif @@ -3904,6 +3920,13 @@ static const char VertexAttribs4dvNV_names[] = ""; #endif +#if defined(need_GL_IBM_multimode_draw_arrays) +static const char MultiModeDrawArraysIBM_names[] = + "pppii\0" /* Parameter signature */ + "glMultiModeDrawArraysIBM\0" + ""; +#endif + #if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) static const char VertexAttrib4dARB_names[] = "idddd\0" /* Parameter signature */ @@ -3933,6 +3956,13 @@ static const char VertexWeightfEXT_names[] = ""; #endif +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3fEXT_names[] = + "fff\0" /* Parameter signature */ + "glBinormal3fEXT\0" + ""; +#endif + #if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord) static const char FogCoordfvEXT_names[] = "p\0" /* Parameter signature */ @@ -4048,10 +4078,10 @@ static const char BlendFuncSeparateEXT_names[] = ""; #endif -#if defined(need_GL_APPLE_vertex_array_object) -static const char IsVertexArrayAPPLE_names[] = - "i\0" /* Parameter signature */ - "glIsVertexArrayAPPLE\0" +#if defined(need_GL_ARB_map_buffer_range) +static const char MapBufferRange_names[] = + "iiii\0" /* Parameter signature */ + "glMapBufferRange\0" ""; #endif @@ -4296,6 +4326,13 @@ static const char SpriteParameterivSGIX_names[] = ""; #endif +#if defined(need_GL_EXT_provoking_vertex) +static const char ProvokingVertexEXT_names[] = + "i\0" /* Parameter signature */ + "glProvokingVertexEXT\0" + ""; +#endif + #if defined(need_GL_VERSION_1_3) static const char MultiTexCoord1fARB_names[] = "if\0" /* Parameter signature */ @@ -4940,8 +4977,8 @@ static const struct dri_extension_function GL_3DFX_tbuffer_functions[] = { static const struct dri_extension_function GL_APPLE_vertex_array_object_functions[] = { { DeleteVertexArraysAPPLE_names, DeleteVertexArraysAPPLE_remap_index, -1 }, { GenVertexArraysAPPLE_names, GenVertexArraysAPPLE_remap_index, -1 }, - { BindVertexArrayAPPLE_names, BindVertexArrayAPPLE_remap_index, -1 }, { IsVertexArrayAPPLE_names, IsVertexArrayAPPLE_remap_index, -1 }, + { BindVertexArrayAPPLE_names, BindVertexArrayAPPLE_remap_index, -1 }, { NULL, 0, 0 } }; #endif @@ -4986,6 +5023,14 @@ static const struct dri_extension_function GL_ARB_framebuffer_object_functions[] }; #endif +#if defined(need_GL_ARB_map_buffer_range) +static const struct dri_extension_function GL_ARB_map_buffer_range_functions[] = { + { FlushMappedBufferRange_names, FlushMappedBufferRange_remap_index, -1 }, + { MapBufferRange_names, MapBufferRange_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + #if defined(need_GL_ARB_matrix_palette) static const struct dri_extension_function GL_ARB_matrix_palette_functions[] = { { MatrixIndexusvARB_names, MatrixIndexusvARB_remap_index, -1 }, @@ -5094,6 +5139,16 @@ static const struct dri_extension_function GL_ARB_transpose_matrix_functions[] = }; #endif +#if defined(need_GL_ARB_vertex_array_object) +static const struct dri_extension_function GL_ARB_vertex_array_object_functions[] = { + { DeleteVertexArraysAPPLE_names, DeleteVertexArraysAPPLE_remap_index, -1 }, + { GenVertexArrays_names, GenVertexArrays_remap_index, -1 }, + { BindVertexArray_names, BindVertexArray_remap_index, -1 }, + { IsVertexArrayAPPLE_names, IsVertexArrayAPPLE_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + #if defined(need_GL_ARB_vertex_blend) static const struct dri_extension_function GL_ARB_vertex_blend_functions[] = { { WeightubvARB_names, WeightubvARB_remap_index, -1 }, @@ -5347,7 +5402,6 @@ static const struct dri_extension_function GL_EXT_coordinate_frame_functions[] = { Binormal3ivEXT_names, Binormal3ivEXT_remap_index, -1 }, { Tangent3sEXT_names, Tangent3sEXT_remap_index, -1 }, { Tangent3fvEXT_names, Tangent3fvEXT_remap_index, -1 }, - { Binormal3fEXT_names, Binormal3fEXT_remap_index, -1 }, { Tangent3dvEXT_names, Tangent3dvEXT_remap_index, -1 }, { Binormal3bvEXT_names, Binormal3bvEXT_remap_index, -1 }, { Binormal3dEXT_names, Binormal3dEXT_remap_index, -1 }, @@ -5356,6 +5410,7 @@ static const struct dri_extension_function GL_EXT_coordinate_frame_functions[] = { Tangent3ivEXT_names, Tangent3ivEXT_remap_index, -1 }, { Tangent3dEXT_names, Tangent3dEXT_remap_index, -1 }, { Binormal3svEXT_names, Binormal3svEXT_remap_index, -1 }, + { Binormal3fEXT_names, Binormal3fEXT_remap_index, -1 }, { Binormal3dvEXT_names, Binormal3dvEXT_remap_index, -1 }, { Tangent3iEXT_names, Tangent3iEXT_remap_index, -1 }, { Tangent3bvEXT_names, Tangent3bvEXT_remap_index, -1 }, @@ -5541,6 +5596,13 @@ static const struct dri_extension_function GL_EXT_polygon_offset_functions[] = { }; #endif +#if defined(need_GL_EXT_provoking_vertex) +static const struct dri_extension_function GL_EXT_provoking_vertex_functions[] = { + { ProvokingVertexEXT_names, ProvokingVertexEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + #if defined(need_GL_EXT_secondary_color) static const struct dri_extension_function GL_EXT_secondary_color_functions[] = { { SecondaryColor3iEXT_names, SecondaryColor3iEXT_remap_index, -1 }, @@ -6038,11 +6100,11 @@ static const struct dri_extension_function GL_SGIX_igloo_interface_functions[] = #if defined(need_GL_SGIX_instruments) static const struct dri_extension_function GL_SGIX_instruments_functions[] = { { ReadInstrumentsSGIX_names, ReadInstrumentsSGIX_remap_index, -1 }, + { PollInstrumentsSGIX_names, PollInstrumentsSGIX_remap_index, -1 }, { GetInstrumentsSGIX_names, GetInstrumentsSGIX_remap_index, -1 }, { StartInstrumentsSGIX_names, StartInstrumentsSGIX_remap_index, -1 }, { StopInstrumentsSGIX_names, StopInstrumentsSGIX_remap_index, -1 }, { InstrumentsBufferSGIX_names, InstrumentsBufferSGIX_remap_index, -1 }, - { PollInstrumentsSGIX_names, PollInstrumentsSGIX_remap_index, -1 }, { NULL, 0, 0 } }; #endif diff --git a/src/mesa/drivers/dri/common/xmlpool.h b/src/mesa/drivers/dri/common/xmlpool.h index 7fbc6e800d0..587517ea10a 100644 --- a/src/mesa/drivers/dri/common/xmlpool.h +++ b/src/mesa/drivers/dri/common/xmlpool.h @@ -60,6 +60,10 @@ #define DRI_CONF_OPT_BEGIN(name,type,def) \ "<option name=\""#name"\" type=\""#type"\" default=\""#def"\">\n" +/** \brief Begin an option definition with qouted default value */ +#define DRI_CONF_OPT_BEGIN_Q(name,type,def) \ +"<option name=\""#name"\" type=\""#type"\" default="#def">\n" + /** \brief Begin an option definition with restrictions on valid values */ #define DRI_CONF_OPT_BEGIN_V(name,type,def,valid) \ "<option name=\""#name"\" type=\""#type"\" default=\""#def"\" valid=\""valid"\">\n" diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index cbee9f9efe9..9c6f891dd32 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -737,12 +737,6 @@ i830_assert_not_dirty( struct intel_context *intel ) assert(!get_dirty(state)); } -static void -i830_note_unlock( struct intel_context *intel ) -{ - /* nothing */ -} - void i830InitVtbl(struct i830_context *i830) { @@ -757,6 +751,5 @@ i830InitVtbl(struct i830_context *i830) i830->intel.vtbl.render_start = i830_render_start; i830->intel.vtbl.render_prevalidate = i830_render_prevalidate; i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; - i830->intel.vtbl.note_unlock = i830_note_unlock; i830->intel.vtbl.finish_batch = intel_finish_vb; } diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 2fca247af19..fe1be93a6d0 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -692,13 +692,6 @@ i915_assert_not_dirty( struct intel_context *intel ) assert(!dirty); } -static void -i915_note_unlock( struct intel_context *intel ) -{ - /* nothing */ -} - - void i915InitVtbl(struct i915_context *i915) { @@ -713,6 +706,5 @@ i915InitVtbl(struct i915_context *i915) i915->intel.vtbl.update_texture_state = i915UpdateTextureState; i915->intel.vtbl.flush_cmd = i915_flush_cmd; i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; - i915->intel.vtbl.note_unlock = i915_note_unlock; i915->intel.vtbl.finish_batch = intel_finish_vb; } diff --git a/src/mesa/drivers/dri/i915/intel_pixel_read.c b/src/mesa/drivers/dri/i915/intel_pixel_read.c index 56087aacd4e..cc4589f4d42 100644..120000 --- a/src/mesa/drivers/dri/i915/intel_pixel_read.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_read.c @@ -1,306 +1 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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 TUNGSTEN 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. - * - **************************************************************************/ - -#include "main/glheader.h" -#include "main/enums.h" -#include "main/mtypes.h" -#include "main/macros.h" -#include "main/image.h" -#include "main/bufferobj.h" -#include "swrast/swrast.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_buffers.h" -#include "intel_regions.h" -#include "intel_pixel.h" -#include "intel_buffer_objects.h" - -/* For many applications, the new ability to pull the source buffers - * back out of the GTT and then do the packing/conversion operations - * in software will be as much of an improvement as trying to get the - * blitter and/or texture engine to do the work. - * - * This step is gated on private backbuffers. - * - * Obviously the frontbuffer can't be pulled back, so that is either - * an argument for blit/texture readpixels, or for blitting to a - * temporary and then pulling that back. - * - * When the destination is a pbo, however, it's not clear if it is - * ever going to be pulled to main memory (though the access param - * will be a good hint). So it sounds like we do want to be able to - * choose between blit/texture implementation on the gpu and pullback - * and cpu-based copying. - * - * Unless you can magically turn client memory into a PBO for the - * duration of this call, there will be a cpu-based copying step in - * any case. - */ - - -static GLboolean -do_texture_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - struct intel_region *dest_region) -{ -#if 0 - struct intel_context *intel = intel_context(ctx); - intelScreenPrivate *screen = intel->intelScreen; - GLint pitch = pack->RowLength ? pack->RowLength : width; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int textureFormat; - GLenum glTextureFormat; - int destFormat, depthFormat, destPitch; - drm_clip_rect_t tmp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if (ctx->_ImageTransferState || - pack->SwapBytes || pack->LsbFirst || !pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); - return GL_FALSE; - } - - intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); - - if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: couldn't set dest %s/%s\n", - __FUNCTION__, - _mesa_lookup_enum_by_nr(type), - _mesa_lookup_enum_by_nr(format)); - return GL_FALSE; - } - - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - intel->vtbl.install_meta_state(intel); - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE(intel); - SET_STATE(i830, state); - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - /* Set the frontbuffer up as a large rectangular texture. - */ - intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); - - - intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); - - - /* Set the 3d engine to draw into the destination region: - */ - - intel->vtbl.meta_draw_region(intel, dest_region); - intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ - - - /* Draw a single quad, no cliprects: - */ - intel->vtbl.meta_disable_cliprects(intel); - - intel->vtbl.draw_quad(intel, - 0, width, 0, height, - 0x00ff00ff, x, x + width, y, y + height); - - intel->vtbl.leave_meta_state(intel); - } - UNLOCK_HARDWARE(intel); - - intel_region_wait_fence(ctx, dest_region); /* required by GL */ - return GL_TRUE; -#endif - - return GL_FALSE; -} - - - - -static GLboolean -do_blit_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, GLvoid * pixels) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *src = intel_readbuf_region(intel); - struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); - GLuint dst_offset; - GLuint rowLength; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s\n", __FUNCTION__); - - if (!src) - return GL_FALSE; - - if (dst) { - /* XXX This validation should be done by core mesa: - */ - if (!_mesa_validate_pbo_access(2, pack, width, height, 1, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); - return GL_TRUE; - } - } - else { - /* PBO only for now: - */ - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - not PBO\n", __FUNCTION__); - return GL_FALSE; - } - - - if (ctx->_ImageTransferState || - !intel_check_blit_format(src, format, type)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad format for blit\n", __FUNCTION__); - return GL_FALSE; - } - - if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: bad packing params\n", __FUNCTION__); - return GL_FALSE; - } - - if (pack->RowLength > 0) - rowLength = pack->RowLength; - else - rowLength = width; - - if (pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__); - return GL_FALSE; - } - else { - rowLength = -rowLength; - } - - /* XXX 64-bit cast? */ - dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, - format, type, 0, 0, 0); - - - /* Although the blits go on the command buffer, need to do this and - * fire with lock held to guarentee cliprects are correct. - */ - intelFlush(&intel->ctx); - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - GLboolean all = (width * height * src->cpp == dst->Base.Size && - x == 0 && dst_offset == 0); - - dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int nbox = dPriv->numClipRects; - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t rect; - drm_clip_rect_t src_rect; - int i; - - src_rect.x1 = dPriv->x + x; - src_rect.y1 = dPriv->y + dPriv->h - (y + height); - src_rect.x2 = src_rect.x1 + width; - src_rect.y2 = src_rect.y1 + height; - - - - for (i = 0; i < nbox; i++) { - if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) - continue; - - intelEmitCopyBlit(intel, - src->cpp, - src->pitch, src->buffer, 0, src->tiling, - rowLength, dst_buffer, dst_offset, GL_FALSE, - rect.x1, - rect.y1, - rect.x1 - src_rect.x1, - rect.y2 - src_rect.y2, - rect.x2 - rect.x1, rect.y2 - rect.y1, - GL_COPY); - } - } - UNLOCK_HARDWARE(intel); - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - DONE\n", __FUNCTION__); - - return GL_TRUE; -} - -void -intelReadPixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, GLvoid * pixels) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - intelFlush(ctx); - - if (do_blit_readpixels - (ctx, x, y, width, height, format, type, pack, pixels)) - return; - - if (do_texture_readpixels - (ctx, x, y, width, height, format, type, pack, pixels)) - return; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); - - _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); -} +../intel/intel_pixel_read.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index 1d39278cbf0..a905455342d 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -1255,11 +1255,9 @@ intel_meta_draw_poly(struct intel_context *intel, { union fi *vb; GLint i; - GLboolean was_locked = intel->locked; unsigned int saved_vertex_size = intel->vertex_size; - if (!was_locked) - LOCK_HARDWARE(intel); + LOCK_HARDWARE(intel); intel->vertex_size = 6; @@ -1283,8 +1281,7 @@ intel_meta_draw_poly(struct intel_context *intel, intel->vertex_size = saved_vertex_size; - if (!was_locked) - UNLOCK_HARDWARE(intel); + UNLOCK_HARDWARE(intel); } static void diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 9712c387254..00a42111da0 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -23,6 +23,7 @@ DRIVER_SOURCES = \ intel_pixel_bitmap.c \ intel_pixel_copy.c \ intel_pixel_draw.c \ + intel_pixel_read.c \ intel_state.c \ intel_swapbuffers.c \ intel_tex.c \ diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index 5cffcebde43..54d30a3f422 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -65,21 +65,31 @@ static void compile_clip_prog( struct brw_context *brw, c.func.single_program_flow = 1; c.key = *key; - + c.need_ff_sync = BRW_IS_IGDNG(brw); /* Need to locate the two positions present in vertex + header. * These are currently hardcoded: */ c.header_position_offset = ATTR_SIZE; - for (i = 0, delta = REG_SIZE; i < VERT_RESULT_MAX; i++) + if (BRW_IS_IGDNG(brw)) + delta = 3 * REG_SIZE; + else + delta = REG_SIZE; + + for (i = 0; i < VERT_RESULT_MAX; i++) if (c.key.attrs & (1<<i)) { c.offset[i] = delta; delta += ATTR_SIZE; } c.nr_attrs = brw_count_bits(c.key.attrs); - c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ + + if (BRW_IS_IGDNG(brw)) + c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */ + else + c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ + c.nr_bytes = c.nr_regs * REG_SIZE; c.prog_data.clip_mode = c.key.clip_mode; /* XXX */ @@ -148,7 +158,11 @@ static void upload_clip_prog(struct brw_context *brw) key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT); /* _NEW_TRANSFORM */ key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled); - key.clip_mode = BRW_CLIPMODE_NORMAL; + + if (BRW_IS_IGDNG(brw)) + key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP; + else + key.clip_mode = BRW_CLIPMODE_NORMAL; /* _NEW_POLYGON */ if (key.primitive == GL_TRIANGLES) { diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h index e06747864b5..12e8548df1f 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.h +++ b/src/mesa/drivers/dri/i965/brw_clip.h @@ -117,6 +117,7 @@ struct brw_clip_compile { GLuint header_position_offset; GLuint offset[VERT_ATTRIB_MAX]; + GLboolean need_ff_sync; }; #define ATTR_SIZE (4*4) @@ -171,5 +172,5 @@ struct brw_reg get_tmp( struct brw_clip_compile *c ); void brw_clip_project_position(struct brw_clip_compile *c, struct brw_reg pos ); - +void brw_clip_ff_sync(struct brw_clip_compile *c); #endif diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index d830e49e50a..9abd0642aa2 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -130,7 +130,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) struct brw_instruction *plane_loop; struct brw_instruction *plane_active; struct brw_instruction *is_negative; - struct brw_instruction *is_neg2; + struct brw_instruction *is_neg2 = NULL; struct brw_instruction *not_culled; struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD); @@ -148,7 +148,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_clip_init_clipmask(c); /* -ve rhw workaround */ - if (!BRW_IS_G4X(p->brw)) { + if (BRW_IS_965(p->brw)) { brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<20)); @@ -185,7 +185,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) * Both can be negative on GM965/G965 due to RHW workaround * if so, this object should be rejected. */ - if (!BRW_IS_G4X(p->brw)) { + if (BRW_IS_965(p->brw)) { brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0)); is_neg2 = brw_IF(p, BRW_EXECUTE_1); { @@ -210,7 +210,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) /* If both are positive, do nothing */ /* Only on GM965/G965 */ - if (!BRW_IS_G4X(p->brw)) { + if (BRW_IS_965(p->brw)) { brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); is_neg2 = brw_IF(p, BRW_EXECUTE_1); } @@ -225,7 +225,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_set_predicate_control(p, BRW_PREDICATE_NONE); } - if (!BRW_IS_G4X(p->brw)) { + if (BRW_IS_965(p->brw)) { brw_ENDIF(p, is_neg2); } } @@ -246,6 +246,8 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1); brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0)); + if (c->need_ff_sync) + brw_clip_ff_sync(c); not_culled = brw_IF(p, BRW_EXECUTE_1); { brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, GL_FALSE); diff --git a/src/mesa/drivers/dri/i965/brw_clip_point.c b/src/mesa/drivers/dri/i965/brw_clip_point.c index d17b199b898..97382991686 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_point.c +++ b/src/mesa/drivers/dri/i965/brw_clip_point.c @@ -50,5 +50,7 @@ void brw_emit_point_clip( struct brw_clip_compile *c ) /* Send an empty message to kill the thread: */ brw_clip_tri_alloc_regs(c, 0); + if (c->need_ff_sync) + brw_clip_ff_sync(c); brw_clip_kill_thread(c); } diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c index 9b0d7eab7bf..5762c9577c6 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_state.c +++ b/src/mesa/drivers/dri/i965/brw_clip_state.c @@ -95,7 +95,14 @@ clip_unit_create_from_key(struct brw_context *brw, * even number. */ assert(key->nr_urb_entries % 2 == 0); - clip.thread4.max_threads = 2 - 1; + + /* Although up to 16 concurrent Clip threads are allowed on IGDNG, + * only 2 threads can output VUEs at a time. + */ + if (BRW_IS_IGDNG(brw)) + clip.thread4.max_threads = 16 - 1; + else + clip.thread4.max_threads = 2 - 1; } else { assert(key->nr_urb_entries >= 5); clip.thread4.max_threads = 1 - 1; diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index 7fd37bd05ff..4c2d655fb10 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -77,6 +77,10 @@ void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, if (c->nr_attrs & 1) { for (j = 0; j < 3; j++) { GLuint delta = c->nr_attrs*16 + 32; + + if (BRW_IS_IGDNG(c->func.brw)) + delta = c->nr_attrs * 16 + 32 * 3; + brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0)); } } @@ -562,7 +566,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c ) /* if -ve rhw workaround bit is set, do cliptest */ - if (!BRW_IS_G4X(p->brw)) { + if (BRW_IS_965(p->brw)) { brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<20)); @@ -579,11 +583,14 @@ void brw_emit_tri_clip( struct brw_clip_compile *c ) if (c->key.do_flat_shading) brw_clip_tri_flat_shade(c); - if (c->key.clip_mode == BRW_CLIPMODE_NORMAL) + if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) || + (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP)) do_clip_tri(c); else maybe_do_clip_tri(c); - + + if (c->need_ff_sync) + brw_clip_ff_sync(c); brw_clip_tri_emit_polygon(c); /* Send an empty message to kill the thread: diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c index d7ca517927b..26950383c1b 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c +++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c @@ -496,6 +496,8 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c ) } brw_ENDIF(p, do_clip); + if (c->need_ff_sync) + brw_clip_ff_sync(c); emit_unfilled_primitives(c); brw_clip_kill_thread(c); } diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c index 9d3b0be694a..e09efc07ed4 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_util.c +++ b/src/mesa/drivers/dri/i965/brw_clip_util.c @@ -140,6 +140,10 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, /* Just copy the vertex header: */ + /* + * After CLIP stage, only first 256 bits of the VUE are read + * back on IGDNG, so needn't change it + */ brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1); /* Iterate over each attribute (could be done in pairs?) @@ -147,6 +151,9 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, for (i = 0; i < c->nr_attrs; i++) { GLuint delta = i*16 + 32; + if (BRW_IS_IGDNG(p->brw)) + delta = i * 16 + 32 * 3; + if (delta == c->offset[VERT_RESULT_EDGE]) { if (force_edgeflag) brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1)); @@ -177,6 +184,10 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, if (i & 1) { GLuint delta = i*16 + 32; + + if (BRW_IS_IGDNG(p->brw)) + delta = i * 16 + 32 * 3; + brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0)); } @@ -343,3 +354,19 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c ) } } +void brw_clip_ff_sync(struct brw_clip_compile *c) +{ + struct brw_compile *p = &c->func; + brw_ff_sync(p, + c->reg.R0, + 0, + c->reg.R0, + 1, + 1, /* used */ + 1, /* msg length */ + 1, /* response length */ + 0, /* eot */ + 1, /* write compelete */ + 0, /* urb offset */ + BRW_URB_SWIZZLE_NONE); +} diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 873fc8ffff6..57ddf75413a 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -129,7 +129,6 @@ struct brw_context; #define BRW_NEW_PRIMITIVE 0x40 #define BRW_NEW_CONTEXT 0x80 #define BRW_NEW_WM_INPUT_DIMENSIONS 0x100 -#define BRW_NEW_INPUT_VARYING 0x200 #define BRW_NEW_PSP 0x800 #define BRW_NEW_WM_SURFACES 0x1000 #define BRW_NEW_FENCE 0x2000 @@ -246,9 +245,6 @@ struct brw_vs_ouput_sizes { }; -/** Number of general purpose registers (VS, WM, etc) */ -#define BRW_MAX_GRF 128 - /** Number of texture sampler units */ #define BRW_MAX_TEX_UNIT 16 @@ -405,7 +401,6 @@ struct brw_vertex_element { struct brw_vertex_info { - GLuint varying; /* varying:1[VERT_ATTRIB_MAX] */ GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[VERT_ATTRIB_MAX] */ }; @@ -614,9 +609,10 @@ struct brw_context struct brw_wm_prog_data *prog_data; struct brw_wm_compile *compile_data; - /* Input sizes, calculated from active vertex program: + /** Input sizes, calculated from active vertex program. + * One bit per fragment program input attribute. */ - GLuint input_size_masks[4]; + GLbitfield input_size_masks[4]; /** Array of surface default colors (texture border color) */ dri_bo *sdc_bo[BRW_MAX_TEX_UNIT]; diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 98fc909c2ad..d166250b4fe 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -139,6 +139,7 @@ #define BRW_CLIPMODE_CLIP_NON_REJECTED 2 #define BRW_CLIPMODE_REJECT_ALL 3 #define BRW_CLIPMODE_ACCEPT_ALL 4 +#define BRW_CLIPMODE_KERNEL_CLIP 5 #define BRW_CLIP_NDCSPACE 0 #define BRW_CLIP_SCREENSPACE 1 @@ -670,6 +671,25 @@ #define BRW_SAMPLER_MESSAGE_SIMD8_LD 3 #define BRW_SAMPLER_MESSAGE_SIMD16_LD 3 +#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG 0 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_IGDNG 0 +#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG 0 +#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG 1 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_BIAS_IGDNG 1 +#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG 1 +#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_IGDNG 2 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD_IGDNG 2 +#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD_IGDNG 2 +#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG 3 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE_IGDNG 3 +#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG 3 + +/* for IGDNG only */ +#define BRW_SAMPLER_SIMD_MODE_SIMD4X2 0 +#define BRW_SAMPLER_SIMD_MODE_SIMD8 1 +#define BRW_SAMPLER_SIMD_MODE_SIMD16 2 +#define BRW_SAMPLER_SIMD_MODE_SIMD32_64 3 + #define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2 @@ -819,8 +839,11 @@ #include "intel_chipset.h" #define BRW_IS_G4X(brw) (IS_G4X((brw)->intel.intelScreen->deviceID)) -#define CMD_PIPELINE_SELECT(brw) (BRW_IS_G4X(brw) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965) -#define CMD_VF_STATISTICS(brw) (BRW_IS_G4X(brw) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965) -#define URB_SIZES(brw) (BRW_IS_G4X(brw) ? 384 : 256) /* 512 bit units */ +#define BRW_IS_IGDNG(brw) (IS_IGDNG((brw)->intel.intelScreen->deviceID)) +#define BRW_IS_965(brw) (!(BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))) +#define CMD_PIPELINE_SELECT(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965) +#define CMD_VF_STATISTICS(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965) +#define URB_SIZES(brw) (BRW_IS_IGDNG(brw) ? 1024 : \ + (BRW_IS_G4X(brw) ? 384 : 256)) /* 512 bit units */ #endif diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 5342622a737..5152c3f3a5f 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -187,19 +187,13 @@ static void brw_merge_inputs( struct brw_context *brw, brw->vb.inputs[i].glarray = arrays[i]; if (arrays[i]->StrideB != 0) - brw->vb.info.varying |= 1 << i; - brw->vb.info.sizes[i/16] |= (brw->vb.inputs[i].glarray->Size - 1) << ((i%16) * 2); } - /* Raise statechanges if input sizes and varying have changed: - */ + /* Raise statechanges if input sizes have changed. */ if (memcmp(brw->vb.info.sizes, old.sizes, sizeof(old.sizes)) != 0) brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS; - - if (brw->vb.info.varying != old.varying) - brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING; } /* XXX: could split the primitive list to fallback only on the @@ -416,6 +410,8 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, out: UNLOCK_HARDWARE(intel); + brw_state_cache_check_size(brw); + if (warn) fprintf(stderr, "i965: Single primitive emit potentially exceeded " "available aperture space\n"); diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 1b8bcc14ec0..c29f1dd5c03 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -512,7 +512,19 @@ static void brw_emit_vertices(struct brw_context *brw) OUT_RELOC(input->bo, I915_GEM_DOMAIN_VERTEX, 0, input->offset); - OUT_BATCH(brw->vb.max_index); + if (BRW_IS_IGDNG(brw)) { + if (input->stride) { + OUT_RELOC(input->bo, + I915_GEM_DOMAIN_VERTEX, 0, + input->offset + input->stride * input->count); + } else { + assert(input->count == 1); + OUT_RELOC(input->bo, + I915_GEM_DOMAIN_VERTEX, 0, + input->offset + input->element_size); + } + } else + OUT_BATCH(brw->vb.max_index); OUT_BATCH(0); /* Instance data step rate */ } ADVANCE_BATCH(); @@ -542,11 +554,18 @@ static void brw_emit_vertices(struct brw_context *brw) BRW_VE0_VALID | (format << BRW_VE0_FORMAT_SHIFT) | (0 << BRW_VE0_SRC_OFFSET_SHIFT)); - OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) | - (comp1 << BRW_VE1_COMPONENT_1_SHIFT) | - (comp2 << BRW_VE1_COMPONENT_2_SHIFT) | - (comp3 << BRW_VE1_COMPONENT_3_SHIFT) | - ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT)); + + if (BRW_IS_IGDNG(brw)) + OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) | + (comp1 << BRW_VE1_COMPONENT_1_SHIFT) | + (comp2 << BRW_VE1_COMPONENT_2_SHIFT) | + (comp3 << BRW_VE1_COMPONENT_3_SHIFT)); + else + OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) | + (comp1 << BRW_VE1_COMPONENT_1_SHIFT) | + (comp2 << BRW_VE1_COMPONENT_2_SHIFT) | + (comp3 << BRW_VE1_COMPONENT_3_SHIFT) | + ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT)); } ADVANCE_BATCH(); } @@ -635,7 +654,7 @@ static void brw_emit_indices(struct brw_context *brw) if (index_buffer == NULL) return; - ib_size = get_size(index_buffer->type) * index_buffer->count; + ib_size = get_size(index_buffer->type) * index_buffer->count - 1; /* Emit the indexbuffer packet: */ diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index bc7756ceab4..30603bdd0e6 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -171,9 +171,9 @@ static INLINE struct brw_reg brw_reg( GLuint file, { struct brw_reg reg; if (type == BRW_GENERAL_REGISTER_FILE) - assert(nr < 128); + assert(nr < BRW_MAX_GRF); else if (type == BRW_MESSAGE_REGISTER_FILE) - assert(nr < 9); + assert(nr < BRW_MAX_MRF); else if (type == BRW_ARCHITECTURE_REGISTER_FILE) assert(nr <= BRW_ARF_IP); @@ -538,6 +538,7 @@ static INLINE struct brw_reg brw_mask_reg( GLuint subnr ) static INLINE struct brw_reg brw_message_reg( GLuint nr ) { + assert(nr < BRW_MAX_MRF); return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0); @@ -815,6 +816,19 @@ void brw_urb_WRITE(struct brw_compile *p, GLuint offset, GLuint swizzle); +void brw_ff_sync(struct brw_compile *p, + struct brw_reg dest, + GLuint msg_reg_nr, + struct brw_reg src0, + GLboolean allocate, + GLboolean used, + GLuint msg_length, + GLuint response_length, + GLboolean eot, + GLboolean writes_complete, + GLuint offset, + GLuint swizzle); + void brw_fb_WRITE(struct brw_compile *p, struct brw_reg dest, GLuint msg_reg_nr, @@ -834,7 +848,9 @@ void brw_SAMPLE(struct brw_compile *p, GLuint msg_type, GLuint response_length, GLuint msg_length, - GLboolean eot); + GLboolean eot, + GLuint header_present, + GLuint simd_mode); void brw_math_16( struct brw_compile *p, struct brw_reg dest, @@ -855,12 +871,10 @@ void brw_math( struct brw_compile *p, void brw_dp_READ_16( struct brw_compile *p, struct brw_reg dest, - GLuint msg_reg_nr, GLuint scratch_offset ); void brw_dp_READ_4( struct brw_compile *p, struct brw_reg dest, - GLuint msg_reg_nr, GLboolean relAddr, GLuint location, GLuint bind_table_index ); @@ -875,7 +889,6 @@ void brw_dp_READ_4_vs( struct brw_compile *p, void brw_dp_WRITE_16( struct brw_compile *p, struct brw_reg src, - GLuint msg_reg_nr, GLuint scratch_offset ); /* If/else/endif. Works by manipulating the execution flags on each diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 60ea44f7a96..2412014248c 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -241,7 +241,8 @@ void brw_set_src1( struct brw_instruction *insn, -static void brw_set_math_message( struct brw_instruction *insn, +static void brw_set_math_message( struct brw_context *brw, + struct brw_instruction *insn, GLuint msg_length, GLuint response_length, GLuint function, @@ -252,18 +253,35 @@ static void brw_set_math_message( struct brw_instruction *insn, { brw_set_src1(insn, brw_imm_d(0)); - insn->bits3.math.function = function; - insn->bits3.math.int_type = integer_type; - insn->bits3.math.precision = low_precision; - insn->bits3.math.saturate = saturate; - insn->bits3.math.data_type = dataType; - insn->bits3.math.response_length = response_length; - insn->bits3.math.msg_length = msg_length; - insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH; - insn->bits3.math.end_of_thread = 0; + if (BRW_IS_IGDNG(brw)) { + insn->bits3.math_igdng.function = function; + insn->bits3.math_igdng.int_type = integer_type; + insn->bits3.math_igdng.precision = low_precision; + insn->bits3.math_igdng.saturate = saturate; + insn->bits3.math_igdng.data_type = dataType; + insn->bits3.math_igdng.snapshot = 0; + insn->bits3.math_igdng.header_present = 0; + insn->bits3.math_igdng.response_length = response_length; + insn->bits3.math_igdng.msg_length = msg_length; + insn->bits3.math_igdng.end_of_thread = 0; + insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_MATH; + insn->bits2.send_igdng.end_of_thread = 0; + } else { + insn->bits3.math.function = function; + insn->bits3.math.int_type = integer_type; + insn->bits3.math.precision = low_precision; + insn->bits3.math.saturate = saturate; + insn->bits3.math.data_type = dataType; + insn->bits3.math.response_length = response_length; + insn->bits3.math.msg_length = msg_length; + insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH; + insn->bits3.math.end_of_thread = 0; + } } -static void brw_set_urb_message( struct brw_instruction *insn, + +static void brw_set_ff_sync_message( struct brw_context *brw, + struct brw_instruction *insn, GLboolean allocate, GLboolean used, GLuint msg_length, @@ -273,21 +291,64 @@ static void brw_set_urb_message( struct brw_instruction *insn, GLuint offset, GLuint swizzle_control ) { - brw_set_src1(insn, brw_imm_d(0)); + brw_set_src1(insn, brw_imm_d(0)); + + insn->bits3.urb_igdng.opcode = 1; + insn->bits3.urb_igdng.offset = offset; + insn->bits3.urb_igdng.swizzle_control = swizzle_control; + insn->bits3.urb_igdng.allocate = allocate; + insn->bits3.urb_igdng.used = used; + insn->bits3.urb_igdng.complete = complete; + insn->bits3.urb_igdng.header_present = 1; + insn->bits3.urb_igdng.response_length = response_length; + insn->bits3.urb_igdng.msg_length = msg_length; + insn->bits3.urb_igdng.end_of_thread = end_of_thread; + insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB; + insn->bits2.send_igdng.end_of_thread = end_of_thread; +} - insn->bits3.urb.opcode = 0; /* ? */ - insn->bits3.urb.offset = offset; - insn->bits3.urb.swizzle_control = swizzle_control; - insn->bits3.urb.allocate = allocate; - insn->bits3.urb.used = used; /* ? */ - insn->bits3.urb.complete = complete; - insn->bits3.urb.response_length = response_length; - insn->bits3.urb.msg_length = msg_length; - insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB; - insn->bits3.urb.end_of_thread = end_of_thread; +static void brw_set_urb_message( struct brw_context *brw, + struct brw_instruction *insn, + GLboolean allocate, + GLboolean used, + GLuint msg_length, + GLuint response_length, + GLboolean end_of_thread, + GLboolean complete, + GLuint offset, + GLuint swizzle_control ) +{ + brw_set_src1(insn, brw_imm_d(0)); + + if (BRW_IS_IGDNG(brw)) { + insn->bits3.urb_igdng.opcode = 0; /* ? */ + insn->bits3.urb_igdng.offset = offset; + insn->bits3.urb_igdng.swizzle_control = swizzle_control; + insn->bits3.urb_igdng.allocate = allocate; + insn->bits3.urb_igdng.used = used; /* ? */ + insn->bits3.urb_igdng.complete = complete; + insn->bits3.urb_igdng.header_present = 1; + insn->bits3.urb_igdng.response_length = response_length; + insn->bits3.urb_igdng.msg_length = msg_length; + insn->bits3.urb_igdng.end_of_thread = end_of_thread; + insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB; + insn->bits2.send_igdng.end_of_thread = end_of_thread; + } else { + insn->bits3.urb.opcode = 0; /* ? */ + insn->bits3.urb.offset = offset; + insn->bits3.urb.swizzle_control = swizzle_control; + insn->bits3.urb.allocate = allocate; + insn->bits3.urb.used = used; /* ? */ + insn->bits3.urb.complete = complete; + insn->bits3.urb.response_length = response_length; + insn->bits3.urb.msg_length = msg_length; + insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB; + insn->bits3.urb.end_of_thread = end_of_thread; + } } -static void brw_set_dp_write_message( struct brw_instruction *insn, +static void brw_set_dp_write_message( struct brw_context *brw, + struct brw_instruction *insn, GLuint binding_table_index, GLuint msg_control, GLuint msg_type, @@ -298,18 +359,33 @@ static void brw_set_dp_write_message( struct brw_instruction *insn, { brw_set_src1(insn, brw_imm_d(0)); - insn->bits3.dp_write.binding_table_index = binding_table_index; - insn->bits3.dp_write.msg_control = msg_control; - insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear; - insn->bits3.dp_write.msg_type = msg_type; - insn->bits3.dp_write.send_commit_msg = 0; - insn->bits3.dp_write.response_length = response_length; - insn->bits3.dp_write.msg_length = msg_length; - insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE; - insn->bits3.urb.end_of_thread = end_of_thread; + if (BRW_IS_IGDNG(brw)) { + insn->bits3.dp_write_igdng.binding_table_index = binding_table_index; + insn->bits3.dp_write_igdng.msg_control = msg_control; + insn->bits3.dp_write_igdng.pixel_scoreboard_clear = pixel_scoreboard_clear; + insn->bits3.dp_write_igdng.msg_type = msg_type; + insn->bits3.dp_write_igdng.send_commit_msg = 0; + insn->bits3.dp_write_igdng.header_present = 1; + insn->bits3.dp_write_igdng.response_length = response_length; + insn->bits3.dp_write_igdng.msg_length = msg_length; + insn->bits3.dp_write_igdng.end_of_thread = end_of_thread; + insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_DATAPORT_WRITE; + insn->bits2.send_igdng.end_of_thread = end_of_thread; + } else { + insn->bits3.dp_write.binding_table_index = binding_table_index; + insn->bits3.dp_write.msg_control = msg_control; + insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear; + insn->bits3.dp_write.msg_type = msg_type; + insn->bits3.dp_write.send_commit_msg = 0; + insn->bits3.dp_write.response_length = response_length; + insn->bits3.dp_write.msg_length = msg_length; + insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE; + insn->bits3.dp_write.end_of_thread = end_of_thread; + } } -static void brw_set_dp_read_message( struct brw_instruction *insn, +static void brw_set_dp_read_message( struct brw_context *brw, + struct brw_instruction *insn, GLuint binding_table_index, GLuint msg_control, GLuint msg_type, @@ -320,15 +396,29 @@ static void brw_set_dp_read_message( struct brw_instruction *insn, { brw_set_src1(insn, brw_imm_d(0)); - insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/ - insn->bits3.dp_read.msg_control = msg_control; /*8:11*/ - insn->bits3.dp_read.msg_type = msg_type; /*12:13*/ - insn->bits3.dp_read.target_cache = target_cache; /*14:15*/ - insn->bits3.dp_read.response_length = response_length; /*16:19*/ - insn->bits3.dp_read.msg_length = msg_length; /*20:23*/ - insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ; /*24:27*/ - insn->bits3.dp_read.pad1 = 0; /*28:30*/ - insn->bits3.dp_read.end_of_thread = end_of_thread; /*31*/ + if (BRW_IS_IGDNG(brw)) { + insn->bits3.dp_read_igdng.binding_table_index = binding_table_index; + insn->bits3.dp_read_igdng.msg_control = msg_control; + insn->bits3.dp_read_igdng.msg_type = msg_type; + insn->bits3.dp_read_igdng.target_cache = target_cache; + insn->bits3.dp_read_igdng.header_present = 1; + insn->bits3.dp_read_igdng.response_length = response_length; + insn->bits3.dp_read_igdng.msg_length = msg_length; + insn->bits3.dp_read_igdng.pad1 = 0; + insn->bits3.dp_read_igdng.end_of_thread = end_of_thread; + insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_DATAPORT_READ; + insn->bits2.send_igdng.end_of_thread = end_of_thread; + } else { + insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/ + insn->bits3.dp_read.msg_control = msg_control; /*8:11*/ + insn->bits3.dp_read.msg_type = msg_type; /*12:13*/ + insn->bits3.dp_read.target_cache = target_cache; /*14:15*/ + insn->bits3.dp_read.response_length = response_length; /*16:19*/ + insn->bits3.dp_read.msg_length = msg_length; /*20:23*/ + insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ; /*24:27*/ + insn->bits3.dp_read.pad1 = 0; /*28:30*/ + insn->bits3.dp_read.end_of_thread = end_of_thread; /*31*/ + } } static void brw_set_sampler_message(struct brw_context *brw, @@ -338,11 +428,25 @@ static void brw_set_sampler_message(struct brw_context *brw, GLuint msg_type, GLuint response_length, GLuint msg_length, - GLboolean eot) + GLboolean eot, + GLuint header_present, + GLuint simd_mode) { + assert(eot == 0); brw_set_src1(insn, brw_imm_d(0)); - if (BRW_IS_G4X(brw)) { + if (BRW_IS_IGDNG(brw)) { + insn->bits3.sampler_igdng.binding_table_index = binding_table_index; + insn->bits3.sampler_igdng.sampler = sampler; + insn->bits3.sampler_igdng.msg_type = msg_type; + insn->bits3.sampler_igdng.simd_mode = simd_mode; + insn->bits3.sampler_igdng.header_present = header_present; + insn->bits3.sampler_igdng.response_length = response_length; + insn->bits3.sampler_igdng.msg_length = msg_length; + insn->bits3.sampler_igdng.end_of_thread = eot; + insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_SAMPLER; + insn->bits2.send_igdng.end_of_thread = eot; + } else if (BRW_IS_G4X(brw)) { insn->bits3.sampler_g4x.binding_table_index = binding_table_index; insn->bits3.sampler_g4x.sampler = sampler; insn->bits3.sampler_g4x.msg_type = msg_type; @@ -484,6 +588,10 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p, { struct brw_instruction *insn = brw_alu2(p, BRW_OPCODE_JMPI, dest, src0, src1); + insn->header.execution_size = 1; + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.mask_control = BRW_MASK_DISABLE; + p->current->header.predicate_control = BRW_PREDICATE_NONE; return insn; @@ -540,6 +648,10 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p, struct brw_instruction *if_insn) { struct brw_instruction *insn; + GLuint br = 1; + + if (BRW_IS_IGDNG(p->brw)) + br = 2; if (p->single_program_flow) { insn = next_insn(p, BRW_OPCODE_ADD); @@ -566,7 +678,7 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p, } else { assert(if_insn->header.opcode == BRW_OPCODE_IF); - if_insn->bits3.if_else.jump_count = insn - if_insn; + if_insn->bits3.if_else.jump_count = br * (insn - if_insn); if_insn->bits3.if_else.pop_count = 1; if_insn->bits3.if_else.pad0 = 0; } @@ -577,6 +689,11 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p, void brw_ENDIF(struct brw_compile *p, struct brw_instruction *patch_insn) { + GLuint br = 1; + + if (BRW_IS_IGDNG(p->brw)) + br = 2; + if (p->single_program_flow) { /* In single program flow mode, there's no need to execute an ENDIF, * since we don't need to do any stack operations, and if we're executing @@ -608,11 +725,11 @@ void brw_ENDIF(struct brw_compile *p, /* Automagically turn it into an IFF: */ patch_insn->header.opcode = BRW_OPCODE_IFF; - patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; + patch_insn->bits3.if_else.jump_count = br * (insn - patch_insn + 1); patch_insn->bits3.if_else.pop_count = 0; patch_insn->bits3.if_else.pad0 = 0; } else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) { - patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; + patch_insn->bits3.if_else.jump_count = br * (insn - patch_insn + 1); patch_insn->bits3.if_else.pop_count = 1; patch_insn->bits3.if_else.pad0 = 0; } else { @@ -686,6 +803,10 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p, struct brw_instruction *do_insn) { struct brw_instruction *insn; + GLuint br = 1; + + if (BRW_IS_IGDNG(p->brw)) + br = 2; if (p->single_program_flow) insn = next_insn(p, BRW_OPCODE_ADD); @@ -706,7 +827,7 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p, insn->header.execution_size = do_insn->header.execution_size; assert(do_insn->header.opcode == BRW_OPCODE_DO); - insn->bits3.if_else.jump_count = do_insn - insn + 1; + insn->bits3.if_else.jump_count = br * (do_insn - insn + 1); insn->bits3.if_else.pop_count = 0; insn->bits3.if_else.pad0 = 0; } @@ -725,11 +846,15 @@ void brw_land_fwd_jump(struct brw_compile *p, struct brw_instruction *jmp_insn) { struct brw_instruction *landing = &p->store[p->nr_insn]; + GLuint jmpi = 1; + + if (BRW_IS_IGDNG(p->brw)) + jmpi = 2; assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI); assert(jmp_insn->bits1.da1.src1_reg_file = BRW_IMMEDIATE_VALUE); - jmp_insn->bits3.ud = (landing - jmp_insn) - 1; + jmp_insn->bits3.ud = jmpi * ((landing - jmp_insn) - 1); } @@ -794,7 +919,8 @@ void brw_math( struct brw_compile *p, brw_set_dest(insn, dest); brw_set_src0(insn, src); - brw_set_math_message(insn, + brw_set_math_message(p->brw, + insn, msg_length, response_length, function, BRW_MATH_INTEGER_UNSIGNED, @@ -830,7 +956,8 @@ void brw_math_16( struct brw_compile *p, brw_set_dest(insn, dest); brw_set_src0(insn, src); - brw_set_math_message(insn, + brw_set_math_message(p->brw, + insn, msg_length, response_length, function, BRW_MATH_INTEGER_UNSIGNED, @@ -846,7 +973,8 @@ void brw_math_16( struct brw_compile *p, brw_set_dest(insn, offset(dest,1)); brw_set_src0(insn, src); - brw_set_math_message(insn, + brw_set_math_message(p->brw, + insn, msg_length, response_length, function, BRW_MATH_INTEGER_UNSIGNED, @@ -865,9 +993,9 @@ void brw_math_16( struct brw_compile *p, */ void brw_dp_WRITE_16( struct brw_compile *p, struct brw_reg src, - GLuint msg_reg_nr, GLuint scratch_offset ) { + GLuint msg_reg_nr = 1; { brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); @@ -877,7 +1005,7 @@ void brw_dp_WRITE_16( struct brw_compile *p, brw_MOV(p, retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D), brw_imm_d(scratch_offset)); - + brw_pop_insn_state(p); } @@ -893,7 +1021,8 @@ void brw_dp_WRITE_16( struct brw_compile *p, brw_set_dest(insn, dest); brw_set_src0(insn, src); - brw_set_dp_write_message(insn, + brw_set_dp_write_message(p->brw, + insn, 255, /* binding table index (255=stateless) */ BRW_DATAPORT_OWORD_BLOCK_4_OWORDS, /* msg_control */ BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE, /* msg_type */ @@ -912,9 +1041,9 @@ void brw_dp_WRITE_16( struct brw_compile *p, */ void brw_dp_READ_16( struct brw_compile *p, struct brw_reg dest, - GLuint msg_reg_nr, GLuint scratch_offset ) { + GLuint msg_reg_nr = 1; { brw_push_insn_state(p); brw_set_compression_control(p, BRW_COMPRESSION_NONE); @@ -924,7 +1053,7 @@ void brw_dp_READ_16( struct brw_compile *p, brw_MOV(p, retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D), brw_imm_d(scratch_offset)); - + brw_pop_insn_state(p); } @@ -938,7 +1067,8 @@ void brw_dp_READ_16( struct brw_compile *p, brw_set_dest(insn, dest); /* UW? */ brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW)); - brw_set_dp_read_message(insn, + brw_set_dp_read_message(p->brw, + insn, 255, /* binding table index (255=stateless) */ 3, /* msg_control (3 means 4 Owords) */ BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */ @@ -958,21 +1088,26 @@ void brw_dp_READ_16( struct brw_compile *p, */ void brw_dp_READ_4( struct brw_compile *p, struct brw_reg dest, - GLuint msg_reg_nr, GLboolean relAddr, GLuint location, GLuint bind_table_index ) { + /* XXX: relAddr not implemented */ + GLuint msg_reg_nr = 1; { + struct brw_reg b; brw_push_insn_state(p); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); - /* set message header global offset field (reg 0, element 2) */ - /* Note that grf[0] will be copied to mrf[1] implicitly by the SEND instr */ - brw_MOV(p, - retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_UD), - brw_imm_d(location)); + /* Setup MRF[1] with location/offset into const buffer */ + b = brw_message_reg(msg_reg_nr); + b = retype(b, BRW_REGISTER_TYPE_UD); + /* XXX I think we're setting all the dwords of MRF[1] to 'location'. + * when the docs say only dword[2] should be set. Hmmm. But it works. + */ + brw_MOV(p, b, brw_imm_ud(location)); brw_pop_insn_state(p); } @@ -988,9 +1123,10 @@ void brw_dp_READ_4( struct brw_compile *p, dest = retype(vec8(dest), BRW_REGISTER_TYPE_UW); brw_set_dest(insn, dest); - brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW)); + brw_set_src0(insn, brw_null_reg()); - brw_set_dp_read_message(insn, + brw_set_dp_read_message(p->brw, + insn, bind_table_index, 0, /* msg_control (0 means 1 Oword) */ BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */ @@ -1061,7 +1197,8 @@ void brw_dp_READ_4_vs(struct brw_compile *p, brw_set_dest(insn, dest); brw_set_src0(insn, brw_null_reg()); - brw_set_dp_read_message(insn, + brw_set_dp_read_message(p->brw, + insn, bind_table_index, oword, /* 0 = lower Oword, 1 = upper Oword */ BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */ @@ -1091,7 +1228,8 @@ void brw_fb_WRITE(struct brw_compile *p, brw_set_dest(insn, dest); brw_set_src0(insn, src0); - brw_set_dp_write_message(insn, + brw_set_dp_write_message(p->brw, + insn, binding_table_index, BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE, /* msg_control */ BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */ @@ -1117,7 +1255,9 @@ void brw_SAMPLE(struct brw_compile *p, GLuint msg_type, GLuint response_length, GLuint msg_length, - GLboolean eot) + GLboolean eot, + GLuint header_present, + GLuint simd_mode) { GLboolean need_stall = 0; @@ -1192,7 +1332,9 @@ void brw_SAMPLE(struct brw_compile *p, msg_type, response_length, msg_length, - eot); + eot, + header_present, + simd_mode); } if (need_stall) { @@ -1227,7 +1369,7 @@ void brw_urb_WRITE(struct brw_compile *p, { struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); - assert(msg_length < 16); + assert(msg_length < BRW_MAX_MRF); brw_set_dest(insn, dest); brw_set_src0(insn, src0); @@ -1235,7 +1377,8 @@ void brw_urb_WRITE(struct brw_compile *p, insn->header.destreg__conditonalmod = msg_reg_nr; - brw_set_urb_message(insn, + brw_set_urb_message(p->brw, + insn, allocate, used, msg_length, @@ -1246,3 +1389,37 @@ void brw_urb_WRITE(struct brw_compile *p, swizzle); } +void brw_ff_sync(struct brw_compile *p, + struct brw_reg dest, + GLuint msg_reg_nr, + struct brw_reg src0, + GLboolean allocate, + GLboolean used, + GLuint msg_length, + GLuint response_length, + GLboolean eot, + GLboolean writes_complete, + GLuint offset, + GLuint swizzle) +{ + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + + assert(msg_length < 16); + + brw_set_dest(insn, dest); + brw_set_src0(insn, src0); + brw_set_src1(insn, brw_imm_d(0)); + + insn->header.destreg__conditonalmod = msg_reg_nr; + + brw_set_ff_sync_message(p->brw, + insn, + allocate, + used, + msg_length, + response_length, + eot, + writes_complete, + offset, + swizzle); +} diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index 299357409ce..d27c6c24ca5 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -37,6 +37,9 @@ #include "tnl/tnl.h" #include "brw_context.h" #include "brw_fallback.h" +#include "intel_chipset.h" +#include "intel_fbo.h" +#include "intel_regions.h" #include "glapi/glapi.h" @@ -44,6 +47,7 @@ static GLboolean do_check_fallback(struct brw_context *brw) { + struct intel_context *intel = &brw->intel; GLcontext *ctx = &brw->intel.ctx; GLuint i; @@ -81,6 +85,33 @@ static GLboolean do_check_fallback(struct brw_context *brw) return GL_TRUE; } + /* _NEW_BUFFERS */ + if (IS_965(intel->intelScreen->deviceID) && + !IS_G4X(intel->intelScreen->deviceID)) { + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + + /* The original gen4 hardware couldn't set up WM surfaces pointing + * at an offset within a tile, which can happen when rendering to + * anything but the base level of a texture or the +X face/0 depth. + * This was fixed with the 4 Series hardware. + * + * For these original chips, you would have to make the depth and + * color destination surfaces include information on the texture + * type, LOD, face, and various limits to use them as a destination. + * I would have done this, but there's also a nasty requirement that + * the depth and the color surfaces all be of the same LOD, which + * may be a worse requirement than this alignment. (Also, we may + * want to just demote the texture to untiled, instead). + */ + if (irb->region && irb->region->tiling != I915_TILING_NONE && + (irb->region->draw_offset & 4095)) { + DBG("FALLBACK: non-tile-aligned destination for tiled FBO\n"); + return GL_TRUE; + } + } + } return GL_FALSE; } diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index a8b74a0afe6..48c2b9a41ce 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -54,12 +54,17 @@ static void compile_gs_prog( struct brw_context *brw, memset(&c, 0, sizeof(c)); c.key = *key; - + c.need_ff_sync = BRW_IS_IGDNG(brw); /* Need to locate the two positions present in vertex + header. * These are currently hardcoded: */ c.nr_attrs = brw_count_bits(c.key.attrs); - c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ + + if (BRW_IS_IGDNG(brw)) + c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */ + else + c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ + c.nr_bytes = c.nr_regs * REG_SIZE; diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h index 18a4537c323..bbb991ea2e5 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.h +++ b/src/mesa/drivers/dri/i965/brw_gs.h @@ -62,6 +62,7 @@ struct brw_gs_compile { GLuint nr_attrs; GLuint nr_regs; GLuint nr_bytes; + GLboolean need_ff_sync; }; #define ATTR_SIZE (4*4) diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c index 22e0d25c2e7..980eac7646d 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c @@ -101,6 +101,23 @@ static void brw_gs_emit_vue(struct brw_gs_compile *c, BRW_URB_SWIZZLE_NONE); } +void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim) +{ + struct brw_compile *p = &c->func; + brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim)); + brw_ff_sync(p, + c->reg.R0, + 0, + c->reg.R0, + 1, + 1, /* used */ + 1, /* msg length */ + 1, /* response length */ + 0, /* eot */ + 1, /* write compelete */ + 0, /* urb offset */ + BRW_URB_SWIZZLE_NONE); +} void brw_gs_quads( struct brw_gs_compile *c ) @@ -110,6 +127,8 @@ void brw_gs_quads( struct brw_gs_compile *c ) /* Use polygons for correct edgeflag behaviour. Note that vertex 3 * is the PV for quads, but vertex 0 for polygons: */ + if (c->need_ff_sync) + brw_gs_ff_sync(c, 1); brw_gs_emit_vue(c, c->reg.vertex[3], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START)); brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2)); @@ -120,6 +139,8 @@ void brw_gs_quad_strip( struct brw_gs_compile *c ) { brw_gs_alloc_regs(c, 4); + if (c->need_ff_sync) + brw_gs_ff_sync(c, 1); brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START)); brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2)); brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); @@ -129,6 +150,9 @@ void brw_gs_quad_strip( struct brw_gs_compile *c ) void brw_gs_tris( struct brw_gs_compile *c ) { brw_gs_alloc_regs(c, 3); + + if (c->need_ff_sync) + brw_gs_ff_sync(c, 1); brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_TRILIST << 2) | R02_PRIM_START)); brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_TRILIST << 2)); brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_TRILIST << 2) | R02_PRIM_END)); @@ -137,6 +161,9 @@ void brw_gs_tris( struct brw_gs_compile *c ) void brw_gs_lines( struct brw_gs_compile *c ) { brw_gs_alloc_regs(c, 2); + + if (c->need_ff_sync) + brw_gs_ff_sync(c, 1); brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_START)); brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_END)); } @@ -144,6 +171,9 @@ void brw_gs_lines( struct brw_gs_compile *c ) void brw_gs_points( struct brw_gs_compile *c ) { brw_gs_alloc_regs(c, 1); + + if (c->need_ff_sync) + brw_gs_ff_sync(c, 1); brw_gs_emit_vue(c, c->reg.vertex[0], 1, ((_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END)); } diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c index 27023cf0344..a761c03153c 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_state.c +++ b/src/mesa/drivers/dri/i965/brw_gs_state.c @@ -95,6 +95,9 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key) gs.thread4.max_threads = 0; /* Hardware requirement */ + if (BRW_IS_IGDNG(brw)) + gs.thread4.rendering_enable = 1; + if (INTEL_DEBUG & DEBUG_STATS) gs.thread4.stats_enable = 1; diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 4784254bc7d..85a7706404f 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -211,7 +211,7 @@ static void emit_depthbuffer(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct intel_region *region = brw->state.depth_region; - unsigned int len = BRW_IS_G4X(brw) ? 6 : 5; + unsigned int len = (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? 6 : 5; if (region == NULL) { BEGIN_BATCH(len, IGNORE_CLIPRECTS); @@ -222,7 +222,7 @@ static void emit_depthbuffer(struct brw_context *brw) OUT_BATCH(0); OUT_BATCH(0); - if (BRW_IS_G4X(brw)) + if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) OUT_BATCH(0); ADVANCE_BATCH(); @@ -244,6 +244,8 @@ static void emit_depthbuffer(struct brw_context *brw) return; } + assert(region->tiling != I915_TILING_X); + BEGIN_BATCH(len, IGNORE_CLIPRECTS); OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2)); OUT_BATCH(((region->pitch * region->cpp) - 1) | @@ -259,7 +261,7 @@ static void emit_depthbuffer(struct brw_context *brw) ((region->height - 1) << 19)); OUT_BATCH(0); - if (BRW_IS_G4X(brw)) + if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) OUT_BATCH(0); ADVANCE_BATCH(); @@ -372,7 +374,7 @@ static void upload_aa_line_parameters(struct brw_context *brw) { struct brw_aa_line_parameters balp; - if (!BRW_IS_G4X(brw)) + if (BRW_IS_965(brw)) return; /* use legacy aa line coverage computation */ @@ -509,14 +511,27 @@ static void upload_state_base_address( struct brw_context *brw ) /* Output the structure (brw_state_base_address) directly to the * batchbuffer, so we can emit relocations inline. */ - BEGIN_BATCH(6, IGNORE_CLIPRECTS); - OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2)); - OUT_BATCH(1); /* General state base address */ - OUT_BATCH(1); /* Surface state base address */ - OUT_BATCH(1); /* Indirect object base address */ - OUT_BATCH(1); /* General state upper bound */ - OUT_BATCH(1); /* Indirect object upper bound */ - ADVANCE_BATCH(); + if (BRW_IS_IGDNG(brw)) { + BEGIN_BATCH(8, IGNORE_CLIPRECTS); + OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2)); + OUT_BATCH(1); /* General state base address */ + OUT_BATCH(1); /* Surface state base address */ + OUT_BATCH(1); /* Indirect object base address */ + OUT_BATCH(1); /* Instruction base address */ + OUT_BATCH(1); /* General state upper bound */ + OUT_BATCH(1); /* Indirect object upper bound */ + OUT_BATCH(1); /* Instruction access upper bound */ + ADVANCE_BATCH(); + } else { + BEGIN_BATCH(6, IGNORE_CLIPRECTS); + OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2)); + OUT_BATCH(1); /* General state base address */ + OUT_BATCH(1); /* Surface state base address */ + OUT_BATCH(1); /* Indirect object base address */ + OUT_BATCH(1); /* General state upper bound */ + OUT_BATCH(1); /* Indirect object upper bound */ + ADVANCE_BATCH(); + } } const struct brw_tracked_state brw_state_base_address = { diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index c3c85978f4d..e1c2c7777b5 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -166,6 +166,9 @@ static void upload_sf_prog(struct brw_context *brw) key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT); key.do_twoside_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide); + /* _NEW_HINT */ + key.linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST); + /* _NEW_POLYGON */ if (key.do_twoside_color) { /* If we're rendering to a FBO, we have to invert the polygon @@ -188,7 +191,7 @@ static void upload_sf_prog(struct brw_context *brw) const struct brw_tracked_state brw_sf_prog = { .dirty = { - .mesa = (_NEW_LIGHT|_NEW_POLYGON|_NEW_POINT), + .mesa = (_NEW_HINT | _NEW_LIGHT | _NEW_POLYGON | _NEW_POINT), .brw = (BRW_NEW_REDUCED_PRIMITIVE), .cache = CACHE_NEW_VS_PROG }, diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h index 1c0fb70fe06..6426b6df9ff 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.h +++ b/src/mesa/drivers/dri/i965/brw_sf.h @@ -51,7 +51,8 @@ struct brw_sf_prog_key { GLuint do_flat_shading:1; GLuint frontface_ccw:1; GLuint do_point_sprite:1; - GLuint pad:10; + GLuint linear_color:1; /**< linear interp vs. perspective interp */ + GLuint pad:25; GLenum SpriteOrigin; }; diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index 862835f157a..ca8f97f9f9e 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -151,6 +151,8 @@ static void do_flatshade_triangle( struct brw_sf_compile *c ) struct brw_compile *p = &c->func; struct brw_reg ip = brw_ip_reg(); GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS); + GLuint jmpi = 1; + if (!nr) return; @@ -159,18 +161,21 @@ static void do_flatshade_triangle( struct brw_sf_compile *c ) if (c->key.primitive == SF_UNFILLED_TRIS) return; + if (BRW_IS_IGDNG(p->brw)) + jmpi = 2; + brw_push_insn_state(p); - brw_MUL(p, c->pv, c->pv, brw_imm_ud(nr*2+1)); + brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1))); brw_JMPI(p, ip, ip, c->pv); copy_colors(c, c->vert[1], c->vert[0]); copy_colors(c, c->vert[2], c->vert[0]); - brw_JMPI(p, ip, ip, brw_imm_ud(nr*4+1)); + brw_JMPI(p, ip, ip, brw_imm_d(jmpi*(nr*4+1))); copy_colors(c, c->vert[0], c->vert[1]); copy_colors(c, c->vert[2], c->vert[1]); - brw_JMPI(p, ip, ip, brw_imm_ud(nr*2)); + brw_JMPI(p, ip, ip, brw_imm_d(jmpi*nr*2)); copy_colors(c, c->vert[0], c->vert[2]); copy_colors(c, c->vert[1], c->vert[2]); @@ -184,7 +189,8 @@ static void do_flatshade_line( struct brw_sf_compile *c ) struct brw_compile *p = &c->func; struct brw_reg ip = brw_ip_reg(); GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS); - + GLuint jmpi = 1; + if (!nr) return; @@ -193,13 +199,16 @@ static void do_flatshade_line( struct brw_sf_compile *c ) if (c->key.primitive == SF_UNFILLED_TRIS) return; + if (BRW_IS_IGDNG(p->brw)) + jmpi = 2; + brw_push_insn_state(p); - brw_MUL(p, c->pv, c->pv, brw_imm_ud(nr+1)); + brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1))); brw_JMPI(p, ip, ip, c->pv); copy_colors(c, c->vert[1], c->vert[0]); - brw_JMPI(p, ip, ip, brw_imm_ud(nr)); + brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr)); copy_colors(c, c->vert[0], c->vert[1]); brw_pop_insn_state(p); @@ -218,7 +227,7 @@ static void alloc_regs( struct brw_sf_compile *c ) /* Values computed by fixed function unit: */ - c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD); + c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_D); c->det = brw_vec1_grf(1, 2); c->dx0 = brw_vec1_grf(1, 3); c->dx2 = brw_vec1_grf(1, 4); @@ -295,9 +304,6 @@ static void invert_det( struct brw_sf_compile *c) } -#define NON_PERPECTIVE_ATTRS (FRAG_BIT_WPOS | \ - FRAG_BIT_COL0 | \ - FRAG_BIT_COL1) static GLboolean calculate_masks( struct brw_sf_compile *c, GLuint reg, @@ -306,9 +312,16 @@ static GLboolean calculate_masks( struct brw_sf_compile *c, GLushort *pc_linear) { GLboolean is_last_attr = (reg == c->nr_setup_regs - 1); - GLuint persp_mask = c->key.attrs & ~NON_PERPECTIVE_ATTRS; + GLuint persp_mask; GLuint linear_mask; + if (c->key.do_flat_shading || c->key.linear_color) + persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS | + FRAG_BIT_COL0 | + FRAG_BIT_COL1); + else + persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS); + if (c->key.do_flat_shading) linear_mask = c->key.attrs & ~(FRAG_BIT_COL0|FRAG_BIT_COL1); else @@ -674,7 +687,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) (1<<_3DPRIM_POLYGON) | (1<<_3DPRIM_RECTLIST) | (1<<_3DPRIM_TRIFAN_NOSTIPPLE))); - jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); + jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)); { saveflag = p->flag_value; brw_push_insn_state(p); @@ -695,7 +708,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) (1<<_3DPRIM_LINESTRIP_CONT) | (1<<_3DPRIM_LINESTRIP_BF) | (1<<_3DPRIM_LINESTRIP_CONT_BF))); - jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); + jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)); { saveflag = p->flag_value; brw_push_insn_state(p); @@ -708,7 +721,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE)); - jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); + jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)); { saveflag = p->flag_value; brw_push_insn_state(p); diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index c99918724b3..e73e57a1c83 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -162,7 +162,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, { struct brw_sf_unit_state sf; dri_bo *bo; - + int chipset_max_threads; memset(&sf, 0, sizeof(sf)); sf.thread0.grf_reg_count = ALIGN(key->total_grf, 16) / 16 - 1; @@ -171,13 +171,26 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, sf.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; sf.thread3.dispatch_grf_start_reg = 3; - sf.thread3.urb_entry_read_offset = 1; + + if (BRW_IS_IGDNG(brw)) + sf.thread3.urb_entry_read_offset = 3; + else + sf.thread3.urb_entry_read_offset = 1; + sf.thread3.urb_entry_read_length = key->urb_entry_read_length; sf.thread4.nr_urb_entries = key->nr_urb_entries; sf.thread4.urb_entry_allocation_size = key->sfsize - 1; - /* Each SF thread produces 1 PUE, and there can be up to 24 threads */ - sf.thread4.max_threads = MIN2(24, key->nr_urb_entries) - 1; + + /* Each SF thread produces 1 PUE, and there can be up to 24(Pre-IGDNG) or + * 48(IGDNG) threads + */ + if (BRW_IS_IGDNG(brw)) + chipset_max_threads = 48; + else + chipset_max_threads = 24; + + sf.thread4.max_threads = MIN2(chipset_max_threads, key->nr_urb_entries) - 1; if (INTEL_DEBUG & DEBUG_SINGLE_THREAD) sf.thread4.max_threads = 0; diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c index a7132622696..e94fa7d2b4c 100644 --- a/src/mesa/drivers/dri/i965/brw_state_dump.c +++ b/src/mesa/drivers/dri/i965/brw_state_dump.c @@ -126,6 +126,8 @@ static void dump_wm_surface_state(struct brw_context *brw) surf->ss3.pitch + 1, surf->ss3.tiled_surface ? "" : "not "); state_out(name, surf, surfoff, 4, "mip base %d\n", surf->ss4.min_lod); + state_out(name, surf, surfoff, 5, "x,y offset: %d,%d\n", + surf->ss5.x_offset, surf->ss5.y_offset); dri_bo_unmap(surf_bo); } diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index c6dfea4743c..38d9dd8991e 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -205,7 +205,6 @@ static struct dirty_bit_map brw_bits[] = { DEFINE_BIT(BRW_NEW_PRIMITIVE), DEFINE_BIT(BRW_NEW_CONTEXT), DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS), - DEFINE_BIT(BRW_NEW_INPUT_VARYING), DEFINE_BIT(BRW_NEW_PSP), DEFINE_BIT(BRW_NEW_FENCE), DEFINE_BIT(BRW_NEW_INDICES), diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h index 89e29812034..8ba7eb27b36 100644 --- a/src/mesa/drivers/dri/i965/brw_structs.h +++ b/src/mesa/drivers/dri/i965/brw_structs.h @@ -33,6 +33,14 @@ #ifndef BRW_STRUCTS_H #define BRW_STRUCTS_H + +/** Number of general purpose registers (VS, WM, etc) */ +#define BRW_MAX_GRF 128 + +/** Number of message register file registers */ +#define BRW_MAX_MRF 16 + + /* Command packets: */ struct header @@ -815,7 +823,9 @@ struct brw_gs_unit_state struct { - GLuint pad0:10; + GLuint pad0:8; + GLuint rendering_enable:1; /* for IGDNG */ + GLuint pad4:1; GLuint stats_enable:1; GLuint nr_urb_entries:7; GLuint pad1:1; @@ -923,6 +933,28 @@ struct brw_wm_unit_state GLfloat global_depth_offset_constant; GLfloat global_depth_offset_scale; + + /* for IGDNG only */ + struct { + GLuint pad0:1; + GLuint grf_reg_count_1:3; + GLuint pad1:2; + GLuint kernel_start_pointer_1:26; + } wm8; + + struct { + GLuint pad0:1; + GLuint grf_reg_count_2:3; + GLuint pad1:2; + GLuint kernel_start_pointer_2:26; + } wm9; + + struct { + GLuint pad0:1; + GLuint grf_reg_count_3:3; + GLuint pad1:2; + GLuint kernel_start_pointer_3:26; + } wm10; }; struct brw_sampler_default_color { @@ -1075,7 +1107,7 @@ struct brw_surface_state GLuint y_offset:4; GLuint pad0:1; GLuint x_offset:7; - } ss5; /* NEW in Integrated Graphics Device */ + } ss5; /* New in G4X */ }; @@ -1298,6 +1330,14 @@ struct brw_instruction GLuint pad1:6; } ia16; + struct + { + GLuint pad:26; + GLuint end_of_thread:1; + GLuint pad1:1; + GLuint sfid:4; + } send_igdng; /* for IGDNG only */ + } bits2; union @@ -1385,6 +1425,21 @@ struct brw_instruction } math; struct { + GLuint function:4; + GLuint int_type:1; + GLuint precision:1; + GLuint saturate:1; + GLuint data_type:1; + GLuint snapshot:1; + GLuint pad0:10; + GLuint header_present:1; + GLuint response_length:5; + GLuint msg_length:4; + GLuint pad1:2; + GLuint end_of_thread:1; + } math_igdng; + + struct { GLuint binding_table_index:8; GLuint sampler:4; GLuint return_format:2; @@ -1407,9 +1462,38 @@ struct brw_instruction GLuint end_of_thread:1; } sampler_g4x; + struct { + GLuint binding_table_index:8; + GLuint sampler:4; + GLuint msg_type:4; + GLuint simd_mode:2; + GLuint pad0:1; + GLuint header_present:1; + GLuint response_length:5; + GLuint msg_length:4; + GLuint pad1:2; + GLuint end_of_thread:1; + } sampler_igdng; + struct brw_urb_immediate urb; struct { + GLuint opcode:4; + GLuint offset:6; + GLuint swizzle_control:2; + GLuint pad:1; + GLuint allocate:1; + GLuint used:1; + GLuint complete:1; + GLuint pad0:3; + GLuint header_present:1; + GLuint response_length:5; + GLuint msg_length:4; + GLuint pad1:2; + GLuint end_of_thread:1; + } urb_igdng; + + struct { GLuint binding_table_index:8; GLuint msg_control:4; GLuint msg_type:2; @@ -1423,6 +1507,19 @@ struct brw_instruction struct { GLuint binding_table_index:8; + GLuint msg_control:3; + GLuint msg_type:3; + GLuint target_cache:2; + GLuint pad0:3; + GLuint header_present:1; + GLuint response_length:5; + GLuint msg_length:4; + GLuint pad1:2; + GLuint end_of_thread:1; + } dp_read_igdng; + + struct { + GLuint binding_table_index:8; GLuint msg_control:3; GLuint pixel_scoreboard_clear:1; GLuint msg_type:3; @@ -1435,6 +1532,20 @@ struct brw_instruction } dp_write; struct { + GLuint binding_table_index:8; + GLuint msg_control:3; + GLuint pixel_scoreboard_clear:1; + GLuint msg_type:3; + GLuint send_commit_msg:1; + GLuint pad0:3; + GLuint header_present:1; + GLuint response_length:5; + GLuint msg_length:4; + GLuint pad1:2; + GLuint end_of_thread:1; + } dp_write_igdng; + + struct { GLuint pad:16; GLuint response_length:4; GLuint msg_length:4; @@ -1443,6 +1554,15 @@ struct brw_instruction GLuint end_of_thread:1; } generic; + struct { + GLuint pad:19; + GLuint header_present:1; + GLuint response_length:5; + GLuint msg_length:4; + GLuint pad1:2; + GLuint end_of_thread:1; + } generic_igdng; + GLint d; GLuint ud; } bits3; diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 5c5455813a4..7f9b2535340 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -36,6 +36,7 @@ #include "intel_tex_layout.h" #include "intel_context.h" #include "main/macros.h" +#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_MIPTREE @@ -48,6 +49,77 @@ GLboolean brw_miptree_layout(struct intel_context *intel, switch (mt->target) { case GL_TEXTURE_CUBE_MAP: + if (IS_IGDNG(intel->intelScreen->deviceID)) { + GLuint align_h = 2, align_w = 4; + GLuint level; + GLuint x = 0; + GLuint y = 0; + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint qpitch = 0; + GLuint y_pitch = 0; + + mt->pitch = mt->width0; + intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h); + y_pitch = ALIGN(height, align_h); + + if (mt->compressed) { + mt->pitch = ALIGN(mt->width0, align_w); + qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * mt->pitch * mt->cpp; + mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6; + } else { + qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * mt->pitch * mt->cpp; + mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6; + } + + if (mt->first_level != mt->last_level) { + GLuint mip1_width; + + if (mt->compressed) { + mip1_width = ALIGN(minify(mt->width0), align_w) + + ALIGN(minify(minify(mt->width0)), align_w); + } else { + mip1_width = ALIGN(minify(mt->width0), align_w) + + minify(minify(mt->width0)); + } + + if (mip1_width > mt->pitch) { + mt->pitch = mip1_width; + } + } + + mt->pitch = intel_miptree_pitch_align(intel, mt, tiling, mt->pitch); + + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint img_height; + GLuint nr_images = 6; + GLuint q = 0; + + intel_miptree_set_level_info(mt, level, nr_images, x, y, width, + height, 1); + + for (q = 0; q < nr_images; q++) + intel_miptree_set_image_offset_ex(mt, level, q, x, y, q * qpitch); + + if (mt->compressed) + img_height = MAX2(1, height/4); + else + img_height = ALIGN(height, align_h); + + if (level == mt->first_level + 1) { + x += ALIGN(width, align_w); + } + else { + y += img_height; + } + + width = minify(width); + height = minify(height); + } + + break; + } + case GL_TEXTURE_3D: { GLuint width = mt->width0; GLuint height = mt->height0; @@ -59,9 +131,9 @@ GLboolean brw_miptree_layout(struct intel_context *intel, GLuint align_w = 4; mt->total_height = 0; + intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h); if (mt->compressed) { - align_w = intel_compressed_alignment(mt->internal_format); mt->pitch = ALIGN(width, align_w); pack_y_pitch = (height + 3) / 4; } else { @@ -69,7 +141,7 @@ GLboolean brw_miptree_layout(struct intel_context *intel, pack_y_pitch = ALIGN(mt->height0, align_h); } - pack_x_pitch = mt->pitch; + pack_x_pitch = width; pack_x_nr = 1; for (level = mt->first_level ; level <= mt->last_level ; level++) { diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c index 7673dd36eb9..8c6f4355a6e 100644 --- a/src/mesa/drivers/dri/i965/brw_urb.c +++ b/src/mesa/drivers/dri/i965/brw_urb.c @@ -143,7 +143,29 @@ static void recalculate_urb_fence( struct brw_context *brw ) brw->urb.nr_clip_entries = limits[CLP].preferred_nr_entries; brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries; brw->urb.nr_cs_entries = limits[CS].preferred_nr_entries; - + + brw->urb.constrained = 0; + + if (BRW_IS_IGDNG(brw)) { + brw->urb.nr_vs_entries = 128; + brw->urb.nr_sf_entries = 48; + if (check_urb_layout(brw)) { + goto done; + } else { + brw->urb.constrained = 1; + brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries; + brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries; + } + } else if (BRW_IS_G4X(brw)) { + brw->urb.nr_vs_entries = 64; + if (check_urb_layout(brw)) { + goto done; + } else { + brw->urb.constrained = 1; + brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries; + } + } + if (!check_urb_layout(brw)) { brw->urb.nr_vs_entries = limits[VS].min_nr_entries; brw->urb.nr_gs_entries = limits[GS].min_nr_entries; @@ -169,9 +191,8 @@ static void recalculate_urb_fence( struct brw_context *brw ) if (INTEL_DEBUG & (DEBUG_URB|DEBUG_FALLBACKS)) _mesa_printf("URB CONSTRAINED\n"); } - else - brw->urb.constrained = 0; +done: if (INTEL_DEBUG & DEBUG_URB) _mesa_printf("URB fence: %d ..VS.. %d ..GS.. %d ..CLP.. %d ..SF.. %d ..CS.. %d\n", brw->urb.vs_start, diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index 1e4f66091e3..4a591365c98 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -58,6 +58,7 @@ struct brw_vs_compile { GLuint first_output; GLuint nr_outputs; + GLuint first_overflow_output; /**< VERT_ATTRIB_x */ GLuint first_tmp; GLuint last_tmp; diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c index 2637344b482..249a800bf4b 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_constval.c +++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c @@ -39,8 +39,8 @@ */ struct tracker { GLboolean twoside; - GLubyte active[PROGRAM_OUTPUT+1][128]; - GLuint size_masks[4]; + GLubyte active[PROGRAM_OUTPUT+1][MAX_PROGRAM_TEMPS]; + GLbitfield size_masks[4]; /**< one bit per fragment program input attrib */ }; @@ -53,8 +53,10 @@ static void set_active_component( struct tracker *t, case PROGRAM_TEMPORARY: case PROGRAM_INPUT: case PROGRAM_OUTPUT: + assert(file < PROGRAM_OUTPUT + 1); + assert(index < Elements(t->active[0])); t->active[file][index] |= active; - + break; default: break; } @@ -108,10 +110,15 @@ static GLubyte get_active( struct tracker *t, return active; } +/** + * Return the size (1,2,3 or 4) of the output/result for VERT_RESULT_idx. + */ static GLubyte get_output_size( struct tracker *t, GLuint idx ) { - GLubyte active = t->active[PROGRAM_OUTPUT][idx]; + GLubyte active; + assert(idx < VERT_RESULT_MAX); + active = t->active[PROGRAM_OUTPUT][idx]; if (active & (1<<3)) return 4; if (active & (1<<2)) return 3; if (active & (1<<1)) return 2; @@ -123,7 +130,7 @@ static GLubyte get_output_size( struct tracker *t, */ static void calc_sizes( struct tracker *t ) { - GLuint i; + GLint vertRes; if (t->twoside) { t->active[PROGRAM_OUTPUT][VERT_RESULT_COL0] |= @@ -133,12 +140,27 @@ static void calc_sizes( struct tracker *t ) t->active[PROGRAM_OUTPUT][VERT_RESULT_BFC1]; } - for (i = 0; i < FRAG_ATTRIB_MAX; i++) { - switch (get_output_size(t, i)) { - case 4: t->size_masks[4-1] |= 1<<i; - case 3: t->size_masks[3-1] |= 1<<i; - case 2: t->size_masks[2-1] |= 1<<i; - case 1: t->size_masks[1-1] |= 1<<i; + /* Examine vertex program output sizes to set the size_masks[] info + * which describes the fragment program input sizes. + */ + for (vertRes = VERT_RESULT_TEX0; vertRes < VERT_RESULT_MAX; vertRes++) { + GLint fragAttrib; + + /* map vertex program output index to fragment program input index */ + if (vertRes <= VERT_RESULT_TEX7) + fragAttrib = FRAG_ATTRIB_TEX0 + vertRes - VERT_RESULT_TEX0; + else if (vertRes >= VERT_RESULT_VAR0) + fragAttrib = FRAG_ATTRIB_VAR0 + vertRes - VERT_RESULT_VAR0; + else + continue; + assert(fragAttrib >= FRAG_ATTRIB_TEX0); + assert(fragAttrib <= FRAG_ATTRIB_MAX); + + switch (get_output_size(t, vertRes)) { + case 4: t->size_masks[4-1] |= 1 << fragAttrib; + case 3: t->size_masks[3-1] |= 1 << fragAttrib; + case 2: t->size_masks[2-1] |= 1 << fragAttrib; + case 1: t->size_masks[1-1] |= 1 << fragAttrib; break; } } diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index d7f75e3685e..514f15d5e3a 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -129,15 +129,21 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) } } - /* Allocate outputs: TODO: could organize the non-position outputs - * to go straight into message regs. + /* Allocate outputs. The non-position outputs go straight into message regs. */ c->nr_outputs = 0; c->first_output = reg; - mrf = 4; + c->first_overflow_output = 0; + + if (BRW_IS_IGDNG(c->func.brw)) + mrf = 8; + else + mrf = 4; + for (i = 0; i < VERT_RESULT_MAX; i++) { if (c->prog_data.outputs_written & (1 << i)) { c->nr_outputs++; + assert(i < Elements(c->regs[PROGRAM_OUTPUT])); if (i == VERT_RESULT_HPOS) { c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0); reg++; @@ -148,8 +154,17 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) mrf++; /* just a placeholder? XXX fix later stages & remove this */ } else { - c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf); - mrf++; + if (mrf < 16) { + c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf); + mrf++; + } + else { + /* too many vertex results to fit in MRF, use GRF for overflow */ + if (!c->first_overflow_output) + c->first_overflow_output = i; + c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0); + reg++; + } } } } @@ -206,7 +221,11 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) */ c->prog_data.urb_read_length = (c->nr_inputs + 1) / 2; - c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4; + if (BRW_IS_IGDNG(c->func.brw)) + c->prog_data.urb_entry_size = (c->nr_outputs + 6 + 3) / 4; + else + c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4; + c->prog_data.total_grf = reg; if (INTEL_DEBUG & DEBUG_VS) { @@ -1067,6 +1086,8 @@ static void emit_vertex_write( struct brw_vs_compile *c) struct brw_reg m0 = brw_message_reg(0); struct brw_reg pos = c->regs[PROGRAM_OUTPUT][VERT_RESULT_HPOS]; struct brw_reg ndc; + int eot; + GLuint len_vertext_header = 2; if (c->key.copy_edgeflag) { brw_MOV(p, @@ -1076,14 +1097,16 @@ static void emit_vertex_write( struct brw_vs_compile *c) /* Build ndc coords */ ndc = get_tmp(c); + /* ndc = 1.0 / pos.w */ emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL); + /* ndc.xyz = pos * ndc */ brw_MUL(p, brw_writemask(ndc, WRITEMASK_XYZ), pos, ndc); /* Update the header for point size, user clipping flags, and -ve rhw * workaround. */ if ((c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) || - c->key.nr_userclip || !BRW_IS_G4X(p->brw)) + c->key.nr_userclip || BRW_IS_965(p->brw)) { struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); GLuint i; @@ -1114,7 +1137,7 @@ static void emit_vertex_write( struct brw_vs_compile *c) * Later, clipping will detect ucp[6] and ensure the primitive is * clipped against all fixed planes. */ - if (!BRW_IS_G4X(p->brw)) { + if (BRW_IS_965(p->brw)) { brw_CMP(p, vec8(brw_null_reg()), BRW_CONDITIONAL_L, @@ -1141,7 +1164,23 @@ static void emit_vertex_write( struct brw_vs_compile *c) */ brw_set_access_mode(p, BRW_ALIGN_1); brw_MOV(p, offset(m0, 2), ndc); - brw_MOV(p, offset(m0, 3), pos); + + if (BRW_IS_IGDNG(p->brw)) { + /* There are 20 DWs (D0-D19) in VUE vertex header on IGDNG */ + brw_MOV(p, offset(m0, 3), pos); /* a portion of vertex header */ + /* m4, m5 contain the distances from vertex to the user clip planeXXX. + * Seems it is useless for us. + * m6 is used for aligning, so that the remainder of vertex element is + * reg-aligned. + */ + brw_MOV(p, offset(m0, 7), pos); /* the remainder of vertex element */ + len_vertext_header = 6; + } else { + brw_MOV(p, offset(m0, 3), pos); + len_vertext_header = 2; + } + + eot = (c->first_overflow_output == 0); brw_urb_WRITE(p, brw_null_reg(), /* dest */ @@ -1149,12 +1188,43 @@ static void emit_vertex_write( struct brw_vs_compile *c) c->r0, /* src */ 0, /* allocate */ 1, /* used */ - c->nr_outputs + 3, /* msg len */ + MIN2(c->nr_outputs + 1 + len_vertext_header, (BRW_MAX_MRF-1)), /* msg len */ 0, /* response len */ - 1, /* eot */ + eot, /* eot */ 1, /* writes complete */ 0, /* urb destination offset */ BRW_URB_SWIZZLE_INTERLEAVE); + + if (c->first_overflow_output > 0) { + /* Not all of the vertex outputs/results fit into the MRF. + * Move the overflowed attributes from the GRF to the MRF and + * issue another brw_urb_WRITE(). + */ + /* XXX I'm not 100% sure about which MRF regs to use here. Starting + * at mrf[4] atm... + */ + GLuint i, mrf = 0; + for (i = c->first_overflow_output; i < VERT_RESULT_MAX; i++) { + if (c->prog_data.outputs_written & (1 << i)) { + /* move from GRF to MRF */ + brw_MOV(p, brw_message_reg(4+mrf), c->regs[PROGRAM_OUTPUT][i]); + mrf++; + } + } + + brw_urb_WRITE(p, + brw_null_reg(), /* dest */ + 4, /* starting mrf reg nr */ + c->r0, /* src */ + 0, /* allocate */ + 1, /* used */ + mrf+1, /* msg len */ + 0, /* response len */ + 1, /* eot */ + 1, /* writes complete */ + BRW_MAX_MRF-1, /* urb destination offset */ + BRW_URB_SWIZZLE_INTERLEAVE); + } } @@ -1183,15 +1253,15 @@ post_vs_emit( struct brw_vs_compile *c, */ void brw_vs_emit(struct brw_vs_compile *c ) { -#define MAX_IFSN 32 +#define MAX_IF_DEPTH 32 +#define MAX_LOOP_DEPTH 32 struct brw_compile *p = &c->func; - GLuint nr_insns = c->vp->program.Base.NumInstructions; - GLuint insn, if_insn = 0; + const GLuint nr_insns = c->vp->program.Base.NumInstructions; + GLuint insn, if_depth = 0, loop_depth = 0; GLuint end_offset = 0; struct brw_instruction *end_inst, *last_inst; - struct brw_instruction *if_inst[MAX_IFSN]; - struct brw_indirect stack_index = brw_indirect(0, 0); - + struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH]; + const struct brw_indirect stack_index = brw_indirect(0, 0); GLuint index; GLuint file; @@ -1382,16 +1452,51 @@ void brw_vs_emit(struct brw_vs_compile *c ) emit_xpd(p, dst, args[0], args[1]); break; case OPCODE_IF: - assert(if_insn < MAX_IFSN); - if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8); + assert(if_depth < MAX_IF_DEPTH); + if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8); break; case OPCODE_ELSE: - if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]); + if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]); break; case OPCODE_ENDIF: - assert(if_insn > 0); - brw_ENDIF(p, if_inst[--if_insn]); + assert(if_depth > 0); + brw_ENDIF(p, if_inst[--if_depth]); break; +#if 0 + case OPCODE_BGNLOOP: + loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8); + break; + case OPCODE_BRK: + brw_BREAK(p); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + break; + case OPCODE_CONT: + brw_CONT(p); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + break; + case OPCODE_ENDLOOP: + { + struct brw_instruction *inst0, *inst1; + loop_depth--; + inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]); + /* patch all the BREAK/CONT instructions from last BEGINLOOP */ + while (inst0 > loop_inst[loop_depth]) { + inst0--; + if (inst0->header.opcode == BRW_OPCODE_BREAK) { + inst0->bits3.if_else.jump_count = inst1 - inst0 + 1; + inst0->bits3.if_else.pop_count = 0; + } + else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) { + inst0->bits3.if_else.jump_count = inst1 - inst0; + inst0->bits3.if_else.pop_count = 0; + } + } + } + break; +#else + (void) loop_inst; + (void) loop_depth; +#endif case OPCODE_BRA: brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c index 3d295388437..d790ab65553 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_state.c @@ -97,7 +97,11 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) * brw_urb_WRITE() results. */ vs.thread1.single_program_flow = 0; - vs.thread1.binding_table_entry_count = key->nr_surfaces; + + if (BRW_IS_IGDNG(brw)) + vs.thread1.binding_table_entry_count = 0; /* hardware requirement */ + else + vs.thread1.binding_table_entry_count = key->nr_surfaces; vs.thread3.urb_entry_read_length = key->urb_entry_read_length; vs.thread3.const_urb_entry_read_length = key->curb_entry_read_length; @@ -105,10 +109,16 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) vs.thread3.urb_entry_read_offset = 0; vs.thread3.const_urb_entry_read_offset = key->curbe_offset * 2; - vs.thread4.nr_urb_entries = key->nr_urb_entries; + if (BRW_IS_IGDNG(brw)) + vs.thread4.nr_urb_entries = key->nr_urb_entries >> 2; + else + vs.thread4.nr_urb_entries = key->nr_urb_entries; + vs.thread4.urb_entry_allocation_size = key->urb_size - 1; - if (BRW_IS_G4X(brw)) + if (BRW_IS_IGDNG(brw)) + chipset_max_threads = 72; + else if (BRW_IS_G4X(brw)) chipset_max_threads = 32; else chipset_max_threads = 16; @@ -120,6 +130,8 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) /* No samplers for ARB_vp programs: */ + /* It has to be set to 0 for IGDNG + */ vs.vs5.sampler_count = 0; if (INTEL_DEBUG & DEBUG_STATS) diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index ba03afd6c13..ac117901515 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -177,14 +177,6 @@ static void brw_note_fence( struct intel_context *intel, GLuint fence ) brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_FENCE; } - -static void brw_note_unlock( struct intel_context *intel ) -{ - struct brw_context *brw = brw_context(&intel->ctx); - brw_state_cache_check_size(brw); -} - - /* called from intelWaitForIdle() and intelFlush() * * For now, just flush everything. Could be smarter later. @@ -194,7 +186,7 @@ static GLuint brw_flush_cmd( void ) struct brw_mi_flush flush; flush.opcode = CMD_MI_FLUSH; flush.pad = 0; - flush.flags = BRW_FLUSH_READ_CACHE | BRW_FLUSH_STATE_CACHE; + flush.flags = BRW_FLUSH_STATE_CACHE; return *(GLuint *)&flush; } @@ -215,7 +207,6 @@ void brwInitVtbl( struct brw_context *brw ) brw->intel.vtbl.invalidate_state = brw_invalidate_state; brw->intel.vtbl.note_fence = brw_note_fence; - brw->intel.vtbl.note_unlock = brw_note_unlock; brw->intel.vtbl.new_batch = brw_new_batch; brw->intel.vtbl.finish_batch = brw_finish_batch; brw->intel.vtbl.destroy = brw_destroy_context; diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 3e476fd3be5..14e05be4f6c 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -267,11 +267,14 @@ static void brw_wm_populate_key( struct brw_context *brw, /* BRW_NEW_WM_INPUT_DIMENSIONS */ - key->projtex_mask = brw->wm.input_size_masks[4-1] >> (FRAG_ATTRIB_TEX0 - FRAG_ATTRIB_WPOS); + key->proj_attrib_mask = brw->wm.input_size_masks[4-1]; /* _NEW_LIGHT */ key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT); + /* _NEW_HINT */ + key->linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST); + /* _NEW_TEXTURE */ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { const struct gl_texture_unit *unit = &ctx->Texture.Unit[i]; @@ -351,6 +354,7 @@ const struct brw_tracked_state brw_wm_prog = { .dirty = { .mesa = (_NEW_COLOR | _NEW_DEPTH | + _NEW_HINT | _NEW_STENCIL | _NEW_POLYGON | _NEW_LINE | diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index fb15c03e83d..ba497432c60 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -63,9 +63,10 @@ struct brw_wm_prog_key { GLuint computes_depth:1; /* could be derived from program string */ GLuint source_depth_to_render_target:1; GLuint flat_shade:1; + GLuint linear_color:1; /**< linear interpolation vs perspective interp */ GLuint runtime_check_aads_emit:1; - GLuint projtex_mask:16; + GLbitfield proj_attrib_mask; /**< one bit per fragment program attribute */ GLuint shadowtex_mask:16; GLuint yuvtex_mask:16; GLuint yuvtex_swap_mask:16; /* UV swaped */ diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index 14ab9042de7..9f82916c025 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -714,6 +714,7 @@ static void emit_tex( struct brw_wm_compile *c, GLuint msgLength, responseLength; GLuint i, nr; GLuint emit; + GLuint msg_type; /* How many input regs are there? */ @@ -751,6 +752,18 @@ static void emit_tex( struct brw_wm_compile *c, responseLength = 8; /* always */ + if (BRW_IS_IGDNG(p->brw)) { + if (inst->tex_shadow) + msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG; + else + msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG; + } else { + if (inst->tex_shadow) + msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE; + else + msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE; + } + brw_SAMPLE(p, retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW), 1, @@ -758,12 +771,12 @@ static void emit_tex( struct brw_wm_compile *c, SURF_INDEX_TEXTURE(inst->tex_unit), inst->tex_unit, /* sampler */ inst->writemask, - (inst->tex_shadow ? - BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE : - BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE), + msg_type, responseLength, msgLength, - 0); + 0, + 1, + BRW_SAMPLER_SIMD_MODE_SIMD16); } @@ -775,7 +788,7 @@ static void emit_txb( struct brw_wm_compile *c, { struct brw_compile *p = &c->func; GLuint msgLength; - + GLuint msg_type; /* Shadow ignored for txb. */ switch (inst->tex_idx) { @@ -800,6 +813,11 @@ static void emit_txb( struct brw_wm_compile *c, brw_MOV(p, brw_message_reg(8), arg[3]); msgLength = 9; + if (BRW_IS_IGDNG(p->brw)) + msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG; + else + msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS; + brw_SAMPLE(p, retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW), 1, @@ -807,10 +825,12 @@ static void emit_txb( struct brw_wm_compile *c, SURF_INDEX_TEXTURE(inst->tex_unit), inst->tex_unit, /* sampler */ inst->writemask, - BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, + msg_type, 8, /* responseLength */ msgLength, - 0); + 0, + 1, + BRW_SAMPLER_SIMD_MODE_SIMD16); } @@ -1022,7 +1042,7 @@ static void emit_fb_write( struct brw_wm_compile *c, get_element_ud(brw_vec8_grf(1,0), 6), brw_imm_ud(1<<26)); - jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); + jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)); { emit_aa(c, arg1, 2); fire_fb_write(c, 0, nr, target, eot); @@ -1057,7 +1077,6 @@ static void emit_spill( struct brw_wm_compile *c, */ brw_dp_WRITE_16(p, retype(vec16(brw_vec8_grf(0, 0)), BRW_REGISTER_TYPE_UW), - 1, slot); } @@ -1085,7 +1104,6 @@ static void emit_unspill( struct brw_wm_compile *c, brw_dp_READ_16(p, retype(vec16(reg), BRW_REGISTER_TYPE_UW), - 1, slot); } diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 1798d842c79..b9e8dd2e96e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -354,13 +354,25 @@ static void emit_interp( struct brw_wm_compile *c, src_undef()); } else { - emit_op(c, - WM_LINTERP, - dst, - 0, - interp, - deltas, - src_undef()); + if (c->key.linear_color) { + emit_op(c, + WM_LINTERP, + dst, + 0, + interp, + deltas, + src_undef()); + } + else { + /* perspective-corrected color interpolation */ + emit_op(c, + WM_PINTERP, + dst, + 0, + interp, + deltas, + get_pixel_w(c)); + } } break; case FRAG_ATTRIB_FOGC: @@ -834,10 +846,16 @@ static void precalc_tex( struct brw_wm_compile *c, } +/** + * Check if the given TXP instruction really needs the divide-by-W step. + */ static GLboolean projtex( struct brw_wm_compile *c, const struct prog_instruction *inst ) { - struct prog_src_register src = inst->SrcReg[0]; + const struct prog_src_register src = inst->SrcReg[0]; + GLboolean retVal; + + assert(inst->Opcode == OPCODE_TXP); /* Only try to detect the simplest cases. Could detect (later) * cases where we are trying to emit code like RCP {1.0}, MUL x, @@ -847,16 +865,21 @@ static GLboolean projtex( struct brw_wm_compile *c, * user-provided fragment programs anyway: */ if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) - return 0; /* ut2004 gun rendering !?! */ + retVal = GL_FALSE; /* ut2004 gun rendering !?! */ else if (src.File == PROGRAM_INPUT && GET_SWZ(src.Swizzle, W) == W && - (c->key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0) - return 0; + (c->key.proj_attrib_mask & (1 << src.Index)) == 0) + retVal = GL_FALSE; else - return 1; + retVal = GL_TRUE; + + return retVal; } +/** + * Emit code for TXP. + */ static void precalc_txp( struct brw_wm_compile *c, const struct prog_instruction *inst ) { diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 0e6a2f8ef09..19f777fe32e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -446,7 +446,6 @@ static void fetch_constants(struct brw_wm_compile *c, /* need to fetch the constant now */ brw_dp_READ_4(p, c->current_const[i].reg, /* writeback dest */ - 1, /* msg_reg */ src->RelAddr, /* relative indexing? */ 16 * src->Index, /* byte offset */ SURF_INDEX_FRAG_CONST_BUFFER/* binding table index */ @@ -2626,6 +2625,7 @@ static void emit_txb(struct brw_wm_compile *c, struct brw_reg dst[4], src[4], payload_reg; GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit]; GLuint i; + GLuint msg_type; payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0); @@ -2654,6 +2654,14 @@ static void emit_txb(struct brw_wm_compile *c, } brw_MOV(p, brw_message_reg(5), src[3]); /* bias */ brw_MOV(p, brw_message_reg(6), brw_imm_f(0)); /* ref (unused?) */ + + if (BRW_IS_IGDNG(p->brw)) { + msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG; + } else { + /* Does it work well on SIMD8? */ + msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS; + } + brw_SAMPLE(p, retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */ 1, /* msg_reg_nr */ @@ -2661,10 +2669,12 @@ static void emit_txb(struct brw_wm_compile *c, SURF_INDEX_TEXTURE(unit), unit, /* sampler */ inst->DstReg.WriteMask, /* writemask */ - BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, /* msg_type */ + msg_type, /* msg_type */ 4, /* response_length */ 4, /* msg_length */ - 0); /* eot */ + 0, /* eot */ + 1, + BRW_SAMPLER_SIMD_MODE_SIMD8); } @@ -2678,6 +2688,7 @@ static void emit_tex(struct brw_wm_compile *c, GLuint i, nr; GLuint emit; GLboolean shadow = (c->key.shadowtex_mask & (1<<unit)) ? 1 : 0; + GLuint msg_type; payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0); @@ -2718,6 +2729,16 @@ static void emit_tex(struct brw_wm_compile *c, brw_MOV(p, brw_message_reg(6), src[2]); /* ref value / R coord */ } + if (BRW_IS_IGDNG(p->brw)) { + if (shadow) + msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG; + else + msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG; + } else { + /* Does it work for shadow on SIMD8 ? */ + msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE; + } + brw_SAMPLE(p, retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */ 1, /* msg_reg_nr */ @@ -2725,10 +2746,12 @@ static void emit_tex(struct brw_wm_compile *c, SURF_INDEX_TEXTURE(unit), unit, /* sampler */ inst->DstReg.WriteMask, /* writemask */ - BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE, /* msg_type */ + msg_type, /* msg_type */ 4, /* response_length */ shadow ? 6 : 4, /* msg_length */ - 0); /* eot */ + 0, /* eot */ + 1, + BRW_SAMPLER_SIMD_MODE_SIMD8); if (shadow) brw_MOV(p, dst[3], brw_imm_f(1.0)); @@ -2745,11 +2768,10 @@ static void post_wm_emit( struct brw_wm_compile *c ) static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) { -#define MAX_IFSN 32 +#define MAX_IF_DEPTH 32 #define MAX_LOOP_DEPTH 32 - struct brw_instruction *if_inst[MAX_IFSN], *loop_inst[MAX_LOOP_DEPTH]; - struct brw_instruction *inst0, *inst1; - int i, if_insn = 0, loop_insn = 0; + struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH]; + GLuint i, if_depth = 0, loop_depth = 0; struct brw_compile *p = &c->func; struct brw_indirect stack_index = brw_indirect(0, 0); @@ -2831,6 +2853,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) emit_trunc(c, inst); break; case OPCODE_MOV: + case OPCODE_SWZ: emit_mov(c, inst); break; case OPCODE_DP3: @@ -2922,15 +2945,15 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) emit_kil(c); break; case OPCODE_IF: - assert(if_insn < MAX_IFSN); - if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8); + assert(if_depth < MAX_IF_DEPTH); + if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8); break; case OPCODE_ELSE: - if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]); + if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]); break; case OPCODE_ENDIF: - assert(if_insn > 0); - brw_ENDIF(p, if_inst[--if_insn]); + assert(if_depth > 0); + brw_ENDIF(p, if_inst[--if_depth]); break; case OPCODE_BGNSUB: brw_save_label(p, inst->Comment, p->nr_insn); @@ -2964,7 +2987,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) break; case OPCODE_BGNLOOP: /* XXX may need to invalidate the current_constant regs */ - loop_inst[loop_insn++] = brw_DO(p, BRW_EXECUTE_8); + loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8); break; case OPCODE_BRK: brw_BREAK(p); @@ -2975,21 +2998,29 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) brw_set_predicate_control(p, BRW_PREDICATE_NONE); break; case OPCODE_ENDLOOP: - loop_insn--; - inst0 = inst1 = brw_WHILE(p, loop_inst[loop_insn]); - /* patch all the BREAK instructions from - last BEGINLOOP */ - while (inst0 > loop_inst[loop_insn]) { - inst0--; - if (inst0->header.opcode == BRW_OPCODE_BREAK) { - inst0->bits3.if_else.jump_count = inst1 - inst0 + 1; + { + struct brw_instruction *inst0, *inst1; + GLuint br = 1; + + if (BRW_IS_IGDNG(brw)) + br = 2; + + loop_depth--; + inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]); + /* patch all the BREAK/CONT instructions from last BEGINLOOP */ + while (inst0 > loop_inst[loop_depth]) { + inst0--; + if (inst0->header.opcode == BRW_OPCODE_BREAK) { + inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1); inst0->bits3.if_else.pop_count = 0; - } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) { - inst0->bits3.if_else.jump_count = inst1 - inst0; + } + else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) { + inst0->bits3.if_else.jump_count = br * (inst1 - inst0); inst0->bits3.if_else.pop_count = 0; - } - } - break; + } + } + } + break; default: _mesa_printf("unsupported IR in fragment shader %d\n", inst->Opcode); diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index 67b41173fb2..39f8c6d522b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -71,7 +71,9 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) key->max_threads = 1; else { /* WM maximum threads is number of EUs times number of threads per EU. */ - if (BRW_IS_G4X(brw)) + if (BRW_IS_IGDNG(brw)) + key->max_threads = 12 * 6; + else if (BRW_IS_G4X(brw)) key->max_threads = 10 * 5; else key->max_threads = 8 * 4; @@ -141,7 +143,11 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, wm.thread0.kernel_start_pointer = brw->wm.prog_bo->offset >> 6; /* reloc */ wm.thread1.depth_coef_urb_read_offset = 1; wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; - wm.thread1.binding_table_entry_count = key->nr_surfaces; + + if (BRW_IS_IGDNG(brw)) + wm.thread1.binding_table_entry_count = 0; /* hardware requirement */ + else + wm.thread1.binding_table_entry_count = key->nr_surfaces; if (key->total_scratch != 0) { wm.thread2.scratch_space_base_pointer = @@ -158,7 +164,11 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, wm.thread3.const_urb_entry_read_length = key->curb_entry_read_length; wm.thread3.const_urb_entry_read_offset = key->curbe_offset * 2; - wm.wm4.sampler_count = (key->sampler_count + 1) / 4; + if (BRW_IS_IGDNG(brw)) + wm.wm4.sampler_count = 0; /* hardware requirement */ + else + wm.wm4.sampler_count = (key->sampler_count + 1) / 4; + if (brw->wm.sampler_bo != NULL) { /* reloc */ wm.wm4.sampler_state_pointer = brw->wm.sampler_bo->offset >> 5; diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index c49a5f6b4ec..096f74394eb 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -578,7 +578,27 @@ brw_update_renderbuffer_surface(struct brw_context *brw, surf.ss0.surface_format = key.surface_format; surf.ss0.surface_type = key.surface_type; - surf.ss1.base_addr = key.draw_offset; + if (key.tiling == I915_TILING_NONE) { + surf.ss1.base_addr = key.draw_offset; + } else { + uint32_t tile_offset = key.draw_offset % 4096; + + surf.ss1.base_addr = key.draw_offset - tile_offset; + + assert(BRW_IS_G4X(brw) || tile_offset == 0); + if (BRW_IS_G4X(brw)) { + if (key.tiling == I915_TILING_X) { + /* Note that the low bits of these fields are missing, so + * there's the possibility of getting in trouble. + */ + surf.ss5.x_offset = (tile_offset % 512) / key.cpp / 4; + surf.ss5.y_offset = tile_offset / 512 / 2; + } else { + surf.ss5.x_offset = (tile_offset % 128) / key.cpp / 4; + surf.ss5.y_offset = tile_offset / 128 / 2; + } + } + } if (region_bo != NULL) surf.ss1.base_addr += region_bo->offset; /* reloc */ @@ -609,7 +629,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit], offsetof(struct brw_surface_state, ss1), region_bo, - key.draw_offset, + surf.ss1.base_addr, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); } diff --git a/src/mesa/drivers/dri/i965/intel_pixel_read.c b/src/mesa/drivers/dri/i965/intel_pixel_read.c new file mode 120000 index 00000000000..cc4589f4d42 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_pixel_read.c @@ -0,0 +1 @@ +../intel/intel_pixel_read.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 29dc05c518e..0f87fc46a44 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -195,7 +195,6 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file, { struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; - GLboolean was_locked = intel->locked; if (used == 0) { batch->cliprect_mode = IGNORE_CLIPRECTS; @@ -243,13 +242,9 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file, /* TODO: Just pass the relocation list and dma buffer up to the * kernel. */ - if (!was_locked) - LOCK_HARDWARE(intel); - + LOCK_HARDWARE(intel); do_flush_locked(batch, used, GL_FALSE); - - if (!was_locked) - UNLOCK_HARDWARE(intel); + UNLOCK_HARDWARE(intel); if (INTEL_DEBUG & DEBUG_SYNC) { fprintf(stderr, "waiting for idle\n"); diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 49198281316..2e95bd1013f 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -108,6 +108,8 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; } + assert(src->tiling != I915_TILING_Y); + assert(dst->tiling != I915_TILING_Y); #ifndef I915 if (src->tiling != I915_TILING_NONE) { CMD |= XY_SRC_TILED; @@ -175,66 +177,6 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, UNLOCK_HARDWARE(intel); } - - - -void -intelEmitFillBlit(struct intel_context *intel, - GLuint cpp, - GLshort dst_pitch, - dri_bo *dst_buffer, - GLuint dst_offset, - uint32_t dst_tiling, - GLshort x, GLshort y, - GLshort w, GLshort h, - GLuint color) -{ - GLuint BR13, CMD; - BATCH_LOCALS; - - dst_pitch *= cpp; - - switch (cpp) { - case 1: - BR13 = (0xF0 << 16); - CMD = XY_COLOR_BLT_CMD; - break; - case 2: - BR13 = (0xF0 << 16) | BR13_565; - CMD = XY_COLOR_BLT_CMD; - break; - case 4: - BR13 = (0xF0 << 16) | BR13_8888; - CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; - break; - default: - return; - } -#ifndef I915 - if (dst_tiling != I915_TILING_NONE) { - CMD |= XY_DST_TILED; - dst_pitch /= 4; - } -#endif - - DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", - __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); - - assert(w > 0); - assert(h > 0); - - BEGIN_BATCH(6, NO_LOOP_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13 | dst_pitch); - OUT_BATCH((y << 16) | x); - OUT_BATCH(((y + h) << 16) | (x + w)); - OUT_RELOC(dst_buffer, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - dst_offset); - OUT_BATCH(color); - ADVANCE_BATCH(); -} - static GLuint translate_raster_op(GLenum logicop) { switch(logicop) { @@ -261,7 +203,7 @@ static GLuint translate_raster_op(GLenum logicop) /* Copy BitBlt */ -void +GLboolean intelEmitCopyBlit(struct intel_context *intel, GLuint cpp, GLshort src_pitch, @@ -283,6 +225,19 @@ intelEmitCopyBlit(struct intel_context *intel, dri_bo *aper_array[3]; BATCH_LOCALS; + if (dst_tiling != I915_TILING_NONE) { + if (dst_offset & 4095) + return GL_FALSE; + if (dst_tiling == I915_TILING_Y) + return GL_FALSE; + } + if (src_tiling != I915_TILING_NONE) { + if (src_offset & 4095) + return GL_FALSE; + if (src_tiling == I915_TILING_Y) + return GL_FALSE; + } + /* do space/cliprects check before going any further */ do { aper_array[0] = intel->batch->buf; @@ -297,12 +252,7 @@ intelEmitCopyBlit(struct intel_context *intel, } while (pass < 2); if (pass >= 2) { - GLboolean locked = GL_FALSE; - if (!intel->locked) { - LOCK_HARDWARE(intel); - locked = GL_TRUE; - } - + LOCK_HARDWARE(intel); dri_bo_map(dst_buffer, GL_TRUE); dri_bo_map(src_buffer, GL_FALSE); _mesa_copy_rect((GLubyte *)dst_buffer->virtual + dst_offset, @@ -316,11 +266,9 @@ intelEmitCopyBlit(struct intel_context *intel, dri_bo_unmap(src_buffer); dri_bo_unmap(dst_buffer); - - if (locked) - UNLOCK_HARDWARE(intel); + UNLOCK_HARDWARE(intel); - return; + return GL_TRUE; } intel_batchbuffer_require_space(intel->batch, 8 * 4, NO_LOOP_CLIPRECTS); @@ -347,7 +295,7 @@ intelEmitCopyBlit(struct intel_context *intel, CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; break; default: - return; + return GL_FALSE; } #ifndef I915 @@ -362,7 +310,7 @@ intelEmitCopyBlit(struct intel_context *intel, #endif if (dst_y2 <= dst_y || dst_x2 <= dst_x) { - return; + return GL_TRUE; } assert(dst_x < dst_x2); @@ -384,6 +332,8 @@ intelEmitCopyBlit(struct intel_context *intel, ADVANCE_BATCH(); intel_batchbuffer_emit_mi_flush(intel->batch); + + return GL_TRUE; } @@ -596,7 +546,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) UNLOCK_HARDWARE(intel); } -void +GLboolean intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLuint cpp, GLubyte *src_bits, GLuint src_size, @@ -612,11 +562,18 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, int dwords = ALIGN(src_size, 8) / 4; uint32_t opcode, br13, blit_cmd; + if (dst_tiling != I915_TILING_NONE) { + if (dst_offset & 4095) + return GL_FALSE; + if (dst_tiling == I915_TILING_Y) + return GL_FALSE; + } + assert( logic_op - GL_CLEAR >= 0 ); assert( logic_op - GL_CLEAR < 0x10 ); if (w < 0 || h < 0) - return; + return GL_TRUE; dst_pitch *= cpp; @@ -673,4 +630,6 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, REFERENCES_CLIPRECTS ); intel_batchbuffer_emit_mi_flush(intel->batch); + + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/intel/intel_blit.h b/src/mesa/drivers/dri/intel/intel_blit.h index 52065b13ed7..152fa3f17bf 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.h +++ b/src/mesa/drivers/dri/intel/intel_blit.h @@ -35,7 +35,8 @@ extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv, extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask); -extern void intelEmitCopyBlit(struct intel_context *intel, +GLboolean +intelEmitCopyBlit(struct intel_context *intel, GLuint cpp, GLshort src_pitch, dri_bo *src_buffer, @@ -50,16 +51,7 @@ extern void intelEmitCopyBlit(struct intel_context *intel, GLshort w, GLshort h, GLenum logicop ); -extern void intelEmitFillBlit(struct intel_context *intel, - GLuint cpp, - GLshort dst_pitch, - dri_bo *dst_buffer, - GLuint dst_offset, - uint32_t dst_tiling, - GLshort x, GLshort y, - GLshort w, GLshort h, GLuint color); - -void +GLboolean intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLuint cpp, GLubyte *src_bits, GLuint src_size, diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index 23ba3b9ef67..9600557f2cc 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -243,6 +243,9 @@ intel_bufferobj_map(GLcontext * ctx, return obj->Pointer; } + if (!read_only) + intelFlush(ctx); + if (intel_obj->region) intel_bufferobj_cow(intel, intel_obj); @@ -274,7 +277,10 @@ intel_bufferobj_unmap(GLcontext * ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - if (intel_obj->buffer != NULL) { + if (intel_obj->sys_buffer != NULL) { + assert(obj->Pointer); + obj->Pointer = NULL; + } else if (intel_obj->buffer != NULL) { assert(obj->Pointer); if (intel_obj->mapped_gtt) { drm_intel_gem_bo_unmap_gtt(intel_obj->buffer); @@ -300,14 +306,19 @@ intel_bufferobj_buffer(struct intel_context *intel, } if (intel_obj->buffer == NULL) { + void *sys_buffer = intel_obj->sys_buffer; + + /* only one of buffer and sys_buffer could be non-NULL */ intel_bufferobj_alloc_buffer(intel, intel_obj); + intel_obj->sys_buffer = NULL; + intel_bufferobj_subdata(&intel->ctx, GL_ARRAY_BUFFER_ARB, 0, intel_obj->Base.Size, - intel_obj->sys_buffer, + sys_buffer, &intel_obj->Base); - _mesa_free(intel_obj->sys_buffer); + _mesa_free(sys_buffer); intel_obj->sys_buffer = NULL; } @@ -315,15 +326,13 @@ intel_bufferobj_buffer(struct intel_context *intel, } void -intel_bufferobj_init(struct intel_context *intel) +intelInitBufferObjectFuncs(struct dd_function_table *functions) { - GLcontext *ctx = &intel->ctx; - - ctx->Driver.NewBufferObject = intel_bufferobj_alloc; - ctx->Driver.DeleteBuffer = intel_bufferobj_free; - ctx->Driver.BufferData = intel_bufferobj_data; - ctx->Driver.BufferSubData = intel_bufferobj_subdata; - ctx->Driver.GetBufferSubData = intel_bufferobj_get_subdata; - ctx->Driver.MapBuffer = intel_bufferobj_map; - ctx->Driver.UnmapBuffer = intel_bufferobj_unmap; + functions->NewBufferObject = intel_bufferobj_alloc; + functions->DeleteBuffer = intel_bufferobj_free; + functions->BufferData = intel_bufferobj_data; + functions->BufferSubData = intel_bufferobj_subdata; + functions->GetBufferSubData = intel_bufferobj_get_subdata; + functions->MapBuffer = intel_bufferobj_map; + functions->UnmapBuffer = intel_bufferobj_unmap; } diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.h b/src/mesa/drivers/dri/intel/intel_buffer_objects.h index 04310156319..8164407f079 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.h @@ -60,7 +60,7 @@ dri_bo *intel_bufferobj_buffer(struct intel_context *intel, /* Hook the bufferobject implementation into mesa: */ -void intel_bufferobj_init(struct intel_context *intel); +void intelInitBufferObjectFuncs(struct dd_function_table *functions); @@ -72,10 +72,7 @@ void intel_bufferobj_init(struct intel_context *intel); static INLINE struct intel_buffer_object * intel_buffer_object(struct gl_buffer_object *obj) { - if (obj->Name) - return (struct intel_buffer_object *) obj; - else - return NULL; + return (struct intel_buffer_object *) obj; } /* Helpers for zerocopy image uploads. See also intel_regions.h: diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index df5c3fc1766..e7357e78c53 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -345,6 +345,23 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode) static void intelReadBuffer(GLcontext * ctx, GLenum mode) { + if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { + struct intel_context *const intel = intel_context(ctx); + const GLboolean was_front_buffer_reading = + intel->is_front_buffer_reading; + + intel->is_front_buffer_reading = (mode == GL_FRONT_LEFT) + || (mode == GL_FRONT); + + /* If we weren't front-buffer reading before but we are now, make sure + * that the front-buffer has actually been allocated. + */ + if (!was_front_buffer_reading && intel->is_front_buffer_reading) { + intel_update_renderbuffers(intel->driContext, + intel->driContext->driDrawablePriv); + } + } + if (ctx->ReadBuffer == ctx->DrawBuffer) { /* This will update FBO completeness status. * A framebuffer will be incomplete if the GL_READ_BUFFER setting diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h index 4593d90df3d..3c38f1676c9 100644 --- a/src/mesa/drivers/dri/intel/intel_chipset.h +++ b/src/mesa/drivers/dri/intel/intel_chipset.h @@ -67,13 +67,18 @@ #define PCI_CHIP_G45_G 0x2E22 #define PCI_CHIP_G41_G 0x2E32 +#define PCI_CHIP_ILD_G 0x0042 +#define PCI_CHIP_ILM_G 0x0046 + #define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \ devid == PCI_CHIP_I915_GM || \ devid == PCI_CHIP_I945_GM || \ devid == PCI_CHIP_I945_GME || \ devid == PCI_CHIP_I965_GM || \ devid == PCI_CHIP_I965_GME || \ - devid == PCI_CHIP_GM45_GM || IS_IGD(devid)) + devid == PCI_CHIP_GM45_GM || \ + IS_IGD(devid) || \ + devid == PCI_CHIP_ILM_G) #define IS_G45(devid) (devid == PCI_CHIP_IGD_E_G || \ devid == PCI_CHIP_Q45_G || \ @@ -82,6 +87,10 @@ #define IS_GM45(devid) (devid == PCI_CHIP_GM45_GM) #define IS_G4X(devid) (IS_G45(devid) || IS_GM45(devid)) +#define IS_ILD(devid) (devid == PCI_CHIP_ILD_G) +#define IS_ILM(devid) (devid == PCI_CHIP_ILM_G) +#define IS_IGDNG(devid) (IS_ILD(devid) || IS_ILM(devid)) + #define IS_915(devid) (devid == PCI_CHIP_I915_G || \ devid == PCI_CHIP_E7221_G || \ devid == PCI_CHIP_I915_GM) @@ -99,7 +108,8 @@ devid == PCI_CHIP_I965_GM || \ devid == PCI_CHIP_I965_GME || \ devid == PCI_CHIP_I946_GZ || \ - IS_G4X(devid)) + IS_G4X(devid) || \ + IS_IGDNG(devid)) #define IS_9XX(devid) (IS_915(devid) || \ IS_945(devid) || \ diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index 309ac1923bc..cfddabd3182 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -57,237 +57,6 @@ #define FILE_DEBUG_FLAG DEBUG_BLIT -#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \ - BUFFER_BIT_FRONT_LEFT | \ - BUFFER_BIT_COLOR0 | \ - BUFFER_BIT_COLOR1 | \ - BUFFER_BIT_COLOR2 | \ - BUFFER_BIT_COLOR3 | \ - BUFFER_BIT_COLOR4 | \ - BUFFER_BIT_COLOR5 | \ - BUFFER_BIT_COLOR6 | \ - BUFFER_BIT_COLOR7) - - -/** - * Per-context one-time init of things for intl_clear_tris(). - * Basically set up a private array object for vertex/color arrays. - */ -static void -init_clear(GLcontext *ctx) -{ - struct intel_context *intel = intel_context(ctx); - struct gl_array_object *arraySave = NULL; - const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name; - const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name; - - /* create new array object */ - intel->clear.arrayObj = _mesa_new_array_object(ctx, ~0); - - /* save current array object, bind new one */ - _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); - - /* one-time setup of vertex arrays (pos, color) */ - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), intel->clear.color); - _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), intel->clear.vertices); - _mesa_Enable(GL_COLOR_ARRAY); - _mesa_Enable(GL_VERTEX_ARRAY); - - /* restore original array object */ - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); - _mesa_reference_array_object(ctx, &arraySave, NULL); - - /* restore original buffer objects */ - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer); -} - - - -/** - * Perform glClear where mask contains only color, depth, and/or stencil. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering. The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ -void -intel_clear_tris(GLcontext *ctx, GLbitfield mask) -{ - struct intel_context *intel = intel_context(ctx); - GLfloat dst_z; - struct gl_framebuffer *fb = ctx->DrawBuffer; - int i; - GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; - GLuint saved_shader_program = 0; - unsigned int saved_active_texture; - struct gl_array_object *arraySave = NULL; - - if (!intel->clear.arrayObj) - init_clear(ctx); - - assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | - BUFFER_BIT_STENCIL)) == 0); - - _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | - GL_CURRENT_BIT | - GL_DEPTH_BUFFER_BIT | - GL_ENABLE_BIT | - GL_POLYGON_BIT | - GL_STENCIL_BUFFER_BIT | - GL_TRANSFORM_BIT | - GL_CURRENT_BIT); - saved_active_texture = ctx->Texture.CurrentUnit; - - /* Disable existing GL state we don't want to apply to a clear. */ - _mesa_Disable(GL_ALPHA_TEST); - _mesa_Disable(GL_BLEND); - _mesa_Disable(GL_CULL_FACE); - _mesa_Disable(GL_FOG); - _mesa_Disable(GL_POLYGON_SMOOTH); - _mesa_Disable(GL_POLYGON_STIPPLE); - _mesa_Disable(GL_POLYGON_OFFSET_FILL); - _mesa_Disable(GL_LIGHTING); - _mesa_Disable(GL_CLIP_PLANE0); - _mesa_Disable(GL_CLIP_PLANE1); - _mesa_Disable(GL_CLIP_PLANE2); - _mesa_Disable(GL_CLIP_PLANE3); - _mesa_Disable(GL_CLIP_PLANE4); - _mesa_Disable(GL_CLIP_PLANE5); - _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { - saved_fp_enable = GL_TRUE; - _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { - saved_vp_enable = GL_TRUE; - _mesa_Disable(GL_VERTEX_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { - saved_shader_program = ctx->Shader.CurrentProgram->Name; - _mesa_UseProgramObjectARB(0); - } - - if (ctx->Texture._EnabledUnits != 0) { - int i; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - _mesa_ActiveTextureARB(GL_TEXTURE0 + i); - _mesa_Disable(GL_TEXTURE_1D); - _mesa_Disable(GL_TEXTURE_2D); - _mesa_Disable(GL_TEXTURE_3D); - if (ctx->Extensions.ARB_texture_cube_map) - _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); - if (ctx->Extensions.NV_texture_rectangle) - _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); - if (ctx->Extensions.MESA_texture_array) { - _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); - _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); - } - } - } - - /* save current array object, bind our private one */ - _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); - - intel_meta_set_passthrough_transform(intel); - - for (i = 0; i < 4; i++) { - COPY_4FV(intel->clear.color[i], ctx->Color.ClearColor); - } - - /* convert clear Z from [0,1] to NDC coord in [-1,1] */ - dst_z = -1.0 + 2.0 * ctx->Depth.Clear; - - /* Prepare the vertices, which are the same regardless of which buffer we're - * drawing to. - */ - intel->clear.vertices[0][0] = fb->_Xmin; - intel->clear.vertices[0][1] = fb->_Ymin; - intel->clear.vertices[0][2] = dst_z; - intel->clear.vertices[1][0] = fb->_Xmax; - intel->clear.vertices[1][1] = fb->_Ymin; - intel->clear.vertices[1][2] = dst_z; - intel->clear.vertices[2][0] = fb->_Xmax; - intel->clear.vertices[2][1] = fb->_Ymax; - intel->clear.vertices[2][2] = dst_z; - intel->clear.vertices[3][0] = fb->_Xmin; - intel->clear.vertices[3][1] = fb->_Ymax; - intel->clear.vertices[3][2] = dst_z; - - while (mask != 0) { - GLuint this_mask = 0; - GLuint color_bit; - - color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); - if (color_bit != 0) - this_mask |= (1 << (color_bit - 1)); - - /* Clear depth/stencil in the same pass as color. */ - this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - - /* Select the current color buffer and use the color write mask if - * we have one, otherwise don't write any color channels. - */ - if (this_mask & BUFFER_BIT_FRONT_LEFT) - _mesa_DrawBuffer(GL_FRONT_LEFT); - else if (this_mask & BUFFER_BIT_BACK_LEFT) - _mesa_DrawBuffer(GL_BACK_LEFT); - else if (color_bit != 0) - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + - (color_bit - BUFFER_COLOR0 - 1)); - else - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - /* Control writing of the depth clear value to depth. */ - if (this_mask & BUFFER_BIT_DEPTH) { - _mesa_DepthFunc(GL_ALWAYS); - _mesa_Enable(GL_DEPTH_TEST); - } else { - _mesa_Disable(GL_DEPTH_TEST); - _mesa_DepthMask(GL_FALSE); - } - - /* Control writing of the stencil clear value to stencil. */ - if (this_mask & BUFFER_BIT_STENCIL) { - _mesa_Enable(GL_STENCIL_TEST); - _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, - GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, - ctx->Stencil.Clear, - ctx->Stencil.WriteMask[0]); - } else { - _mesa_Disable(GL_STENCIL_TEST); - } - - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); - - mask &= ~this_mask; - } - - intel_meta_restore_transform(intel); - - _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); - if (saved_fp_enable) - _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); - if (saved_vp_enable) - _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - - if (saved_shader_program) - _mesa_UseProgramObjectARB(saved_shader_program); - - _mesa_PopAttrib(); - - /* restore current array object */ - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); - _mesa_reference_array_object(ctx, &arraySave, NULL); -} - static const char *buffer_names[] = { [BUFFER_FRONT_LEFT] = "front", [BUFFER_BACK_LEFT] = "back", @@ -313,6 +82,7 @@ static const char *buffer_names[] = { static void intelClear(GLcontext *ctx, GLbitfield mask) { + struct intel_context *intel = intel_context(ctx); const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); GLbitfield tri_mask = 0; GLbitfield blit_mask = 0; @@ -412,7 +182,7 @@ intelClear(GLcontext *ctx, GLbitfield mask) } DBG("\n"); } - intel_clear_tris(ctx, tri_mask); + meta_clear_tris(&intel->meta, tri_mask); } if (swrast_mask) { diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index f88b37d0f3a..4abb525f78e 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -67,10 +67,12 @@ int INTEL_DEBUG = (0); #endif -#define DRIVER_DATE "20090114" +#define DRIVER_DATE "20090712 2009Q2 RC3" #define DRIVER_DATE_GEM "GEM " DRIVER_DATE +static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush); + static const GLubyte * intelGetString(GLcontext * ctx, GLenum name) { @@ -159,6 +161,12 @@ intelGetString(GLcontext * ctx, GLenum name) case PCI_CHIP_G41_G: chipset = "Intel(R) G41"; break; + case PCI_CHIP_ILD_G: + chipset = "Intel(R) IGDNG_D"; + break; + case PCI_CHIP_ILM_G: + chipset = "Intel(R) IGDNG_M"; + break; default: chipset = "Unknown Intel Chipset"; break; @@ -218,7 +226,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct intel_renderbuffer *stencil_rb; i = 0; - if ((intel->is_front_buffer_rendering || !intel_fb->color_rb[1]) + if ((intel->is_front_buffer_rendering || + intel->is_front_buffer_reading || + !intel_fb->color_rb[1]) && intel_fb->color_rb[0]) { attachments[i++] = __DRI_BUFFER_FRONT_LEFT; attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]); @@ -394,7 +404,16 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) if (!driContext->driScreenPriv->dri2.enabled) return; - if (!intel->internal_viewport_call && ctx->DrawBuffer->Name == 0) { + if (!intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) { + /* If we're rendering to the fake front buffer, make sure all the pending + * drawing has landed on the real front buffer. Otherwise when we + * eventually get to DRI2GetBuffersWithFormat the stale real front + * buffer contents will get copied to the new fake front buffer. + */ + if (intel->is_front_buffer_rendering) { + intel_flush(ctx, GL_FALSE); + } + intel_update_renderbuffers(driContext, driContext->driDrawablePriv); if (driContext->driDrawablePriv != driContext->driReadablePriv) intel_update_renderbuffers(driContext, driContext->driReadablePriv); @@ -526,7 +545,7 @@ intelFinish(GLcontext * ctx) irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]); - if (irb->region) + if (irb && irb->region) dri_bo_wait_rendering(irb->region->buffer); } if (fb->_DepthBuffer) { @@ -557,6 +576,7 @@ intelInitDriverFunctions(struct dd_function_table *functions) intelInitClearFuncs(functions); intelInitBufferFuncs(functions); intelInitPixelFuncs(functions); + intelInitBufferObjectFuncs(functions); } @@ -652,6 +672,7 @@ intelInitContext(struct intel_context *intel, */ _mesa_init_point(ctx); + meta_init_metaops(ctx, &intel->meta); ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ if (IS_965(intelScreen->deviceID)) { if (MAX_WIDTH > 8192) @@ -717,7 +738,6 @@ intelInitContext(struct intel_context *intel, intel->batch = intel_batchbuffer_alloc(intel); - intel_bufferobj_init(intel); intel_fbo_init(intel); if (intel->ctx.Mesa_DXTn) { @@ -729,6 +749,12 @@ intelInitContext(struct intel_context *intel, } intel->use_texture_tiling = driQueryOptionb(&intel->optionCache, "texture_tiling"); + if (intel->use_texture_tiling && + !intel->intelScreen->kernel_exec_fencing) { + fprintf(stderr, "No kernel support for execution fencing, " + "disabling texture tiling"); + intel->use_texture_tiling = GL_FALSE; + } intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z"); intel->prim.primitive = ~0; @@ -769,8 +795,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) INTEL_FIREVERTICES(intel); - if (intel->clear.arrayObj) - _mesa_delete_array_object(&intel->ctx, intel->clear.arrayObj); + meta_destroy_metaops(&intel->meta); intel->vtbl.destroy(intel); @@ -858,7 +883,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) /* free the Mesa context */ _mesa_free_context_data(&intel->ctx); - + FREE(intel); + driContextPriv->driverPrivate = NULL; } } @@ -975,7 +1001,6 @@ intelContendedLock(struct intel_context *intel, GLuint flags) int me = intel->hHWContext; drmGetLock(intel->driFd, intel->hHWContext, flags); - intel->locked = 1; if (INTEL_DEBUG & DEBUG_LOCK) _mesa_printf("%s - got contended lock\n", __progname); @@ -1032,9 +1057,12 @@ void LOCK_HARDWARE( struct intel_context *intel ) struct intel_framebuffer *intel_fb = NULL; struct intel_renderbuffer *intel_rb = NULL; - _glthread_LOCK_MUTEX(lockMutex); - assert(!intel->locked); - intel->locked = 1; + intel->locked++; + if (intel->locked >= 2) + return; + + if (!sPriv->dri2.enabled) + _glthread_LOCK_MUTEX(lockMutex); if (intel->driDrawable) { intel_fb = intel->driDrawable->driverPrivate; @@ -1081,13 +1109,16 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) { __DRIscreen *sPriv = intel->driScreen; - intel->vtbl.note_unlock( intel ); - intel->locked = 0; + intel->locked--; + if (intel->locked > 0) + return; - if (!sPriv->dri2.enabled) - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + assert(intel->locked == 0); - _glthread_UNLOCK_MUTEX(lockMutex); + if (!sPriv->dri2.enabled) { + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + _glthread_UNLOCK_MUTEX(lockMutex); + } if (INTEL_DEBUG & DEBUG_LOCK) _mesa_printf("%s - unlocked\n", __progname); diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 7d3c80bb21c..08bea88c958 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -33,6 +33,7 @@ #include "main/mtypes.h" #include "main/mm.h" #include "texmem.h" +#include "dri_metaops.h" #include "drm.h" #include "intel_bufmgr.h" @@ -91,7 +92,6 @@ struct intel_context void (*new_batch) (struct intel_context * intel); void (*emit_invarient_state) (struct intel_context * intel); void (*note_fence) (struct intel_context *intel, GLuint fence); - void (*note_unlock) (struct intel_context *intel); void (*update_texture_state) (struct intel_context * intel); void (*render_start) (struct intel_context * intel); @@ -158,29 +158,7 @@ struct intel_context void (*debug_batch)(struct intel_context *intel); } vtbl; - struct { - struct gl_fragment_program *bitmap_fp; - struct gl_vertex_program *passthrough_vp; - struct gl_buffer_object *texcoord_vbo; - - struct gl_fragment_program *saved_fp; - GLboolean saved_fp_enable; - struct gl_vertex_program *saved_vp; - GLboolean saved_vp_enable; - - struct gl_fragment_program *tex2d_fp; - - GLboolean saved_texcoord_enable; - struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; - GLenum saved_texcoord_type; - GLsizei saved_texcoord_size, saved_texcoord_stride; - const void *saved_texcoord_ptr; - int saved_active_texture; - - GLint saved_vp_x, saved_vp_y; - GLsizei saved_vp_width, saved_vp_height; - GLenum saved_matrix_mode; - } meta; + struct dri_metaops meta; GLint refcount; GLuint Fallback; @@ -192,7 +170,6 @@ struct intel_context struct intel_region *front_region; struct intel_region *back_region; struct intel_region *depth_region; - GLboolean internal_viewport_call; /** * This value indicates that the kernel memory manager is being used @@ -225,13 +202,6 @@ struct intel_context GLuint ClearColor565; GLuint ClearColor8888; - /* info for intel_clear_tris() */ - struct - { - struct gl_array_object *arrayObj; - GLfloat vertices[4][3]; - GLfloat color[4][4]; - } clear; /* Offsets of fields within the current vertex: */ @@ -304,6 +274,14 @@ struct intel_context * easily. */ GLboolean is_front_buffer_rendering; + /** + * Track whether front-buffer is the current read target. + * + * This is closely associated with is_front_buffer_rendering, but may + * be set separately. The DRI2 fake front buffer must be referenced + * either way. + */ + GLboolean is_front_buffer_reading; GLboolean use_texture_tiling; GLboolean use_early_z; diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c index 1e8b1878abe..7742609d242 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions.c +++ b/src/mesa/drivers/dri/intel/intel_extensions.c @@ -34,6 +34,7 @@ #define need_GL_ARB_occlusion_query #define need_GL_ARB_point_parameters #define need_GL_ARB_shader_objects +#define need_GL_ARB_vertex_array_object #define need_GL_ARB_vertex_program #define need_GL_ARB_vertex_shader #define need_GL_ARB_window_pos @@ -45,6 +46,7 @@ #define need_GL_EXT_fog_coord #define need_GL_EXT_framebuffer_object #define need_GL_EXT_framebuffer_blit +#define need_GL_EXT_gpu_program_parameters #define need_GL_EXT_point_parameters #define need_GL_EXT_secondary_color #define need_GL_EXT_stencil_two_side @@ -66,6 +68,7 @@ * i965_dri. */ static const struct dri_extension card_extensions[] = { + { "GL_ARB_half_float_pixel", NULL }, { "GL_ARB_multitexture", NULL }, { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, { "GL_ARB_texture_border_clamp", NULL }, @@ -76,6 +79,7 @@ static const struct dri_extension card_extensions[] = { { "GL_ARB_texture_env_dot3", NULL }, { "GL_ARB_texture_mirrored_repeat", NULL }, { "GL_ARB_texture_rectangle", NULL }, + { "GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions}, { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, @@ -86,6 +90,7 @@ static const struct dri_extension card_extensions[] = { { "GL_EXT_blend_subtract", NULL }, { "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions }, { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions }, { "GL_EXT_packed_depth_stencil", NULL }, { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, { "GL_EXT_stencil_wrap", NULL }, diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 0ea413aee1d..666893596e1 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -516,6 +516,7 @@ intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, irb->Base.BlueBits = texImage->TexFormat->BlueBits; irb->Base.AlphaBits = texImage->TexFormat->AlphaBits; irb->Base.DepthBits = texImage->TexFormat->DepthBits; + irb->Base.StencilBits = texImage->TexFormat->StencilBits; irb->Base.Delete = intel_delete_renderbuffer; irb->Base.AllocStorage = intel_nop_alloc_storage; diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c index 1060fbd9e59..fe986092db6 100644 --- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c +++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c @@ -88,7 +88,7 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name, if (status != GL_FRAMEBUFFER_COMPLETE_EXT) return GL_FALSE; - intel_meta_set_passthrough_transform(intel); + meta_set_passthrough_transform(&intel->meta); /* XXX: Doing it right would involve setting up the transformation to do * 0-1 mapping or something, and not changing the vertex data. @@ -104,12 +104,12 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name, _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); - intel_meta_set_default_texrect(intel); + meta_set_default_texrect(&intel->meta); - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - intel_meta_restore_texcoords(intel); - intel_meta_restore_transform(intel); + meta_restore_texcoords(&intel->meta); + meta_restore_transform(&intel->meta); return GL_TRUE; } @@ -153,9 +153,9 @@ intel_generate_mipmap_2d(GLcontext *ctx, _mesa_GenFramebuffersEXT(1, &fb_name); _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_name); - intel_meta_set_fragment_program(intel, &intel->meta.tex2d_fp, - intel_fp_tex2d); - intel_meta_set_passthrough_vertex_program(intel); + meta_set_fragment_program(&intel->meta, &intel->meta.tex2d_fp, + intel_fp_tex2d); + meta_set_passthrough_vertex_program(&intel->meta); max_levels = _mesa_max_texture_levels(ctx, texObj->Target); start_level = texObj->BaseLevel; @@ -202,8 +202,8 @@ intel_generate_mipmap_2d(GLcontext *ctx, success = GL_TRUE; fail: - intel_meta_restore_fragment_program(intel); - intel_meta_restore_vertex_program(intel); + meta_restore_fragment_program(&intel->meta); + meta_restore_vertex_program(&intel->meta); _mesa_DeleteFramebuffersEXT(1, &fb_name); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 0d34f28311e..c985da5aa25 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -101,6 +101,7 @@ intel_miptree_create_internal(struct intel_context *intel, struct intel_mipmap_tree * intel_miptree_create(struct intel_context *intel, GLenum target, + GLenum base_format, GLenum internal_format, GLuint first_level, GLuint last_level, @@ -113,9 +114,14 @@ intel_miptree_create(struct intel_context *intel, uint32_t tiling; if (intel->use_texture_tiling && compress_byte == 0 && - intel->intelScreen->kernel_exec_fencing) - tiling = I915_TILING_X; - else + intel->intelScreen->kernel_exec_fencing) { + if (IS_965(intel->intelScreen->deviceID) && + (base_format == GL_DEPTH_COMPONENT || + base_format == GL_DEPTH_STENCIL_EXT)) + tiling = I915_TILING_Y; + else + tiling = I915_TILING_X; + } else tiling = I915_TILING_NONE; mt = intel_miptree_create_internal(intel, target, internal_format, @@ -347,23 +353,31 @@ intel_miptree_set_level_info(struct intel_mipmap_tree *mt, } - void -intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, - GLuint level, GLuint img, - GLuint x, GLuint y) +intel_miptree_set_image_offset_ex(struct intel_mipmap_tree *mt, + GLuint level, GLuint img, + GLuint x, GLuint y, + GLuint offset) { if (img == 0 && level == 0) assert(x == 0 && y == 0); assert(img < mt->level[level].nr_images); - mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp; + mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp + offset; DBG("%s level %d img %d pos %d,%d image_offset %x\n", __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); } +void +intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, + GLuint level, GLuint img, + GLuint x, GLuint y) +{ + intel_miptree_set_image_offset_ex(mt, level, img, x, y, 0); +} + /* Although we use the image_offset[] array to store relative offsets * to cube faces, Mesa doesn't know anything about this and expects @@ -473,11 +487,11 @@ intel_miptree_image_data(struct intel_context *intel, 0, 0, /* source x, y */ dst->level[level].width, height); /* width, height */ - src += src_image_pitch * dst->cpp; + src = (char *)src + src_image_pitch * dst->cpp; } } -extern GLuint intel_compressed_alignment(GLenum); +extern void intel_get_texture_alignment_unit(GLenum, GLuint *, GLuint *); /* Copy mipmap image between trees */ void @@ -494,20 +508,37 @@ intel_miptree_image_copy(struct intel_context *intel, const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); GLuint i; + GLboolean success; if (dst->compressed) { - GLuint alignment = intel_compressed_alignment(dst->internal_format); + GLuint align_w, align_h; + + intel_get_texture_alignment_unit(dst->internal_format, &align_w, &align_h); height = (height + 3) / 4; - width = ((width + alignment - 1) & ~(alignment - 1)); + width = ALIGN(width, align_w); } for (i = 0; i < depth; i++) { - intel_region_copy(intel, - dst->region, dst_offset + dst_depth_offset[i], - 0, - 0, - src->region, src_offset + src_depth_offset[i], - 0, 0, width, height); + success = intel_region_copy(intel, + dst->region, dst_offset + dst_depth_offset[i], + 0, 0, + src->region, src_offset + src_depth_offset[i], + 0, 0, width, height, GL_COPY); + if (!success) { + GLubyte *src_ptr, *dst_ptr; + + src_ptr = intel_region_map(intel, src->region); + dst_ptr = intel_region_map(intel, dst->region); + + _mesa_copy_rect(dst_ptr + dst_offset + dst_depth_offset[i], + dst->cpp, + dst->pitch, + 0, 0, width, height, + src_ptr + src_offset + src_depth_offset[i], + src->pitch, + 0, 0); + intel_region_unmap(intel, src->region); + intel_region_unmap(intel, dst->region); + } } - } diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 3af9966827f..c890b2a0d04 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -126,6 +126,7 @@ struct intel_mipmap_tree struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, GLenum target, + GLenum base_format, GLenum internal_format, GLuint first_level, GLuint last_level, @@ -195,6 +196,11 @@ void intel_miptree_set_level_info(struct intel_mipmap_tree *mt, GLuint x, GLuint y, GLuint w, GLuint h, GLuint d); +void intel_miptree_set_image_offset_ex(struct intel_mipmap_tree *mt, + GLuint level, + GLuint img, GLuint x, GLuint y, + GLuint offset); + void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, GLuint level, GLuint img, GLuint x, GLuint y); diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index 36a684b3b85..a3001416559 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -177,246 +177,6 @@ intel_check_blit_format(struct intel_region * region, } void -intel_meta_set_passthrough_transform(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - intel->meta.saved_vp_x = ctx->Viewport.X; - intel->meta.saved_vp_y = ctx->Viewport.Y; - intel->meta.saved_vp_width = ctx->Viewport.Width; - intel->meta.saved_vp_height = ctx->Viewport.Height; - intel->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - - intel->internal_viewport_call = GL_TRUE; - _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - intel->internal_viewport_call = GL_FALSE; - - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); - _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); -} - -void -intel_meta_restore_transform(struct intel_context *intel) -{ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PopMatrix(); - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PopMatrix(); - - _mesa_MatrixMode(intel->meta.saved_matrix_mode); - - intel->internal_viewport_call = GL_TRUE; - _mesa_Viewport(intel->meta.saved_vp_x, intel->meta.saved_vp_y, - intel->meta.saved_vp_width, intel->meta.saved_vp_height); - intel->internal_viewport_call = GL_FALSE; -} - -/** - * Set up a vertex program to pass through the position and first texcoord - * for pixel path. - */ -void -intel_meta_set_passthrough_vertex_program(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - static const char *vp = - "!!ARBvp1.0\n" - "TEMP vertexClip;\n" - "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n" - "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n" - "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n" - "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n" - "MOV result.position, vertexClip;\n" - "MOV result.texcoord[0], vertex.texcoord[0];\n" - "MOV result.color, vertex.color;\n" - "END\n"; - - assert(intel->meta.saved_vp == NULL); - - _mesa_reference_vertprog(ctx, &intel->meta.saved_vp, - ctx->VertexProgram.Current); - if (intel->meta.passthrough_vp == NULL) { - GLuint prog_name; - _mesa_GenPrograms(1, &prog_name); - _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name); - _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(vp), (const GLubyte *)vp); - _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, - ctx->VertexProgram.Current); - _mesa_DeletePrograms(1, &prog_name); - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, - intel->meta.passthrough_vp); - ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, - &intel->meta.passthrough_vp->Base); - - intel->meta.saved_vp_enable = ctx->VertexProgram.Enabled; - _mesa_Enable(GL_VERTEX_PROGRAM_ARB); -} - -/** - * Restores the previous vertex program after - * intel_meta_set_passthrough_vertex_program() - */ -void -intel_meta_restore_vertex_program(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, - intel->meta.saved_vp); - _mesa_reference_vertprog(ctx, &intel->meta.saved_vp, NULL); - ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, - &ctx->VertexProgram.Current->Base); - - if (!intel->meta.saved_vp_enable) - _mesa_Disable(GL_VERTEX_PROGRAM_ARB); -} - -/** - * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the - * program object. - */ -void -intel_meta_set_fragment_program(struct intel_context *intel, - struct gl_fragment_program **prog, - const char *prog_string) -{ - GLcontext *ctx = &intel->ctx; - assert(intel->meta.saved_fp == NULL); - - _mesa_reference_fragprog(ctx, &intel->meta.saved_fp, - ctx->FragmentProgram.Current); - if (*prog == NULL) { - GLuint prog_name; - _mesa_GenPrograms(1, &prog_name); - _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name); - _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, - GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(prog_string), (const GLubyte *)prog_string); - _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current); - /* Note that DeletePrograms unbinds the program on us */ - _mesa_DeletePrograms(1, &prog_name); - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog); - ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base)); - - intel->meta.saved_fp_enable = ctx->FragmentProgram.Enabled; - _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); -} - -/** - * Restores the previous fragment program after - * intel_meta_set_fragment_program() - */ -void -intel_meta_restore_fragment_program(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, - intel->meta.saved_fp); - _mesa_reference_fragprog(ctx, &intel->meta.saved_fp, NULL); - ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, - &ctx->FragmentProgram.Current->Base); - - if (!intel->meta.saved_fp_enable) - _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); -} - -static const float default_texcoords[4][2] = { { 0.0, 0.0 }, - { 1.0, 0.0 }, - { 1.0, 1.0 }, - { 0.0, 1.0 } }; - -void -intel_meta_set_default_texrect(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - struct gl_client_array *old_texcoord_array; - - intel->meta.saved_active_texture = ctx->Texture.CurrentUnit; - if (intel->meta.saved_array_vbo == NULL) { - _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, - ctx->Array.ArrayBufferObj); - } - - old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; - intel->meta.saved_texcoord_type = old_texcoord_array->Type; - intel->meta.saved_texcoord_size = old_texcoord_array->Size; - intel->meta.saved_texcoord_stride = old_texcoord_array->Stride; - intel->meta.saved_texcoord_enable = old_texcoord_array->Enabled; - intel->meta.saved_texcoord_ptr = old_texcoord_array->Ptr; - _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, - old_texcoord_array->BufferObj); - - _mesa_ClientActiveTextureARB(GL_TEXTURE0); - - if (intel->meta.texcoord_vbo == NULL) { - GLuint vbo_name; - - _mesa_GenBuffersARB(1, &vbo_name); - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); - _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), - default_texcoords, GL_STATIC_DRAW_ARB); - _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, - ctx->Array.ArrayBufferObj); - } else { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, - intel->meta.texcoord_vbo->Name); - } - _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); - - _mesa_Enable(GL_TEXTURE_COORD_ARRAY); -} - -void -intel_meta_restore_texcoords(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - /* Restore the old TexCoordPointer */ - if (intel->meta.saved_texcoord_vbo) { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, - intel->meta.saved_texcoord_vbo->Name); - _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, NULL); - } else { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - } - - _mesa_TexCoordPointer(intel->meta.saved_texcoord_size, - intel->meta.saved_texcoord_type, - intel->meta.saved_texcoord_stride, - intel->meta.saved_texcoord_ptr); - if (!intel->meta.saved_texcoord_enable) - _mesa_Disable(GL_TEXTURE_COORD_ARRAY); - - _mesa_ClientActiveTextureARB(GL_TEXTURE0 + - intel->meta.saved_active_texture); - - if (intel->meta.saved_array_vbo) { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, - intel->meta.saved_array_vbo->Name); - _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, NULL); - } else { - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - } -} - -void intelInitPixelFuncs(struct dd_function_table *functions) { functions->Accum = _swrast_Accum; @@ -424,20 +184,7 @@ intelInitPixelFuncs(struct dd_function_table *functions) functions->Bitmap = intelBitmap; functions->CopyPixels = intelCopyPixels; functions->DrawPixels = intelDrawPixels; -#ifdef I915 - functions->ReadPixels = intelReadPixels; -#endif } -} - -void -intel_free_pixel_state(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, NULL); - _mesa_reference_fragprog(ctx, &intel->meta.bitmap_fp, NULL); - _mesa_reference_fragprog(ctx, &intel->meta.tex2d_fp, NULL); - _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, NULL); + functions->ReadPixels = intelReadPixels; } diff --git a/src/mesa/drivers/dri/intel/intel_pixel.h b/src/mesa/drivers/dri/intel/intel_pixel.h index 6acf0813c8c..96a6dd17b25 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.h +++ b/src/mesa/drivers/dri/intel/intel_pixel.h @@ -31,19 +31,6 @@ #include "main/mtypes.h" void intelInitPixelFuncs(struct dd_function_table *functions); -void intel_meta_set_passthrough_transform(struct intel_context *intel); -void intel_meta_restore_transform(struct intel_context *intel); -void intel_meta_set_passthrough_vertex_program(struct intel_context *intel); -void intel_meta_restore_vertex_program(struct intel_context *intel); -void intel_meta_set_fragment_program(struct intel_context *intel, - struct gl_fragment_program **prog, - const char *prog_string); -void intel_meta_restore_fragment_program(struct intel_context *intel); -void intel_free_pixel_state(struct intel_context *intel); -void intel_meta_set_default_texrect(struct intel_context *intel); -void intel_meta_set_default_texrect(struct intel_context *intel); -void intel_meta_restore_texcoords(struct intel_context *intel); - GLboolean intel_check_blit_fragment_ops(GLcontext * ctx, GLboolean src_alpha_is_one); @@ -79,6 +66,4 @@ void intelBitmap(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, const GLubyte * pixels); -void intel_clear_tris(GLcontext *ctx, GLbitfield mask); - #endif diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 80d3239189c..540e7620a9d 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -42,6 +42,7 @@ #include "main/varray.h" #include "main/attrib.h" #include "main/enable.h" +#include "main/viewport.h" #include "shader/arbprogram.h" #include "glapi/dispatch.h" #include "swrast/swrast.h" @@ -194,7 +195,7 @@ do_blit_bitmap( GLcontext *ctx, struct gl_framebuffer *fb = ctx->DrawBuffer; GLfloat tmpColor[4]; GLubyte ubcolor[4]; - GLuint color8888, color565; + GLuint color; unsigned int num_cliprects; drm_clip_rect_t *cliprects; int x_off, y_off; @@ -232,8 +233,11 @@ do_blit_bitmap( GLcontext *ctx, UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]); UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]); - color8888 = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], ubcolor[2], ubcolor[3]); - color565 = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]); + if (dst->cpp == 2) + color = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]); + else + color = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1], + ubcolor[2], ubcolor[3]); if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F)) return GL_FALSE; @@ -307,21 +311,21 @@ do_blit_bitmap( GLcontext *ctx, fb->Name == 0 ? GL_TRUE : GL_FALSE) == 0) continue; - /* - */ - intelEmitImmediateColorExpandBlit( intel, - dst->cpp, - (GLubyte *)stipple, - sz, - (dst->cpp == 2) ? color565 : color8888, - dst->pitch, - dst->buffer, - 0, - dst->tiling, - box_x + px, - box_y + py, - w, h, - logic_op); + if (!intelEmitImmediateColorExpandBlit(intel, + dst->cpp, + (GLubyte *)stipple, + sz, + color, + dst->pitch, + dst->buffer, + 0, + dst->tiling, + box_x + px, + box_y + py, + w, h, + logic_op)) { + return GL_FALSE; + } } } } @@ -408,6 +412,12 @@ intel_texture_bitmap(GLcontext * ctx, return GL_FALSE; } + if (ctx->Fog.Enabled) { + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "glBitmap() fallback: fog\n"); + return GL_FALSE; + } + /* Check that we can load in a texture this big. */ if (width > (1 << (ctx->Const.MaxTextureLevels - 1)) || height > (1 << (ctx->Const.MaxTextureLevels - 1))) { @@ -466,15 +476,18 @@ intel_texture_bitmap(GLcontext * ctx, GL_ALPHA, GL_UNSIGNED_BYTE, a8_bitmap); _mesa_free(a8_bitmap); - intel_meta_set_fragment_program(intel, &intel->meta.bitmap_fp, fp); + meta_set_fragment_program(&intel->meta, &intel->meta.bitmap_fp, fp); _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, ctx->Current.RasterColor); - intel_meta_set_passthrough_vertex_program(intel); - intel_meta_set_passthrough_transform(intel); + meta_set_passthrough_vertex_program(&intel->meta); + meta_set_passthrough_transform(&intel->meta); /* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */ dst_z = -1.0 + 2.0 * ctx->Current.RasterPos[2]; + /* RasterPos[2] already takes into account the DepthRange mapping. */ + _mesa_DepthRange(0.0, 1.0); + vertices[0][0] = dst_x; vertices[0][1] = dst_y; vertices[0][2] = dst_z; @@ -494,13 +507,13 @@ intel_texture_bitmap(GLcontext * ctx, _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); - intel_meta_set_default_texrect(intel); - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + meta_set_default_texrect(&intel->meta); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - intel_meta_restore_texcoords(intel); - intel_meta_restore_transform(intel); - intel_meta_restore_fragment_program(intel); - intel_meta_restore_vertex_program(intel); + meta_restore_texcoords(&intel->meta); + meta_restore_transform(&intel->meta); + meta_restore_fragment_program(&intel->meta); + meta_restore_vertex_program(&intel->meta); _mesa_PopClientAttrib(); _mesa_Disable(GL_TEXTURE_2D); /* asserted that it was disabled at entry */ diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index d50dd68092d..5d52335dee3 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -272,6 +272,12 @@ do_blit_copypixels(GLcontext * ctx, drm_clip_rect_t *cliprects; int x_off, y_off; + if (type == GL_DEPTH || type == GL_STENCIL) { + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "glCopyPixels() fallback: GL_DEPTH || GL_STENCIL\n"); + return GL_FALSE; + } + /* Update draw buffer bounds */ _mesa_update_state(ctx); @@ -362,14 +368,16 @@ do_blit_copypixels(GLcontext * ctx, &clip_x, &clip_y, &clip_w, &clip_h)) continue; - intelEmitCopyBlit(intel, dst->cpp, - src->pitch, src->buffer, 0, src->tiling, - dst->pitch, dst->buffer, 0, dst->tiling, - clip_x + delta_x, clip_y + delta_y, /* srcx, srcy */ - clip_x, clip_y, /* dstx, dsty */ - clip_w, clip_h, - ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY); + if (!intel_region_copy(intel, + dst, 0, clip_x, clip_y, + src, 0, clip_x + delta_x, clip_y + delta_y, + clip_w, clip_h, + ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY)) { + DBG("%s: blit failure\n", __FUNCTION__); + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } } } out: diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index 46d27f1a93a..a6b6824164a 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -45,6 +45,7 @@ #include "main/depth.h" #include "main/hash.h" #include "main/blend.h" +#include "main/viewport.h" #include "glapi/dispatch.h" #include "swrast/swrast.h" @@ -128,7 +129,7 @@ intel_texture_drawpixels(GLcontext * ctx, } _mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | - GL_CURRENT_BIT); + GL_CURRENT_BIT | GL_VIEWPORT_BIT); _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); /* XXX: pixel store stuff */ @@ -149,11 +150,14 @@ intel_texture_drawpixels(GLcontext * ctx, _mesa_TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, pixels); - intel_meta_set_passthrough_transform(intel); + meta_set_passthrough_transform(&intel->meta); /* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */ z = -1.0 + 2.0 * ctx->Current.RasterPos[2]; + /* RasterPos[2] already takes into account the DepthRange mapping. */ + _mesa_DepthRange(0.0, 1.0); + /* Create the vertex buffer based on the current raster pos. The x and y * we're handed are ctx->Current.RasterPos[0,1] rounded to integers. * We also apply the depth. However, the W component is already multiplied @@ -178,12 +182,12 @@ intel_texture_drawpixels(GLcontext * ctx, _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); - intel_meta_set_default_texrect(intel); + meta_set_default_texrect(&intel->meta); - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - intel_meta_restore_texcoords(intel); - intel_meta_restore_transform(intel); + meta_restore_texcoords(&intel->meta); + meta_restore_transform(&intel->meta); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); _mesa_PopClientAttrib(); @@ -211,8 +215,9 @@ intel_stencil_drawpixels(GLcontext * ctx, struct gl_renderbuffer *rb; struct gl_pixelstore_attrib old_unpack; GLstencil *stencil_pixels; - int row; + int row, y1, y2; GLint old_active_texture; + GLboolean rendering_to_fbo = ctx->DrawBuffer->Name != 0; if (format != GL_STENCIL_INDEX) return GL_FALSE; @@ -347,24 +352,35 @@ intel_stencil_drawpixels(GLcontext * ctx, ctx->Unpack = old_unpack; _mesa_free(stencil_pixels); - intel_meta_set_passthrough_transform(intel); + meta_set_passthrough_transform(&intel->meta); + + /* Since we're rendering to the framebuffer as if it was an FBO, + * if it's the window system we have to flip the coordinates. + */ + if (rendering_to_fbo) { + y1 = y; + y2 = y + height * ctx->Pixel.ZoomY; + } else { + y1 = irb->Base.Height - (y + height * ctx->Pixel.ZoomY); + y2 = irb->Base.Height - y; + } vertices[0][0] = x; - vertices[0][1] = y; + vertices[0][1] = y1; vertices[1][0] = x + width * ctx->Pixel.ZoomX; - vertices[1][1] = y; + vertices[1][1] = y1; vertices[2][0] = x + width * ctx->Pixel.ZoomX; - vertices[2][1] = y + height * ctx->Pixel.ZoomY; + vertices[2][1] = y2; vertices[3][0] = x; - vertices[3][1] = y + height * ctx->Pixel.ZoomY; + vertices[3][1] = y2; _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); _mesa_Enable(GL_VERTEX_ARRAY); - intel_meta_set_default_texrect(intel); + meta_set_default_texrect(&intel->meta); - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - intel_meta_restore_texcoords(intel); - intel_meta_restore_transform(intel); + meta_restore_texcoords(&intel->meta); + meta_restore_transform(&intel->meta); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fb_name); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c new file mode 100644 index 00000000000..8713463ace2 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c @@ -0,0 +1,324 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#include "main/glheader.h" +#include "main/enums.h" +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/image.h" +#include "main/bufferobj.h" +#include "main/state.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "intel_buffer_objects.h" + +/* For many applications, the new ability to pull the source buffers + * back out of the GTT and then do the packing/conversion operations + * in software will be as much of an improvement as trying to get the + * blitter and/or texture engine to do the work. + * + * This step is gated on private backbuffers. + * + * Obviously the frontbuffer can't be pulled back, so that is either + * an argument for blit/texture readpixels, or for blitting to a + * temporary and then pulling that back. + * + * When the destination is a pbo, however, it's not clear if it is + * ever going to be pulled to main memory (though the access param + * will be a good hint). So it sounds like we do want to be able to + * choose between blit/texture implementation on the gpu and pullback + * and cpu-based copying. + * + * Unless you can magically turn client memory into a PBO for the + * duration of this call, there will be a cpu-based copying step in + * any case. + */ + + +static GLboolean +do_texture_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + struct intel_region *dest_region) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + intelScreenPrivate *screen = intel->intelScreen; + GLint pitch = pack->RowLength ? pack->RowLength : width; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int textureFormat; + GLenum glTextureFormat; + int destFormat, depthFormat, destPitch; + drm_clip_rect_t tmp; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if (ctx->_ImageTransferState || + pack->SwapBytes || pack->LsbFirst || !pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); + + if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: couldn't set dest %s/%s\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(type), + _mesa_lookup_enum_by_nr(format)); + return GL_FALSE; + } + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + intel->vtbl.install_meta_state(intel); + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + + if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { + UNLOCK_HARDWARE(intel); + SET_STATE(i830, state); + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); + return GL_TRUE; + } + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + /* Set the frontbuffer up as a large rectangular texture. + */ + intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); + + + intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); + + + /* Set the 3d engine to draw into the destination region: + */ + + intel->vtbl.meta_draw_region(intel, dest_region); + intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ + + + /* Draw a single quad, no cliprects: + */ + intel->vtbl.meta_disable_cliprects(intel); + + intel->vtbl.draw_quad(intel, + 0, width, 0, height, + 0x00ff00ff, x, x + width, y, y + height); + + intel->vtbl.leave_meta_state(intel); + } + UNLOCK_HARDWARE(intel); + + intel_region_wait_fence(ctx, dest_region); /* required by GL */ + return GL_TRUE; +#endif + + return GL_FALSE; +} + + + + +static GLboolean +do_blit_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *src = intel_readbuf_region(intel); + struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); + GLuint dst_offset; + GLuint rowLength; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s\n", __FUNCTION__); + + if (!src) + return GL_FALSE; + + if (pack->BufferObj->Name) { + /* XXX This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, pack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - not PBO\n", __FUNCTION__); + return GL_FALSE; + } + + + if (ctx->_ImageTransferState || + !intel_check_blit_format(src, format, type)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad format for blit\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: bad packing params\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->RowLength > 0) + rowLength = pack->RowLength; + else + rowLength = width; + + if (pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__); + return GL_FALSE; + } + else { + rowLength = -rowLength; + } + + /* XXX 64-bit cast? */ + dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, + format, type, 0, 0, 0); + + + /* Although the blits go on the command buffer, need to do this and + * fire with lock held to guarentee cliprects are correct. + */ + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + GLboolean all = (width * height * src->cpp == dst->Base.Size && + x == 0 && dst_offset == 0); + + dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + drm_clip_rect_t src_rect; + int i; + + src_rect.x1 = dPriv->x + x; + src_rect.y1 = dPriv->y + dPriv->h - (y + height); + src_rect.x2 = src_rect.x1 + width; + src_rect.y2 = src_rect.y1 + height; + + + + for (i = 0; i < nbox; i++) { + if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) + continue; + + if (!intelEmitCopyBlit(intel, + src->cpp, + src->pitch, src->buffer, 0, src->tiling, + rowLength, dst_buffer, dst_offset, GL_FALSE, + rect.x1, + rect.y1, + rect.x1 - src_rect.x1, + rect.y2 - src_rect.y2, + rect.x2 - rect.x1, rect.y2 - rect.y1, + GL_COPY)) { + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } + } + } + UNLOCK_HARDWARE(intel); + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - DONE\n", __FUNCTION__); + + return GL_TRUE; +} + +void +intelReadPixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush(ctx); + +#ifdef I915 + if (do_blit_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (do_texture_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; +#else + (void)do_blit_readpixels; + (void)do_texture_readpixels; +#endif + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + /* Update Mesa state before calling down into _swrast_ReadPixels, as + * the spans code requires the computed buffer states to be up to date, + * but _swrast_ReadPixels only updates Mesa state after setting up + * the spans code. + */ + + if (ctx->NewState) + _mesa_update_state(ctx); + + _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); +} diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 49bcb3c1ddd..7525cd9c4d7 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -111,12 +111,15 @@ debug_backtrace(void) GLubyte * intel_region_map(struct intel_context *intel, struct intel_region *region) { + intelFlush(&intel->ctx); + _DBG("%s %p\n", __FUNCTION__, region); if (!region->map_refcount++) { if (region->pbo) intel_region_cow(intel, region); - if (intel->intelScreen->kernel_exec_fencing) + if (region->tiling != I915_TILING_NONE && + intel->intelScreen->kernel_exec_fencing) drm_intel_gem_bo_map_gtt(region->buffer); else dri_bo_map(region->buffer, GL_TRUE); @@ -131,7 +134,8 @@ intel_region_unmap(struct intel_context *intel, struct intel_region *region) { _DBG("%s %p\n", __FUNCTION__, region); if (!--region->map_refcount) { - if (intel->intelScreen->kernel_exec_fencing) + if (region->tiling != I915_TILING_NONE && + intel->intelScreen->kernel_exec_fencing) drm_intel_gem_bo_unmap_gtt(region->buffer); else dri_bo_unmap(region->buffer); @@ -189,7 +193,7 @@ intel_region_alloc(struct intel_context *intel, pitch, buffer); if (tiling != I915_TILING_NONE) { - assert(((pitch * cpp) & 511) == 0); + assert(((pitch * cpp) & 127) == 0); drm_intel_bo_set_tiling(buffer, &tiling, pitch * cpp); drm_intel_bo_get_tiling(buffer, ®ion->tiling, ®ion->bit_6_swizzle); } @@ -323,8 +327,6 @@ intel_region_data(struct intel_context *intel, const void *src, GLuint src_pitch, GLuint srcx, GLuint srcy, GLuint width, GLuint height) { - GLboolean locked = GL_FALSE; - _DBG("%s\n", __FUNCTION__); if (intel == NULL) @@ -338,39 +340,33 @@ intel_region_data(struct intel_context *intel, intel_region_cow(intel, dst); } - if (!intel->locked) { - LOCK_HARDWARE(intel); - locked = GL_TRUE; - } - + LOCK_HARDWARE(intel); _mesa_copy_rect(intel_region_map(intel, dst) + dst_offset, dst->cpp, dst->pitch, dstx, dsty, width, height, src, src_pitch, srcx, srcy); intel_region_unmap(intel, dst); - - if (locked) - UNLOCK_HARDWARE(intel); - + UNLOCK_HARDWARE(intel); } /* Copy rectangular sub-regions. Need better logic about when to * push buffers into AGP - will currently do so whenever possible. */ -void +GLboolean intel_region_copy(struct intel_context *intel, struct intel_region *dst, GLuint dst_offset, GLuint dstx, GLuint dsty, struct intel_region *src, GLuint src_offset, - GLuint srcx, GLuint srcy, GLuint width, GLuint height) + GLuint srcx, GLuint srcy, GLuint width, GLuint height, + GLenum logicop) { _DBG("%s\n", __FUNCTION__); if (intel == NULL) - return; + return GL_FALSE; if (dst->pbo) { if (dstx == 0 && @@ -382,41 +378,12 @@ intel_region_copy(struct intel_context *intel, assert(src->cpp == dst->cpp); - intelEmitCopyBlit(intel, - dst->cpp, - src->pitch, src->buffer, src_offset, src->tiling, - dst->pitch, dst->buffer, dst_offset, dst->tiling, - srcx, srcy, dstx, dsty, width, height, - GL_COPY); -} - -/* Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -void -intel_region_fill(struct intel_context *intel, - struct intel_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - GLuint width, GLuint height, GLuint color) -{ - _DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - if (dst->pbo) { - if (dstx == 0 && - dsty == 0 && width == dst->pitch && height == dst->height) - intel_region_release_pbo(intel, dst); - else - intel_region_cow(intel, dst); - } - - intelEmitFillBlit(intel, - dst->cpp, - dst->pitch, dst->buffer, dst_offset, dst->tiling, - dstx, dsty, width, height, color); + return intelEmitCopyBlit(intel, + dst->cpp, + src->pitch, src->buffer, src_offset, src->tiling, + dst->pitch, dst->buffer, dst_offset, dst->tiling, + srcx, srcy, dstx, dsty, width, height, + logicop); } /* Attach to a pbo, discarding our data. Effectively zero-copy upload @@ -427,6 +394,8 @@ intel_region_attach_pbo(struct intel_context *intel, struct intel_region *region, struct intel_buffer_object *pbo) { + dri_bo *buffer; + if (region->pbo == pbo) return; @@ -447,10 +416,13 @@ intel_region_attach_pbo(struct intel_context *intel, region->buffer = NULL; } + /* make sure pbo has a buffer of its own */ + buffer = intel_bufferobj_buffer(intel, pbo, INTEL_WRITE_FULL); + region->pbo = pbo; region->pbo->region = region; - dri_bo_reference(pbo->buffer); - region->buffer = pbo->buffer; + dri_bo_reference(buffer); + region->buffer = buffer; } @@ -480,10 +452,6 @@ void intel_region_cow(struct intel_context *intel, struct intel_region *region) { struct intel_buffer_object *pbo = region->pbo; - GLboolean was_locked = intel->locked; - - if (intel == NULL) - return; intel_region_release_pbo(intel, region); @@ -494,20 +462,15 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region) /* Now blit from the texture buffer to the new buffer: */ - was_locked = intel->locked; - if (!was_locked) - LOCK_HARDWARE(intel); - - intelEmitCopyBlit(intel, - region->cpp, - region->pitch, region->buffer, 0, region->tiling, - region->pitch, pbo->buffer, 0, region->tiling, - 0, 0, 0, 0, - region->pitch, region->height, - GL_COPY); - - if (!was_locked) - UNLOCK_HARDWARE(intel); + LOCK_HARDWARE(intel); + assert(intelEmitCopyBlit(intel, + region->cpp, + region->pitch, pbo->buffer, 0, region->tiling, + region->pitch, region->buffer, 0, region->tiling, + 0, 0, 0, 0, + region->pitch, region->height, + GL_COPY)); + UNLOCK_HARDWARE(intel); } dri_bo * diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index bd3c8e7325b..0d379bdc6e2 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -110,21 +110,15 @@ void intel_region_data(struct intel_context *intel, /* Copy rectangular sub-regions */ -void intel_region_copy(struct intel_context *intel, - struct intel_region *dest, - GLuint dest_offset, - GLuint destx, GLuint desty, - struct intel_region *src, - GLuint src_offset, - GLuint srcx, GLuint srcy, GLuint width, GLuint height); - -/* Fill a rectangular sub-region - */ -void intel_region_fill(struct intel_context *intel, - struct intel_region *dest, - GLuint dest_offset, - GLuint destx, GLuint desty, - GLuint width, GLuint height, GLuint color); +GLboolean +intel_region_copy(struct intel_context *intel, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + struct intel_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height, + GLenum logicop); /* Helpers for zerocopy uploads, particularly texture image uploads: */ diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 8da96ede644..6bbc995c1e6 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -69,11 +69,7 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_DESC_END DRI_CONF_OPT_END -#ifdef I915 - DRI_CONF_TEXTURE_TILING(false) -#else - DRI_CONF_TEXTURE_TILING(true) -#endif + DRI_CONF_TEXTURE_TILING(false) DRI_CONF_OPT_BEGIN(early_z, bool, false) DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).") @@ -320,7 +316,7 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv) dri_bufmgr_destroy(intelScreen->bufmgr); intelUnmapScreenRegions(intelScreen); - driDestroyOptionCache(&intelScreen->optionCache); + driDestroyOptionInfo(&intelScreen->optionCache); FREE(intelScreen); sPriv->private = NULL; @@ -410,6 +406,30 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, static void intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) { + struct intel_framebuffer *intel_fb = driDrawPriv->driverPrivate; + struct intel_renderbuffer *depth_rb; + struct intel_renderbuffer *stencil_rb; + + if (intel_fb) { + if (intel_fb->color_rb[0]) { + intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL); + } + + if (intel_fb->color_rb[1]) { + intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL); + } + + depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + if (depth_rb) { + intel_renderbuffer_set_region(depth_rb, NULL); + } + + stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + if (stencil_rb) { + intel_renderbuffer_set_region(stencil_rb, NULL); + } + } + _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL); } @@ -578,7 +598,7 @@ intel_init_bufmgr(intelScreenPrivate *intelScreen) GLboolean gem_supported; struct drm_i915_getparam gp; __DRIscreenPrivate *spriv = intelScreen->driScrnPriv; - int num_fences; + int num_fences = 0; intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL; diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 260235b1eb1..028b49c14d3 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -73,11 +73,8 @@ get_teximage_source(struct intel_context *intel, GLenum internalFormat) return NULL; case GL_RGBA: case GL_RGBA8: - return intel_readbuf_region(intel); case GL_RGB: - if (intel->ctx.Visual.rgbBits == 16) - return intel_readbuf_region(intel); - return NULL; + return intel_readbuf_region(intel); default: return NULL; } @@ -99,14 +96,24 @@ do_copy_texsubimage(struct intel_context *intel, if (!intelImage->mt || !src) { if (INTEL_DEBUG & DEBUG_FALLBACKS) - fprintf(stderr, "%s fail %p %p\n", - __FUNCTION__, intelImage->mt, src); + fprintf(stderr, "%s fail %p %p (0x%08x)\n", + __FUNCTION__, intelImage->mt, src, internalFormat); + return GL_FALSE; + } + + if (intelImage->mt->cpp != src->cpp) { + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "%s fail %d vs %d cpp\n", + __FUNCTION__, intelImage->mt->cpp, src->cpp); return GL_FALSE; } intelFlush(ctx); LOCK_HARDWARE(intel); { + drm_intel_bo *dst_bo = intel_region_buffer(intel, + intelImage->mt->region, + INTEL_WRITE_PART); GLuint image_offset = intel_miptree_image_offset(intelImage->mt, intelImage->face, intelImage->level); @@ -144,18 +151,21 @@ do_copy_texsubimage(struct intel_context *intel, src_pitch = src->pitch; } - intelEmitCopyBlit(intel, - intelImage->mt->cpp, - src_pitch, - src->buffer, - 0, - src->tiling, - intelImage->mt->pitch, - intelImage->mt->region->buffer, - image_offset, - intelImage->mt->region->tiling, - x, y, dstx, dsty, width, height, - GL_COPY); + if (!intelEmitCopyBlit(intel, + intelImage->mt->cpp, + src_pitch, + src->buffer, + 0, + src->tiling, + intelImage->mt->pitch, + dst_bo, + image_offset, + intelImage->mt->region->tiling, + x, y, dstx, dsty, width, height, + GL_COPY)) { + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } } UNLOCK_HARDWARE(intel); diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index e9a3823078a..c5f52208376 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -131,6 +131,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel, comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat); intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, + intelImage->base._BaseFormat, intelImage->base.InternalFormat, firstLevel, lastLevel, @@ -205,7 +206,7 @@ try_pbo_upload(struct intel_context *intel, GLuint src_offset, src_stride; GLuint dst_offset, dst_stride; - if (!pbo || + if (unpack->BufferObj->Name == 0 || intel->ctx._ImageTransferState || unpack->SkipPixels || unpack->SkipRows) { DBG("%s: failure 1\n", __FUNCTION__); @@ -235,12 +236,15 @@ try_pbo_upload(struct intel_context *intel, INTEL_WRITE_FULL); - intelEmitCopyBlit(intel, - intelImage->mt->cpp, - src_stride, src_buffer, src_offset, GL_FALSE, - dst_stride, dst_buffer, dst_offset, GL_FALSE, - 0, 0, 0, 0, width, height, - GL_COPY); + if (!intelEmitCopyBlit(intel, + intelImage->mt->cpp, + src_stride, src_buffer, src_offset, GL_FALSE, + dst_stride, dst_buffer, dst_offset, GL_FALSE, + 0, 0, 0, 0, width, height, + GL_COPY)) { + UNLOCK_HARDWARE(intel); + return GL_FALSE; + } } UNLOCK_HARDWARE(intel); @@ -260,7 +264,7 @@ try_pbo_zcopy(struct intel_context *intel, GLuint src_offset, src_stride; GLuint dst_offset, dst_stride; - if (!pbo || + if (unpack->BufferObj->Name == 0 || intel->ctx._ImageTransferState || unpack->SkipPixels || unpack->SkipRows) { DBG("%s: failure 1\n", __FUNCTION__); @@ -409,7 +413,9 @@ intelTexImage(GLcontext * ctx, * a miptree, so create one just for our level and store it in the image. * It'll get moved into the object miptree at validate time. */ - intelImage->mt = intel_miptree_create(intel, target, internalFormat, + intelImage->mt = intel_miptree_create(intel, target, + intelImage->base.TexFormat->BaseFormat, + internalFormat, level, level, width, height, depth, intelImage->base.TexFormat->TexelBytes, @@ -421,7 +427,7 @@ intelTexImage(GLcontext * ctx, */ if (dims <= 2 && intelImage->mt && - intel_buffer_object(unpack->BufferObj) && + unpack->BufferObj->Name != 0 && check_pbo_format(internalFormat, format, type, intelImage->base.TexFormat)) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index 2c1b722b7f5..7d69ea4484a 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -35,28 +35,39 @@ #include "intel_context.h" #include "main/macros.h" -GLuint intel_compressed_alignment(GLenum internalFormat) +void intel_get_texture_alignment_unit(GLenum internalFormat, GLuint *w, GLuint *h) { - GLuint alignment = 4; - switch (internalFormat) { case GL_COMPRESSED_RGB_FXT1_3DFX: case GL_COMPRESSED_RGBA_FXT1_3DFX: - alignment = 8; + *w = 8; + *h = 4; + break; + + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + *w = 4; + *h = 4; break; default: + *w = 4; + *h = 2; break; } - - return alignment; } void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt, uint32_t tiling ) { - GLint align_h = 2, align_w = 4; + GLuint align_h = 2, align_w = 4; GLuint level; GLuint x = 0; GLuint y = 0; @@ -64,9 +75,9 @@ void i945_miptree_layout_2d( struct intel_context *intel, GLuint height = mt->height0; mt->pitch = mt->width0; + intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h); if (mt->compressed) { - align_w = intel_compressed_alignment(mt->internal_format); mt->pitch = ALIGN(mt->width0, align_w); } diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index 7bc25b6bcb1..c9de9b56784 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -41,4 +41,4 @@ static GLuint minify( GLuint d ) extern void i945_miptree_layout_2d(struct intel_context *intel, struct intel_mipmap_tree *mt, uint32_t tiling); -extern GLuint intel_compressed_alignment(GLenum); +extern void intel_get_texture_alignment_unit(GLenum, GLuint *, GLuint *); diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index b5cb7597d16..a284d5475f4 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -199,6 +199,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) if (!intelObj->mt) { intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, + firstImage->base._BaseFormat, firstImage->base.InternalFormat, intelObj->firstLevel, intelObj->lastLevel, diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c index 451dcd1b553..4ae7bf5b97d 100644 --- a/src/mesa/drivers/dri/r128/r128_state.c +++ b/src/mesa/drivers/dri/r128/r128_state.c @@ -771,6 +771,11 @@ static void r128DDLightModelfv( GLcontext *ctx, GLenum pname, FLUSH_BATCH( rmesa ); updateSpecularLighting(ctx); } + + if ( pname == GL_LIGHT_MODEL_TWO_SIDE ) { + FLUSH_BATCH( rmesa ); + r128ChooseRenderState( ctx ); + } } static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) diff --git a/src/mesa/drivers/dri/r128/r128_tris.c b/src/mesa/drivers/dri/r128/r128_tris.c index bcc9ffa651e..5b91271d740 100644 --- a/src/mesa/drivers/dri/r128/r128_tris.c +++ b/src/mesa/drivers/dri/r128/r128_tris.c @@ -426,7 +426,7 @@ r128_fallback_point( r128ContextPtr rmesa, #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) #define _R128_NEW_RENDER_STATE (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS) -static void r128ChooseRenderState(GLcontext *ctx) +void r128ChooseRenderState(GLcontext *ctx) { r128ContextPtr rmesa = R128_CONTEXT(ctx); GLuint flags = ctx->_TriangleCaps; diff --git a/src/mesa/drivers/dri/r128/r128_tris.h b/src/mesa/drivers/dri/r128/r128_tris.h index d90ca31534e..c0667edb61f 100644 --- a/src/mesa/drivers/dri/r128/r128_tris.h +++ b/src/mesa/drivers/dri/r128/r128_tris.h @@ -38,7 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/mtypes.h" extern void r128InitTriFuncs( GLcontext *ctx ); - +extern void r128ChooseRenderState( GLcontext *ctx ); extern void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); #define FALLBACK( rmesa, bit, mode ) r128Fallback( rmesa->glCtx, bit, mode ) diff --git a/src/mesa/drivers/dri/r200/.gitignore b/src/mesa/drivers/dri/r200/.gitignore index 3773d8ea73f..2f9cd1a987b 100644 --- a/src/mesa/drivers/dri/r200/.gitignore +++ b/src/mesa/drivers/dri/r200/.gitignore @@ -1,3 +1,15 @@ +radeon_bocs_wrapper.h +radeon_bo_legacy.[ch] radeon_chipset.h -radeon_screen.* +radeon_cmdbuf.h +radeon_common.[ch] +radeon_common_context.[ch] +radeon_cs_legacy.[ch] +radeon_dma.[ch] +radeon_fbo.c +radeon_lock.[ch] +radeon_mipmap_tree.[ch] +radeon_screen.[ch] +radeon_span.[ch] +radeon_texture.[ch] server diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 6a246edf7cb..4686241957b 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -13,6 +13,10 @@ ifeq ($(USING_EGL), 1) EGL_SOURCES = server/radeon_egl.c endif +ifeq ($(RADEON_LDFLAGS),) +CS_SOURCES = radeon_cs_space_drm.c +endif + RADEON_COMMON_SOURCES = \ radeon_texture.c \ radeon_common_context.c \ @@ -42,7 +46,8 @@ DRIVER_SOURCES = r200_context.c \ r200_vertprog.c \ radeon_screen.c \ $(EGL_SOURCES) \ - $(RADEON_COMMON_SOURCES) + $(RADEON_COMMON_SOURCES) \ + $(CS_SOURCES) C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) @@ -82,7 +87,8 @@ COMMON_SYMLINKS = \ radeon_texture.h \ radeon_dma.c \ radeon_dma.h \ - radeon_fbo.c + radeon_fbo.c \ + $(CS_SOURCES) DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c index df9dd83344c..25e30eda522 100644 --- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c +++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c @@ -225,6 +225,7 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, GLuint min_nr ) { GLushort *retval; + int ret; if (R200_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive); @@ -239,10 +240,11 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa, rmesa->radeon.tcl.elt_dma_offset = 0; rmesa->tcl.elt_used = min_nr * 2; - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.tcl.elt_dma_bo, - RADEON_GEM_DOMAIN_GTT, 0); - if (radeon_revalidate_bos(rmesa->radeon.glCtx) == GL_FALSE) + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.tcl.elt_dma_bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) { fprintf(stderr,"failure to revalidate BOs - badness\n"); + } radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1); retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset; diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 8924849d082..9a92a320797 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -357,6 +357,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, /* FIXME: When no memory manager is available we should set this * to some reasonable value based on texture memory pool size */ ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = 2048; ctx->Const.MaxTextureMaxAnisotropy = 16.0; @@ -388,6 +391,8 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, ctx->Const.MaxDrawBuffers = 1; + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 0b3398a730e..4dbda39eb95 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -58,11 +58,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_TIMEOUT 512 #define R200_IDLE_RETRY 16 -static void r200UserClear(GLcontext *ctx, GLuint mask) -{ - radeon_clear_tris(ctx, mask); -} - static void r200KernelClear(GLcontext *ctx, GLuint flags) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -196,7 +191,10 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) GLuint orig_mask = mask; if ( R200_DEBUG & DEBUG_IOCTL ) { - fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage); + if (rmesa->radeon.sarea) + fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage); + else + fprintf( stderr, "r200Clear %x radeon->sarea is NULL\n", mask); } { @@ -250,7 +248,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) } if (rmesa->radeon.radeonScreen->kernel_mm) - r200UserClear(ctx, orig_mask); + radeonUserClear(ctx, orig_mask); else { r200KernelClear(ctx, flags); rmesa->radeon.hw.all_dirty = GL_TRUE; diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index f8ebe0df57e..5a6fd20d8c2 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -574,6 +574,10 @@ static void r200FrontFace( GLcontext *ctx, GLenum mode ) R200_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_CULL_FRONT_IS_CCW; + /* Winding is inverted when rendering to FBO */ + if (ctx->DrawBuffer && ctx->DrawBuffer->Name) + mode = (mode == GL_CW) ? GL_CCW : GL_CW; + switch ( mode ) { case GL_CW: rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CW; @@ -709,14 +713,20 @@ static void r200ColorMask( GLcontext *ctx, GLboolean b, GLboolean a ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLuint mask = radeonPackColor( rmesa->radeon.radeonScreen->cpp, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP] ); - + GLuint mask; + struct radeon_renderbuffer *rrb; GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE; + rrb = radeon_get_colorbuffer(&rmesa->radeon); + if (!rrb) + return; + mask = radeonPackColor( rrb->cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] ); + + if (!(r && g && b && a)) flag |= R200_PLANE_MASK_ENABLE; @@ -1720,11 +1730,16 @@ static void r200ClearColor( GLcontext *ctx, const GLfloat c[4] ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); GLubyte color[4]; + struct radeon_renderbuffer *rrb; + + rrb = radeon_get_colorbuffer(&rmesa->radeon); + if (!rrb) + return; CLAMPED_FLOAT_TO_UBYTE(color[0], c[0]); CLAMPED_FLOAT_TO_UBYTE(color[1], c[1]); CLAMPED_FLOAT_TO_UBYTE(color[2], c[2]); CLAMPED_FLOAT_TO_UBYTE(color[3], c[3]); - rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp, + rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp, color[0], color[1], color[2], color[3] ); } @@ -2274,23 +2289,23 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx) { r200ContextPtr rmesa = R200_CONTEXT(ctx); struct radeon_renderbuffer *rrb; - int i; + int i, ret; - radeon_validate_reset_bos(&rmesa->radeon); + radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); rrb = radeon_get_colorbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); } /* depth buffer */ rrb = radeon_get_depthbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); } for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { @@ -2301,17 +2316,17 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx) t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); if (t->image_override && t->bo) - radeon_validate_bo(&rmesa->radeon, t->bo, + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); else if (t->mt->bo) - radeon_validate_bo(&rmesa->radeon, t->mt->bo, + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); } - if (rmesa->radeon.dma.current) - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); - - return radeon_revalidate_bos(ctx); + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + return GL_TRUE; } GLboolean r200ValidateState( GLcontext *ctx ) diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index 83920093378..bc871d99048 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -484,8 +484,17 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) atom->cmd[CTX_RB3D_CNTL] &= ~(0xf << 10); if (rrb->cpp == 4) atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB8888; - else + else switch (rrb->base._ActualFormat) { + case GL_RGB5: atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_RGB565; + break; + case GL_RGBA4: + atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB4444; + break; + case GL_RGB5_A1: + atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB1555; + break; + } cbpitch = (rrb->pitch / rrb->cpp); if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) @@ -585,6 +594,8 @@ static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) radeon_mipmap_level *lvl; int hastexture = 1; + if (!r200->state.texture.unit[i].unitneeded) + hastexture = 0; if (!t) hastexture = 0; else { @@ -620,6 +631,30 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom) { r200ContextPtr r200 = R200_CONTEXT(ctx); BATCH_LOCALS(&r200->radeon); + uint32_t dwords = 3; + int i = atom->idx, j; + radeonTexObj *t = r200->state.texture.unit[i].texobj; + radeon_mipmap_level *lvl; + + BEGIN_BATCH_NO_AUTOSTATE(dwords + (3 * 5)); + /* XXX that size won't really match with image_override... */ + OUT_BATCH_TABLE(atom->cmd, 2); + + if (t && !t->image_override) { + lvl = &t->mt->levels[0]; + OUT_BATCH_TABLE((atom->cmd + 2), 1); + for (j = 1; j <= 5; j++) { + OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset, + RADEON_GEM_DOMAIN_VRAM, 0, 0); + } + } + END_BATCH(); +} + +static void cube_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) +{ + r200ContextPtr r200 = R200_CONTEXT(ctx); + BATCH_LOCALS(&r200->radeon); uint32_t dwords = 2; int i = atom->idx, j; radeonTexObj *t = r200->state.texture.unit[i].texobj; @@ -752,7 +787,10 @@ void r200InitState( r200ContextPtr rmesa ) ALLOC_STATE( cube[4], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-4", 4 ); ALLOC_STATE( cube[5], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-5", 5 ); for (i = 0; i < 5; i++) - rmesa->hw.cube[i].emit = cube_emit; + if (rmesa->radeon.radeonScreen->kernel_mm) + rmesa->hw.cube[i].emit = cube_emit_cs; + else + rmesa->hw.cube[i].emit = cube_emit; } else { ALLOC_STATE( cube[0], never, CUBE_STATE_SIZE, "CUBE/tex-0", 0 ); diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c index ed1995e147c..4e53672aee2 100644 --- a/src/mesa/drivers/dri/r200/r200_texstate.c +++ b/src/mesa/drivers/dri/r200/r200_texstate.c @@ -834,7 +834,7 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo rImage->mt = NULL; } _mesa_init_teximage_fields(radeon->glCtx, target, texImage, - rb->width, rb->height, 1, 0, rb->cpp); + rb->base.Width, rb->base.Height, 1, 0, rb->cpp); texImage->RowStride = rb->pitch / rb->cpp; texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx, internalFormat, @@ -866,8 +866,8 @@ void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter; break; } - t->pp_txsize = ((rb->width - 1) << RADEON_TEX_USIZE_SHIFT) - | ((rb->height - 1) << RADEON_TEX_VSIZE_SHIFT); + t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT) + | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT); t->pp_txformat |= R200_TXFORMAT_NON_POWER2; t->pp_txpitch = pitch_val; t->pp_txpitch -= 32; diff --git a/src/mesa/drivers/dri/r300/.gitignore b/src/mesa/drivers/dri/r300/.gitignore index 3689a6a78e5..2f9cd1a987b 100644 --- a/src/mesa/drivers/dri/r300/.gitignore +++ b/src/mesa/drivers/dri/r300/.gitignore @@ -1,4 +1,15 @@ +radeon_bocs_wrapper.h +radeon_bo_legacy.[ch] radeon_chipset.h +radeon_cmdbuf.h +radeon_common.[ch] +radeon_common_context.[ch] +radeon_cs_legacy.[ch] +radeon_dma.[ch] +radeon_fbo.c +radeon_lock.[ch] +radeon_mipmap_tree.[ch] radeon_screen.[ch] -radeon_span.h +radeon_span.[ch] +radeon_texture.[ch] server diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index bdb09624be4..a77209074ae 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -13,6 +13,10 @@ ifeq ($(USING_EGL), 1) EGL_SOURCES = server/radeon_egl.c endif +ifeq ($(RADEON_LDFLAGS),) +CS_SOURCES = radeon_cs_space_drm.c +endif + COMMON_SOURCES = \ ../../common/driverfuncs.c \ ../common/mm.c \ @@ -59,7 +63,8 @@ DRIVER_SOURCES = \ r300_emit.c \ r300_swtcl.c \ $(RADEON_COMMON_SOURCES) \ - $(EGL_SOURCES) + $(EGL_SOURCES) \ + $(CS_SOURCES) C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) @@ -100,7 +105,8 @@ COMMON_SYMLINKS = \ radeon_mipmap_tree.h \ radeon_texture.c \ radeon_texture.h \ - radeon_fbo.c + radeon_fbo.c \ + $(CS_SOURCES) DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 0261a5b1d8a..af535037d06 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -232,8 +232,8 @@ void r300_emit_scissor(GLcontext *ctx) } else { x1 = 0; y1 = 0; - x2 = rrb->width - 1; - y2 = rrb->height - 1; + x2 = rrb->base.Width - 1; + y2 = rrb->base.Height - 1; } if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) { x1 += R300_SCISSORS_OFFSET; @@ -264,11 +264,22 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) return; } + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr,"rrb is %p %d %dx%d\n", rrb, offset, rrb->base.Width, rrb->base.Height); cbpitch = (rrb->pitch / rrb->cpp); if (rrb->cpp == 4) cbpitch |= R300_COLOR_FORMAT_ARGB8888; - else + else switch (rrb->base._ActualFormat) { + case GL_RGB5: cbpitch |= R300_COLOR_FORMAT_RGB565; + break; + case GL_RGBA4: + cbpitch |= R300_COLOR_FORMAT_ARGB4444; + break; + case GL_RGB5_A1: + cbpitch |= R300_COLOR_FORMAT_ARGB1555; + break; + } if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) cbpitch |= R300_COLOR_TILE_ENABLE; @@ -289,14 +300,14 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) BEGIN_BATCH_NO_AUTOSTATE(3); OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2); OUT_BATCH(0); - OUT_BATCH(((rrb->width - 1) << R300_SCISSORS_X_SHIFT) | - ((rrb->height - 1) << R300_SCISSORS_Y_SHIFT)); + OUT_BATCH(((rrb->base.Width - 1) << R300_SCISSORS_X_SHIFT) | + ((rrb->base.Height - 1) << R300_SCISSORS_Y_SHIFT)); END_BATCH(); BEGIN_BATCH_NO_AUTOSTATE(16); for (i = 0; i < 4; i++) { OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2); OUT_BATCH((0 << R300_CLIPRECT_X_SHIFT) | (0 << R300_CLIPRECT_Y_SHIFT)); - OUT_BATCH(((rrb->width - 1) << R300_CLIPRECT_X_SHIFT) | ((rrb->height - 1) << R300_CLIPRECT_Y_SHIFT)); + OUT_BATCH(((rrb->base.Width - 1) << R300_CLIPRECT_X_SHIFT) | ((rrb->base.Height - 1) << R300_CLIPRECT_Y_SHIFT)); } OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1); OUT_BATCH(0xAAAA); @@ -308,15 +319,15 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom) OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2); OUT_BATCH((R300_SCISSORS_OFFSET << R300_SCISSORS_X_SHIFT) | (R300_SCISSORS_OFFSET << R300_SCISSORS_Y_SHIFT)); - OUT_BATCH(((rrb->width + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_X_SHIFT) | - ((rrb->height + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_Y_SHIFT)); + OUT_BATCH(((rrb->base.Width + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_X_SHIFT) | + ((rrb->base.Height + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_Y_SHIFT)); END_BATCH(); BEGIN_BATCH_NO_AUTOSTATE(16); for (i = 0; i < 4; i++) { OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2); OUT_BATCH((R300_SCISSORS_OFFSET << R300_CLIPRECT_X_SHIFT) | (R300_SCISSORS_OFFSET << R300_CLIPRECT_Y_SHIFT)); - OUT_BATCH(((R300_SCISSORS_OFFSET + rrb->width - 1) << R300_CLIPRECT_X_SHIFT) | - ((R300_SCISSORS_OFFSET + rrb->height - 1) << R300_CLIPRECT_Y_SHIFT)); + OUT_BATCH(((R300_SCISSORS_OFFSET + rrb->base.Width - 1) << R300_CLIPRECT_X_SHIFT) | + ((R300_SCISSORS_OFFSET + rrb->base.Height - 1) << R300_CLIPRECT_Y_SHIFT)); } OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1); OUT_BATCH(0xAAAA); @@ -333,23 +344,33 @@ static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom) BATCH_LOCALS(&r300->radeon); struct radeon_renderbuffer *rrb; uint32_t zbpitch; + uint32_t dw; rrb = radeon_get_depthbuffer(&r300->radeon); if (!rrb) return; zbpitch = (rrb->pitch / rrb->cpp); - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - zbpitch |= R300_DEPTHMACROTILE_ENABLE; - } - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ - zbpitch |= R300_DEPTHMICROTILE_TILED; + if (!r300->radeon.radeonScreen->kernel_mm) { + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { + zbpitch |= R300_DEPTHMACROTILE_ENABLE; + } + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ + zbpitch |= R300_DEPTHMICROTILE_TILED; + } } - BEGIN_BATCH_NO_AUTOSTATE(6); + dw = 6; + if (r300->radeon.radeonScreen->kernel_mm) + dw += 2; + BEGIN_BATCH_NO_AUTOSTATE(dw); OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1); OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); - OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, zbpitch); + OUT_BATCH_REGSEQ(R300_ZB_DEPTHPITCH, 1); + if (!r300->radeon.radeonScreen->kernel_mm) + OUT_BATCH(zbpitch); + else + OUT_BATCH_RELOC(cbpitch, rrb->bo, zbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0); END_BATCH(); } @@ -503,7 +524,7 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_STATE_FLUSH_REG, 1); r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH_1] = 0; r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_CNTL, 1); - if (is_r500) { + if (is_r500 && !r300->radeon.radeonScreen->kernel_mm) { ALLOC_STATE(vap_index_offset, always, 2, 0); r300->hw.vap_index_offset.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_VAP_INDEX_OFFSET, 1); r300->hw.vap_index_offset.cmd[1] = 0; diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 394521a051f..6f3aab986d2 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -124,6 +124,7 @@ const struct dri_extension card_extensions[] = { {"GL_EXT_texture_lod_bias", NULL}, {"GL_EXT_texture_mirror_clamp", NULL}, {"GL_EXT_texture_rectangle", NULL}, + {"GL_EXT_texture_sRGB", NULL}, {"GL_EXT_vertex_array_bgra", NULL}, {"GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions}, {"GL_ATI_texture_env_combine3", NULL}, @@ -269,10 +270,16 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) ctx->Const.MaxTextureMaxAnisotropy = 16.0; ctx->Const.MaxTextureLodBias = 16.0; - if (screen->chip_family >= CHIP_FAMILY_RV515) + if (screen->chip_family >= CHIP_FAMILY_RV515) { ctx->Const.MaxTextureLevels = 13; - else + ctx->Const.MaxCubeTextureLevels = 13; + ctx->Const.MaxTextureRectSize = 4096; + } + else { ctx->Const.MaxTextureLevels = 12; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = 2048; + } ctx->Const.MinPointSize = 1.0; ctx->Const.MinPointSizeAA = 1.0; @@ -409,6 +416,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, r300InitConstValues(ctx, screen); + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 026c33c67cb..f7af7d4e574 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -405,12 +405,13 @@ struct r300_hw_state { #undef TAG struct r300_vertex_program { + struct gl_vertex_program *Base; struct r300_vertex_program *next; struct r300_vertex_program_key { - GLuint InputsRead; - GLuint OutputsWritten; - GLuint OutputsAdded; + GLuint FpReads; + GLuint FogAttr; + GLuint WPosAttr; } key; struct r300_vertex_shader_hw_code { @@ -426,13 +427,17 @@ struct r300_vertex_program { int pos_end; int num_temporaries; /* Number of temp vars used by program */ - int wpos_idx; int inputs[VERT_ATTRIB_MAX]; int outputs[VERT_RESULT_MAX]; }; struct r300_vertex_program_cont { - struct gl_vertex_program mesa_program; /* Must be first */ + /* This is the unmodified vertex program mesa provided us with. + * We need to keep it unchanged because we may need to create another + * hw specific vertex program based on this. + */ + struct gl_vertex_program mesa_program; + /* This is the list of hw specific vertex programs derived from mesa_program */ struct r300_vertex_program *progs; }; @@ -546,7 +551,7 @@ struct r500_fragment_program_code { * to render with that program. */ struct r300_fragment_program { - struct gl_fragment_program Base; + struct gl_program *Base; GLboolean translated; GLboolean error; @@ -559,6 +564,23 @@ struct r300_fragment_program { GLboolean writes_depth; GLuint optimization; + + struct r300_fragment_program *next; + + /* attribute that we are sending the WPOS in */ + gl_frag_attrib wpos_attr; + /* attribute that we are sending the fog coordinate in */ + gl_frag_attrib fog_attr; +}; + +struct r300_fragment_program_cont { + /* This is the unmodified fragment program mesa provided us with. + * We need to keep it unchanged because we may need to create another + * hw specific fragment program based on this. + */ + struct gl_fragment_program Base; + /* This is the list of hw specific fragment programs derived from Base */ + struct r300_fragment_program *progs; }; struct r300_fragment_program_compiler { @@ -633,6 +655,7 @@ struct r300_context { struct r300_hw_state hw; struct r300_vertex_program *selected_vp; + struct r300_fragment_program *selected_fp; /* Vertex buffers */ @@ -664,11 +687,7 @@ extern GLboolean r300CreateContext(const __GLcontextModes * glVisual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); -extern void r300SelectVertexShader(r300ContextPtr r300); extern void r300InitShaderFuncs(struct dd_function_table *functions); -extern int r300VertexProgUpdateParams(GLcontext * ctx, - struct r300_vertex_program_cont *vp, - float *dst); extern void r300InitShaderFunctions(r300ContextPtr r300); diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c index cc5650fb7c8..9769ff53994 100644 --- a/src/mesa/drivers/dri/r300/r300_draw.c +++ b/src/mesa/drivers/dri/r300/r300_draw.c @@ -195,6 +195,11 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st } GLfloat *dst_ptr, *tmp; + + /* Convert value for first element only */ + if (input->StrideB == 0) + count = 1; + tmp = dst_ptr = _mesa_malloc(sizeof(GLfloat) * input->Size * count); switch (input->Type) { @@ -228,13 +233,17 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st type = GL_FLOAT; r300_attr.free_needed = GL_TRUE; r300_attr.data = tmp; - r300_attr.stride = sizeof(GLfloat) * input->Size; + if (input->StrideB == 0) { + r300_attr.stride = 0; + } else { + r300_attr.stride = sizeof(GLfloat) * input->Size; + } r300_attr.dwords = input->Size; } else { type = input->Type; r300_attr.free_needed = GL_FALSE; r300_attr.data = (GLvoid *)src_ptr; - r300_attr.stride = stride; + r300_attr.stride = input->StrideB; r300_attr.dwords = (getTypeSize(type) * input->Size + 3)/ 4; } @@ -332,7 +341,7 @@ static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *ar { int i, tmp; - tmp = r300->selected_vp->key.InputsRead; + tmp = r300->selected_vp->Base->Base.InputsRead; i = 0; vbuf->num_attribs = 0; while (tmp) { @@ -417,12 +426,18 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, r300FixupIndexBuffer(ctx, ib, bo, &nr_bo); + /* ensure we have the cmd buf space in advance to cover + * the state + DMA AOS pointers */ + rcommonEnsureCmdBufSpace(&r300->radeon, + r300->radeon.hw.max_state_size + (50*sizeof(int)), + __FUNCTION__); + r300SetVertexFormat(ctx, arrays, max_index + 1, bo, &nr_bo); if (r300->fallback) return GL_FALSE; - r300SetupVAP(ctx, r300->selected_vp->key.InputsRead, r300->selected_vp->key.OutputsWritten); + r300SetupVAP(ctx, r300->selected_vp->Base->Base.InputsRead, r300->selected_vp->Base->Base.OutputsWritten); r300UpdateShaderStates(r300); @@ -442,8 +457,6 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, return GL_TRUE; } -/* TODO: rebase if number of indices in any of primitives is > 8192 for 32bit indices or 16384 for 16bit indices */ - static void r300DrawPrims(GLcontext *ctx, const struct gl_client_array *arrays[], const struct _mesa_prim *prim, @@ -452,12 +465,25 @@ static void r300DrawPrims(GLcontext *ctx, GLuint min_index, GLuint max_index) { + struct split_limits limits; GLboolean retval; + if (ib) + limits.max_verts = 0xffffffff; + else + limits.max_verts = 65535; + + limits.max_indices = 65535; + limits.max_vb_size = 1024*1024; + if (min_index) { vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims ); return; } + if ((ib && ib->count > 65535)) { + vbo_split_prims (ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims, &limits); + return; + } /* Make an attempt at drawing */ retval = r300TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index c3817721dc4..feb3370f372 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -81,17 +81,17 @@ GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead) return vic_1; } -GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) +GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes) { GLuint ret = 0; if (vp_writes & (1 << VERT_RESULT_HPOS)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; - if (vp_writes & (1 << VERT_RESULT_COL0) && fp_reads & FRAG_BIT_COL0) + if (vp_writes & (1 << VERT_RESULT_COL0)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT; - if (vp_writes & (1 << VERT_RESULT_COL1) && fp_reads & FRAG_BIT_COL1) + if (vp_writes & (1 << VERT_RESULT_COL1)) ret |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT; /* Two sided lighting works only if all 4 colors are written */ @@ -105,26 +105,17 @@ GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) return ret; } -GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads) +GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes) { GLuint i, ret = 0, first_free_texcoord = 0; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (vp_writes & (1 << (VERT_RESULT_TEX0 + i)) && fp_reads & FRAG_BIT_TEX(i)) { + if (vp_writes & (1 << (VERT_RESULT_TEX0 + i))) { ret |= (4 << (3 * first_free_texcoord)); ++first_free_texcoord; } } - if (fp_reads & FRAG_BIT_WPOS) { - ret |= (4 << (3 * first_free_texcoord)); - ++first_free_texcoord; - } - - if (vp_writes & (1 << VERT_RESULT_FOGC) && fp_reads & FRAG_BIT_FOGC) { - ret |= 4 << (3 * first_free_texcoord); - } - if (first_free_texcoord > 8) { fprintf(stderr, "\tout of free texcoords\n"); _mesa_exit(-1); diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h index 2fb8b82d3a1..3f8c60ffae1 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h @@ -225,7 +225,7 @@ extern void r300EmitCacheFlush(r300ContextPtr rmesa); extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead); extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead); -extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads); -extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes, GLuint fp_reads); +extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint vp_writes); +extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes); #endif diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c index abc8757ba1f..f5c4c0f4a0e 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c @@ -50,13 +50,6 @@ #include "radeon_program.h" #include "radeon_program_alu.h" -static void update_params(GLcontext *ctx, struct gl_fragment_program *fp) -{ - /* Ask Mesa nicely to fill in ParameterValues for us */ - if (fp->Base.Parameters) - _mesa_load_state_parameters(ctx, fp->Base.Parameters); -} - static void nqssadce_init(struct nqssadce_state* s) { s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW; @@ -74,10 +67,12 @@ static void nqssadce_init(struct nqssadce_state* s) */ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) { - GLuint InputsRead = compiler->fp->Base.Base.InputsRead; + GLuint InputsRead = compiler->fp->Base->InputsRead; - if (!(InputsRead & FRAG_BIT_WPOS)) + if (!(InputsRead & FRAG_BIT_WPOS)) { + compiler->fp->wpos_attr = FRAG_ATTRIB_MAX; return; + } static gl_state_index tokens[STATE_LENGTH] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0 @@ -85,10 +80,23 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) struct prog_instruction *fpi; GLuint window_index; int i = 0; + + for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i) + { + if (!(InputsRead & (1 << i))) { + InputsRead &= ~(1 << FRAG_ATTRIB_WPOS); + InputsRead |= 1 << i; + compiler->fp->Base->InputsRead = InputsRead; + compiler->fp->wpos_attr = i; + break; + } + } + GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY); _mesa_insert_instructions(compiler->program, 0, 3); fpi = compiler->program->Instructions; + i = 0; /* perspective divide */ fpi[i].Opcode = OPCODE_RCP; @@ -99,7 +107,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) fpi[i].DstReg.CondMask = COND_TR; fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; + fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr; fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW; i++; @@ -111,7 +119,7 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) fpi[i].DstReg.CondMask = COND_TR; fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; + fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr; fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY; @@ -154,6 +162,57 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler) } } + +/** + * Rewrite fragment.fogcoord to use a texture coordinate slot. + * Note that fogcoord is forced into an X001 pattern, and this enforcement + * is done here. + * + * See also the counterpart rewriting for vertex programs. + */ +static void rewriteFog(struct r300_fragment_program_compiler *compiler) +{ + struct r300_fragment_program *fp = compiler->fp; + GLuint InputsRead; + int i; + + InputsRead = fp->Base->InputsRead; + + if (!(InputsRead & FRAG_BIT_FOGC)) { + fp->fog_attr = FRAG_ATTRIB_MAX; + return; + } + + for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i) + { + if (!(InputsRead & (1 << i))) { + InputsRead &= ~(1 << FRAG_ATTRIB_FOGC); + InputsRead |= 1 << i; + fp->Base->InputsRead = InputsRead; + fp->fog_attr = i; + break; + } + } + + { + struct prog_instruction *inst; + + inst = compiler->program->Instructions; + while (inst->Opcode != OPCODE_END) { + const int src_regs = _mesa_num_inst_src_regs(inst->Opcode); + for (i = 0; i < src_regs; ++i) { + if (inst->SrcReg[i].File == PROGRAM_INPUT && inst->SrcReg[i].Index == FRAG_ATTRIB_FOGC) { + inst->SrcReg[i].Index = fp->fog_attr; + inst->SrcReg[i].Swizzle = combine_swizzles( + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE), + inst->SrcReg[i].Swizzle); + } + } + ++inst; + } + } +} + static GLuint build_dtm(GLuint depthmode) { switch(depthmode) { @@ -175,7 +234,7 @@ static GLuint build_func(GLuint comparefunc) */ static void build_state( r300ContextPtr r300, - struct r300_fragment_program *fp, + struct gl_fragment_program *fp, struct r300_fragment_program_external_state *state) { int unit; @@ -183,7 +242,7 @@ static void build_state( _mesa_bzero(state, sizeof(*state)); for(unit = 0; unit < 16; ++unit) { - if (fp->Base.Base.ShadowSamplers & (1 << unit)) { + if (fp->Base.ShadowSamplers & (1 << unit)) { struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current; state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode); @@ -192,100 +251,149 @@ static void build_state( } } -void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp) +static void rewrite_depth_out(struct gl_program *prog) { - r300ContextPtr r300 = R300_CONTEXT(ctx); - struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)fp; - struct r300_fragment_program_external_state state; + struct prog_instruction *inst; - build_state(r300, r300_fp, &state); - if (_mesa_memcmp(&r300_fp->state, &state, sizeof(state))) { - /* TODO: cache compiled programs */ - r300_fp->translated = GL_FALSE; - _mesa_memcpy(&r300_fp->state, &state, sizeof(state)); - } - - if (!r300_fp->translated) { - struct r300_fragment_program_compiler compiler; + for (inst = prog->Instructions; inst->Opcode != OPCODE_END; ++inst) { + if (inst->DstReg.File != PROGRAM_OUTPUT || inst->DstReg.Index != FRAG_RESULT_DEPTH) + continue; - compiler.r300 = r300; - compiler.fp = r300_fp; - compiler.code = &r300_fp->code; - compiler.program = _mesa_clone_program(ctx, &fp->Base); + if (inst->DstReg.WriteMask & WRITEMASK_Z) { + inst->DstReg.WriteMask = WRITEMASK_W; + } else { + inst->DstReg.WriteMask = 0; + continue; + } - if (RADEON_DEBUG & DEBUG_PIXEL) { - fflush(stdout); - _mesa_printf("Fragment Program: Initial program:\n"); - _mesa_print_program(compiler.program); - fflush(stdout); + switch (inst->Opcode) { + case OPCODE_FRC: + case OPCODE_MOV: + inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]); + break; + case OPCODE_ADD: + case OPCODE_MAX: + case OPCODE_MIN: + case OPCODE_MUL: + inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]); + inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]); + break; + case OPCODE_CMP: + case OPCODE_MAD: + inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]); + inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]); + inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]); + break; + default: + // Scalar instructions needn't be reswizzled + break; } + } +} - insert_WPOS_trailer(&compiler); +void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_fragment_program_compiler compiler; + + compiler.r300 = r300; + compiler.fp = fp; + compiler.code = &fp->code; + compiler.program = fp->Base; + + if (RADEON_DEBUG & DEBUG_PIXEL) { + fflush(stdout); + _mesa_printf("Fragment Program: Initial program:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } - if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { - struct radeon_program_transformation transformations[] = { - { &r500_transform_TEX, &compiler }, - { &radeonTransformALU, 0 }, - { &radeonTransformDeriv, 0 }, - { &radeonTransformTrigScale, 0 } - }; - radeonLocalTransform(ctx, compiler.program, 4, transformations); - } else { - struct radeon_program_transformation transformations[] = { - { &r300_transform_TEX, &compiler }, - { &radeonTransformALU, 0 }, - { &radeonTransformTrigSimple, 0 } - }; - radeonLocalTransform(ctx, compiler.program, 3, transformations); - } + insert_WPOS_trailer(&compiler); + + rewriteFog(&compiler); + + rewrite_depth_out(compiler.program); + + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + struct radeon_program_transformation transformations[] = { + { &r500_transform_TEX, &compiler }, + { &radeonTransformALU, 0 }, + { &radeonTransformDeriv, 0 }, + { &radeonTransformTrigScale, 0 } + }; + radeonLocalTransform(ctx, compiler.program, 4, transformations); + } else { + struct radeon_program_transformation transformations[] = { + { &r300_transform_TEX, &compiler }, + { &radeonTransformALU, 0 }, + { &radeonTransformTrigSimple, 0 } + }; + radeonLocalTransform(ctx, compiler.program, 3, transformations); + } - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Fragment Program: After native rewrite:\n"); - _mesa_print_program(compiler.program); - fflush(stdout); - } + if (RADEON_DEBUG & DEBUG_PIXEL) { + _mesa_printf("Fragment Program: After native rewrite:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } - if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { - struct radeon_nqssadce_descr nqssadce = { - .Init = &nqssadce_init, - .IsNativeSwizzle = &r500FPIsNativeSwizzle, - .BuildSwizzle = &r500FPBuildSwizzle, - .RewriteDepthOut = GL_TRUE - }; - radeonNqssaDce(ctx, compiler.program, &nqssadce); - } else { - struct radeon_nqssadce_descr nqssadce = { - .Init = &nqssadce_init, - .IsNativeSwizzle = &r300FPIsNativeSwizzle, - .BuildSwizzle = &r300FPBuildSwizzle, - .RewriteDepthOut = GL_TRUE - }; - radeonNqssaDce(ctx, compiler.program, &nqssadce); - } + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + struct radeon_nqssadce_descr nqssadce = { + .Init = &nqssadce_init, + .IsNativeSwizzle = &r500FPIsNativeSwizzle, + .BuildSwizzle = &r500FPBuildSwizzle + }; + radeonNqssaDce(ctx, compiler.program, &nqssadce); + } else { + struct radeon_nqssadce_descr nqssadce = { + .Init = &nqssadce_init, + .IsNativeSwizzle = &r300FPIsNativeSwizzle, + .BuildSwizzle = &r300FPBuildSwizzle + }; + radeonNqssaDce(ctx, compiler.program, &nqssadce); + } - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Compiler: after NqSSA-DCE:\n"); - _mesa_print_program(compiler.program); - fflush(stdout); - } + if (RADEON_DEBUG & DEBUG_PIXEL) { + _mesa_printf("Compiler: after NqSSA-DCE:\n"); + _mesa_print_program(compiler.program); + fflush(stdout); + } - if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler)) - r300_fp->error = GL_TRUE; + if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler)) + fp->error = GL_TRUE; - /* Subtle: Rescue any parameters that have been added during transformations */ - _mesa_free_parameter_list(fp->Base.Parameters); - fp->Base.Parameters = compiler.program->Parameters; - compiler.program->Parameters = 0; + fp->translated = GL_TRUE; - _mesa_reference_program(ctx, &compiler.program, NULL); + if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) + r300->vtbl.FragmentProgramDump(&fp->code); +} - r300_fp->translated = GL_TRUE; +struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_fragment_program_cont *fp_list; + struct r300_fragment_program *fp; + struct r300_fragment_program_external_state state; - r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + fp_list = (struct r300_fragment_program_cont *)ctx->FragmentProgram._Current; + build_state(r300, ctx->FragmentProgram._Current, &state); - if (r300_fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) - r300->vtbl.FragmentProgramDump(&r300_fp->code); + fp = fp_list->progs; + while (fp) { + if (_mesa_memcmp(&fp->state, &state, sizeof(state)) == 0) { + return r300->selected_fp = fp; + } + fp = fp->next; } - update_params(ctx, fp); + fp = _mesa_calloc(sizeof(struct r300_fragment_program)); + + fp->state = state; + fp->translated = GL_FALSE; + fp->Base = _mesa_clone_program(ctx, &ctx->FragmentProgram._Current->Base); + + fp->next = fp_list->progs; + fp_list->progs = fp; + + return r300->selected_fp = fp; } diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.h b/src/mesa/drivers/dri/r300/r300_fragprog_common.h index 85ea86fecb1..5e103ee4086 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.h @@ -30,6 +30,10 @@ #include "main/mtypes.h" -extern void r300TranslateFragmentShader(GLcontext *ctx, struct gl_fragment_program *fp); +#include "r300_context.h" + +extern void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp); + +struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx); #endif diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 104079b4dbe..ddabd539925 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -68,11 +68,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static void r300EmitClearState(GLcontext * ctx); -static void r300UserClear(GLcontext *ctx, GLuint mask) -{ - radeon_clear_tris(ctx, mask); -} - static void r300ClearBuffer(r300ContextPtr r300, int flags, struct radeon_renderbuffer *rrb, struct radeon_renderbuffer *rrbd) @@ -540,19 +535,50 @@ static void r300EmitClearState(GLcontext * ctx) } } -static void r300KernelClear(GLcontext *ctx, GLuint flags) +static int r300KernelClear(GLcontext *ctx, GLuint flags) { r300ContextPtr r300 = R300_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon); struct radeon_framebuffer *rfb = dPriv->driverPrivate; struct radeon_renderbuffer *rrb; struct radeon_renderbuffer *rrbd; - int bits = 0; + int bits = 0, ret; /* Make sure it fits there. */ + radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs); + + if (flags & BUFFER_BIT_COLOR0) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0); + radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, + rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } + + if (flags & BUFFER_BIT_FRONT_LEFT) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT); + radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, + rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } + + if (flags & BUFFER_BIT_BACK_LEFT) { + rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT); + radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, + rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } + + rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); + if (rrbd) { + radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, + rrbd->bo, 0, RADEON_GEM_DOMAIN_VRAM); + } + + ret = radeon_cs_space_check(r300->radeon.cmdbuf.cs); + if (ret) + return -1; + rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); if (flags || bits) r300EmitClearState(ctx); + rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); if (rrbd && (flags & BUFFER_BIT_DEPTH)) bits |= CLEARBUFFER_DEPTH; @@ -582,6 +608,7 @@ static void r300KernelClear(GLcontext *ctx, GLuint flags) r300ClearBuffer(r300, bits, NULL, rrbd); COMMIT_BATCH(); + return 0; } /** @@ -593,7 +620,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon); const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); GLbitfield swrast_mask = 0, tri_mask = 0; - int i; + int i, ret; struct gl_framebuffer *fb = ctx->DrawBuffer; if (RADEON_DEBUG & DEBUG_IOCTL) @@ -614,6 +641,8 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) if (colorMask == ~0) tri_mask |= (mask & BUFFER_BITS_COLOR); + else + tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)); /* HW stencil */ @@ -643,12 +672,18 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) /* SW fallback clearing */ swrast_mask = mask & ~tri_mask; + ret = 0; if (tri_mask) { if (r300->radeon.radeonScreen->kernel_mm) - r300UserClear(ctx, tri_mask); - else - r300KernelClear(ctx, tri_mask); + radeonUserClear(ctx, tri_mask); + else { + /* if kernel clear fails due to size restraints fallback */ + ret = r300KernelClear(ctx, tri_mask); + if (ret < 0) + swrast_mask |= tri_mask; + } } + if (swrast_mask) { if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index c22616b95f6..357c600af97 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -1467,6 +1467,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_TX_FORMAT_3D (1 << 25) # define R300_TX_FORMAT_CUBIC_MAP (2 << 25) +# define R300_TX_FORMAT_GAMMA (1 << 21) + /* gap */ /* Floating point formats */ /* Note - hardware supports both 16 and 32 bit floating point */ diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 1356305a212..08d67b73edc 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -243,7 +243,6 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset) fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr, offset); - if (!rmesa->radeon.radeonScreen->kernel_mm) { BEGIN_BATCH(sz+2+(nr * 2)); OUT_BATCH_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1); @@ -360,31 +359,15 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim) if (type < 0 || num_verts <= 0) return; - /* Make space for at least 64 dwords. + /* Make space for at least 128 dwords. * This is supposed to ensure that we can get all rendering * commands into a single command buffer. */ rcommonEnsureCmdBufSpace(&rmesa->radeon, 128, __FUNCTION__); if (rmesa->ind_buf.ptr) { - if (num_verts > 65535) { - /* not implemented yet */ - WARN_ONCE("Too many elts\n"); - return; - } - /* Note: The following is incorrect, but it's the best I can do - * without a major refactoring of how DMA memory is handled. - * The problem: Ensuring that both vertex arrays *and* index - * arrays are at the right position, and then ensuring that - * the LOAD_VBPNTR, DRAW_INDX and INDX_BUFFER packets are emitted - * at once. - * - * So why is the following incorrect? Well, it seems like - * allocating the index array might actually evict the vertex - * arrays. *sigh* - */ r300EmitElts(ctx, num_verts); - r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start); + r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, 0); if (rmesa->radeon.radeonScreen->kernel_mm) { BEGIN_BATCH_NO_AUTOSTATE(2); OUT_BATCH_REGSEQ(R300_VAP_VF_MAX_VTX_INDX, 1); @@ -469,7 +452,8 @@ void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode) if (mode) { if ((fallback_warn & bit) == 0) { - _mesa_fprintf(stderr, "WARNING! Falling back to software for %s\n", getFallbackString(bit)); + if (RADEON_DEBUG & DEBUG_FALLBACKS) + _mesa_fprintf(stderr, "WARNING! Falling back to software for %s\n", getFallbackString(bit)); fallback_warn |= bit; } rmesa->fallback |= bit; diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index 0133b837966..62228a3786e 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -32,22 +32,45 @@ #include "r300_context.h" #include "r300_fragprog_common.h" +static void freeFragProgCache(GLcontext *ctx, struct r300_fragment_program_cont *cache) +{ + struct r300_fragment_program *tmp, *fp = cache->progs; + + while (fp) { + tmp = fp->next; + _mesa_reference_program(ctx, &fp->Base, NULL); + _mesa_free(fp); + fp = tmp; + } +} + +static void freeVertProgCache(GLcontext *ctx, struct r300_vertex_program_cont *cache) +{ + struct r300_vertex_program *tmp, *vp = cache->progs; + + while (vp) { + tmp = vp->next; + _mesa_reference_vertprog(ctx, &vp->Base, NULL); + _mesa_free(vp); + vp = tmp; + } +} + static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, GLuint id) { struct r300_vertex_program_cont *vp; - struct r300_fragment_program *fp; + struct r300_fragment_program_cont *fp; switch (target) { case GL_VERTEX_STATE_PROGRAM_NV: case GL_VERTEX_PROGRAM_ARB: vp = CALLOC_STRUCT(r300_vertex_program_cont); - return _mesa_init_vertex_program(ctx, &vp->mesa_program, - target, id); + return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id); case GL_FRAGMENT_PROGRAM_NV: case GL_FRAGMENT_PROGRAM_ARB: - fp = CALLOC_STRUCT(r300_fragment_program); + fp = CALLOC_STRUCT(r300_fragment_program_cont); return _mesa_init_fragment_program(ctx, &fp->Base, target, id); default: @@ -59,21 +82,35 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog) { + struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog; + struct r300_fragment_program_cont *fp = (struct r300_fragment_program_cont *)prog; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + freeVertProgCache(ctx, vp); + break; + case GL_FRAGMENT_PROGRAM_ARB: + freeFragProgCache(ctx, fp); + break; + } + _mesa_delete_program(ctx, prog); } static void r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { - struct r300_vertex_program_cont *vp = (void *)prog; - struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)prog; + struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog; + struct r300_fragment_program_cont *fp = (struct r300_fragment_program_cont *)prog; switch (target) { case GL_VERTEX_PROGRAM_ARB: + freeVertProgCache(ctx, vp); vp->progs = NULL; break; case GL_FRAGMENT_PROGRAM_ARB: - r300_fp->translated = GL_FALSE; + freeFragProgCache(ctx, fp); + fp->progs = NULL; break; } @@ -85,13 +122,18 @@ static GLboolean r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) { if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct r300_fragment_program *fp = (struct r300_fragment_program *)prog; + struct r300_fragment_program *fp = r300SelectFragmentShader(ctx); if (!fp->translated) - r300TranslateFragmentShader(ctx, &fp->Base); + r300TranslateFragmentShader(ctx, fp); return !fp->error; - } else - return GL_TRUE; + } else { + struct r300_vertex_program *vp = r300SelectVertexShader(ctx); + if (!vp->translated) + r300TranslateVertexShader(vp); + + return !vp->error; + } } void r300InitShaderFuncs(struct dd_function_table *functions) diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index c0eda977db8..12fbf281d99 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -434,6 +434,10 @@ static void r300UpdateCulling(GLcontext * ctx) break; } + /* Winding is inverted when rendering to FBO */ + if (ctx->DrawBuffer && ctx->DrawBuffer->Name) + val ^= R300_FRONT_FACE_CW; + R300_STATECHANGE(r300, cul); r300->hw.cul.cmd[R300_CUL_CULL] = val; } @@ -452,9 +456,9 @@ static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state) static GLboolean current_fragment_program_writes_depth(GLcontext* ctx) { - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + r300ContextPtr r300 = R300_CONTEXT(ctx); - return (fp && fp->writes_depth); + return ctx->FragmentProgram._Current && r300->selected_fp->writes_depth; } static void r300SetEarlyZState(GLcontext * ctx) @@ -1093,24 +1097,25 @@ r300FetchStateParameter(GLcontext * ctx, * Update R300's own internal state parameters. * For now just STATE_R300_WINDOW_DIMENSION */ -void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) +static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) { - struct r300_fragment_program *fp; + r300ContextPtr rmesa = R300_CONTEXT(ctx); struct gl_program_parameter_list *paramList; GLuint i; if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS))) return; - fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current; - if (!fp) + if (!ctx->FragmentProgram._Current || !rmesa->selected_fp) return; - paramList = fp->Base.Base.Parameters; + paramList = rmesa->selected_fp->Base->Parameters; if (!paramList) return; + _mesa_load_state_parameters(ctx, paramList); + for (i = 0; i < paramList->NumParameters; i++) { if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { r300FetchStateParameter(ctx, @@ -1225,8 +1230,7 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) { r300ContextPtr r300 = R300_CONTEXT(ctx); int i; - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; - struct r300_fragment_program_code *code = &fp->code.r300; + struct r300_fragment_program_code *code = &r300->selected_fp->code.r300; R300_STATECHANGE(r300, fpt); @@ -1266,9 +1270,9 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) { + r300ContextPtr r300 = R300_CONTEXT(ctx); int i; - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; - struct r500_fragment_program_code *code = &fp->code.r500; + struct r500_fragment_program_code *code = &r300->selected_fp->code.r500; /* find all the texture instructions and relocate the texture units */ for (i = 0; i < code->inst_end + 1; i++) { @@ -1316,8 +1320,6 @@ static void r300SetupTextures(GLcontext * ctx) int hw_tmu = 0; int last_hw_tmu = -1; /* -1 translates into no setup costs for fields */ int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, }; - struct r300_fragment_program *fp = (struct r300_fragment_program *) - (char *)ctx->FragmentProgram._Current; R300_STATECHANGE(r300, txe); R300_STATECHANGE(r300, tex.filter); @@ -1420,7 +1422,7 @@ static void r300SetupTextures(GLcontext * ctx) cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1); if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) { - if (fp->Base.UsesKill && last_hw_tmu < 0) { + if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) { // The KILL operation requires the first texture unit // to be enabled. r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1; @@ -1458,11 +1460,11 @@ static void r300SetupRSUnit(GLcontext * ctx) hw_tcl_on = r300->options.hw_tcl_enabled; if (hw_tcl_on) - OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten; + OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten; else RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset); - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; + InputsRead = r300->selected_fp->Base->InputsRead; R300_STATECHANGE(r300, ri); R300_STATECHANGE(r300, rc); @@ -1521,29 +1523,6 @@ static void r300SetupRSUnit(GLcontext * ctx) ++fp_reg; } - if (InputsRead & FRAG_BIT_WPOS) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | R300_RS_TEX_PTR(rs_tex_count); - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_WPOS; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } - - if (InputsRead & FRAG_BIT_FOGC) { - if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(R300_RS_SEL_K0) | R300_RS_SEL_R(R300_RS_SEL_K0); - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_Q(R300_RS_SEL_K1) | R300_RS_TEX_PTR(rs_tex_count); - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_FOGC; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } else { - WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n"); - } - } - /* Setup default color if no color or tex was set */ if (rs_tex_count == 0 && col_ip == 0) { r300->hw.rr.cmd[R300_RR_INST_0] = R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_ADDR(0); @@ -1575,11 +1554,11 @@ static void r500SetupRSUnit(GLcontext * ctx) hw_tcl_on = r300->options.hw_tcl_enabled; if (hw_tcl_on) - OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten; + OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten; else RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset); - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; + InputsRead = r300->selected_fp->Base->InputsRead; R300_STATECHANGE(r300, ri); R300_STATECHANGE(r300, rc); @@ -1642,36 +1621,6 @@ static void r500SetupRSUnit(GLcontext * ctx) ++fp_reg; } - if (InputsRead & FRAG_BIT_WPOS) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) | - ((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) | - ((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) | - ((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT); - - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_WPOS; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } - - if (InputsRead & FRAG_BIT_FOGC) { - if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= (rs_tex_count << R500_RS_IP_TEX_PTR_S_SHIFT) | - (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | - (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | - (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); - - r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_FOGC; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } else { - WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n"); - } - } - /* Setup default color if no color or tex was set */ if (rs_tex_count == 0 && col_ip == 0) { r300->hw.rr.cmd[R300_RR_INST_0] = R500_RS_INST_COL_ID(0) | R500_RS_INST_COL_ADDR(0); @@ -2036,43 +1985,51 @@ static void r300ResetHwState(r300ContextPtr r300) void r300UpdateShaders(r300ContextPtr rmesa) { - GLcontext *ctx; - struct r300_fragment_program *fp; - int i; - - ctx = rmesa->radeon.glCtx; - fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + GLcontext *ctx = rmesa->radeon.glCtx; /* should only happenen once, just after context is created */ /* TODO: shouldn't we fallback to sw here? */ - if (!fp) { + if (!ctx->FragmentProgram._Current) { _mesa_fprintf(stderr, "No ctx->FragmentProgram._Current!!\n"); return; } - if (rmesa->radeon.NewGLState && rmesa->options.hw_tcl_enabled) { - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - rmesa->temp_attrib[i] = - TNL_CONTEXT(ctx)->vb.AttribPtr[i]; - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - &rmesa->dummy_attrib[i]; - } + { + struct r300_fragment_program *fp; - _tnl_UpdateFixedFunctionProgram(ctx); + fp = r300SelectFragmentShader(ctx); + if (!fp->translated) + r300TranslateFragmentShader(ctx, fp); - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - rmesa->temp_attrib[i]; - } - - r300SelectVertexShader(rmesa); - r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, rmesa->selected_vp->error); + r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error); } - if (!fp->translated || rmesa->radeon.NewGLState) - r300TranslateFragmentShader(ctx, ctx->FragmentProgram._Current); + if (rmesa->options.hw_tcl_enabled) { + struct r300_vertex_program *vp; + + if (rmesa->radeon.NewGLState) { + int i; + for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { + rmesa->temp_attrib[i] = + TNL_CONTEXT(ctx)->vb.AttribPtr[i]; + TNL_CONTEXT(ctx)->vb.AttribPtr[i] = + &rmesa->dummy_attrib[i]; + } + + _tnl_UpdateFixedFunctionProgram(ctx); + + for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { + TNL_CONTEXT(ctx)->vb.AttribPtr[i] = + rmesa->temp_attrib[i]; + } + } + + vp = r300SelectVertexShader(ctx); + if (!vp->translated) + r300TranslateVertexShader(vp); - r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error); + r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, vp->error); + } r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); rmesa->radeon.NewGLState = 0; @@ -2102,7 +2059,7 @@ static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx, static void r300SetupPixelShader(GLcontext *ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + struct r300_fragment_program *fp = rmesa->selected_fp; struct r300_fragment_program_code *code; int i, k; @@ -2148,8 +2105,7 @@ static void r300SetupPixelShader(GLcontext *ctx) R300_STATECHANGE(rmesa, fpp); rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4); for (i = 0; i < code->const_nr; i++) { - const GLfloat *constant = get_fragmentprogram_constant(ctx, - &fp->Base.Base, code->constant[i]); + const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(constant[0]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(constant[1]); rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(constant[2]); @@ -2174,7 +2130,7 @@ static void r300SetupPixelShader(GLcontext *ctx) static void r500SetupPixelShader(GLcontext *ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; + struct r300_fragment_program *fp = rmesa->selected_fp; int i; struct r500_fragment_program_code *code; @@ -2210,8 +2166,7 @@ static void r500SetupPixelShader(GLcontext *ctx) R300_STATECHANGE(rmesa, r500fp_const); for (i = 0; i < code->const_nr; i++) { - const GLfloat *constant = get_fragmentprogram_constant(ctx, - &fp->Base.Base, code->constant[i]); + const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(constant[0]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(constant[1]); rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(constant[2]); @@ -2274,20 +2229,17 @@ void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten) rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead); rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead); - rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead); - rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead); + rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten); + rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten); } void r300UpdateShaderStates(r300ContextPtr rmesa) { GLcontext *ctx; ctx = rmesa->radeon.glCtx; - struct r300_fragment_program *r300_fp; - - r300_fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current; /* should only happenen once, just after context is created */ - if (!r300_fp) + if (!ctx->FragmentProgram._Current) return; r300SetEarlyZState(ctx); @@ -2323,8 +2275,6 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) R300_STATECHANGE(r300, cb); } - r300UpdateStateParameters(ctx, new_state); - r300->radeon.NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h index 23282894202..d46bf9f1796 100644 --- a/src/mesa/drivers/dri/r300/r300_state.h +++ b/src/mesa/drivers/dri/r300/r300_state.h @@ -52,7 +52,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. void r300UpdateViewportOffset (GLcontext * ctx); void r300UpdateDrawBuffer (GLcontext * ctx); -void r300UpdateStateParameters (GLcontext * ctx, GLuint new_state); void r300UpdateShaders (r300ContextPtr rmesa); void r300UpdateShaderStates (r300ContextPtr rmesa); void r300InitState (r300ContextPtr r300); diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index ce4179208eb..56ed519cf41 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -76,7 +76,7 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_ GLuint InputsRead = 0; GLuint OutputsWritten = 0; int num_attrs = 0; - GLuint fp_reads = ctx->FragmentProgram._Current->Base.InputsRead; + GLuint fp_reads = rmesa->selected_fp->Base->InputsRead; struct vertex_attribute *attrs = rmesa->vbuf.attribs; rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0; @@ -150,6 +150,22 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_ ADD_ATTR(VERT_ATTRIB_POINT_SIZE, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_POINT_SIZE, swiz, MASK_X, 0); } + if (rmesa->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) { + int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0; + + VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS]; + VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_POS]; + RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id); + } + + if (rmesa->selected_fp->fog_attr != FRAG_ATTRIB_MAX) { + int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0; + + VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG]; + VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG]; + RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id); + } + /** * Sending only one texcoord component may lead to lock up, * so for all textures always output 4 texcoord components to RS. @@ -192,31 +208,9 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_ } } - /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */ - if (fp_reads & FRAG_BIT_WPOS) { - if (first_free_tex >= ctx->Const.MaxTextureUnits) { - fprintf(stderr, "\tout of free texcoords to write w pos\n"); - _mesa_exit(-1); - } - - InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex); - OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex); - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F ); - ADD_ATTR(VERT_ATTRIB_POS, R300_DATA_TYPE_FLOAT_4, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW, 0); - ++first_free_tex; - } - - if (fp_reads & FRAG_BIT_FOGC) { - if (first_free_tex >= ctx->Const.MaxTextureUnits) { - fprintf(stderr, "\tout of free texcoords to write fog coordinate\n"); - _mesa_exit(-1); - } - - InputsRead |= 1 << VERT_ATTRIB_FOG; - OutputsWritten |= 1 << VERT_RESULT_FOGC; - GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO); - EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F ); - ADD_ATTR(VERT_ATTRIB_FOG, R300_DATA_TYPE_FLOAT_1, SWTCL_OVM_TEX(first_free_tex), swiz, MASK_XYZW, 0); + if (first_free_tex >= ctx->Const.MaxTextureUnits) { + fprintf(stderr, "\tout of free texcoords to write fog coordinate\n"); + _mesa_exit(-1); } R300_NEWPRIM(rmesa); @@ -497,11 +491,13 @@ void r300RenderStart(GLcontext *ctx) r300ContextPtr rmesa = R300_CONTEXT( ctx ); r300ChooseRenderState(ctx); + + r300UpdateShaders(rmesa); + r300PrepareVertices(ctx); r300ValidateBuffers(ctx); - r300UpdateShaders(rmesa); r300UpdateShaderStates(rmesa); r300EmitCacheFlush(rmesa); diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 6d6a90aa88a..6f489ace7bf 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -119,6 +119,10 @@ static const struct tx_table { _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)), _ASSIGN(S8_Z24, R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8)), _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)), + /* EXT_texture_sRGB */ + _ASSIGN(SRGBA8, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) | R300_TX_FORMAT_GAMMA), + _ASSIGN(SLA8, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) | R300_TX_FORMAT_GAMMA), + _ASSIGN(SL8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8) | R300_TX_FORMAT_GAMMA), /* *INDENT-ON* */ }; @@ -277,21 +281,24 @@ GLboolean r300ValidateBuffers(GLcontext * ctx) r300ContextPtr rmesa = R300_CONTEXT(ctx); struct radeon_renderbuffer *rrb; int i; + int ret; - radeon_validate_reset_bos(&rmesa->radeon); + radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); rrb = radeon_get_colorbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + rrb->bo, 0, + RADEON_GEM_DOMAIN_VRAM); } /* depth buffer */ rrb = radeon_get_depthbuffer(&rmesa->radeon); if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + rrb->bo, 0, + RADEON_GEM_DOMAIN_VRAM); } for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { @@ -307,17 +314,19 @@ GLboolean r300ValidateBuffers(GLcontext * ctx) } t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); if (t->image_override && t->bo) - radeon_validate_bo(&rmesa->radeon, t->bo, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + t->bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); else if (t->mt->bo) - radeon_validate_bo(&rmesa->radeon, t->mt->bo, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + t->mt->bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); } - if (rmesa->radeon.dma.current) - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); - return radeon_revalidate_bos(ctx); + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + return GL_TRUE; } void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, @@ -433,7 +442,7 @@ void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo rImage->mt = NULL; } _mesa_init_teximage_fields(radeon->glCtx, target, texImage, - rb->width, rb->height, 1, 0, rb->cpp); + rb->base.Width, rb->base.Height, 1, 0, rb->cpp); texImage->RowStride = rb->pitch / rb->cpp; texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx, internalFormat, @@ -469,15 +478,15 @@ void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo break; } pitch_val--; - t->pp_txsize = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) | - ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT); + t->pp_txsize = ((rb->base.Width - 1) << R300_TX_WIDTHMASK_SHIFT) | + ((rb->base.Height - 1) << R300_TX_HEIGHTMASK_SHIFT); t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN; t->pp_txpitch |= pitch_val; if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { - if (rb->width > 2048) + if (rb->base.Width > 2048) t->pp_txpitch |= R500_TXWIDTH_BIT11; - if (rb->height > 2048) + if (rb->base.Height > 2048) t->pp_txpitch |= R500_TXHEIGHT_BIT11; } t->validated = GL_TRUE; diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index c41a8fdd621..de32013032f 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -32,12 +32,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "main/enums.h" #include "shader/program.h" +#include "shader/programopt.h" #include "shader/prog_instruction.h" +#include "shader/prog_optimize.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "shader/prog_statevars.h" #include "tnl/tnl.h" +#include "radeon_nqssadce.h" #include "r300_context.h" #include "r300_state.h" @@ -71,15 +74,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \ } while (0) -int r300VertexProgUpdateParams(GLcontext * ctx, - struct r300_vertex_program_cont *vp, float *dst) +static int r300VertexProgUpdateParams(GLcontext * ctx, struct gl_vertex_program *vp, float *dst) { int pi; - struct gl_vertex_program *mesa_vp = &vp->mesa_program; float *dst_o = dst; struct gl_program_parameter_list *paramList; - if (mesa_vp->IsNVProgram) { + if (vp->IsNVProgram) { _mesa_load_tracked_matrices(ctx); for (pi = 0; pi < MAX_NV_VERTEX_PROGRAM_PARAMS; pi++) { @@ -91,16 +92,18 @@ int r300VertexProgUpdateParams(GLcontext * ctx, return dst - dst_o; } - assert(mesa_vp->Base.Parameters); - _mesa_load_state_parameters(ctx, mesa_vp->Base.Parameters); + if (!vp->Base.Parameters) + return 0; - if (mesa_vp->Base.Parameters->NumParameters * 4 > + _mesa_load_state_parameters(ctx, vp->Base.Parameters); + + if (vp->Base.Parameters->NumParameters * 4 > VSF_MAX_FRAGMENT_LENGTH) { fprintf(stderr, "%s:Params exhausted\n", __FUNCTION__); _mesa_exit(-1); } - paramList = mesa_vp->Base.Parameters; + paramList = vp->Base.Parameters; for (pi = 0; pi < paramList->NumParameters; pi++) { switch (paramList->Parameters[pi].Type) { case PROGRAM_STATE_VAR: @@ -933,10 +936,14 @@ static void t_inputs_outputs(struct r300_vertex_program *vp) { int i; int cur_reg; + GLuint OutputsWritten, InputsRead; + + OutputsWritten = vp->Base->Base.OutputsWritten; + InputsRead = vp->Base->Base.InputsRead; cur_reg = -1; for (i = 0; i < VERT_ATTRIB_MAX; i++) { - if (vp->key.InputsRead & (1 << i)) + if (InputsRead & (1 << i)) vp->inputs[i] = ++cur_reg; else vp->inputs[i] = -1; @@ -946,13 +953,13 @@ static void t_inputs_outputs(struct r300_vertex_program *vp) for (i = 0; i < VERT_RESULT_MAX; i++) vp->outputs[i] = -1; - assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)); + assert(OutputsWritten & (1 << VERT_RESULT_HPOS)); - if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)) { + if (OutputsWritten & (1 << VERT_RESULT_HPOS)) { vp->outputs[VERT_RESULT_HPOS] = cur_reg++; } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ)) { + if (OutputsWritten & (1 << VERT_RESULT_PSIZ)) { vp->outputs[VERT_RESULT_PSIZ] = cur_reg++; } @@ -962,46 +969,46 @@ static void t_inputs_outputs(struct r300_vertex_program *vp) * pretend it does by skipping output index reg so the colors * get written into appropriate output vectors. */ - if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) { + if (OutputsWritten & (1 << VERT_RESULT_COL0)) { vp->outputs[VERT_RESULT_COL0] = cur_reg++; - } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0) || - vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + } else if (OutputsWritten & (1 << VERT_RESULT_BFC0) || + OutputsWritten & (1 << VERT_RESULT_BFC1)) { cur_reg++; } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) { + if (OutputsWritten & (1 << VERT_RESULT_COL1)) { vp->outputs[VERT_RESULT_COL1] = cur_reg++; - } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0) || - vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + } else if (OutputsWritten & (1 << VERT_RESULT_BFC0) || + OutputsWritten & (1 << VERT_RESULT_BFC1)) { cur_reg++; } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) { + if (OutputsWritten & (1 << VERT_RESULT_BFC0)) { vp->outputs[VERT_RESULT_BFC0] = cur_reg++; - } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + } else if (OutputsWritten & (1 << VERT_RESULT_BFC1)) { cur_reg++; } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { + if (OutputsWritten & (1 << VERT_RESULT_BFC1)) { vp->outputs[VERT_RESULT_BFC1] = cur_reg++; - } else if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) { + } else if (OutputsWritten & (1 << VERT_RESULT_BFC0)) { cur_reg++; } for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) { - if (vp->key.OutputsWritten & (1 << i)) { + if (OutputsWritten & (1 << i)) { vp->outputs[i] = cur_reg++; } } - if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) { + if (OutputsWritten & (1 << VERT_RESULT_FOGC)) { vp->outputs[VERT_RESULT_FOGC] = cur_reg++; } } -static void r300TranslateVertexShader(struct r300_vertex_program *vp, - struct prog_instruction *vpi) +void r300TranslateVertexShader(struct r300_vertex_program *vp) { + struct prog_instruction *vpi = vp->Base->Base.Instructions; int i; GLuint *inst; unsigned long num_operands; @@ -1191,313 +1198,463 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp, } } -/* DP4 version seems to trigger some hw peculiarity */ -//#define PREFER_DP4 +static void insert_wpos(struct gl_program *prog, GLuint temp_index, int tex_id) +{ + struct prog_instruction *vpi; + + _mesa_insert_instructions(prog, prog->NumInstructions - 1, 2); + + vpi = &prog->Instructions[prog->NumInstructions - 3]; + + vpi->Opcode = OPCODE_MOV; + + vpi->DstReg.File = PROGRAM_OUTPUT; + vpi->DstReg.Index = VERT_RESULT_HPOS; + vpi->DstReg.WriteMask = WRITEMASK_XYZW; + vpi->DstReg.CondMask = COND_TR; + + vpi->SrcReg[0].File = PROGRAM_TEMPORARY; + vpi->SrcReg[0].Index = temp_index; + vpi->SrcReg[0].Swizzle = SWIZZLE_XYZW; + + ++vpi; + + vpi->Opcode = OPCODE_MOV; -static void position_invariant(struct gl_program *prog) + vpi->DstReg.File = PROGRAM_OUTPUT; + vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id; + vpi->DstReg.WriteMask = WRITEMASK_XYZW; + vpi->DstReg.CondMask = COND_TR; + + vpi->SrcReg[0].File = PROGRAM_TEMPORARY; + vpi->SrcReg[0].Index = temp_index; + vpi->SrcReg[0].Swizzle = SWIZZLE_XYZW; + + ++vpi; + + vpi->Opcode = OPCODE_END; +} + +static void pos_as_texcoord(struct gl_program *prog, int tex_id) { struct prog_instruction *vpi; - struct gl_program_parameter_list *paramList; - int i; + GLuint tempregi = prog->NumTemporaries; - gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 }; + prog->NumTemporaries++; - /* tokens[4] = matrix modifier */ -#ifdef PREFER_DP4 - tokens[4] = 0; /* not transposed or inverted */ -#else - tokens[4] = STATE_MATRIX_TRANSPOSE; -#endif - paramList = prog->Parameters; - - vpi = _mesa_alloc_instructions(prog->NumInstructions + 4); - _mesa_init_instructions(vpi, prog->NumInstructions + 4); - - for (i = 0; i < 4; i++) { - GLint idx; - tokens[2] = tokens[3] = i; /* matrix row[i]..row[i] */ - idx = _mesa_add_state_reference(paramList, tokens); -#ifdef PREFER_DP4 - vpi[i].Opcode = OPCODE_DP4; - vpi[i].StringPos = 0; - vpi[i].Data = 0; - - vpi[i].DstReg.File = PROGRAM_OUTPUT; - vpi[i].DstReg.Index = VERT_RESULT_HPOS; - vpi[i].DstReg.WriteMask = 1 << i; - vpi[i].DstReg.CondMask = COND_TR; - - vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; - vpi[i].SrcReg[0].Index = idx; - vpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - - vpi[i].SrcReg[1].File = PROGRAM_INPUT; - vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS; - vpi[i].SrcReg[1].Swizzle = SWIZZLE_XYZW; -#else - if (i == 0) - vpi[i].Opcode = OPCODE_MUL; - else - vpi[i].Opcode = OPCODE_MAD; + for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) { + if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_HPOS) { + vpi->DstReg.File = PROGRAM_TEMPORARY; + vpi->DstReg.Index = tempregi; + } + } - vpi[i].Data = 0; + insert_wpos(prog, tempregi, tex_id); - if (i == 3) - vpi[i].DstReg.File = PROGRAM_OUTPUT; - else - vpi[i].DstReg.File = PROGRAM_TEMPORARY; - vpi[i].DstReg.Index = 0; - vpi[i].DstReg.WriteMask = 0xf; - vpi[i].DstReg.CondMask = COND_TR; - - vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; - vpi[i].SrcReg[0].Index = idx; - vpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - - vpi[i].SrcReg[1].File = PROGRAM_INPUT; - vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS; - vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i); - - if (i > 0) { - vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY; - vpi[i].SrcReg[2].Index = 0; - vpi[i].SrcReg[2].Swizzle = SWIZZLE_XYZW; + prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id); +} + +/** + * The fogcoord attribute is special in that only the first component + * is relevant, and the remaining components are always fixed (when read + * from by the fragment program) to yield an X001 pattern. + * + * We need to enforce this either in the vertex program or in the fragment + * program, and this code chooses not to enforce it in the vertex program. + * This is slightly cheaper, as long as the fragment program does not use + * weird swizzles. + * + * And it seems that usually, weird swizzles are not used, so... + * + * See also the counterpart rewriting for fragment programs. + */ +static void fog_as_texcoord(struct gl_program *prog, int tex_id) +{ + struct prog_instruction *vpi; + + vpi = prog->Instructions; + while (vpi->Opcode != OPCODE_END) { + if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_FOGC) { + vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id; + vpi->DstReg.WriteMask = WRITEMASK_X; } -#endif + + ++vpi; } - _mesa_copy_instructions(&vpi[i], prog->Instructions, - prog->NumInstructions); + prog->OutputsWritten &= ~(1 << VERT_RESULT_FOGC); + prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id); +} - free(prog->Instructions); +static int translateABS(struct gl_program *prog, int pos) +{ + struct prog_instruction *inst; - prog->Instructions = vpi; + inst = &prog->Instructions[pos]; - prog->NumInstructions += 4; - vpi = &prog->Instructions[prog->NumInstructions - 1]; + inst->Opcode = OPCODE_MAX; + inst->SrcReg[1] = inst->SrcReg[0]; + inst->SrcReg[1].Negate ^= NEGATE_XYZW; - assert(vpi->Opcode == OPCODE_END); + return 0; } -static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog, - GLuint temp_index) +static int translateDP3(struct gl_program *prog, int pos) { - struct prog_instruction *vpi; - struct prog_instruction *vpi_insert; - int i = 0; + struct prog_instruction *inst; - vpi = _mesa_alloc_instructions(prog->NumInstructions + 2); - _mesa_init_instructions(vpi, prog->NumInstructions + 2); - /* all but END */ - _mesa_copy_instructions(vpi, prog->Instructions, - prog->NumInstructions - 1); - /* END */ - _mesa_copy_instructions(&vpi[prog->NumInstructions + 1], - &prog->Instructions[prog->NumInstructions - 1], - 1); - vpi_insert = &vpi[prog->NumInstructions - 1]; + inst = &prog->Instructions[pos]; - vpi_insert[i].Opcode = OPCODE_MOV; + inst->Opcode = OPCODE_DP4; + inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - vpi_insert[i].DstReg.File = PROGRAM_OUTPUT; - vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS; - vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW; - vpi_insert[i].DstReg.CondMask = COND_TR; + return 0; +} + +static int translateDPH(struct gl_program *prog, int pos) +{ + struct prog_instruction *inst; + + inst = &prog->Instructions[pos]; + + inst->Opcode = OPCODE_DP4; + inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); - vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; - vpi_insert[i].SrcReg[0].Index = temp_index; - vpi_insert[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - i++; + return 0; +} - vpi_insert[i].Opcode = OPCODE_MOV; +static int translateFLR(struct gl_program *prog, int pos) +{ + struct prog_instruction *inst; + struct prog_dst_register dst; + int tmp_idx; - vpi_insert[i].DstReg.File = PROGRAM_OUTPUT; - vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0 + vp->wpos_idx; - vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW; - vpi_insert[i].DstReg.CondMask = COND_TR; + tmp_idx = prog->NumTemporaries++; - vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; - vpi_insert[i].SrcReg[0].Index = temp_index; - vpi_insert[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - i++; + _mesa_insert_instructions(prog, pos + 1, 1); - free(prog->Instructions); + inst = &prog->Instructions[pos]; + dst = inst->DstReg; - prog->Instructions = vpi; + inst->Opcode = OPCODE_FRC; + inst->DstReg.File = PROGRAM_TEMPORARY; + inst->DstReg.Index = tmp_idx; + ++inst; - prog->NumInstructions += i; - vpi = &prog->Instructions[prog->NumInstructions - 1]; + inst->Opcode = OPCODE_ADD; + inst->DstReg = dst; + inst->SrcReg[0] = (inst-1)->SrcReg[0]; + inst->SrcReg[1].File = PROGRAM_TEMPORARY; + inst->SrcReg[1].Index = tmp_idx; + inst->SrcReg[1].Negate = NEGATE_XYZW; - assert(vpi->Opcode == OPCODE_END); + return 1; } -static void pos_as_texcoord(struct r300_vertex_program *vp, - struct gl_program *prog) +static int translateSUB(struct gl_program *prog, int pos) { - struct prog_instruction *vpi; - GLuint tempregi = prog->NumTemporaries; - /* should do something else if no temps left... */ - prog->NumTemporaries++; + struct prog_instruction *inst; - for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) { - if (vpi->DstReg.File == PROGRAM_OUTPUT - && vpi->DstReg.Index == VERT_RESULT_HPOS) { - vpi->DstReg.File = PROGRAM_TEMPORARY; - vpi->DstReg.Index = tempregi; - } - } - insert_wpos(vp, prog, tempregi); + inst = &prog->Instructions[pos]; + + inst->Opcode = OPCODE_ADD; + inst->SrcReg[1].Negate ^= NEGATE_XYZW; + + return 0; } -static struct r300_vertex_program *build_program(struct r300_vertex_program_key - *wanted_key, struct gl_vertex_program - *mesa_vp, GLint wpos_idx) +static int translateSWZ(struct gl_program *prog, int pos) { - struct r300_vertex_program *vp; + prog->Instructions[pos].Opcode = OPCODE_MOV; - vp = _mesa_calloc(sizeof(*vp)); - _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); - vp->wpos_idx = wpos_idx; + return 0; +} - if (mesa_vp->IsPositionInvariant) { - position_invariant(&mesa_vp->Base); - } +static int translateXPD(struct gl_program *prog, int pos) +{ + struct prog_instruction *inst; + int tmp_idx; + + tmp_idx = prog->NumTemporaries++; + + _mesa_insert_instructions(prog, pos + 1, 1); + + inst = &prog->Instructions[pos]; + + *(inst+1) = *inst; + + inst->Opcode = OPCODE_MUL; + inst->DstReg.File = PROGRAM_TEMPORARY; + inst->DstReg.Index = tmp_idx; + inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W); + inst->SrcReg[1].Swizzle = combine_swizzles4(inst->SrcReg[1].Swizzle, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W); + ++inst; + + inst->Opcode = OPCODE_MAD; + inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W); + inst->SrcReg[1].Swizzle = combine_swizzles4(inst->SrcReg[1].Swizzle, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W); + inst->SrcReg[1].Negate ^= NEGATE_XYZW; + inst->SrcReg[2].File = PROGRAM_TEMPORARY; + inst->SrcReg[2].Index = tmp_idx; + + return 1; +} + +static void translateInsts(struct gl_program *prog) +{ + struct prog_instruction *inst; + int i; + + for (i = 0; i < prog->NumInstructions; ++i) { + inst = &prog->Instructions[i]; - if (wpos_idx > -1) { - pos_as_texcoord(vp, &mesa_vp->Base); + switch (inst->Opcode) { + case OPCODE_ABS: + i += translateABS(prog, i); + break; + case OPCODE_DP3: + i += translateDP3(prog, i); + break; + case OPCODE_DPH: + i += translateDPH(prog, i); + break; + case OPCODE_FLR: + i += translateFLR(prog, i); + break; + case OPCODE_SUB: + i += translateSUB(prog, i); + break; + case OPCODE_SWZ: + i += translateSWZ(prog, i); + break; + case OPCODE_XPD: + i += translateXPD(prog, i); + break; + default: + break; + } } +} - if (RADEON_DEBUG & DEBUG_VERTS) { - fprintf(stderr, "Vertex program after native rewrite:\n"); - _mesa_print_program(&mesa_vp->Base); - fflush(stdout); +#define ADD_OUTPUT(fp_attr, vp_result) \ + do { \ + if ((FpReads & (1 << (fp_attr))) && !(prog->OutputsWritten & (1 << (vp_result)))) { \ + OutputsAdded |= 1 << (vp_result); \ + count++; \ + } \ + } while (0) + +static void addArtificialOutputs(GLcontext *ctx, struct gl_program *prog) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + GLuint OutputsAdded, FpReads; + int i, count; + + OutputsAdded = 0; + count = 0; + FpReads = r300->selected_fp->Base->InputsRead; + + ADD_OUTPUT(FRAG_ATTRIB_COL0, VERT_RESULT_COL0); + ADD_OUTPUT(FRAG_ATTRIB_COL1, VERT_RESULT_COL1); + + for (i = 0; i < 7; ++i) { + ADD_OUTPUT(FRAG_ATTRIB_TEX0 + i, VERT_RESULT_TEX0 + i); } /* Some outputs may be artificially added, to match the inputs of the fragment program. * Issue 16 of vertex program spec says that all vertex attributes that are unwritten by * vertex program are undefined, so just use MOV [vertex_result], CONST[0] */ - { - int i, count = 0; + if (count > 0) { + struct prog_instruction *inst; + + _mesa_insert_instructions(prog, prog->NumInstructions - 1, count); + inst = &prog->Instructions[prog->NumInstructions - 1 - count]; + for (i = 0; i < VERT_RESULT_MAX; ++i) { - if (vp->key.OutputsAdded & (1 << i)) { - ++count; + if (OutputsAdded & (1 << i)) { + inst->Opcode = OPCODE_MOV; + + inst->DstReg.File = PROGRAM_OUTPUT; + inst->DstReg.Index = i; + inst->DstReg.WriteMask = WRITEMASK_XYZW; + inst->DstReg.CondMask = COND_TR; + + inst->SrcReg[0].File = PROGRAM_CONSTANT; + inst->SrcReg[0].Index = 0; + inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; + + ++inst; } } - if (count > 0) { - struct prog_instruction *inst; + prog->OutputsWritten |= OutputsAdded; + } +} - _mesa_insert_instructions(&mesa_vp->Base, mesa_vp->Base.NumInstructions - 1, count); - inst = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions - 1 - count]; +#undef ADD_OUTPUT - for (i = 0; i < VERT_RESULT_MAX; ++i) { - if (vp->key.OutputsAdded & (1 << i)) { - inst->Opcode = OPCODE_MOV; +static void nqssadceInit(struct nqssadce_state* s) +{ + r300ContextPtr r300 = R300_CONTEXT(s->Ctx); + GLuint fp_reads; - inst->DstReg.File = PROGRAM_OUTPUT; - inst->DstReg.Index = i; - inst->DstReg.WriteMask = WRITEMASK_XYZW; - inst->DstReg.CondMask = COND_TR; + fp_reads = r300->selected_fp->Base->InputsRead; + { + if (fp_reads & FRAG_BIT_COL0) { + s->Outputs[VERT_RESULT_COL0].Sourced = WRITEMASK_XYZW; + s->Outputs[VERT_RESULT_BFC0].Sourced = WRITEMASK_XYZW; + } - inst->SrcReg[0].File = PROGRAM_CONSTANT; - inst->SrcReg[0].Index = 0; - inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; + if (fp_reads & FRAG_BIT_COL1) { + s->Outputs[VERT_RESULT_COL1].Sourced = WRITEMASK_XYZW; + s->Outputs[VERT_RESULT_BFC1].Sourced = WRITEMASK_XYZW; + } + } - ++inst; - } + { + int i; + for (i = 0; i < 8; ++i) { + if (fp_reads & FRAG_BIT_TEX(i)) { + s->Outputs[VERT_RESULT_TEX0 + i].Sourced = WRITEMASK_XYZW; } } } - assert(mesa_vp->Base.NumInstructions); - vp->num_temporaries = mesa_vp->Base.NumTemporaries; - r300TranslateVertexShader(vp, mesa_vp->Base.Instructions); - - return vp; + s->Outputs[VERT_RESULT_HPOS].Sourced = WRITEMASK_XYZW; + if (s->Program->OutputsWritten & (1 << VERT_RESULT_PSIZ)) + s->Outputs[VERT_RESULT_PSIZ].Sourced = WRITEMASK_X; } -static void add_outputs(struct r300_vertex_program_key *key, GLint vert) +static GLboolean swizzleIsNative(GLuint opcode, struct prog_src_register reg) { - if (key->OutputsWritten & (1 << vert)) - return; + (void) opcode; + (void) reg; - key->OutputsWritten |= 1 << vert; - key->OutputsAdded |= 1 << vert; + return GL_TRUE; } -void r300SelectVertexShader(r300ContextPtr r300) +static struct r300_vertex_program *build_program(GLcontext *ctx, + struct r300_vertex_program_key *wanted_key, + const struct gl_vertex_program *mesa_vp) { - GLcontext *ctx = ctx = r300->radeon.glCtx; - GLuint InputsRead; - struct r300_vertex_program_key wanted_key = { 0 }; - GLint i; - struct r300_vertex_program_cont *vpc; + r300ContextPtr r300 = R300_CONTEXT(ctx); struct r300_vertex_program *vp; - GLint wpos_idx; + struct gl_program *prog; - vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; - wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; - wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten; - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; - - wpos_idx = -1; - if (InputsRead & FRAG_BIT_WPOS) { - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) - if (!(InputsRead & (FRAG_BIT_TEX0 << i))) - break; + vp = _mesa_calloc(sizeof(*vp)); + vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base); + _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); - if (i == ctx->Const.MaxTextureUnits) { - fprintf(stderr, "\tno free texcoord found\n"); - _mesa_exit(-1); - } + prog = &vp->Base->Base; + + if (RADEON_DEBUG & DEBUG_VERTS) { + fprintf(stderr, "Initial vertex program:\n"); + _mesa_print_program(prog); + fflush(stdout); + } - wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); - wpos_idx = i; + if (vp->Base->IsPositionInvariant) { + _mesa_insert_mvp_code(ctx, vp->Base); } - if (vpc->mesa_program.IsPositionInvariant) { - wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); - wanted_key.OutputsWritten |= (1 << VERT_RESULT_HPOS); - } else { - add_outputs(&wanted_key, VERT_RESULT_HPOS); + if (r300->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) { + pos_as_texcoord(&vp->Base->Base, r300->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0); } - if (InputsRead & FRAG_BIT_COL0) { - add_outputs(&wanted_key, VERT_RESULT_COL0); + if (r300->selected_fp->fog_attr != FRAG_ATTRIB_MAX) { + fog_as_texcoord(&vp->Base->Base, r300->selected_fp->fog_attr - FRAG_ATTRIB_TEX0); } - if (InputsRead & FRAG_BIT_COL1) { - add_outputs(&wanted_key, VERT_RESULT_COL1); + addArtificialOutputs(ctx, prog); + + translateInsts(prog); + + if (RADEON_DEBUG & DEBUG_VERTS) { + fprintf(stderr, "Vertex program after native rewrite:\n"); + _mesa_print_program(prog); + fflush(stdout); } - if (InputsRead & FRAG_BIT_FOGC) { - add_outputs(&wanted_key, VERT_RESULT_FOGC); + { + struct radeon_nqssadce_descr nqssadce = { + .Init = &nqssadceInit, + .IsNativeSwizzle = &swizzleIsNative, + .BuildSwizzle = NULL + }; + radeonNqssaDce(ctx, prog, &nqssadce); + + /* We need this step for reusing temporary registers */ + _mesa_optimize_program(ctx, prog); + + if (RADEON_DEBUG & DEBUG_VERTS) { + fprintf(stderr, "Vertex program after NQSSADCE:\n"); + _mesa_print_program(prog); + fflush(stdout); + } } - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (InputsRead & (FRAG_BIT_TEX0 << i)) { - add_outputs(&wanted_key, VERT_RESULT_TEX0 + i); + assert(prog->NumInstructions); + { + struct prog_instruction *inst; + int max, i, tmp; + + inst = prog->Instructions; + max = -1; + while (inst->Opcode != OPCODE_END) { + tmp = _mesa_num_inst_src_regs(inst->Opcode); + for (i = 0; i < tmp; ++i) { + if (inst->SrcReg[i].File == PROGRAM_TEMPORARY) { + if ((int) inst->SrcReg[i].Index > max) { + max = inst->SrcReg[i].Index; + } + } + } + + if (_mesa_num_inst_dst_regs(inst->Opcode)) { + if (inst->DstReg.File == PROGRAM_TEMPORARY) { + if ((int) inst->DstReg.Index > max) { + max = inst->DstReg.Index; + } + } + } + ++inst; } + + /* We actually want highest index of used temporary register, + * not the number of temporaries used. + * These values aren't always the same. + */ + vp->num_temporaries = max + 1; } - for (vp = vpc->progs; vp; vp = vp->next) + return vp; +} + +struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_vertex_program_key wanted_key = { 0 }; + struct r300_vertex_program_cont *vpc; + struct r300_vertex_program *vp; + + vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; + wanted_key.FpReads = r300->selected_fp->Base->InputsRead; + wanted_key.FogAttr = r300->selected_fp->fog_attr; + wanted_key.WPosAttr = r300->selected_fp->wpos_attr; + + for (vp = vpc->progs; vp; vp = vp->next) { if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) { - r300->selected_vp = vp; - return; + return r300->selected_vp = vp; } - - if (RADEON_DEBUG & DEBUG_VERTS) { - fprintf(stderr, "Initial vertex program:\n"); - _mesa_print_program(&vpc->mesa_program.Base); - fflush(stdout); } - vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx); + vp = build_program(ctx, &wanted_key, &vpc->mesa_program); vp->next = vpc->progs; vpc->progs = vp; - r300->selected_vp = vp; + + return r300->selected_vp = vp; } #define bump_vpu_count(ptr, new_count) do { \ @@ -1544,25 +1701,22 @@ void r300SetupVertexProgram(r300ContextPtr rmesa) struct r300_vertex_program *prog = rmesa->selected_vp; int inst_count = 0; int param_count = 0; - + /* Reset state, in case we don't use something */ ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0; ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0; ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0; - + R300_STATECHANGE(rmesa, vpp); - param_count = r300VertexProgUpdateParams(ctx, - (struct r300_vertex_program_cont *) - ctx->VertexProgram._Current, - (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]); + param_count = r300VertexProgUpdateParams(ctx, prog->Base, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]); bump_vpu_count(rmesa->hw.vpp.cmd, param_count); param_count /= 4; r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->hw_code)); inst_count = (prog->hw_code.length / 4) - 1; - r300VapCntl(rmesa, _mesa_bitcount(prog->key.InputsRead), - _mesa_bitcount(prog->key.OutputsWritten), prog->num_temporaries); + r300VapCntl(rmesa, _mesa_bitcount(prog->Base->Base.InputsRead), + _mesa_bitcount(prog->Base->Base.OutputsWritten), prog->num_temporaries); R300_STATECHANGE(rmesa, pvs); rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = (0 << R300_PVS_FIRST_INST_SHIFT) | (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) | diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.h b/src/mesa/drivers/dri/r300/r300_vertprog.h index b552e3fb1bd..2dab11c3378 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.h +++ b/src/mesa/drivers/dri/r300/r300_vertprog.h @@ -34,4 +34,8 @@ void r300SetupVertexProgram(r300ContextPtr rmesa); +struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx); + +void r300TranslateVertexShader(struct r300_vertex_program *vp); + #endif diff --git a/src/mesa/drivers/dri/r300/radeon_nqssadce.c b/src/mesa/drivers/dri/r300/radeon_nqssadce.c index 4a2e1cba402..840c9733b16 100644 --- a/src/mesa/drivers/dri/r300/radeon_nqssadce.c +++ b/src/mesa/drivers/dri/r300/radeon_nqssadce.c @@ -46,6 +46,7 @@ static struct register_state *get_reg_state(struct nqssadce_state* s, GLuint fil switch(file) { case PROGRAM_TEMPORARY: return &s->Temps[index]; case PROGRAM_OUTPUT: return &s->Outputs[index]; + case PROGRAM_ADDRESS: return &s->Address; default: return 0; } } @@ -56,7 +57,7 @@ static struct register_state *get_reg_state(struct nqssadce_state* s, GLuint fil * * @note Works correctly only for X, Y, Z, W swizzles, not for constant swizzles. */ -static struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg) +struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg) { struct prog_src_register tmp = srcreg; int i; @@ -114,47 +115,19 @@ static struct prog_instruction* track_used_srcreg(struct nqssadce_state* s, deswz_source = sourced; } - struct register_state *regstate = get_reg_state(s, inst->SrcReg[src].File, inst->SrcReg[src].Index); + struct register_state *regstate; + + if (inst->SrcReg[src].RelAddr) + regstate = get_reg_state(s, PROGRAM_ADDRESS, 0); + else + regstate = get_reg_state(s, inst->SrcReg[src].File, inst->SrcReg[src].Index); + if (regstate) regstate->Sourced |= deswz_source & 0xf; return inst; } - -static void rewrite_depth_out(struct prog_instruction *inst) -{ - if (inst->DstReg.WriteMask & WRITEMASK_Z) { - inst->DstReg.WriteMask = WRITEMASK_W; - } else { - inst->DstReg.WriteMask = 0; - return; - } - - switch (inst->Opcode) { - case OPCODE_FRC: - case OPCODE_MOV: - inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]); - break; - case OPCODE_ADD: - case OPCODE_MAX: - case OPCODE_MIN: - case OPCODE_MUL: - inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]); - inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]); - break; - case OPCODE_CMP: - case OPCODE_MAD: - inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]); - inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]); - inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]); - break; - default: - // Scalar instructions needn't be reswizzled - break; - } -} - static void unalias_srcregs(struct prog_instruction *inst, GLuint oldindex, GLuint newindex) { int nsrc = _mesa_num_inst_src_regs(inst->Opcode); @@ -189,11 +162,6 @@ static void process_instruction(struct nqssadce_state* s) return; if (inst->Opcode != OPCODE_KIL) { - if (s->Descr->RewriteDepthOut) { - if (inst->DstReg.File == PROGRAM_OUTPUT && inst->DstReg.Index == FRAG_RESULT_DEPTH) - rewrite_depth_out(inst); - } - struct register_state *regstate = get_reg_state(s, inst->DstReg.File, inst->DstReg.Index); if (!regstate) { _mesa_problem(s->Ctx, "NqssaDce: bad destination register (%i[%i])\n", @@ -217,6 +185,7 @@ static void process_instruction(struct nqssadce_state* s) * might change the instruction stream under us, so we have * to be careful with the inst pointer. */ switch (inst->Opcode) { + case OPCODE_ARL: case OPCODE_DDX: case OPCODE_DDY: case OPCODE_FRC: @@ -227,6 +196,8 @@ static void process_instruction(struct nqssadce_state* s) case OPCODE_MAX: case OPCODE_MIN: case OPCODE_MUL: + case OPCODE_SGE: + case OPCODE_SLT: inst = track_used_srcreg(s, inst, 0, inst->DstReg.WriteMask); inst = track_used_srcreg(s, inst, 1, inst->DstReg.WriteMask); break; @@ -258,12 +229,51 @@ static void process_instruction(struct nqssadce_state* s) case OPCODE_TXP: inst = track_used_srcreg(s, inst, 0, 0xf); break; + case OPCODE_DST: + inst = track_used_srcreg(s, inst, 0, 0x6); + inst = track_used_srcreg(s, inst, 1, 0xa); + break; + case OPCODE_EXP: + case OPCODE_LOG: + case OPCODE_POW: + inst = track_used_srcreg(s, inst, 0, 0x3); + break; + case OPCODE_LIT: + inst = track_used_srcreg(s, inst, 0, 0xb); + break; default: _mesa_problem(s->Ctx, "NqssaDce: Unknown opcode %d\n", inst->Opcode); return; } } +static void calculateInputsOutputs(struct gl_program *p) +{ + struct prog_instruction *inst; + GLuint InputsRead, OutputsWritten; + + inst = p->Instructions; + InputsRead = 0; + OutputsWritten = 0; + while (inst->Opcode != OPCODE_END) + { + int i, num_src_regs; + + num_src_regs = _mesa_num_inst_src_regs(inst->Opcode); + for (i = 0; i < num_src_regs; ++i) { + if (inst->SrcReg[i].File == PROGRAM_INPUT) + InputsRead |= 1 << inst->SrcReg[i].Index; + } + + if (inst->DstReg.File == PROGRAM_OUTPUT) + OutputsWritten |= 1 << inst->DstReg.Index; + + ++inst; + } + + p->InputsRead = InputsRead; + p->OutputsWritten = OutputsWritten; +} void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce_descr* descr) { @@ -280,4 +290,6 @@ void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce s.IP--; process_instruction(&s); } + + calculateInputsOutputs(p); } diff --git a/src/mesa/drivers/dri/r300/radeon_nqssadce.h b/src/mesa/drivers/dri/r300/radeon_nqssadce.h index a4f94abcb62..8626f21c25e 100644 --- a/src/mesa/drivers/dri/r300/radeon_nqssadce.h +++ b/src/mesa/drivers/dri/r300/radeon_nqssadce.h @@ -58,6 +58,7 @@ struct nqssadce_state { */ struct register_state Temps[MAX_PROGRAM_TEMPS]; struct register_state Outputs[VERT_RESULT_MAX]; + struct register_state Address; }; @@ -83,14 +84,10 @@ struct radeon_nqssadce_descr { */ void (*BuildSwizzle)(struct nqssadce_state*, struct prog_dst_register dst, struct prog_src_register src); - /** - * Rewrite instructions that write to DEPR.z to write to DEPR.w - * instead (rewriting is done *before* the WriteMask test). - */ - GLboolean RewriteDepthOut; void *Data; }; void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce_descr* descr); +struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg); #endif /* __RADEON_PROGRAM_NQSSADCE_H_ */ diff --git a/src/mesa/drivers/dri/r300/radeon_program.h b/src/mesa/drivers/dri/r300/radeon_program.h index b411f69bc88..88474d43a22 100644 --- a/src/mesa/drivers/dri/r300/radeon_program.h +++ b/src/mesa/drivers/dri/r300/radeon_program.h @@ -52,6 +52,38 @@ enum { #define SWIZZLE_0000 MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO) #define SWIZZLE_1111 MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE) +static inline GLuint get_swz(GLuint swz, GLuint idx) +{ + if (idx & 0x4) + return idx; + return GET_SWZ(swz, idx); +} + +static inline GLuint combine_swizzles4(GLuint src, GLuint swz_x, GLuint swz_y, GLuint swz_z, GLuint swz_w) +{ + GLuint ret = 0; + + ret |= get_swz(src, swz_x); + ret |= get_swz(src, swz_y) << 3; + ret |= get_swz(src, swz_z) << 6; + ret |= get_swz(src, swz_w) << 9; + + return ret; +} + +static inline GLuint combine_swizzles(GLuint src, GLuint swz) +{ + GLuint ret = 0; + + ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_X)); + ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Y)) << 3; + ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_Z)) << 6; + ret |= get_swz(src, GET_SWZ(swz, SWIZZLE_W)) << 9; + + return ret; +} + + /** * Transformation context that is passed to local transformations. * diff --git a/src/mesa/drivers/dri/r300/radeon_program_pair.c b/src/mesa/drivers/dri/r300/radeon_program_pair.c index 906d36e5226..d6fb474cf23 100644 --- a/src/mesa/drivers/dri/r300/radeon_program_pair.c +++ b/src/mesa/drivers/dri/r300/radeon_program_pair.c @@ -870,7 +870,7 @@ GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program, _mesa_bzero(&s, sizeof(s)); s.Ctx = ctx; - s.Program = program; + s.Program = _mesa_clone_program(ctx, program); s.Handler = handler; s.UserData = userdata; s.Debug = (RADEON_DEBUG & DEBUG_PIXEL) ? GL_TRUE : GL_FALSE; @@ -904,6 +904,8 @@ GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program, _mesa_free(s.ValuePool); _mesa_free(s.ReaderPool); + _mesa_reference_program(ctx, &s.Program, NULL); + return !s.Error; } diff --git a/src/mesa/drivers/dri/r600/r600_emit.c b/src/mesa/drivers/dri/r600/r600_emit.c index 7f25cb18682..ed51e428e9a 100644 --- a/src/mesa/drivers/dri/r600/r600_emit.c +++ b/src/mesa/drivers/dri/r600/r600_emit.c @@ -98,13 +98,12 @@ shader_again_alloc: goto shader_again_alloc; } - radeon_validate_bo(radeonctx, pbo, RADEON_GEM_DOMAIN_GTT, 0); + if (radeon_cs_space_check_with_bo(radeonctx->cmdbuf.cs, + pbo, + RADEON_GEM_DOMAIN_GTT, 0)) + fprintf(stderr,"failure to revalidate BOs - badness\n"); + - if (radeon_revalidate_bos(radeonctx->glCtx) == GL_FALSE) - { - fprintf(stderr,"failure to revalidate BOs - badness\n"); - } - radeon_bo_map(pbo, 1); radeon_bo_ref(pbo); diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c index 5a249d4f14f..f56cc970d40 100644 --- a/src/mesa/drivers/dri/r600/r600_texstate.c +++ b/src/mesa/drivers/dri/r600/r600_texstate.c @@ -541,23 +541,26 @@ GLboolean r600ValidateBuffers(GLcontext * ctx) context_t *rmesa = R700_CONTEXT(ctx); struct radeon_renderbuffer *rrb; int i; + int ret; - radeon_validate_reset_bos(&rmesa->radeon); + radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); rrb = radeon_get_colorbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + rrb->bo, 0, + RADEON_GEM_DOMAIN_VRAM); } /* depth buffer */ rrb = radeon_get_depthbuffer(&rmesa->radeon); if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + rrb->bo, 0, + RADEON_GEM_DOMAIN_VRAM); } - + for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { radeonTexObj *t; @@ -571,17 +574,19 @@ GLboolean r600ValidateBuffers(GLcontext * ctx) } t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); if (t->image_override && t->bo) - radeon_validate_bo(&rmesa->radeon, t->bo, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + t->bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); else if (t->mt->bo) - radeon_validate_bo(&rmesa->radeon, t->mt->bo, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + t->mt->bo, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); } - if (rmesa->radeon.dma.current) - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); - return radeon_revalidate_bos(ctx); + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + return GL_TRUE; } void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname, @@ -714,7 +719,7 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo rImage->mt = NULL; } _mesa_init_teximage_fields(radeon->glCtx, target, texImage, - rb->width, rb->height, 1, 0, rb->cpp); + rb->base.Width, rb->base.Height, 1, 0, rb->cpp); texImage->RowStride = rb->pitch / rb->cpp; texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx, internalFormat, @@ -779,9 +784,9 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo & ~R700_TEXEL_PITCH_ALIGNMENT_MASK; SETfield(t->SQ_TEX_RESOURCE0, (pitch_val/8)-1, PITCH_shift, PITCH_mask); - SETfield(t->SQ_TEX_RESOURCE0, rb->width - 1, + SETfield(t->SQ_TEX_RESOURCE0, rb->base.Width - 1, TEX_WIDTH_shift, TEX_WIDTH_mask); - SETfield(t->SQ_TEX_RESOURCE1, rb->height - 1, + SETfield(t->SQ_TEX_RESOURCE1, rb->base.Height - 1, TEX_HEIGHT_shift, TEX_HEIGHT_mask); t->validated = GL_TRUE; diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c index 76967956761..e484845cc6c 100644 --- a/src/mesa/drivers/dri/r600/r700_clear.c +++ b/src/mesa/drivers/dri/r600/r700_clear.c @@ -44,11 +44,6 @@ static GLboolean r700ClearFast(context_t *context, GLbitfield mask) return GL_FALSE; } -static void r700UserClear(GLcontext *ctx, GLuint mask) -{ - radeon_clear_tris(ctx, mask); -} - #define R600_NEWPRIM( rmesa ) \ do { \ if ( rmesa->radeon.dma.flush ) \ @@ -80,6 +75,8 @@ void r700Clear(GLcontext * ctx, GLbitfield mask) if (colorMask == ~0) tri_mask |= (mask & BUFFER_BITS_COLOR); + else + tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)); /* HW stencil */ @@ -109,8 +106,10 @@ void r700Clear(GLcontext * ctx, GLbitfield mask) /* SW fallback clearing */ swrast_mask = mask & ~tri_mask; - if (tri_mask) - r700UserClear(ctx, tri_mask); + if (tri_mask) { + radeonUserClear(ctx, tri_mask); + } + if (swrast_mask) { if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index ba409ba8130..b59ad68f445 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -10,6 +10,10 @@ LIBNAME = radeon_dri.so MINIGLX_SOURCES = server/radeon_dri.c +ifeq ($(RADEON_LDFLAGS),) +CS_SOURCES = radeon_cs_space_drm.c +endif + RADEON_COMMON_SOURCES = \ radeon_texture.c \ radeon_common_context.c \ @@ -38,7 +42,8 @@ DRIVER_SOURCES = \ C_SOURCES = \ $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) + $(DRIVER_SOURCES) \ + $(CS_SOURCES) DRIVER_DEFINES = -DRADEON_COMMON=0 diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h index 5720957c78a..655b52a6694 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h +++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h @@ -82,6 +82,7 @@ struct radeon_bo_funcs { int (*bo_map)(struct radeon_bo *bo, int write); int (*bo_unmap)(struct radeon_bo *bo); int (*bo_wait)(struct radeon_bo *bo); + int (*bo_is_static)(struct radeon_bo *bo); }; struct radeon_bo_manager { @@ -185,6 +186,7 @@ static inline int _radeon_bo_wait(struct radeon_bo *bo, { return bo->bom->funcs->bo_wait(bo); } + #ifdef RADEON_DEBUG_BO #define radeon_bo_open(bom, h, s, a, d, f, u)\ _radeon_bo_open(bom, h, s, a, d, f, u, __FILE__, __FUNCTION__, __LINE__) diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c index 94c2d978256..992eb4611b1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c @@ -562,12 +562,21 @@ static int bo_unmap(struct radeon_bo *bo) return 0; } + +static int bo_is_static(struct radeon_bo *bo) +{ + struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; + return bo_legacy->static_bo; +} + static struct radeon_bo_funcs bo_legacy_funcs = { bo_open, bo_ref, bo_unref, bo_map, - bo_unmap + bo_unmap, + NULL, + bo_is_static, }; static int bo_vram_validate(struct radeon_bo *bo, @@ -895,9 +904,3 @@ unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo) return bo->size; } -int radeon_legacy_bo_is_static(struct radeon_bo *bo) -{ - struct bo_legacy *bo_legacy = (struct bo_legacy*)bo; - return bo_legacy->static_bo; -} - diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h index 6f1a0b45358..e0c70dd9a11 100644 --- a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h +++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h @@ -1,21 +1,6 @@ #ifndef RADEON_CS_WRAPPER_H #define RADEON_CS_WRAPPER_H -#ifndef RADEON_PARAM_DEVICE_ID -#define RADEON_PARAM_DEVICE_ID 16 -#endif - -#ifndef RADEON_INFO_DEVICE_ID -#define RADEON_INFO_DEVICE_ID 0 -#endif -#ifndef RADEON_INFO_NUM_GB_PIPES -#define RADEON_INFO_NUM_GB_PIPES 0 -#endif - -#ifndef DRM_RADEON_INFO -#define DRM_RADEON_INFO 0x1 -#endif - #ifdef HAVE_LIBDRM_RADEON #include "radeon_bo.h" @@ -50,6 +35,21 @@ struct drm_radeon_info { }; #endif +#ifndef RADEON_PARAM_DEVICE_ID +#define RADEON_PARAM_DEVICE_ID 16 +#endif + +#ifndef RADEON_INFO_DEVICE_ID +#define RADEON_INFO_DEVICE_ID 0 +#endif +#ifndef RADEON_INFO_NUM_GB_PIPES +#define RADEON_INFO_NUM_GB_PIPES 0 +#endif + +#ifndef DRM_RADEON_INFO +#define DRM_RADEON_INFO 0x1 +#endif + static inline uint32_t radeon_gem_name_bo(struct radeon_bo *dummy) { diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 59ae7814aa3..dde615a4d9d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -45,6 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/glheader.h" #include "main/imports.h" #include "main/context.h" +#include "main/arrayobj.h" #include "main/api_arrayelt.h" #include "main/enums.h" #include "main/colormac.h" @@ -221,7 +222,7 @@ void radeonUpdateScissor( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if ( radeon_get_drawable(rmesa) ) { + if ( !ctx->DrawBuffer->Name ) { __DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa); int x = ctx->Scissor.X; @@ -233,9 +234,14 @@ void radeonUpdateScissor( GLcontext *ctx ) rmesa->state.scissor.rect.y1 = y + dPriv->y; rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; - - radeonRecalcScissorRects( rmesa ); + } else { + rmesa->state.scissor.rect.x1 = ctx->Scissor.X; + rmesa->state.scissor.rect.y1 = ctx->Scissor.Y; + rmesa->state.scissor.rect.x2 = ctx->Scissor.X + ctx->Scissor.Width; + rmesa->state.scissor.rect.y2 = ctx->Scissor.Y + ctx->Scissor.Height; } + + radeonRecalcScissorRects( rmesa ); } /* ============================================================= @@ -739,7 +745,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) } if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { - rrbStencil = radeon_renderbuffer(fb->_DepthBuffer->Wrapped); + rrbStencil = radeon_renderbuffer(fb->_StencilBuffer->Wrapped); if (rrbStencil && rrbStencil->bo) { radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); /* need to re-compute stencil hw state */ @@ -771,9 +777,8 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) ctx->Driver.Enable(ctx, GL_DEPTH_TEST, (ctx->Depth.Test && fb->Visual.depthBits > 0)); /* Need to update the derived ctx->Stencil._Enabled first */ - _mesa_update_stencil(ctx); ctx->Driver.Enable(ctx, GL_STENCIL_TEST, - (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0)); + (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0)); } else { ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL); } @@ -844,6 +849,17 @@ void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) void radeonReadBuffer( GLcontext *ctx, GLenum mode ) { + if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { + struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); + const GLboolean was_front_buffer_reading = rmesa->is_front_buffer_reading; + rmesa->is_front_buffer_reading = (mode == GL_FRONT_LEFT) + || (mode == GL_FRONT); + + if (!was_front_buffer_reading && rmesa->is_front_buffer_reading) { + radeon_update_renderbuffers(rmesa->dri.context, + rmesa->dri.context->driReadablePriv); + } + } /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ if (ctx->ReadBuffer == ctx->DrawBuffer) { /* This will update FBO completeness status. @@ -887,9 +903,14 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he if (!driContext->driScreenPriv->dri2.enabled) return; - radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); - if (driContext->driDrawablePriv != driContext->driReadablePriv) - radeon_update_renderbuffers(driContext, driContext->driReadablePriv); + if (!radeon->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) { + if (radeon->is_front_buffer_rendering) { + radeonFlush(ctx); + } + radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); + if (driContext->driDrawablePriv != driContext->driReadablePriv) + radeon_update_renderbuffers(driContext, driContext->driReadablePriv); + } old_viewport = ctx->Driver.Viewport; ctx->Driver.Viewport = NULL; @@ -989,52 +1010,17 @@ static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty) COMMIT_BATCH(); } -GLboolean radeon_revalidate_bos(GLcontext *ctx) +static GLboolean radeon_revalidate_bos(GLcontext *ctx) { radeonContextPtr radeon = RADEON_CONTEXT(ctx); - int flushed = 0; int ret; -again: - ret = radeon_cs_space_check(radeon->cmdbuf.cs, radeon->state.bos, radeon->state.validated_bo_count); - if (ret == RADEON_CS_SPACE_OP_TO_BIG) + + ret = radeon_cs_space_check(radeon->cmdbuf.cs); + if (ret == RADEON_CS_SPACE_FLUSH) return GL_FALSE; - if (ret == RADEON_CS_SPACE_FLUSH) { - if (ctx->Driver.Flush) - ctx->Driver.Flush(ctx); /* +r6/r7 */ - if (flushed) - return GL_FALSE; - flushed = 1; - goto again; - } return GL_TRUE; } -void radeon_validate_reset_bos(radeonContextPtr radeon) -{ - int i; - - for (i = 0; i < radeon->state.validated_bo_count; i++) { - radeon_bo_unref(radeon->state.bos[i].bo); - radeon->state.bos[i].bo = NULL; - radeon->state.bos[i].read_domains = 0; - radeon->state.bos[i].write_domain = 0; - radeon->state.bos[i].new_accounted = 0; - } - radeon->state.validated_bo_count = 0; -} - -void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) -{ - radeon_bo_ref(bo); - radeon->state.bos[radeon->state.validated_bo_count].bo = bo; - radeon->state.bos[radeon->state.validated_bo_count].read_domains = read_domains; - radeon->state.bos[radeon->state.validated_bo_count].write_domain = write_domain; - radeon->state.bos[radeon->state.validated_bo_count].new_accounted = 0; - radeon->state.validated_bo_count++; - - assert(radeon->state.validated_bo_count < RADEON_MAX_BOS); -} - void radeonEmitState(radeonContextPtr radeon) { if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS)) @@ -1249,6 +1235,9 @@ void rcommonInitCmdBuf(radeonContextPtr rmesa) assert(rmesa->cmdbuf.cs != NULL); rmesa->cmdbuf.size = size; + radeon_cs_space_set_flush(rmesa->cmdbuf.cs, + (void (*)(void *))radeonFlush, rmesa->glCtx); + if (!rmesa->radeonScreen->kernel_mm) { radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]); radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size); @@ -1296,228 +1285,8 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n, } - - -static void -radeon_meta_set_passthrough_transform(radeonContextPtr radeon) -{ - GLcontext *ctx = radeon->glCtx; - - radeon->meta.saved_vp_x = ctx->Viewport.X; - radeon->meta.saved_vp_y = ctx->Viewport.Y; - radeon->meta.saved_vp_width = ctx->Viewport.Width; - radeon->meta.saved_vp_height = ctx->Viewport.Height; - radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - - _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); - _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PushMatrix(); - _mesa_LoadIdentity(); -} - -static void -radeon_meta_restore_transform(radeonContextPtr radeon) -{ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_PopMatrix(); - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_PopMatrix(); - - _mesa_MatrixMode(radeon->meta.saved_matrix_mode); - - _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y, - radeon->meta.saved_vp_width, radeon->meta.saved_vp_height); -} - - -/** - * Perform glClear where mask contains only color, depth, and/or stencil. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering. The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ - - -void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) +void radeonUserClear(GLcontext *ctx, GLuint mask) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat vertices[4][3]; - GLfloat color[4][4]; - GLfloat dst_z; - struct gl_framebuffer *fb = ctx->DrawBuffer; - int i; - GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; - GLboolean saved_shader_program = 0; - unsigned int saved_active_texture; - - assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | - BUFFER_BIT_STENCIL)) == 0); - - _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | - GL_CURRENT_BIT | - GL_DEPTH_BUFFER_BIT | - GL_ENABLE_BIT | - GL_POLYGON_BIT | - GL_STENCIL_BUFFER_BIT | - GL_TRANSFORM_BIT | - GL_CURRENT_BIT); - _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); - saved_active_texture = ctx->Texture.CurrentUnit; - - /* Disable existing GL state we don't want to apply to a clear. */ - _mesa_Disable(GL_ALPHA_TEST); - _mesa_Disable(GL_BLEND); - _mesa_Disable(GL_CULL_FACE); - _mesa_Disable(GL_FOG); - _mesa_Disable(GL_POLYGON_SMOOTH); - _mesa_Disable(GL_POLYGON_STIPPLE); - _mesa_Disable(GL_POLYGON_OFFSET_FILL); - _mesa_Disable(GL_LIGHTING); - _mesa_Disable(GL_CLIP_PLANE0); - _mesa_Disable(GL_CLIP_PLANE1); - _mesa_Disable(GL_CLIP_PLANE2); - _mesa_Disable(GL_CLIP_PLANE3); - _mesa_Disable(GL_CLIP_PLANE4); - _mesa_Disable(GL_CLIP_PLANE5); - _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { - saved_fp_enable = GL_TRUE; - _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { - saved_vp_enable = GL_TRUE; - _mesa_Disable(GL_VERTEX_PROGRAM_ARB); - } - if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { - saved_shader_program = ctx->Shader.CurrentProgram->Name; - _mesa_UseProgramObjectARB(0); - } - - if (ctx->Texture._EnabledUnits != 0) { - int i; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - _mesa_ActiveTextureARB(GL_TEXTURE0 + i); - _mesa_Disable(GL_TEXTURE_1D); - _mesa_Disable(GL_TEXTURE_2D); - _mesa_Disable(GL_TEXTURE_3D); - if (ctx->Extensions.ARB_texture_cube_map) - _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); - if (ctx->Extensions.NV_texture_rectangle) - _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); - if (ctx->Extensions.MESA_texture_array) { - _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); - _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); - } - } - } - -#if FEATURE_ARB_vertex_buffer_object - _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); -#endif - - radeon_meta_set_passthrough_transform(rmesa); - - for (i = 0; i < 4; i++) { - color[i][0] = ctx->Color.ClearColor[0]; - color[i][1] = ctx->Color.ClearColor[1]; - color[i][2] = ctx->Color.ClearColor[2]; - color[i][3] = ctx->Color.ClearColor[3]; - } - - /* convert clear Z from [0,1] to NDC coord in [-1,1] */ - - dst_z = -1.0 + 2.0 * ctx->Depth.Clear; - /* Prepare the vertices, which are the same regardless of which buffer we're - * drawing to. - */ - vertices[0][0] = fb->_Xmin; - vertices[0][1] = fb->_Ymin; - vertices[0][2] = dst_z; - vertices[1][0] = fb->_Xmax; - vertices[1][1] = fb->_Ymin; - vertices[1][2] = dst_z; - vertices[2][0] = fb->_Xmax; - vertices[2][1] = fb->_Ymax; - vertices[2][2] = dst_z; - vertices[3][0] = fb->_Xmin; - vertices[3][1] = fb->_Ymax; - vertices[3][2] = dst_z; - - _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); - _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); - _mesa_Enable(GL_COLOR_ARRAY); - _mesa_Enable(GL_VERTEX_ARRAY); - - while (mask != 0) { - GLuint this_mask = 0; - GLuint color_bit; - - color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); - if (color_bit != 0) - this_mask |= (1 << (color_bit - 1)); - - /* Clear depth/stencil in the same pass as color. */ - this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - - /* Select the current color buffer and use the color write mask if - * we have one, otherwise don't write any color channels. - */ - if (this_mask & BUFFER_BIT_FRONT_LEFT) - _mesa_DrawBuffer(GL_FRONT_LEFT); - else if (this_mask & BUFFER_BIT_BACK_LEFT) - _mesa_DrawBuffer(GL_BACK_LEFT); - else if (color_bit != 0) - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + - (color_bit - BUFFER_COLOR0 - 1)); - else - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - /* Control writing of the depth clear value to depth. */ - if (this_mask & BUFFER_BIT_DEPTH) { - _mesa_DepthFunc(GL_ALWAYS); - _mesa_DepthMask(GL_TRUE); - _mesa_Enable(GL_DEPTH_TEST); - } else { - _mesa_Disable(GL_DEPTH_TEST); - _mesa_DepthMask(GL_FALSE); - } - - /* Control writing of the stencil clear value to stencil. */ - if (this_mask & BUFFER_BIT_STENCIL) { - _mesa_Enable(GL_STENCIL_TEST); - _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, ctx->Stencil.Clear, - ctx->Stencil.WriteMask[0]); - } else { - _mesa_Disable(GL_STENCIL_TEST); - } - - CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); - - mask &= ~this_mask; - } - - radeon_meta_restore_transform(rmesa); - - _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); - if (saved_fp_enable) - _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); - if (saved_vp_enable) - _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - - if (saved_shader_program) - _mesa_UseProgramObjectARB(saved_shader_program); - - _mesa_PopClientAttrib(); - _mesa_PopAttrib(); + meta_clear_tris(&rmesa->meta, mask); } diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index 2cefb53fe04..cebae18b2d6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -5,23 +5,7 @@ #include "radeon_dma.h" #include "radeon_texture.h" -#ifndef HAVE_LIBDRM_RADEON -#ifndef RADEON_DEBUG_BO -#define RADEON_DEBUG_BO 1 -#endif -#endif - -#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \ - BUFFER_BIT_FRONT_LEFT | \ - BUFFER_BIT_COLOR0 | \ - BUFFER_BIT_COLOR1 | \ - BUFFER_BIT_COLOR2 | \ - BUFFER_BIT_COLOR3 | \ - BUFFER_BIT_COLOR4 | \ - BUFFER_BIT_COLOR5 | \ - BUFFER_BIT_COLOR6 | \ - BUFFER_BIT_COLOR7) - +void radeonUserClear(GLcontext *ctx, GLuint mask); void radeonRecalcScissorRects(radeonContextPtr radeon); void radeonSetCliprects(radeonContextPtr radeon); void radeonUpdateScissor( GLcontext *ctx ); @@ -52,10 +36,6 @@ void radeon_get_cliprects(radeonContextPtr radeon, struct drm_clip_rect **cliprects, unsigned int *num_cliprects, int *x_off, int *y_off); -GLboolean radeon_revalidate_bos(GLcontext *ctx); -void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain); -void radeon_validate_reset_bos(radeonContextPtr radeon); - void radeon_fbo_init(struct radeon_context *radeon); void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 1c7faf048d0..bbe7225ee6c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -190,6 +190,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, ctx = radeon->glCtx; driContextPriv->driverPrivate = radeon; + meta_init_metaops(ctx, &radeon->meta); /* DRI fields */ radeon->dri.context = driContextPriv; radeon->dri.screen = sPriv; @@ -286,7 +287,7 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv ) } radeonReleaseArrays(radeon->glCtx, ~0); - + meta_destroy_metaops(&radeon->meta); if (radeon->vtbl.free_context) radeon->vtbl.free_context(radeon->glCtx); _swsetup_DestroyContext( radeon->glCtx ); @@ -596,8 +597,10 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct radeon_renderbuffer *stencil_rb; i = 0; - if ((radeon->is_front_buffer_rendering || !draw->color_rb[1]) - && draw->color_rb[0]) { + if ((radeon->is_front_buffer_rendering || + radeon->is_front_buffer_reading || + !draw->color_rb[1]) + && draw->color_rb[0]) { attachments[i++] = __DRI_BUFFER_FRONT_LEFT; attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]); } @@ -715,8 +718,8 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) rb->cpp = buffers[i].cpp; rb->pitch = buffers[i].pitch; - rb->width = drawable->w; - rb->height = drawable->h; + rb->base.Width = drawable->w; + rb->base.Height = drawable->h; rb->has_surface = 0; if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 43e705ee593..e4a8da05965 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -13,6 +13,7 @@ #include "dri_util.h" #include "tnl/t_vertex.h" +#include "dri_metaops.h" struct radeon_context; #include "radeon_bocs_wrapper.h" @@ -83,8 +84,6 @@ struct radeon_renderbuffer unsigned int cpp; /* unsigned int offset; */ unsigned int pitch; - unsigned int width; - unsigned int height; uint32_t draw_offset; /* FBO */ /* boo Xorg 6.8.2 compat */ @@ -482,19 +481,16 @@ struct radeon_context { */ GLboolean is_front_buffer_rendering; - struct { - struct gl_fragment_program *bitmap_fp; - struct gl_vertex_program *passthrough_vp; - - struct gl_fragment_program *saved_fp; - GLboolean saved_fp_enable; - struct gl_vertex_program *saved_vp; - GLboolean saved_vp_enable; + /** + * Track whether front-buffer is the current read target. + * + * This is closely associated with is_front_buffer_rendering, but may + * be set separately. The DRI2 fake front buffer must be referenced + * either way. + */ + GLboolean is_front_buffer_reading; - GLint saved_vp_x, saved_vp_y; - GLsizei saved_vp_width, saved_vp_height; - GLenum saved_matrix_mode; - } meta; + struct dri_metaops meta; struct { void (*get_lock)(radeonContextPtr radeon); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 8f780c443c9..c457fb654ea 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -285,8 +285,10 @@ r100CreateContext( const __GLcontextModes *glVisual, /* FIXME: When no memory manager is available we should set this * to some reasonable value based on texture memory pool size */ - /* FIXME: does r100 support 2048x2048 texture ? */ ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = 2048; ctx->Const.MaxTextureMaxAnisotropy = 16.0; @@ -316,6 +318,8 @@ r100CreateContext( const __GLcontextModes *glVisual, ctx->Const.MaxDrawBuffers = 1; + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); @@ -361,7 +365,7 @@ r100CreateContext( const __GLcontextModes *glVisual, _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); } - if (rmesa->radeon.dri.drmMinor >= 9) + if (rmesa->radeon.radeonScreen->kernel_mm || rmesa->radeon.dri.drmMinor >= 9) _mesa_enable_extension( ctx, "GL_NV_texture_rectangle"); /* XXX these should really go right after _mesa_init_driver_functions() */ diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h index 984725a6c9d..ee403d173cc 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h +++ b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h @@ -56,6 +56,8 @@ struct radeon_cs_space_check { uint32_t new_accounted; }; +#define MAX_SPACE_BOS (32) + struct radeon_cs_manager; struct radeon_cs { @@ -72,7 +74,10 @@ struct radeon_cs { const char *section_file; const char *section_func; int section_line; - + struct radeon_cs_space_check bos[MAX_SPACE_BOS]; + int bo_count; + void (*space_flush_fn)(void *); + void *space_flush_data; }; /* cs functions */ @@ -98,16 +103,14 @@ struct radeon_cs_funcs { int (*cs_erase)(struct radeon_cs *cs); int (*cs_need_flush)(struct radeon_cs *cs); void (*cs_print)(struct radeon_cs *cs, FILE *file); - int (*cs_space_check)(struct radeon_cs *cs, struct radeon_cs_space_check *bos, - int num_bo); }; struct radeon_cs_manager { struct radeon_cs_funcs *funcs; int fd; - uint32_t vram_limit, gart_limit; - uint32_t vram_write_used, gart_write_used; - uint32_t read_used; + int32_t vram_limit, gart_limit; + int32_t vram_write_used, gart_write_used; + int32_t read_used; }; static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm, @@ -171,13 +174,6 @@ static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file) cs->csm->funcs->cs_print(cs, file); } -static inline int radeon_cs_space_check(struct radeon_cs *cs, - struct radeon_cs_space_check *bos, - int num_bo) -{ - return cs->csm->funcs->cs_space_check(cs, bos, num_bo); -} - static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit) { @@ -204,4 +200,38 @@ static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword) cs->section_cdw+=2; } } + +static inline void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data) +{ + cs->space_flush_fn = fn; + cs->space_flush_data = data; +} + + +/* + * add a persistent BO to the list + * a persistent BO is one that will be referenced across flushes, + * i.e. colorbuffer, textures etc. + * They get reset when a new "operation" happens, where an operation + * is a state emission with a color/textures etc followed by a bunch of vertices. + */ +void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domains, + uint32_t write_domain); + +/* reset the persistent BO list */ +void radeon_cs_space_reset_bos(struct radeon_cs *cs); + +/* do a space check with the current persistent BO list */ +int radeon_cs_space_check(struct radeon_cs *cs); + +/* do a space check with the current persistent BO list and a temporary BO + * a temporary BO is like a DMA buffer, which gets flushed with the + * command buffer */ +int radeon_cs_space_check_with_bo(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domains, + uint32_t write_domain); + #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index a2727ef6f7f..4f1065ebcf3 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -373,113 +373,6 @@ static void cs_print(struct radeon_cs *cs, FILE *file) { } -static int cs_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo) -{ - struct radeon_cs_manager *csm = cs->csm; - int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0; - uint32_t read_domains, write_domain; - int i; - struct radeon_bo *bo; - - /* check the totals for this operation */ - - if (num_bo == 0) - return 0; - - /* prepare */ - for (i = 0; i < num_bo; i++) - { - bo = bos[i].bo; - - bos[i].new_accounted = 0; - read_domains = bos[i].read_domains; - write_domain = bos[i].write_domain; - - /* pinned bos don't count */ - if (radeon_legacy_bo_is_static(bo)) - continue; - - /* already accounted this bo */ - if (write_domain && (write_domain == bo->space_accounted)) - continue; - - if (read_domains && ((read_domains << 16) == bo->space_accounted)) - continue; - - if (bo->space_accounted == 0) - { - if (write_domain == RADEON_GEM_DOMAIN_VRAM) - this_op_vram_write += bo->size; - else if (write_domain == RADEON_GEM_DOMAIN_GTT) - this_op_gart_write += bo->size; - else - this_op_read += bo->size; - bos[i].new_accounted = (read_domains << 16) | write_domain; - } - else - { - uint16_t old_read, old_write; - - old_read = bo->space_accounted >> 16; - old_write = bo->space_accounted & 0xffff; - - if (write_domain && (old_read & write_domain)) - { - bos[i].new_accounted = write_domain; - /* moving from read to a write domain */ - if (write_domain == RADEON_GEM_DOMAIN_VRAM) - { - this_op_read -= bo->size; - this_op_vram_write += bo->size; - } - else if (write_domain == RADEON_GEM_DOMAIN_VRAM) - { - this_op_read -= bo->size; - this_op_gart_write += bo->size; - } - } - else if (read_domains & old_write) - { - bos[i].new_accounted = bo->space_accounted & 0xffff; - } - else - { - /* rewrite the domains */ - if (write_domain != old_write) - fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write); - if (read_domains != old_read) - fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read); - return RADEON_CS_SPACE_FLUSH; - } - } - } - - if (this_op_read < 0) - this_op_read = 0; - - /* check sizes - operation first */ - if ((this_op_read + this_op_gart_write > csm->gart_limit) || - (this_op_vram_write > csm->vram_limit)) { - return RADEON_CS_SPACE_OP_TO_BIG; - } - - if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) || - ((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) { - return RADEON_CS_SPACE_FLUSH; - } - - csm->gart_write_used += this_op_gart_write; - csm->vram_write_used += this_op_vram_write; - csm->read_used += this_op_read; - /* commit */ - for (i = 0; i < num_bo; i++) { - bo = bos[i].bo; - bo->space_accounted = bos[i].new_accounted; - } - - return RADEON_CS_SPACE_OK; -} - static struct radeon_cs_funcs radeon_cs_legacy_funcs = { cs_create, cs_write_reloc, @@ -490,7 +383,6 @@ static struct radeon_cs_funcs radeon_cs_legacy_funcs = { cs_erase, cs_need_flush, cs_print, - cs_check_space }; struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx) diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c new file mode 100644 index 00000000000..5a8df7bb8cd --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c @@ -0,0 +1,234 @@ +/* + * Copyright © 2009 Red Hat Inc. + * 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 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 THE COPYRIGHT HOLDERS, AUTHORS + * 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + */ +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include "radeon_bocs_wrapper.h" + +struct rad_sizes { + int32_t op_read; + int32_t op_gart_write; + int32_t op_vram_write; +}; + +static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc, struct rad_sizes *sizes) +{ + uint32_t read_domains, write_domain; + struct radeon_bo *bo; + + bo = sc->bo; + sc->new_accounted = 0; + read_domains = sc->read_domains; + write_domain = sc->write_domain; + + /* legacy needs a static check */ + if (radeon_bo_is_static(bo)) { + bo->space_accounted = sc->new_accounted = (read_domains << 16) | write_domain; + return 0; + } + + /* already accounted this bo */ + if (write_domain && (write_domain == bo->space_accounted)) { + sc->new_accounted = bo->space_accounted; + return 0; + } + if (read_domains && ((read_domains << 16) == bo->space_accounted)) { + sc->new_accounted = bo->space_accounted; + return 0; + } + + if (bo->space_accounted == 0) { + if (write_domain == RADEON_GEM_DOMAIN_VRAM) + sizes->op_vram_write += bo->size; + else if (write_domain == RADEON_GEM_DOMAIN_GTT) + sizes->op_gart_write += bo->size; + else + sizes->op_read += bo->size; + sc->new_accounted = (read_domains << 16) | write_domain; + } else { + uint16_t old_read, old_write; + + old_read = bo->space_accounted >> 16; + old_write = bo->space_accounted & 0xffff; + + if (write_domain && (old_read & write_domain)) { + sc->new_accounted = write_domain; + /* moving from read to a write domain */ + if (write_domain == RADEON_GEM_DOMAIN_VRAM) { + sizes->op_read -= bo->size; + sizes->op_vram_write += bo->size; + } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) { + sizes->op_read -= bo->size; + sizes->op_gart_write += bo->size; + } + } else if (read_domains & old_write) { + sc->new_accounted = bo->space_accounted & 0xffff; + } else { + /* rewrite the domains */ + if (write_domain != old_write) + fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write); + if (read_domains != old_read) + fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read); + return RADEON_CS_SPACE_FLUSH; + } + } + return 0; +} + +static int radeon_cs_do_space_check(struct radeon_cs *cs, struct radeon_cs_space_check *new_tmp) +{ + struct radeon_cs_manager *csm = cs->csm; + int i; + struct radeon_bo *bo; + struct rad_sizes sizes; + int ret; + + /* check the totals for this operation */ + + if (cs->bo_count == 0 && !new_tmp) + return 0; + + memset(&sizes, 0, sizeof(struct rad_sizes)); + + /* prepare */ + for (i = 0; i < cs->bo_count; i++) { + ret = radeon_cs_setup_bo(&cs->bos[i], &sizes); + if (ret) + return ret; + } + + if (new_tmp) { + ret = radeon_cs_setup_bo(new_tmp, &sizes); + if (ret) + return ret; + } + + if (sizes.op_read < 0) + sizes.op_read = 0; + + /* check sizes - operation first */ + if ((sizes.op_read + sizes.op_gart_write > csm->gart_limit) || + (sizes.op_vram_write > csm->vram_limit)) { + return RADEON_CS_SPACE_OP_TO_BIG; + } + + if (((csm->vram_write_used + sizes.op_vram_write) > csm->vram_limit) || + ((csm->read_used + csm->gart_write_used + sizes.op_gart_write + sizes.op_read) > csm->gart_limit)) { + return RADEON_CS_SPACE_FLUSH; + } + + csm->gart_write_used += sizes.op_gart_write; + csm->vram_write_used += sizes.op_vram_write; + csm->read_used += sizes.op_read; + /* commit */ + for (i = 0; i < cs->bo_count; i++) { + bo = cs->bos[i].bo; + bo->space_accounted = cs->bos[i].new_accounted; + } + if (new_tmp) + new_tmp->bo->space_accounted = new_tmp->new_accounted; + + return RADEON_CS_SPACE_OK; +} + +void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) +{ + int i; + for (i = 0; i < cs->bo_count; i++) { + if (cs->bos[i].bo == bo && + cs->bos[i].read_domains == read_domains && + cs->bos[i].write_domain == write_domain) + return; + } + radeon_bo_ref(bo); + i = cs->bo_count; + cs->bos[i].bo = bo; + cs->bos[i].read_domains = read_domains; + cs->bos[i].write_domain = write_domain; + cs->bos[i].new_accounted = 0; + cs->bo_count++; + + assert(cs->bo_count < MAX_SPACE_BOS); +} + +static int radeon_cs_check_space_internal(struct radeon_cs *cs, struct radeon_cs_space_check *tmp_bo) +{ + int ret; + int flushed = 0; + +again: + ret = radeon_cs_do_space_check(cs, tmp_bo); + if (ret == RADEON_CS_SPACE_OP_TO_BIG) + return -1; + if (ret == RADEON_CS_SPACE_FLUSH) { + (*cs->space_flush_fn)(cs->space_flush_data); + if (flushed) + return -1; + flushed = 1; + goto again; + } + return 0; +} + +int radeon_cs_space_check_with_bo(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t read_domains, uint32_t write_domain) +{ + struct radeon_cs_space_check temp_bo; + int ret = 0; + + if (bo) { + temp_bo.bo = bo; + temp_bo.read_domains = read_domains; + temp_bo.write_domain = write_domain; + temp_bo.new_accounted = 0; + } + + ret = radeon_cs_check_space_internal(cs, bo ? &temp_bo : NULL); + return ret; +} + +int radeon_cs_space_check(struct radeon_cs *cs) +{ + return radeon_cs_check_space_internal(cs, NULL); +} + +void radeon_cs_space_reset_bos(struct radeon_cs *cs) +{ + int i; + for (i = 0; i < cs->bo_count; i++) { + radeon_bo_unref(cs->bos[i].bo); + cs->bos[i].bo = NULL; + cs->bos[i].read_domains = 0; + cs->bos[i].write_domain = 0; + cs->bos[i].new_accounted = 0; + } + cs->bo_count = 0; +} + + diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c index 2fbf89bf6de..48114a00126 100644 --- a/src/mesa/drivers/dri/radeon/radeon_dma.c +++ b/src/mesa/drivers/dri/radeon/radeon_dma.c @@ -204,10 +204,10 @@ again_alloc: rmesa->dma.current_used = 0; rmesa->dma.current_vertexptr = 0; - radeon_validate_bo(rmesa, rmesa->dma.current, RADEON_GEM_DOMAIN_GTT, 0); - - if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) - fprintf(stderr,"failure to revalidate BOs - badness\n"); + if (radeon_cs_space_check_with_bo(rmesa->cmdbuf.cs, + rmesa->dma.current, + RADEON_GEM_DOMAIN_GTT, 0)) + fprintf(stderr,"failure to revalidate BOs - badness\n"); if (!rmesa->dma.current) { /* Cmd buff have been flushed in radeon_revalidate_bos */ @@ -305,7 +305,7 @@ restart: if (!rmesa->dma.flush) { /* make sure we have enough space to use this in cmdbuf */ rcommonEnsureCmdBufSpace(rmesa, - rmesa->hw.max_state_size + (12*sizeof(int)), + rmesa->hw.max_state_size + (20*sizeof(int)), __FUNCTION__); /* if cmdbuf flushed DMA restart */ if (!rmesa->dma.current) diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index ea18f1ee2db..f28efa33e9a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -146,8 +146,8 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32: - rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; - rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->_ActualFormat = GL_DEPTH_COMPONENT24; + rb->DataType = GL_UNSIGNED_INT; rb->DepthBits = 24; cpp = 4; break; @@ -316,7 +316,7 @@ radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv) rrb->base.DataType = GL_UNSIGNED_SHORT; break; case GL_DEPTH_COMPONENT24: - rrb->base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rrb->base._ActualFormat = GL_DEPTH_COMPONENT24; rrb->base._BaseFormat = GL_DEPTH_COMPONENT; rrb->base.DepthBits = 24; rrb->base.DataType = GL_UNSIGNED_INT; @@ -410,6 +410,20 @@ restart: rrb->base.DataType = GL_UNSIGNED_SHORT; DBG("Render to RGB5 texture OK\n"); } + else if (texImage->TexFormat == &_mesa_texformat_argb1555) { + rrb->cpp = 2; + rrb->base._ActualFormat = GL_RGB5_A1; + rrb->base._BaseFormat = GL_RGBA; + rrb->base.DataType = GL_UNSIGNED_BYTE; + DBG("Render to ARGB1555 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_argb4444) { + rrb->cpp = 2; + rrb->base._ActualFormat = GL_RGBA4; + rrb->base._BaseFormat = GL_RGBA; + rrb->base.DataType = GL_UNSIGNED_BYTE; + DBG("Render to ARGB1555 texture OK\n"); + } else if (texImage->TexFormat == &_mesa_texformat_z16) { rrb->cpp = 2; rrb->base._ActualFormat = GL_DEPTH_COMPONENT16; @@ -448,6 +462,7 @@ restart: rrb->base.BlueBits = texImage->TexFormat->BlueBits; rrb->base.AlphaBits = texImage->TexFormat->AlphaBits; rrb->base.DepthBits = texImage->TexFormat->DepthBits; + rrb->base.StencilBits = texImage->TexFormat->StencilBits; rrb->base.Delete = radeon_delete_renderbuffer; rrb->base.AllocStorage = radeon_nop_alloc_storage; diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 01c45df2dfa..a5e4df79415 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -445,11 +445,6 @@ void radeonEmitAOS( r100ContextPtr rmesa, */ #define RADEON_MAX_CLEARS 256 -static void radeonUserClear(GLcontext *ctx, GLuint mask) -{ - radeon_clear_tris(ctx, mask); -} - static void radeonKernelClear(GLcontext *ctx, GLuint flags) { r100ContextPtr rmesa = R100_CONTEXT(ctx); diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index e28f28662b4..b2a468b4fd6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -51,54 +51,63 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb); -static GLubyte *radeon_ptr32(const struct radeon_renderbuffer * rrb, +/* radeon tiling on r300-r500 has 4 states, + macro-linear/micro-linear + macro-linear/micro-tiled + macro-tiled /micro-linear + macro-tiled /micro-tiled + 1 byte surface + 2 byte surface - two types - we only provide 8x2 microtiling + 4 byte surface + 8/16 byte (unused) +*/ + +static GLubyte *radeon_ptr_4byte(const struct radeon_renderbuffer * rrb, GLint x, GLint y) { GLubyte *ptr = rrb->bo->ptr; uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; GLint offset; - GLint nmacroblkpl; - GLint nmicroblkpl; if (rrb->has_surface || !(rrb->bo->flags & mask)) { offset = x * rrb->cpp + y * rrb->pitch; } else { offset = 0; if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - nmacroblkpl = rrb->pitch >> 5; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x >> 5) << 11; - offset += ((x & 31) >> 2) << 5; - offset += (x & 3) << 2; + if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { + offset = ((y >> 4) * (rrb->pitch >> 7) + (x >> 5)) << 11; + offset += (((y >> 3) ^ (x >> 5)) & 0x1) << 10; + offset += (((y >> 4) ^ (x >> 4)) & 0x1) << 9; + offset += (((y >> 2) ^ (x >> 4)) & 0x1) << 8; + offset += (((y >> 3) ^ (x >> 3)) & 0x1) << 7; + offset += ((y >> 1) & 0x1) << 6; + offset += ((x >> 2) & 0x1) << 5; + offset += (y & 1) << 4; + offset += (x & 3) << 2; } else { - nmacroblkpl = rrb->pitch >> 6; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x >> 6) << 11; - offset += ((x & 63) >> 3) << 5; - offset += (x & 7) << 2; + offset = ((y >> 3) * (rrb->pitch >> 8) + (x >> 6)) << 11; + offset += (((y >> 2) ^ (x >> 6)) & 0x1) << 10; + offset += (((y >> 3) ^ (x >> 5)) & 0x1) << 9; + offset += (((y >> 1) ^ (x >> 5)) & 0x1) << 8; + offset += (((y >> 2) ^ (x >> 4)) & 0x1) << 7; + offset += (y & 1) << 6; + offset += (x & 15) << 2; } } else { - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x >> 3) << 5; - offset += (x & 7) << 2; + offset = ((y >> 1) * (rrb->pitch >> 4) + (x >> 2)) << 5; + offset += (y & 1) << 4; + offset += (x & 3) << 2; } } return &ptr[offset]; } -static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) +static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, + GLint x, GLint y) { GLubyte *ptr = rrb->bo->ptr; uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; GLint offset; - GLint nmacroblkpl; - GLint nmicroblkpl; if (rrb->has_surface || !(rrb->bo->flags & mask)) { offset = x * rrb->cpp + y * rrb->pitch; @@ -106,73 +115,29 @@ static GLubyte *radeon_ptr16(const struct radeon_renderbuffer * rrb, offset = 0; if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - nmacroblkpl = rrb->pitch >> 6; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x >> 6) << 11; - offset += ((x & 63) >> 3) << 5; - offset += (x & 7) << 1; + offset = ((y >> 4) * (rrb->pitch >> 7) + (x >> 6)) << 11; + offset += (((y >> 3) ^ (x >> 6)) & 0x1) << 10; + offset += (((y >> 4) ^ (x >> 5)) & 0x1) << 9; + offset += (((y >> 2) ^ (x >> 5)) & 0x1) << 8; + offset += (((y >> 3) ^ (x >> 4)) & 0x1) << 7; + offset += ((y >> 1) & 0x1) << 6; + offset += ((x >> 3) & 0x1) << 5; + offset += (y & 1) << 4; + offset += (x & 3) << 2; } else { - nmacroblkpl = rrb->pitch >> 7; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x >> 7) << 11; - offset += ((x & 127) >> 4) << 5; + offset = ((y >> 3) * (rrb->pitch >> 8) + (x >> 7)) << 11; + offset += (((y >> 2) ^ (x >> 7)) & 0x1) << 10; + offset += (((y >> 3) ^ (x >> 6)) & 0x1) << 9; + offset += (((y >> 1) ^ (x >> 6)) & 0x1) << 8; + offset += (((y >> 2) ^ (x >> 5)) & 0x1) << 7; + offset += (y & 1) << 6; + offset += ((x >> 4) & 0x1) << 5; offset += (x & 15) << 2; } } else { - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x >> 4) << 5; - offset += (x & 15) << 2; - } - } - return &ptr[offset]; -} - -static GLubyte *radeon_ptr(const struct radeon_renderbuffer * rrb, - GLint x, GLint y) -{ - GLubyte *ptr = rrb->bo->ptr; - uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE; - GLint offset; - GLint microblkxs; - GLint macroblkxs; - GLint nmacroblkpl; - GLint nmicroblkpl; - - if (rrb->has_surface || !(rrb->bo->flags & mask)) { - offset = x * rrb->cpp + y * rrb->pitch; - } else { - offset = 0; - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) { - if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) { - microblkxs = 16 / rrb->cpp; - macroblkxs = 128 / rrb->cpp; - nmacroblkpl = rrb->pitch / macroblkxs; - offset += ((y >> 4) * nmacroblkpl) << 11; - offset += ((y & 15) >> 1) << 8; - offset += (y & 1) << 4; - offset += (x / macroblkxs) << 11; - offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; - } else { - microblkxs = 32 / rrb->cpp; - macroblkxs = 256 / rrb->cpp; - nmacroblkpl = rrb->pitch / macroblkxs; - offset += ((y >> 3) * nmacroblkpl) << 11; - offset += (y & 7) << 8; - offset += (x / macroblkxs) << 11; - offset += ((x & (macroblkxs - 1)) / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; - } - } else { - microblkxs = 32 / rrb->cpp; - nmicroblkpl = ((rrb->pitch + 31) & ~31) >> 5; - offset += (y * nmicroblkpl) << 5; - offset += (x / microblkxs) << 5; - offset += (x & (microblkxs - 1)) * rrb->cpp; + offset = ((y >> 1) * (rrb->pitch >> 4) + (x >> 3)) << 5; + offset += (y & 0x1) << 4; + offset += (x & 0x7) << 1; } } return &ptr[offset]; @@ -239,7 +204,7 @@ s8z24_to_z24s8(uint32_t val) int miny = cliprects[_nc].y1 - y_off; \ int maxx = cliprects[_nc].x2 - x_off; \ int maxy = cliprects[_nc].y2 - y_off; - + /* ================================================================ * Color buffer */ @@ -251,7 +216,27 @@ s8z24_to_z24s8(uint32_t val) #define TAG(x) radeon##x##_RGB565 #define TAG2(x,y) radeon##x##_RGB565##y -#define GET_PTR(X,Y) radeon_ptr16(rrb, (X) + x_off, (Y) + y_off) +#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) +#include "spantmp2.h" + +/* 16 bit, ARGB1555 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV + +#define TAG(x) radeon##x##_ARGB1555 +#define TAG2(x,y) radeon##x##_ARGB1555##y +#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) +#include "spantmp2.h" + +/* 16 bit, RGBA4 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV + +#define TAG(x) radeon##x##_ARGB4444 +#define TAG2(x,y) radeon##x##_ARGB4444##y +#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off) #include "spantmp2.h" /* 32 bit, xRGB8888 color spanline and pixel functions @@ -261,9 +246,9 @@ s8z24_to_z24s8(uint32_t val) #define TAG(x) radeon##x##_xRGB8888 #define TAG2(x,y) radeon##x##_xRGB8888##y -#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) | 0xff000000)) +#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) | 0xff000000)) #define PUT_VALUE(_x, _y, d) { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ *_ptr = d; \ } while (0) #include "spantmp2.h" @@ -275,7 +260,11 @@ s8z24_to_z24s8(uint32_t val) #define TAG(x) radeon##x##_ARGB8888 #define TAG2(x,y) radeon##x##_ARGB8888##y -#define GET_PTR(X,Y) radeon_ptr32(rrb, (X) + x_off, (Y) + y_off) +#define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))) +#define PUT_VALUE(_x, _y, d) { \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ + *_ptr = d; \ +} while (0) #include "spantmp2.h" /* ================================================================ @@ -297,10 +286,10 @@ s8z24_to_z24s8(uint32_t val) #define VALUE_TYPE GLushort #define WRITE_DEPTH( _x, _y, d ) \ - *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off) = d + *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) = d #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)radeon_ptr(rrb, _x + x_off, _y + y_off) + d = *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) #define TAG(x) radeon##x##_z16 #include "depthtmp.h" @@ -315,7 +304,7 @@ s8z24_to_z24s8(uint32_t val) #ifdef COMPILE_R300 #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = *_ptr; \ tmp &= 0x000000ff; \ tmp |= ((d << 8) & 0xffffff00); \ @@ -324,7 +313,7 @@ do { \ #else #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = *_ptr; \ tmp &= 0xff000000; \ tmp |= ((d) & 0x00ffffff); \ @@ -335,11 +324,11 @@ do { \ #ifdef COMPILE_R300 #define READ_DEPTH( d, _x, _y ) \ do { \ - d = (*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \ + d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \ }while(0) #else #define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; + d = *(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; #endif /* fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\ @@ -359,13 +348,13 @@ do { \ #ifdef COMPILE_R300 #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ *_ptr = d; \ } while (0) #else #define WRITE_DEPTH( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = z24s8_to_s8z24(d); \ *_ptr = tmp; \ } while (0) @@ -374,11 +363,11 @@ do { \ #ifdef COMPILE_R300 #define READ_DEPTH( d, _x, _y ) \ do { \ - d = (*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off))); \ + d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \ }while(0) #else #define READ_DEPTH( d, _x, _y ) do { \ - d = s8z24_to_z24s8(*(GLuint*)(radeon_ptr32(rrb, _x + x_off, _y + y_off ))); \ + d = s8z24_to_z24s8(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off ))); \ } while (0) #endif /* @@ -397,7 +386,7 @@ do { \ #ifdef COMPILE_R300 #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \ GLuint tmp = *_ptr; \ tmp &= 0xffffff00; \ tmp |= (d) & 0xff; \ @@ -406,7 +395,7 @@ do { \ #else #define WRITE_STENCIL( _x, _y, d ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32(rrb, _x + x_off, _y + y_off); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \ GLuint tmp = *_ptr; \ tmp &= 0x00ffffff; \ tmp |= (((d) & 0xff) << 24); \ @@ -417,14 +406,14 @@ do { \ #ifdef COMPILE_R300 #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = *_ptr; \ d = tmp & 0x000000ff; \ } while (0) #else #define READ_STENCIL( d, _x, _y ) \ do { \ - GLuint *_ptr = (GLuint*)radeon_ptr32( rrb, _x + x_off, _y + y_off ); \ + GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \ GLuint tmp = *_ptr; \ d = (tmp & 0xff000000) >> 24; \ } while (0) @@ -438,11 +427,13 @@ static void map_unmap_rb(struct gl_renderbuffer *rb, int flag) { struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); int r; - + if (rrb == NULL || !rrb->bo) return; if (flag) { + if (rrb->bo->bom->funcs->bo_wait) + radeon_bo_wait(rrb->bo); r = radeon_bo_map(rrb->bo, 1); if (r) { fprintf(stderr, "(%s) error(%d) mapping buffer.\n", @@ -472,25 +463,30 @@ radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map) ctx->DrawBuffer->Attachment + i; struct gl_texture_object *tex = att->Texture; if (tex) { - /* render to texture */ + /* Render to texture. Note that a mipmapped texture need not + * be complete for render to texture, so we must restrict to + * mapping only the attached image. + */ + radeon_texture_image *image = get_radeon_texture_image(tex->Image[att->CubeMapFace][att->TextureLevel]); ASSERT(att->Renderbuffer); + if (map) - ctx->Driver.MapTexture(ctx, tex); + radeon_teximage_map(image, GL_TRUE); else - ctx->Driver.UnmapTexture(ctx, tex); + radeon_teximage_unmap(image); } } - + map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map); /* depth buffer (Note wrapper!) */ if (ctx->DrawBuffer->_DepthBuffer) map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map); - + if (ctx->DrawBuffer->_StencilBuffer) map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map); - } + static void radeonSpanRenderStart(GLcontext * ctx) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -507,15 +503,13 @@ static void radeonSpanRenderStart(GLcontext * ctx) LOCK_HARDWARE(rmesa); radeonWaitForIdleLocked(rmesa); } + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current); } radeon_map_unmap_buffers(ctx, 1); - - - } static void radeonSpanRenderFinish(GLcontext * ctx) @@ -553,6 +547,10 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb) radeonInitPointers_xRGB8888(&rrb->base); } else if (rrb->base._ActualFormat == GL_RGBA8) { radeonInitPointers_ARGB8888(&rrb->base); + } else if (rrb->base._ActualFormat == GL_RGBA4) { + radeonInitPointers_ARGB4444(&rrb->base); + } else if (rrb->base._ActualFormat == GL_RGB5_A1) { + radeonInitPointers_ARGB1555(&rrb->base); } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT16) { radeonInitDepthPointers_z16(&rrb->base); } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) { @@ -561,5 +559,7 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb) radeonInitDepthPointers_z24_s8(&rrb->base); } else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) { radeonInitStencilPointers_z24_s8(&rrb->base); + } else { + fprintf(stderr, "radeonSetSpanFunctions: bad actual format: 0x%04X\n", rrb->base._ActualFormat); } } diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 06b8c299368..0d1728b747a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -458,6 +458,10 @@ static void radeonFrontFace( GLcontext *ctx, GLenum mode ) RADEON_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW; + /* Winding is inverted when rendering to FBO */ + if (ctx->DrawBuffer && ctx->DrawBuffer->Name) + mode = (mode == GL_CW) ? GL_CCW : GL_CW; + switch ( mode ) { case GL_CW: rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW; @@ -508,11 +512,18 @@ static void radeonColorMask( GLcontext *ctx, GLboolean b, GLboolean a ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); - GLuint mask = radeonPackColor( rmesa->radeon.radeonScreen->cpp, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP] ); + struct radeon_renderbuffer *rrb; + GLuint mask; + + rrb = radeon_get_colorbuffer(&rmesa->radeon); + if (!rrb) + return; + + mask = radeonPackColor( rrb->cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] ); if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) { RADEON_STATECHANGE( rmesa, msk ); @@ -1500,11 +1511,17 @@ static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); GLubyte c[4]; + struct radeon_renderbuffer *rrb; + + rrb = radeon_get_colorbuffer(&rmesa->radeon); + if (!rrb) + return; + CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); - rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp, + rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp, c[0], c[1], c[2], c[3] ); } @@ -2048,23 +2065,23 @@ static GLboolean r100ValidateBuffers(GLcontext *ctx) { r100ContextPtr rmesa = R100_CONTEXT(ctx); struct radeon_renderbuffer *rrb; - int i; + int i, ret; - radeon_validate_reset_bos(&rmesa->radeon); + radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs); rrb = radeon_get_colorbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); } /* depth buffer */ rrb = radeon_get_depthbuffer(&rmesa->radeon); /* color buffer */ if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo, + 0, RADEON_GEM_DOMAIN_VRAM); } for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { @@ -2073,20 +2090,19 @@ static GLboolean r100ValidateBuffers(GLcontext *ctx) if (!ctx->Texture.Unit[i]._ReallyEnabled) continue; - t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); + t = rmesa->state.texture.unit[i].texobj; if (t->image_override && t->bo) - radeon_validate_bo(&rmesa->radeon, t->bo, + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); else if (t->mt->bo) - radeon_validate_bo(&rmesa->radeon, t->mt->bo, + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo, RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); } - if (rmesa->radeon.dma.current) - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, - RADEON_GEM_DOMAIN_GTT, 0); - - return radeon_revalidate_bos(ctx); + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + return GL_TRUE; } GLboolean radeonValidateState( GLcontext *ctx ) diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index f5d4189d669..aaa82b1d6a4 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -390,8 +390,17 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) atom->cmd[CTX_RB3D_CNTL] &= ~(0xf << 10); if (rrb->cpp == 4) atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB8888; - else + else switch (rrb->base._ActualFormat) { + case GL_RGB5: atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_RGB565; + break; + case GL_RGBA4: + atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB4444; + break; + case GL_RGB5_A1: + atom->cmd[CTX_RB3D_CNTL] |= RADEON_COLOR_FORMAT_ARGB1555; + break; + } cbpitch = (rrb->pitch / rrb->cpp); if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) @@ -453,8 +462,8 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) OUT_BATCH(0); OUT_BATCH(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0)); if (rrb) { - OUT_BATCH(((rrb->width - 1) << RADEON_RE_WIDTH_SHIFT) | - ((rrb->height - 1) << RADEON_RE_HEIGHT_SHIFT)); + OUT_BATCH(((rrb->base.Width - 1) << RADEON_RE_WIDTH_SHIFT) | + ((rrb->base.Height - 1) << RADEON_RE_HEIGHT_SHIFT)); } else { OUT_BATCH(0); } @@ -465,6 +474,34 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom) { r100ContextPtr r100 = R100_CONTEXT(ctx); BATCH_LOCALS(&r100->radeon); + uint32_t dwords = 3; + int i = atom->idx, j; + radeonTexObj *t = r100->state.texture.unit[i].texobj; + radeon_mipmap_level *lvl; + + if (!(ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) + return; + + if (!t) + return; + + if (!t->mt) + return; + + BEGIN_BATCH_NO_AUTOSTATE(dwords + (5 * 3)); + OUT_BATCH_TABLE(atom->cmd, 3); + lvl = &t->mt->levels[0]; + for (j = 0; j < 5; j++) { + OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset, + RADEON_GEM_DOMAIN_VRAM, 0, 0); + } + END_BATCH(); +} + +static void cube_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom) +{ + r100ContextPtr r100 = R100_CONTEXT(ctx); + BATCH_LOCALS(&r100->radeon); uint32_t dwords = 2; int i = atom->idx, j; radeonTexObj *t = r100->state.texture.unit[i].texobj; @@ -490,7 +527,7 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom) OUT_BATCH_TABLE(atom->cmd, 2); lvl = &t->mt->levels[0]; for (j = 0; j < 5; j++) { - OUT_BATCH(CP_PACKET0(base_reg + (4 * (j-1)), 0)); + OUT_BATCH(CP_PACKET0(base_reg + (4 * j), 0)); OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset, RADEON_GEM_DOMAIN_VRAM, 0, 0); } @@ -661,7 +698,10 @@ void radeonInitState( r100ContextPtr rmesa ) ALLOC_STATE_IDX( cube[1], cube1, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 ); ALLOC_STATE_IDX( cube[2], cube2, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 ); for (i = 0; i < 3; i++) - rmesa->hw.cube[i].emit = cube_emit; + if (rmesa->radeon.radeonScreen->kernel_mm) + rmesa->hw.cube[i].emit = cube_emit_cs; + else + rmesa->hw.cube[i].emit = cube_emit; } else { diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c index 279bcd4df6a..c29105d7b85 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texstate.c +++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c @@ -706,7 +706,7 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_ rImage->mt = NULL; } _mesa_init_teximage_fields(radeon->glCtx, target, texImage, - rb->width, rb->height, 1, 0, rb->cpp); + rb->base.Width, rb->base.Height, 1, 0, rb->cpp); texImage->RowStride = rb->pitch / rb->cpp; texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx, internalFormat, @@ -738,8 +738,8 @@ void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_ t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter; break; } - t->pp_txsize = ((rb->width - 1) << RADEON_TEX_USIZE_SHIFT) - | ((rb->height - 1) << RADEON_TEX_VSIZE_SHIFT); + t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT) + | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT); t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; t->pp_txpitch = pitch_val; t->pp_txpitch -= 32; @@ -1143,12 +1143,14 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) r100ContextPtr rmesa = R100_CONTEXT(ctx); if (ctx->Texture.Unit[unit]._ReallyEnabled & TEXTURE_3D_BIT) { + rmesa->state.texture.unit[unit].texobj = NULL; return GL_FALSE; } if (!ctx->Texture.Unit[unit]._ReallyEnabled) { /* disable the unit */ disable_tex_obj_state(rmesa, unit); + rmesa->state.texture.unit[unit].texobj = NULL; return GL_TRUE; } @@ -1156,8 +1158,8 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) _mesa_warning(ctx, "failed to validate texture for unit %d.\n", unit); - rmesa->state.texture.unit[unit].texobj = NULL; - return GL_FALSE; + rmesa->state.texture.unit[unit].texobj = NULL; + return GL_FALSE; } rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current); return GL_TRUE; diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index ee66fc2ea0d..ad501c454ce 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -477,6 +477,26 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, case GL_DEPTH_STENCIL_EXT: case GL_DEPTH24_STENCIL8_EXT: return &_mesa_texformat_s8_z24; + + /* EXT_texture_sRGB */ + case GL_SRGB: + case GL_SRGB8: + case GL_SRGB_ALPHA: + case GL_SRGB8_ALPHA8: + case GL_COMPRESSED_SRGB: + case GL_COMPRESSED_SRGB_ALPHA: + return &_mesa_texformat_srgba8; + + case GL_SLUMINANCE: + case GL_SLUMINANCE8: + case GL_COMPRESSED_SLUMINANCE: + return &_mesa_texformat_sl8; + + case GL_SLUMINANCE_ALPHA: + case GL_SLUMINANCE8_ALPHA8: + case GL_COMPRESSED_SLUMINANCE_ALPHA: + return &_mesa_texformat_sla8; + default: _mesa_problem(ctx, "unexpected internalFormat 0x%x in %s", @@ -492,7 +512,7 @@ const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, */ static void radeon_teximage( GLcontext *ctx, int dims, - GLint face, GLint level, + GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint depth, GLsizei imageSize, @@ -509,6 +529,7 @@ static void radeon_teximage( GLint postConvWidth = width; GLint postConvHeight = height; GLuint texelBytes; + GLuint face = radeon_face_for_target(target); radeon_firevertices(rmesa); @@ -594,6 +615,8 @@ static void radeon_teximage( memcpy(texImage->Data, pixels, imageSize); } else { GLuint dstRowStride; + GLuint *dstImageOffsets; + if (image->mt) { radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; dstRowStride = lvl->rowstride; @@ -601,20 +624,37 @@ static void radeon_teximage( dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; } + if (dims == 3) { + int i; + + dstImageOffsets = _mesa_malloc(depth * sizeof(GLuint)) ; + if (!dstImageOffsets) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + + for (i = 0; i < depth; ++i) { + dstImageOffsets[i] = dstRowStride/texImage->TexFormat->TexelBytes * height * i; + } + } else { + dstImageOffsets = texImage->ImageOffsets; + } + if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, texImage->TexFormat, texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ dstRowStride, - texImage->ImageOffsets, + dstImageOffsets, width, height, depth, format, type, pixels, packing)) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + + if (dims == 3) + _mesa_free(dstImageOffsets); } /* SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, texObj->Target, texObj); + radeon_generate_mipmap(ctx, target, texObj); } } @@ -634,7 +674,7 @@ void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1, + radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1, 0, format, type, pixels, packing, texObj, texImage, 0); } @@ -647,9 +687,7 @@ void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_image *texImage) { - GLuint face = radeon_face_for_target(target); - - radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, + radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, 0, format, type, pixels, packing, texObj, texImage, 0); } @@ -660,9 +698,7 @@ void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - GLuint face = radeon_face_for_target(target); - - radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, + radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1); } @@ -675,14 +711,14 @@ void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth, + radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth, 0, format, type, pixels, packing, texObj, texImage, 0); } /** * Update a subregion of the given texture image. */ -static void radeon_texsubimage(GLcontext* ctx, int dims, int level, +static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, @@ -742,7 +778,7 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, int level, /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - radeon_generate_mipmap(ctx, texObj->Target, texObj); + radeon_generate_mipmap(ctx, target, texObj); } } @@ -762,7 +798,7 @@ void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0, + radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0, format, type, pixels, packing, texObj, texImage, 0); } @@ -775,7 +811,7 @@ void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, + radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels, packing, texObj, texImage, 0); } @@ -788,7 +824,7 @@ void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, + radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1); } @@ -802,7 +838,7 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0, + radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0, format, type, pixels, packing, texObj, texImage, 0); } |