diff options
55 files changed, 4634 insertions, 5253 deletions
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 5261a4b55d..883365094d 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -90,7 +90,7 @@ $(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) touch depend $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ - $(ASM_SOURCES) 2>&1 /dev/null + $(ASM_SOURCES) 2> /dev/null # Emacs tags diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index 9bd1d33507..c8fee7dfb5 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -7,20 +7,29 @@ LIBNAME = i915tex_dri.so MINIGLX_SOURCES = server/intel_dri.c DRIVER_SOURCES = \ - i830_context.c \ - i830_metaops.c \ - i830_state.c \ - i830_texblend.c \ - i830_tex.c \ - i830_texstate.c \ - i830_vtbl.c \ + i915_context.c \ + i915_fpc.c \ + i915_fpc_debug.c \ + i915_fpc_emit.c \ + i915_fpc_translate.c \ + i915_program.c \ + i915_state.c \ + i915_state_fp.c \ + i915_state_fp_inputs.c \ + i915_state_fallback.c \ + i915_state_invarient.c \ + i915_state_immediate.c \ + i915_state_map.c \ + i915_state_misc.c \ + i915_state_sampler.c \ + i915_tex_layout.c \ + i915_vtbl.c \ intel_render.c \ intel_idx_render.c \ intel_regions.c \ intel_buffer_objects.c \ intel_batchbuffer.c \ intel_mipmap_tree.c \ - i915_tex_layout.c \ intel_tex_layout.c \ intel_tex_image.c \ intel_tex_subimage.c \ @@ -28,27 +37,20 @@ DRIVER_SOURCES = \ intel_tex_validate.c \ intel_tex_format.c \ intel_tex.c \ + intel_metaops.c \ intel_pixel.c \ intel_pixel_copy.c \ intel_pixel_read.c \ intel_pixel_draw.c \ intel_buffers.c \ intel_blit.c \ - i915_tex.c \ - i915_texstate.c \ - i915_context.c \ - i915_debug.c \ - i915_fragprog.c \ - i915_metaops.c \ - i915_program.c \ - i915_state.c \ - i915_vtbl.c \ intel_context.c \ intel_ioctl.c \ intel_rotate.c \ intel_screen.c \ intel_span.c \ intel_state.c \ + intel_state_callbacks.c \ intel_tris.c \ intel_fbo.c \ intel_depthstencil.c \ diff --git a/src/mesa/drivers/dri/i915tex/i830_metaops.c b/src/mesa/drivers/dri/i915tex/i830_metaops.c deleted file mode 100644 index f76646d89d..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_metaops.c +++ /dev/null @@ -1,457 +0,0 @@ -/************************************************************************** - * - * 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 "glheader.h" -#include "enums.h" -#include "mtypes.h" -#include "macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_regions.h" - -#include "i830_context.h" -#include "i830_reg.h" - -/* A large amount of state doesn't need to be uploaded. - */ -#define ACTIVE (I830_UPLOAD_INVARIENT | \ - I830_UPLOAD_CTX | \ - I830_UPLOAD_BUFFERS | \ - I830_UPLOAD_STIPPLE | \ - I830_UPLOAD_TEXBLEND(0) | \ - I830_UPLOAD_TEX(0)) - - -#define SET_STATE( i830, STATE ) \ -do { \ - i830->current->emitted &= ~ACTIVE; \ - i830->current = &i830->STATE; \ - i830->current->emitted &= ~ACTIVE; \ -} while (0) - - -static void -set_no_stencil_write(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -static void -set_no_depth_write(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Set depth unit to replace. - */ -static void -set_depth_replace(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - * ctx->Driver.DepthMask( ctx, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; - - /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) - */ - i830->meta.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; - i830->meta.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC - (COMPAREFUNC_ALWAYS)); - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -/* Set stencil unit to replace always with the reference value. - */ -static void -set_stencil_replace(struct intel_context *intel, - GLuint s_mask, GLuint s_clear) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK((s_mask & - 0xff))); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | - ENABLE_STENCIL_TEST_FUNC_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_REF_VALUE | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_REF_VALUE((s_clear & 0xff)) | - STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); - - - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void -set_color_mask(struct intel_context *intel, GLboolean state) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | - (1 << WRITEMASK_GREEN_SHIFT) | - (1 << WRITEMASK_BLUE_SHIFT) | - (1 << WRITEMASK_ALPHA_SHIFT)); - - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; - - if (state) { - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= - (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); - } - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Installs a one-stage passthrough texture blend pipeline. Is there - * more that can be done to turn off texturing? - */ -static void -set_no_texture(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - static const struct gl_tex_env_combine_state comb = { - GL_NONE, GL_NONE, - {GL_TEXTURE, 0, 0,}, {GL_TEXTURE, 0, 0,}, - {GL_SRC_COLOR, 0, 0}, {GL_SRC_ALPHA, 0, 0}, - 0, 0, 0, 0 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); -} - -/* Set up a single element blend stage for 'replace' texturing with no - * funny ops. - */ -static void -set_texture_blend_replace(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - static const struct gl_tex_env_combine_state comb = { - GL_REPLACE, GL_REPLACE, - {GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,}, {GL_TEXTURE, GL_TEXTURE, - GL_TEXTURE,}, - {GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR}, {GL_SRC_ALPHA, GL_SRC_ALPHA, - GL_SRC_ALPHA}, - 0, 0, 1, 1 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); - -/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ -/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ -} - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static GLboolean -set_tex_rect_source(struct intel_context *intel, - struct _DriBufferObject *buffer, - GLuint offset, - GLuint pitch, GLuint height, GLenum format, GLenum type) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - GLuint *setup = i830->meta.Tex[0]; - GLint numLevels = 1; - GLuint textureFormat; - GLuint cpp; - - /* A full implementation of this would do the upload through - * glTexImage2d, and get all the conversion operations at that - * point. We are restricted, but still at least have access to the - * fragment program swizzle. - */ - switch (format) { - case GL_BGRA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_RGBA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_BGR: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5_REV: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - case GL_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - - default: - return GL_FALSE; - } - - i830->meta.tex_buffer[0] = buffer; - i830->meta.tex_offset[0] = offset; - - setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - (LOAD_TEXTURE_MAP0 << 0) | 4); - setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | - ((pitch - 1) << TM0S1_WIDTH_SHIFT) | - textureFormat); - setup[I830_TEXREG_TM0S2] = - (((((pitch * cpp) / 4) - - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); - - setup[I830_TEXREG_TM0S3] = - ((((numLevels - - 1) * - 4) << TM0S3_MIN_MIP_SHIFT) | (FILTER_NEAREST << - TM0S3_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT) | (FILTER_NEAREST << - TM0S3_MAG_FILTER_SHIFT)); - - setup[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(0)); - - setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | - MAP_UNIT(0) | - ENABLE_TEXCOORD_PARAMS | - TEXCOORDS_ARE_IN_TEXELUNITS | - TEXCOORDTYPE_CARTESIAN | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | - ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); - - i830->meta.emitted &= ~I830_UPLOAD_TEX(0); - return GL_TRUE; -} - - -static void -set_vertex_format(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | - VFT0_TEX_COUNT(1) | - VFT0_DIFFUSE | VFT0_XYZ); - i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | - VFT1_TEX0_FMT(TEXCOORDFMT_2D) | - VFT1_TEX1_FMT(TEXCOORDFMT_2D) | - VFT1_TEX2_FMT(TEXCOORDFMT_2D) | - VFT1_TEX3_FMT(TEXCOORDFMT_2D)); - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void -meta_import_pixel_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - i830->meta.Ctx[I830_CTXREG_STATE1] = i830->state.Ctx[I830_CTXREG_STATE1]; - i830->meta.Ctx[I830_CTXREG_STATE2] = i830->state.Ctx[I830_CTXREG_STATE2]; - i830->meta.Ctx[I830_CTXREG_STATE3] = i830->state.Ctx[I830_CTXREG_STATE3]; - i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; - i830->meta.Ctx[I830_CTXREG_STATE5] = i830->state.Ctx[I830_CTXREG_STATE5]; - i830->meta.Ctx[I830_CTXREG_IALPHAB] = i830->state.Ctx[I830_CTXREG_IALPHAB]; - i830->meta.Ctx[I830_CTXREG_STENCILTST] = - i830->state.Ctx[I830_CTXREG_STENCILTST]; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] = - i830->state.Ctx[I830_CTXREG_ENABLES_1]; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] = - i830->state.Ctx[I830_CTXREG_ENABLES_2]; - i830->meta.Ctx[I830_CTXREG_AA] = i830->state.Ctx[I830_CTXREG_AA]; - i830->meta.Ctx[I830_CTXREG_FOGCOLOR] = - i830->state.Ctx[I830_CTXREG_FOGCOLOR]; - i830->meta.Ctx[I830_CTXREG_BLENDCOLOR0] = - i830->state.Ctx[I830_CTXREG_BLENDCOLOR0]; - i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = - i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; - i830->meta.Ctx[I830_CTXREG_MCSB0] = i830->state.Ctx[I830_CTXREG_MCSB0]; - i830->meta.Ctx[I830_CTXREG_MCSB1] = i830->state.Ctx[I830_CTXREG_MCSB1]; - - - i830->meta.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - i830->meta.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; - i830->meta.emitted &= ~I830_UPLOAD_CTX; - - - i830->meta.Buffer[I830_DESTREG_SENABLE] = - i830->state.Buffer[I830_DESTREG_SENABLE]; - i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; - i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; - i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; -} - - - -/* Select between front and back draw buffers. - */ -static void -meta_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - i830_state_draw_region(intel, &i830->meta, color_region, depth_region); -} - - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void -install_meta_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - memcpy(&i830->meta, &i830->initial, sizeof(i830->meta)); - - i830->meta.active = ACTIVE; - i830->meta.emitted = 0; - - SET_STATE(i830, meta); - set_vertex_format(intel); - set_no_texture(intel); -} - -static void -leave_meta_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - intel_region_release(&i830->meta.draw_region); - intel_region_release(&i830->meta.depth_region); -/* intel_region_release(intel, &i830->meta.tex_region[0]); */ - SET_STATE(i830, state); -} - - - -void -i830InitMetaFuncs(struct i830_context *i830) -{ - i830->intel.vtbl.install_meta_state = install_meta_state; - i830->intel.vtbl.leave_meta_state = leave_meta_state; - i830->intel.vtbl.meta_no_depth_write = set_no_depth_write; - i830->intel.vtbl.meta_no_stencil_write = set_no_stencil_write; - i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; - i830->intel.vtbl.meta_depth_replace = set_depth_replace; - i830->intel.vtbl.meta_color_mask = set_color_mask; - i830->intel.vtbl.meta_no_texture = set_no_texture; - i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; - i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; - i830->intel.vtbl.meta_draw_region = meta_draw_region; - i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; -} diff --git a/src/mesa/drivers/dri/i915tex/i830_state.c b/src/mesa/drivers/dri/i915tex/i830_state.c index 812daa6524..4643767d70 100644 --- a/src/mesa/drivers/dri/i915tex/i830_state.c +++ b/src/mesa/drivers/dri/i915tex/i830_state.c @@ -1101,8 +1101,6 @@ i830InitState(struct i830_context *i830) i830_init_packets(i830); - intelInitState(ctx); - memcpy(&i830->initial, &i830->state, sizeof(i830->state)); i830->current = &i830->state; diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c index 509a3695bc..323c2db92c 100644 --- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c @@ -646,7 +646,6 @@ i830_assert_not_dirty( struct intel_context *intel ) void i830InitVtbl(struct i830_context *i830) { - i830->intel.vtbl.check_vertex_size = i830_check_vertex_size; i830->intel.vtbl.destroy = i830_destroy_context; i830->intel.vtbl.emit_state = i830_emit_state; i830->intel.vtbl.lost_hardware = i830_lost_hardware; diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c index 9b4d72eab3..4ea8d1d1df 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.c +++ b/src/mesa/drivers/dri/i915tex/i915_context.c @@ -39,6 +39,7 @@ #include "utils.h" #include "i915_reg.h" +#include "i915_state.h" #include "intel_regions.h" #include "intel_batchbuffer.h" @@ -52,6 +53,7 @@ static const struct dri_extension i915_extensions[] = { {"GL_ARB_fragment_program", NULL}, {"GL_ARB_shadow", NULL}, {"GL_ARB_texture_env_crossbar", NULL}, + {"GL_EXT_stencil_two_side", NULL}, {"GL_ARB_texture_non_power_of_two", NULL}, {"GL_EXT_shadow_funcs", NULL}, /* ARB extn won't work if not enabled */ @@ -59,42 +61,12 @@ static const struct dri_extension i915_extensions[] = { {NULL, NULL} }; -/* Override intel default. - */ -static void -i915InvalidateState(GLcontext * ctx, GLuint new_state) -{ - _swrast_InvalidateState(ctx, new_state); - _swsetup_InvalidateState(ctx, new_state); - _vbo_InvalidateState(ctx, new_state); - _tnl_InvalidateState(ctx, new_state); - _tnl_invalidate_vertex_state(ctx, new_state); - intel_context(ctx)->NewGLState |= new_state; - - /* Todo: gather state values under which tracked parameters become - * invalidated, add callbacks for things like - * ProgramLocalParameters, etc. - */ - { - struct i915_fragment_program *p = - (struct i915_fragment_program *) ctx->FragmentProgram._Current; - if (p && p->nr_params) - p->params_uptodate = 0; - } - - if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM)) - i915_update_fog(ctx); -} - static void i915InitDriverFunctions(struct dd_function_table *functions) { intelInitDriverFunctions(functions); - i915InitStateFunctions(functions); - i915InitTextureFuncs(functions); i915InitFragProgFuncs(functions); - functions->UpdateState = i915InvalidateState; } @@ -113,13 +85,9 @@ i915CreateContext(const __GLcontextModes * mesaVis, if (!i915) return GL_FALSE; - if (0) - _mesa_printf("\ntexmem-0-3 branch\n\n"); - i915InitVtbl(i915); - i915InitMetaFuncs(i915); - i915InitDriverFunctions(&functions); + i915_init_state(i915); if (!intelInitContext(intel, mesaVis, driContextPriv, sharedContextPrivate, &functions)) { @@ -162,13 +130,16 @@ i915CreateContext(const __GLcontextModes * mesaVis, driInitExtensions(ctx, i915_extensions, GL_FALSE); + /* always enbale pixel fog. vertex fog uses precaculted fog coord + * will conflict with appended fog program + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, 36 * sizeof(GLfloat)); intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; - i915InitState(i915); - return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h index f594304159..2af65a1151 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.h +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -30,85 +30,15 @@ #include "intel_context.h" -#define I915_FALLBACK_TEXTURE 0x1000 -#define I915_FALLBACK_COLORMASK 0x2000 -#define I915_FALLBACK_STENCIL 0x4000 -#define I915_FALLBACK_STIPPLE 0x8000 -#define I915_FALLBACK_PROGRAM 0x10000 -#define I915_FALLBACK_LOGICOP 0x20000 -#define I915_FALLBACK_POLYGON_SMOOTH 0x40000 -#define I915_FALLBACK_POINT_SMOOTH 0x80000 - -#define I915_UPLOAD_CTX 0x1 -#define I915_UPLOAD_BUFFERS 0x2 -#define I915_UPLOAD_STIPPLE 0x4 -#define I915_UPLOAD_PROGRAM 0x8 -#define I915_UPLOAD_CONSTANTS 0x10 -#define I915_UPLOAD_FOG 0x20 -#define I915_UPLOAD_INVARIENT 0x40 -#define I915_UPLOAD_DEFAULTS 0x80 -#define I915_UPLOAD_TEX(i) (0x00010000<<(i)) -#define I915_UPLOAD_TEX_ALL (0x00ff0000) -#define I915_UPLOAD_TEX_0_SHIFT 16 - - -/* State structure offsets - these will probably disappear. - */ -#define I915_DESTREG_CBUFADDR0 0 -#define I915_DESTREG_CBUFADDR1 1 -#define I915_DESTREG_DBUFADDR0 3 -#define I915_DESTREG_DBUFADDR1 4 -#define I915_DESTREG_DV0 6 -#define I915_DESTREG_DV1 7 -#define I915_DESTREG_SENABLE 8 -#define I915_DESTREG_SR0 9 -#define I915_DESTREG_SR1 10 -#define I915_DESTREG_SR2 11 -#define I915_DEST_SETUP_SIZE 12 - -#define I915_CTXREG_LI 0 -#define I915_CTXREG_LIS2 1 -#define I915_CTXREG_LIS4 2 -#define I915_CTXREG_LIS5 3 -#define I915_CTXREG_LIS6 4 -#define I915_CTXREG_STATE4 5 -#define I915_CTXREG_IAB 6 -#define I915_CTXREG_BLENDCOLOR0 7 -#define I915_CTXREG_BLENDCOLOR1 8 -#define I915_CTX_SETUP_SIZE 9 - -#define I915_FOGREG_COLOR 0 -#define I915_FOGREG_MODE0 1 -#define I915_FOGREG_MODE1 2 -#define I915_FOGREG_MODE2 3 -#define I915_FOGREG_MODE3 4 -#define I915_FOG_SETUP_SIZE 5 - -#define I915_STPREG_ST0 0 -#define I915_STPREG_ST1 1 -#define I915_STP_SETUP_SIZE 2 - -#define I915_TEXREG_MS3 1 -#define I915_TEXREG_MS4 2 -#define I915_TEXREG_SS2 3 -#define I915_TEXREG_SS3 4 -#define I915_TEXREG_SS4 5 -#define I915_TEX_SETUP_SIZE 6 - -#define I915_DEFREG_C0 0 -#define I915_DEFREG_C1 1 -#define I915_DEFREG_S0 2 -#define I915_DEFREG_S1 3 -#define I915_DEFREG_Z0 4 -#define I915_DEFREG_Z1 5 -#define I915_DEF_SETUP_SIZE 6 - #define I915_MAX_CONSTANT 32 #define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) +#define I915_PROGRAM_SIZE 192 -#define I915_PROGRAM_SIZE 192 +#define I915_NEW_INPUT_SIZES (INTEL_NEW_DRIVER0<<0) +#define I915_NEW_VERTEX_FORMAT (INTEL_NEW_DRIVER0<<1) + /* Hardware version of a parsed fragment program. "Derived" from the @@ -116,57 +46,24 @@ */ struct i915_fragment_program { - struct gl_fragment_program FragProg; - - GLboolean translated; - GLboolean params_uptodate; - GLboolean on_hardware; + struct gl_fragment_program Base; GLboolean error; /* If program is malformed for any reason. */ - GLuint nr_tex_indirect; - GLuint nr_tex_insn; - GLuint nr_alu_insn; - GLuint nr_decl_insn; - - - + GLuint id; /* String id */ + GLboolean translated; - /* TODO: split between the stored representation of a program and - * the state used to build that representation. + /* Decls + instructions: */ - GLcontext *ctx; - - GLuint declarations[I915_PROGRAM_SIZE]; GLuint program[I915_PROGRAM_SIZE]; - + GLuint program_size; + + /* Constant buffer: + */ GLfloat constant[I915_MAX_CONSTANT][4]; - GLuint constant_flags[I915_MAX_CONSTANT]; GLuint nr_constants; - GLuint *csr; /* Cursor, points into program. - */ - - GLuint *decl; /* Cursor, points into declarations. - */ - - GLuint decl_s; /* flags for which s regs need to be decl'd */ - GLuint decl_t; /* flags for which t regs need to be decl'd */ - - GLuint temp_flag; /* Tracks temporary regs which are in - * use. - */ - - GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in - * use. - */ - - - - /* Helpers for i915_fragprog.c: + /* Some of which are parameters: */ - GLuint wpos_tex; - GLboolean depth_written; - struct { GLuint reg; /* Hardware constant idx */ @@ -174,20 +71,8 @@ struct i915_fragment_program } param[I915_MAX_CONSTANT]; GLuint nr_params; - - /* Helpers for i915_texprog.c: - */ - GLuint src_texture; /* Reg containing sampled texture color, - * else UREG_BAD. - */ - - GLuint src_previous; /* Reg containing color from previous - * stage. May need to be decl'd. - */ - - GLuint last_tex_stage; /* Number of last enabled texture unit */ - - struct vertex_buffer *VB; + GLuint param_state; + GLuint wpos_tex; }; @@ -199,105 +84,53 @@ struct i915_fragment_program #define I915_TEX_UNITS 8 -struct i915_hw_state -{ - GLuint Ctx[I915_CTX_SETUP_SIZE]; - GLuint Buffer[I915_DEST_SETUP_SIZE]; - GLuint Stipple[I915_STP_SETUP_SIZE]; - GLuint Fog[I915_FOG_SETUP_SIZE]; - GLuint Defaults[I915_DEF_SETUP_SIZE]; - GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE]; - GLuint Constant[I915_CONSTANT_SIZE]; - GLuint ConstantSize; - GLuint Program[I915_PROGRAM_SIZE]; - GLuint ProgramSize; - - /* Region pointers for relocation: - */ - struct intel_region *draw_region; - struct intel_region *depth_region; -/* struct intel_region *tex_region[I915_TEX_UNITS]; */ - /* Regions aren't actually that appropriate here as the memory may - * be from a PBO or FBO. Just use the buffer id. Will have to do - * this for draw and depth for FBO's... - */ - struct _DriBufferObject *tex_buffer[I915_TEX_UNITS]; - GLuint tex_offset[I915_TEX_UNITS]; - - - GLuint active; /* I915_UPLOAD_* */ - GLuint emitted; /* I915_UPLOAD_* */ -}; -#define I915_FOG_PIXEL 2 -#define I915_FOG_VERTEX 1 -#define I915_FOG_NONE 0 struct i915_context { struct intel_context intel; - GLuint last_ReallyEnabled; - GLuint vertex_fog; - GLuint lodbias_ss2[MAX_TEXTURE_UNITS]; - - - struct i915_fragment_program *current_program; - - struct i915_hw_state meta, initial, state, *current; + struct i915_fragment_program *fragment_program; + + struct { + /* Regions aren't actually that appropriate here as the memory may + * be from a PBO or FBO. Just use the buffer id. Will have to do + * this for draw and depth for FBO's... + */ + struct _DriBufferObject *tex_buffer[I915_TEX_UNITS]; + GLuint tex_offset[I915_TEX_UNITS]; + } state; + + struct { + struct intel_tracked_state tracked_state; + + /* For short-circuiting + */ + GLfloat last_buf[I915_MAX_CONSTANT][4]; + GLuint last_bufsz; + } constants; + + struct { + /* I915_NEW_INPUT_DIMENSIONS + */ + GLubyte input_sizes[FRAG_ATTRIB_MAX]; + + GLuint LIS2; + GLuint LIS4; + } fragprog; + + + GLuint program_id; }; -#define I915_STATECHANGE(i915, flag) \ -do { \ - INTEL_FIREVERTICES( &(i915)->intel ); \ - (i915)->state.emitted &= ~(flag); \ -} while (0) - -#define I915_ACTIVESTATE(i915, flag, mode) \ -do { \ - INTEL_FIREVERTICES( &(i915)->intel ); \ - if (mode) \ - (i915)->state.active |= (flag); \ - else \ - (i915)->state.active &= ~(flag); \ -} while (0) - /*====================================================================== * i915_vtbl.c */ extern void i915InitVtbl(struct i915_context *i915); -extern void -i915_state_draw_region(struct intel_context *intel, - struct i915_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region); - - - -#define SZ_TO_HW(sz) ((sz-2)&0x3) -#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) -#define EMIT_ATTR( ATTR, STYLE, S4, SZ ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ - intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ - s4 |= S4; \ - intel->vertex_attr_count++; \ - offset += (SZ); \ -} while (0) - -#define EMIT_PAD( N ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ - intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ - intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ - intel->vertex_attr_count++; \ - offset += (N); \ -} while (0) - /*====================================================================== @@ -309,24 +142,9 @@ extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, /*====================================================================== - * i915_texprog.c - */ -extern void i915ValidateTextureProgram(struct i915_context *i915); - - -/*====================================================================== - * i915_debug.c - */ -extern void i915_disassemble_program(const GLuint * program, GLuint sz); -extern void i915_print_ureg(const char *msg, GLuint ureg); - - -/*====================================================================== * i915_state.c */ extern void i915InitStateFunctions(struct dd_function_table *functions); -extern void i915InitState(struct i915_context *i915); -extern void i915_update_fog(GLcontext * ctx); /*====================================================================== @@ -335,16 +153,11 @@ extern void i915_update_fog(GLcontext * ctx); extern void i915UpdateTextureState(struct intel_context *intel); extern void i915InitTextureFuncs(struct dd_function_table *functions); -/*====================================================================== - * i915_metaops.c - */ -void i915InitMetaFuncs(struct i915_context *i915); /*====================================================================== - * i915_fragprog.c + * i915_program.c */ -extern void i915ValidateFragmentProgram(struct i915_context *i915); extern void i915InitFragProgFuncs(struct dd_function_table *functions); /*====================================================================== diff --git a/src/mesa/drivers/dri/i915tex/i915_fpc.c b/src/mesa/drivers/dri/i915tex/i915_fpc.c new file mode 100644 index 0000000000..30420f05ef --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_fpc.c @@ -0,0 +1,171 @@ +/************************************************************************** + * + * 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 <strings.h> + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "i915_fpc.h" + + + +void +i915_program_error(struct i915_fp_compile *p, const char *msg) +{ + _mesa_problem(NULL, "i915_program_error: %s", msg); + p->fp->error = 1; +} + + +static struct i915_fp_compile * +i915_init_compile(struct i915_context *i915, struct i915_fragment_program *fp) +{ + struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile); + + p->fp = fp; + p->env_param = i915->intel.ctx.FragmentProgram.Parameters; + + p->nr_tex_indirect = 1; /* correct? */ + p->nr_tex_insn = 0; + p->nr_alu_insn = 0; + p->nr_decl_insn = 0; + + memset(p->constant_flags, 0, sizeof(p->constant_flags)); + + p->csr = p->program; + p->decl = p->declarations; + p->decl_s = 0; + p->decl_t = 0; + p->temp_flag = 0xffff000; + p->utemp_flag = ~0x7; + + p->fp->translated = 0; + p->fp->error = 0; + p->fp->nr_constants = 0; + p->fp->wpos_tex = -1; + p->fp->nr_params = 0; + + *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; + + return p; +} + +/* Copy compile results to the fragment program struct and destroy the + * compilation context. + */ +static void +i915_fini_compile(struct i915_fp_compile *p) +{ + GLuint program_size = p->csr - p->program; + GLuint decl_size = p->decl - p->declarations; + + if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) + i915_program_error(p, "Exceeded max nr indirect texture lookups"); + + if (p->nr_tex_insn > I915_MAX_TEX_INSN) + i915_program_error(p, "Exceeded max TEX instructions"); + + if (p->nr_alu_insn > I915_MAX_ALU_INSN) + i915_program_error(p, "Exceeded max ALU instructions"); + + if (p->nr_decl_insn > I915_MAX_DECL_INSN) + i915_program_error(p, "Exceeded max DECL instructions"); + + if (p->fp->error) { + p->fp->Base.Base.NumNativeInstructions = 0; + p->fp->Base.NumNativeAluInstructions = 0; + p->fp->Base.NumNativeTexInstructions = 0; + p->fp->Base.NumNativeTexIndirections = 0; + return; + } + else { + p->fp->Base.Base.NumNativeInstructions = (p->nr_alu_insn + + p->nr_tex_insn + + p->nr_decl_insn); + p->fp->Base.NumNativeAluInstructions = p->nr_alu_insn; + p->fp->Base.NumNativeTexInstructions = p->nr_tex_insn; + p->fp->Base.NumNativeTexIndirections = p->nr_tex_indirect; + } + + p->declarations[0] |= program_size + decl_size - 2; + + /* Copy compilation results to fragment program struct: + */ + memcpy(p->fp->program, + p->declarations, + decl_size * sizeof(GLuint)); + + memcpy(p->fp->program + decl_size, + p->program, + program_size * sizeof(GLuint)); + + p->fp->program_size = program_size + decl_size; + + /* Release the compilation struct: + */ + FREE(p); +} + + + +static void +check_wpos(struct i915_fp_compile *p) +{ + GLuint inputs = p->fp->Base.Base.InputsRead; + GLint i; + + p->fp->wpos_tex = -1; + + if (inputs & FRAG_BIT_WPOS) { + for (i = 0; i < I915_TEX_UNITS; i++) { + if ((inputs & (FRAG_BIT_TEX0 << i)) == 0) { + p->fp->wpos_tex = i; + return; + } + } + + i915_program_error(p, "No free texcoord for wpos value"); + } +} + + + +void i915_compile_fragment_program( struct i915_context *i915, + struct i915_fragment_program *fp ) +{ + struct i915_fp_compile *p = i915_init_compile(i915, fp); + + check_wpos(p); + + i915_translate_program(p); + i915_fixup_depth_write(p); + + i915_fini_compile(p); + fp->translated = 1; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.c b/src/mesa/drivers/dri/i915tex/i915_fpc_debug.c index 974527e14c..22a9342b64 100644 --- a/src/mesa/drivers/dri/i915tex/i915_debug.c +++ b/src/mesa/drivers/dri/i915tex/i915_fpc_debug.c @@ -25,10 +25,12 @@ * **************************************************************************/ -#include "i915_reg.h" -#include "i915_context.h" #include <stdio.h> +#include "i915_reg.h" +#include "i915_fpc.h" +#include "shader/program.h" +#include "shader/program_instruction.h" static const char *opcodes[0x20] = { "NOP", @@ -211,13 +213,6 @@ print_src_reg(GLuint dword) print_reg_neg_swizzle(dword); } -void -i915_print_ureg(const char *msg, GLuint ureg) -{ - fprintf(stderr, "%s: ", msg); - print_src_reg(ureg >> 8); - fprintf(stderr, "\n"); -} static void print_dest_reg(GLuint dword) @@ -310,11 +305,7 @@ i915_disassemble_program(const GLuint * program, GLuint sz) fprintf(stderr, "BEGIN\n"); - if (size + 2 != sz) { - fprintf(stderr, "%s: program size mismatch %d/%d\n", __FUNCTION__, - size + 2, sz); - exit(1); - } + assert(size + 2 == sz); program++; for (i = 1; i < sz; i += 3, program += 3) { @@ -332,3 +323,14 @@ i915_disassemble_program(const GLuint * program, GLuint sz) fprintf(stderr, "END\n\n"); } + + +void i915_print_mesa_instructions( const struct prog_instruction *insn, + GLuint nr ) +{ + GLuint i; + for (i = 0; i < nr; i++, insn++) { + _mesa_printf("%3d: ", i); + _mesa_print_instruction(insn); + } +} diff --git a/src/mesa/drivers/dri/i915tex/i915_fpc_emit.c b/src/mesa/drivers/dri/i915tex/i915_fpc_emit.c new file mode 100644 index 0000000000..dd9d612321 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_fpc_emit.c @@ -0,0 +1,376 @@ +/************************************************************************** + * + * 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 <strings.h> + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_fpc.h" + + +#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) +#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT) +#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT) +#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT) +#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT) + +/* These are special, and don't have swizzle/negate bits. + */ +#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT) +#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \ + (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT)) + + +/* Macros for translating UREG's into the various register fields used + * by the I915 programmable unit. + */ +#define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT) +#define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT) +#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) +#define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT) +#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) +#define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT) + +#define UREG_MASK 0xffffff00 +#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \ + (REG_NR_MASK << UREG_NR_SHIFT)) + + +#define I915_CONSTFLAG_PARAM 0x1f + +GLuint +i915_get_temp(struct i915_fp_compile *p) +{ + int bit = ffs(~p->temp_flag); + if (!bit) { + i915_program_error(p, "i915_get_temp: out of temporaries\n"); + return 0; + } + + p->temp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_R, (bit - 1)); +} + + +GLuint +i915_get_utemp(struct i915_fp_compile * p) +{ + int bit = ffs(~p->utemp_flag); + if (!bit) { + i915_program_error(p, "i915_get_utemp: out of temporaries\n"); + return 0; + } + + p->utemp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_U, (bit - 1)); +} + +void +i915_release_utemps(struct i915_fp_compile *p) +{ + p->utemp_flag = ~0x7; +} + + +GLuint +i915_emit_decl(struct i915_fp_compile *p, + GLuint type, GLuint nr, GLuint d0_flags) +{ + GLuint reg = UREG(type, nr); + + if (type == REG_TYPE_T) { + if (p->decl_t & (1 << nr)) + return reg; + + p->decl_t |= (1 << nr); + } + else if (type == REG_TYPE_S) { + if (p->decl_s & (1 << nr)) + return reg; + + p->decl_s |= (1 << nr); + } + else + return reg; + + *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); + *(p->decl++) = D1_MBZ; + *(p->decl++) = D2_MBZ; + + p->nr_decl_insn++; + return reg; +} + +GLuint +i915_emit_arith(struct i915_fp_compile * p, + GLuint op, + GLuint dest, + GLuint mask, + GLuint saturate, GLuint src0, GLuint src1, GLuint src2) +{ + GLuint c[3]; + GLuint nr_const = 0; + + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); + assert(dest); + + if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) + c[nr_const++] = 0; + if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) + c[nr_const++] = 1; + if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) + c[nr_const++] = 2; + + /* Recursively call this function to MOV additional const values + * into temporary registers. Use utemp registers for this - + * currently shouldn't be possible to run out, but keep an eye on + * this. + */ + if (nr_const > 1) { + GLuint s[3], first, i, old_utemp_flag; + + s[0] = src0; + s[1] = src1; + s[2] = src2; + old_utemp_flag = p->utemp_flag; + + first = GET_UREG_NR(s[c[0]]); + for (i = 1; i < nr_const; i++) { + if (GET_UREG_NR(s[c[i]]) != first) { + GLuint tmp = i915_get_utemp(p); + + i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, + s[c[i]], 0, 0); + s[c[i]] = tmp; + } + } + + src0 = s[0]; + src1 = s[1]; + src2 = s[2]; + p->utemp_flag = old_utemp_flag; /* restore */ + } + + *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); + *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); + *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); + + p->nr_alu_insn++; + return dest; +} + +GLuint i915_emit_texld( struct i915_fp_compile *p, + GLuint dest, + GLuint destmask, + GLuint sampler, + GLuint coord, + GLuint op ) +{ + if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) { + /* No real way to work around this in the general case - need to + * allocate and declare a new temporary register (a utemp won't + * do). Will fallback for now. + */ + i915_program_error(p, "Can't (yet) swizzle TEX arguments"); + return 0; + } + + /* Don't worry about saturate as we only support + */ + if (destmask != A0_DEST_CHANNEL_ALL) { + GLuint tmp = i915_get_utemp(p); + i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); + i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); + return dest; + } + else { + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); + + if (GET_UREG_TYPE(coord) != REG_TYPE_T) { + p->nr_tex_indirect++; + } + + *(p->csr++) = (op | + T0_DEST( dest ) | + T0_SAMPLER( sampler )); + + *(p->csr++) = T1_ADDRESS_REG( coord ); + *(p->csr++) = T2_MBZ; + + p->nr_tex_insn++; + return dest; + } +} + + +GLuint +i915_emit_const1f(struct i915_fp_compile * p, GLfloat c0) +{ + GLint reg, idx; + + if (c0 == 0.0) + return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); + if (c0 == 1.0) + return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 4; idx++) { + if (!(p->constant_flags[reg] & (1 << idx)) || + p->fp->constant[reg][idx] == c0) { + p->fp->constant[reg][idx] = c0; + p->constant_flags[reg] |= 1 << idx; + if (reg + 1 > p->fp->nr_constants) + p->fp->nr_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); + } + } + } + + i915_program_error(p, "i915_emit_const1f: out of constants\n"); + return 0; +} + +GLuint +i915_emit_const2f(struct i915_fp_compile * p, GLfloat c0, GLfloat c1) +{ + GLint reg, idx; + + if (c0 == 0.0) + return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); + if (c0 == 1.0) + return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); + + if (c1 == 0.0) + return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); + if (c1 == 1.0) + return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf || + p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 3; idx++) { + if (!(p->constant_flags[reg] & (3 << idx))) { + p->fp->constant[reg][idx] = c0; + p->fp->constant[reg][idx + 1] = c1; + p->constant_flags[reg] |= 3 << idx; + if (reg + 1 > p->fp->nr_constants) + p->fp->nr_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, + ONE); + } + } + } + + i915_program_error(p, "i915_emit_const2f: out of constants\n"); + return 0; +} + + + +GLuint +i915_emit_const4f(struct i915_fp_compile * p, + GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3) +{ + GLint reg; + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf && + p->fp->constant[reg][0] == c0 && + p->fp->constant[reg][1] == c1 && + p->fp->constant[reg][2] == c2 && + p->fp->constant[reg][3] == c3) { + return UREG(REG_TYPE_CONST, reg); + } + else if (p->constant_flags[reg] == 0) { + p->fp->constant[reg][0] = c0; + p->fp->constant[reg][1] = c1; + p->fp->constant[reg][2] = c2; + p->fp->constant[reg][3] = c3; + p->constant_flags[reg] = 0xf; + if (reg + 1 > p->fp->nr_constants) + p->fp->nr_constants = reg + 1; + return UREG(REG_TYPE_CONST, reg); + } + } + + i915_program_error(p, "i915_emit_const4f: out of constants\n"); + return 0; +} + + +GLuint +i915_emit_const4fv(struct i915_fp_compile * p, const GLfloat * c) +{ + return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); +} + +/* Reserve a slot in the constant file for a Mesa state parameter. + * These will later need to be tracked on statechanges, but that is + * done elsewhere. + */ +GLuint +i915_emit_param4fv(struct i915_fp_compile * p, const GLfloat * values) +{ + struct i915_fragment_program *fp = p->fp; + GLint i; + + for (i = 0; i < fp->nr_params; i++) { + if (fp->param[i].values == values) + return UREG(REG_TYPE_CONST, fp->param[i].reg); + } + + if (fp->nr_constants == I915_MAX_CONSTANT || + fp->nr_params == I915_MAX_CONSTANT) { + i915_program_error(p, "i915_emit_param4fv: out of constants\n"); + return 0; + } + + { + GLint reg = fp->nr_constants++; + GLint i = fp->nr_params++; + + assert (p->constant_flags[reg] == 0); + p->constant_flags[reg] = I915_CONSTFLAG_PARAM; + + fp->param[i].values = values; + fp->param[i].reg = reg; + + return UREG(REG_TYPE_CONST, reg); + } +} diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fpc_translate.c index 8772e70230..26c3894978 100644 --- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915tex/i915_fpc_translate.c @@ -35,7 +35,7 @@ #include "i915_reg.h" #include "i915_context.h" -#include "i915_program.h" +#include "i915_fpc.h" #include "program_instruction.h" #include "program.h" @@ -62,7 +62,7 @@ static const GLfloat cos_constants[4] = { 1.0, * constants, apply swizzling and negation as needed. */ static GLuint -src_vector(struct i915_fragment_program *p, +src_vector(struct i915_fp_compile *p, const struct prog_src_register *source, const struct gl_fragment_program *program) { @@ -80,9 +80,18 @@ src_vector(struct i915_fragment_program *p, src = UREG(REG_TYPE_R, source->Index); break; case PROGRAM_INPUT: + /* XXX: Packing COL1, FOGC into a single attribute works for + * texenv programs, but will fail for real fragment programs + * that use these attributes and expect them to be a full 4 + * components wide. Could use a texcoord to pass these + * attributes if necessary, but that won't work in the general + * case. + * + * We also use a texture coordinate to pass wpos when possible. + */ switch (source->Index) { case FRAG_ATTRIB_WPOS: - src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL); + src = i915_emit_decl(p, REG_TYPE_T, p->fp->wpos_tex, D0_CHANNEL_ALL); break; case FRAG_ATTRIB_COL0: src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); @@ -122,19 +131,14 @@ src_vector(struct i915_fragment_program *p, break; case PROGRAM_ENV_PARAM: - src = - i915_emit_param4fv(p, - p->ctx->FragmentProgram.Parameters[source-> - Index]); + src = i915_emit_param4fv(p, p->env_param[source->Index]); break; case PROGRAM_CONSTANT: case PROGRAM_STATE_VAR: case PROGRAM_NAMED_PARAM: - src = - i915_emit_param4fv(p, - program->Base.Parameters->ParameterValues[source-> - Index]); + src = i915_emit_param4fv( + p, program->Base.Parameters->ParameterValues[source->Index]); break; default: @@ -159,7 +163,7 @@ src_vector(struct i915_fragment_program *p, static GLuint -get_result_vector(struct i915_fragment_program *p, +get_result_vector(struct i915_fp_compile *p, const struct prog_instruction *inst) { switch (inst->DstReg.File) { @@ -168,7 +172,6 @@ get_result_vector(struct i915_fragment_program *p, case FRAG_RESULT_COLR: return UREG(REG_TYPE_OC, 0); case FRAG_RESULT_DEPR: - p->depth_written = 1; return UREG(REG_TYPE_OD, 0); default: i915_program_error(p, "Bad inst->DstReg.Index"); @@ -202,7 +205,7 @@ get_result_flags(const struct prog_instruction *inst) } static GLuint -translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit) +translate_tex_src_target(struct i915_fp_compile *p, GLubyte bit) { switch (bit) { case TEXTURE_1D_INDEX: @@ -264,14 +267,14 @@ do { \ * can lead to confusion -- hopefully we cope with it ok now. * */ -static void -upload_program(struct i915_fragment_program *p) +void +i915_translate_program(struct i915_fp_compile *p) { - const struct gl_fragment_program *program = - p->ctx->FragmentProgram._Current; - const struct prog_instruction *inst = program->Base.Instructions; + const struct gl_fragment_program *program = &p->fp->Base; + const struct prog_instruction *inst = program->Base.Instructions; -/* _mesa_debug_fp_inst(program->Base.NumInstructions, inst); */ + if (1) + i915_print_mesa_instructions(inst, program->Base.NumInstructions); /* Is this a parse-failed program? Ensure a valid program is * loaded, as the flagging of an error isn't sufficient to stop @@ -309,7 +312,9 @@ upload_program(struct i915_fragment_program *p) src0 = src_vector(p, &inst->SrcReg[0], program); src1 = src_vector(p, &inst->SrcReg[1], program); src2 = src_vector(p, &inst->SrcReg[2], program); - i915_emit_arith(p, A0_CMP, get_result_vector(p, inst), get_result_flags(inst), 0, src0, src2, src1); /* NOTE: order of src2, src1 */ + i915_emit_arith(p, A0_CMP, + get_result_vector(p, inst), get_result_flags(inst), + 0, src0, src2, src1); /* NOTE: order of src2, src1 */ break; case OPCODE_COS: @@ -758,10 +763,10 @@ upload_program(struct i915_fragment_program *p) * emit, just move the value into its correct position at the end of * the program: */ -static void -fixup_depth_write(struct i915_fragment_program *p) +void +i915_fixup_depth_write(struct i915_fp_compile *p) { - if (p->depth_written) { + if (p->fp->Base.Base.OutputsWritten & (1<<FRAG_RESULT_DEPR)) { GLuint depth = UREG(REG_TYPE_OD, 0); i915_emit_arith(p, @@ -772,312 +777,5 @@ fixup_depth_write(struct i915_fragment_program *p) } -#define FRAG_BIT_TEX(n) (FRAG_BIT_TEX0 << (n)) - - -static void -check_wpos(struct i915_fragment_program *p) -{ - GLuint inputs = p->FragProg.Base.InputsRead; - GLint i; - - p->wpos_tex = -1; - - for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { - if (inputs & FRAG_BIT_TEX(i)) - continue; - else if (inputs & FRAG_BIT_WPOS) { - p->wpos_tex = i; - inputs &= ~FRAG_BIT_WPOS; - } - } - - if (inputs & FRAG_BIT_WPOS) { - i915_program_error(p, "No free texcoord for wpos value"); - } -} - - -static void -translate_program(struct i915_fragment_program *p) -{ - struct i915_context *i915 = I915_CONTEXT(p->ctx); - - i915_init_program(i915, p); - check_wpos(p); - upload_program(p); - fixup_depth_write(p); - i915_fini_program(p); - - p->translated = 1; -} - - -static void -track_params(struct i915_fragment_program *p) -{ - GLint i; - - if (p->nr_params) - _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters); - - for (i = 0; i < p->nr_params; i++) { - GLint reg = p->param[i].reg; - COPY_4V(p->constant[reg], p->param[i].values); - } - - p->params_uptodate = 1; - p->on_hardware = 0; /* overkill */ -} - - -static void -i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_context *i915 = I915_CONTEXT(ctx); - struct i915_fragment_program *p = (struct i915_fragment_program *) prog; - - if (i915->current_program == p) - return; - - if (i915->current_program) { - i915->current_program->on_hardware = 0; - i915->current_program->params_uptodate = 0; - } - - i915->current_program = p; - - assert(p->on_hardware == 0); - assert(p->params_uptodate == 0); - - /* Hack: make sure fog is correctly enabled according to this - * fragment program's fog options. - */ - ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, - ctx->FragmentProgram.Enabled); - } -} - -static struct gl_program * -i915NewProgram(GLcontext * ctx, GLenum target, GLuint id) -{ - switch (target) { - case GL_VERTEX_PROGRAM_ARB: - return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), - target, id); - - case GL_FRAGMENT_PROGRAM_ARB:{ - struct i915_fragment_program *prog = - CALLOC_STRUCT(i915_fragment_program); - if (prog) { - i915_init_program(I915_CONTEXT(ctx), prog); - - return _mesa_init_fragment_program(ctx, &prog->FragProg, - target, id); - } - else - return NULL; - } - - default: - /* Just fallback: - */ - return _mesa_new_program(ctx, target, id); - } -} - -static void -i915DeleteProgram(GLcontext * ctx, struct gl_program *prog) -{ - if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_context *i915 = I915_CONTEXT(ctx); - struct i915_fragment_program *p = (struct i915_fragment_program *) prog; - - if (i915->current_program == p) - i915->current_program = 0; - } - _mesa_delete_program(ctx, prog); -} - - -static GLboolean -i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_fragment_program *p = (struct i915_fragment_program *) prog; - if (!p->translated) - translate_program(p); - - return !p->error; - } - else - return GL_TRUE; -} - -static void -i915ProgramStringNotify(GLcontext * ctx, - GLenum target, struct gl_program *prog) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_fragment_program *p = (struct i915_fragment_program *) prog; - p->translated = 0; - - /* Hack: make sure fog is correctly enabled according to this - * fragment program's fog options. - */ - ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, - ctx->FragmentProgram.Enabled); - - if (p->FragProg.FogOption) { - /* add extra instructions to do fog, then turn off FogOption field */ - _mesa_append_fog_code(ctx, &p->FragProg); - p->FragProg.FogOption = GL_NONE; - } - } - - _tnl_program_string(ctx, target, prog); -} - - -void -i915ValidateFragmentProgram(struct i915_context *i915) -{ - GLcontext *ctx = &i915->intel.ctx; - struct intel_context *intel = intel_context(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - - struct i915_fragment_program *p = - (struct i915_fragment_program *) ctx->FragmentProgram._Current; - - const GLuint inputsRead = p->FragProg.Base.InputsRead; - GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; - GLuint s2 = S2_TEXCOORD_NONE; - int i, offset = 0; - - if (i915->current_program != p) { - if (i915->current_program) { - i915->current_program->on_hardware = 0; - i915->current_program->params_uptodate = 0; - } - - i915->current_program = p; - } - - - /* Important: - */ - VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; - - if (!p->translated) - translate_program(p); - - intel->vertex_attr_count = 0; - intel->wpos_offset = 0; - intel->wpos_size = 0; - intel->coloroffset = 0; - intel->specoffset = 0; - - if (inputsRead & FRAG_BITS_TEX_ANY) { - EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16); - } - else { - EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12); - } - - if (inputsRead & FRAG_BIT_COL0) { - intel->coloroffset = offset / 4; - EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4); - } - - if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) || - i915->vertex_fog != I915_FOG_NONE) { - - if (inputsRead & FRAG_BIT_COL1) { - intel->specoffset = offset / 4; - EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3); - } - else - EMIT_PAD(3); - - if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) - EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1); - else - EMIT_PAD(1); - } - - /* XXX this was disabled, but enabling this code helped fix the Glean - * tfragprog1 fog tests. - */ -#if 1 - if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) { - EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4); - } -#endif - - for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { - if (inputsRead & FRAG_BIT_TEX(i)) { - int sz = VB->TexCoordPtr[i]->size; - - s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); - s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); - - EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4); - } - else if (i == p->wpos_tex) { - - /* If WPOS is required, duplicate the XYZ position data in an - * unused texture coordinate: - */ - s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); - s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); - - intel->wpos_offset = offset; - intel->wpos_size = 3 * sizeof(GLuint); - - EMIT_PAD(intel->wpos_size); - } - } - - if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || - s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - int k; - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - /* Must do this *after* statechange, so as not to affect - * buffered vertices reliant on the old state: - */ - intel->vertex_size = _tnl_install_attrs(&intel->ctx, - intel->vertex_attrs, - intel->vertex_attr_count, - intel->ViewportMatrix.m, 0); - - intel->vertex_size >>= 2; - - i915->state.Ctx[I915_CTXREG_LIS2] = s2; - i915->state.Ctx[I915_CTXREG_LIS4] = s4; - - k = intel->vtbl.check_vertex_size(intel, intel->vertex_size); - assert(k); - } - - if (!p->params_uptodate) - track_params(p); - - if (!p->on_hardware) - i915_upload_program(i915, p); -} - -void -i915InitFragProgFuncs(struct dd_function_table *functions) -{ - functions->BindProgram = i915BindProgram; - functions->NewProgram = i915NewProgram; - functions->DeleteProgram = i915DeleteProgram; - functions->IsProgramNative = i915IsProgramNative; - functions->ProgramStringNotify = i915ProgramStringNotify; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_metaops.c b/src/mesa/drivers/dri/i915tex/i915_metaops.c deleted file mode 100644 index 3ab62bc806..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_metaops.c +++ /dev/null @@ -1,509 +0,0 @@ -/************************************************************************** - * - * 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 "glheader.h" -#include "enums.h" -#include "mtypes.h" -#include "macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_regions.h" -#include "intel_rotate.h" - -#include "i915_context.h" -#include "i915_reg.h" - -/* We touch almost everything: - */ -#define ACTIVE (I915_UPLOAD_INVARIENT | \ - I915_UPLOAD_CTX | \ - I915_UPLOAD_BUFFERS | \ - I915_UPLOAD_STIPPLE | \ - I915_UPLOAD_PROGRAM | \ - I915_UPLOAD_FOG | \ - I915_UPLOAD_TEX(0)) - -#define SET_STATE( i915, STATE ) \ -do { \ - i915->current->emitted &= ~ACTIVE; \ - i915->current = &i915->STATE; \ - i915->current->emitted &= ~ACTIVE; \ -} while (0) - - -static void -meta_no_stencil_write(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -static void -meta_no_depth_write(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -static void -meta_depth_replace(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) - * ctx->Driver.DepthMask( ctx, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - /* ctx->Driver.DepthFunc( ctx, GL_REPLACE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; - i915->meta.Ctx[I915_CTXREG_LIS6] |= - COMPAREFUNC_ALWAYS << S6_DEPTH_TEST_FUNC_SHIFT; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -/* Set stencil unit to replace always with the reference value. - */ -static void -meta_stencil_replace(struct intel_context *intel, - GLuint s_mask, GLuint s_clear) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint op = STENCILOP_REPLACE; - GLuint func = COMPAREFUNC_ALWAYS; - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(s_mask)); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_PASS_SHIFT)); - - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) | - (func << S5_STENCIL_TEST_FUNC_SHIFT)); - - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -static void -meta_color_mask(struct intel_context *intel, GLboolean state) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - const GLuint mask = (S5_WRITEDISABLE_RED | - S5_WRITEDISABLE_GREEN | - S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA); - - /* Copy colormask state from "regular" hw context. - */ - if (state) { - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask; - i915->meta.Ctx[I915_CTXREG_LIS5] |= - (i915->state.Ctx[I915_CTXREG_LIS5] & mask); - } - else - i915->meta.Ctx[I915_CTXREG_LIS5] |= mask; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - -static void -meta_import_pixel_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - memcpy(i915->meta.Fog, i915->state.Fog, I915_FOG_SETUP_SIZE * 4); - - i915->meta.Ctx[I915_CTXREG_LIS5] = i915->state.Ctx[I915_CTXREG_LIS5]; - i915->meta.Ctx[I915_CTXREG_LIS6] = i915->state.Ctx[I915_CTXREG_LIS6]; - i915->meta.Ctx[I915_CTXREG_STATE4] = i915->state.Ctx[I915_CTXREG_STATE4]; - i915->meta.Ctx[I915_CTXREG_BLENDCOLOR1] = - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1]; - i915->meta.Ctx[I915_CTXREG_IAB] = i915->state.Ctx[I915_CTXREG_IAB]; - - i915->meta.Buffer[I915_DESTREG_SENABLE] = - i915->state.Buffer[I915_DESTREG_SENABLE]; - i915->meta.Buffer[I915_DESTREG_SR1] = i915->state.Buffer[I915_DESTREG_SR1]; - i915->meta.Buffer[I915_DESTREG_SR2] = i915->state.Buffer[I915_DESTREG_SR2]; - - i915->meta.emitted &= ~I915_UPLOAD_FOG; - i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - - -#define REG( type, nr ) (((type)<<5)|(nr)) - -#define REG_R(x) REG(REG_TYPE_R, x) -#define REG_T(x) REG(REG_TYPE_T, x) -#define REG_CONST(x) REG(REG_TYPE_CONST, x) -#define REG_S(x) REG(REG_TYPE_S, x) -#define REG_OC REG(REG_TYPE_OC, 0) -#define REG_OD REG(REG_TYPE_OD, 0) -#define REG_U(x) REG(REG_TYPE_U, x) - -#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE) -#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR) -#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W) -#define REG_T_TEX(x) REG(REG_TYPE_T, x) - - -#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT ) -#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT ) -#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT ) -#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT ) -#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT ) -#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT ) -#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT ) - -#define T0_SAMPLER( unit ) ((unit)<<T0_SAMPLER_NR_SHIFT) - -#define T1_ADDRESS_REG( type, nr ) (((type)<<T1_ADDRESS_REG_TYPE_SHIFT)| \ - ((nr)<<T1_ADDRESS_REG_NR_SHIFT)) - - -#define A1_SRC0_XYZW ((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | \ - (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | \ - (SRC_W << A1_SRC0_CHANNEL_W_SHIFT)) - -#define A1_SRC1_XY ((SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | \ - (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT)) - -#define A2_SRC1_ZW ((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC1_CHANNEL_W_SHIFT)) - -#define A2_SRC2_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ - (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) - - - - - -static void -meta_no_texture(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare incoming diffuse color: - */ - (D0_DCL | D0_DECL_REG(REG_T_DIFFUSE) | D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = mov(t_diffuse) - */ - (A0_MOV | - A0_DEST_REG(REG_OC) | - A0_DEST_CHANNEL_ALL | A0_SRC0_REG(REG_T_DIFFUSE)), - (A1_SRC0_XYZW), - 0, - }; - - - memcpy(i915->meta.Program, prog, sizeof(prog)); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - -static void -meta_texture_blend_replace(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare the sampler: - */ - (D0_DCL | D0_DECL_REG(REG_S(0)) | D0_SAMPLE_TYPE_2D | D0_CHANNEL_NONE), - D1_MBZ, - D2_MBZ, - - /* Declare the interpolated texture coordinate: - */ - (D0_DCL | D0_DECL_REG(REG_T_TEX(0)) | D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = texld(sample0, texcoord0) - */ - (T0_TEXLD | T0_DEST_REG(REG_OC) | T0_SAMPLER(0)), - T1_ADDRESS_REG(REG_TYPE_T, 0), - T2_MBZ - }; - - memcpy(i915->meta.Program, prog, sizeof(prog)); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - - - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static GLboolean -meta_tex_rect_source(struct intel_context *intel, - struct _DriBufferObject *buffer, - GLuint offset, - GLuint pitch, GLuint height, GLenum format, GLenum type) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint unit = 0; - GLint numLevels = 1; - GLuint *state = i915->meta.Tex[0]; - GLuint textureFormat; - GLuint cpp; - - /* A full implementation of this would do the upload through - * glTexImage2d, and get all the conversion operations at that - * point. We are restricted, but still at least have access to the - * fragment program swizzle. - */ - switch (format) { - case GL_BGRA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_RGBA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_BGR: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5_REV: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - case GL_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - - default: - return GL_FALSE; - } - - - if ((pitch * cpp) & 3) { - _mesa_printf("%s: texture is not dword pitch\n", __FUNCTION__); - return GL_FALSE; - } - -/* intel_region_release(&i915->meta.tex_region[0]); */ -/* intel_region_reference(&i915->meta.tex_region[0], region); */ - i915->meta.tex_buffer[0] = buffer; - i915->meta.tex_offset[0] = offset; - - state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | - ((pitch - 1) << MS3_WIDTH_SHIFT) | - textureFormat | MS3_USE_FENCE_REGS); - - state[I915_TEXREG_MS4] = (((((pitch * cpp) / 4) - 1) << MS4_PITCH_SHIFT) | - MS4_CUBE_FACE_ENA_MASK | - ((((numLevels - 1) * 4)) << MS4_MAX_LOD_SHIFT)); - - state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | - (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); - - state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | - (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); - - state[I915_TEXREG_SS4] = 0; - - i915->meta.emitted &= ~I915_UPLOAD_TEX(0); - return GL_TRUE; -} - - -/** - * Set the color and depth drawing region for meta ops. - */ -static void -meta_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->meta, color_region, depth_region); -} - - -static void -set_vertex_format(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - i915->meta.Ctx[I915_CTXREG_LIS2] = - (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | - S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); - - i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK; - - i915->meta.Ctx[I915_CTXREG_LIS4] |= (S4_VFMT_COLOR | S4_VFMT_XYZ); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void -install_meta_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - memcpy(&i915->meta, &i915->initial, sizeof(i915->meta)); - i915->meta.active = ACTIVE; - i915->meta.emitted = 0; - - SET_STATE(i915, meta); - set_vertex_format(intel); - meta_no_texture(intel); -} - -static void -leave_meta_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - intel_region_release(&i915->meta.draw_region); - intel_region_release(&i915->meta.depth_region); -/* intel_region_release(&i915->meta.tex_region[0]); */ - SET_STATE(i915, state); -} - - - -void -i915InitMetaFuncs(struct i915_context *i915) -{ - i915->intel.vtbl.install_meta_state = install_meta_state; - i915->intel.vtbl.leave_meta_state = leave_meta_state; - i915->intel.vtbl.meta_no_depth_write = meta_no_depth_write; - i915->intel.vtbl.meta_no_stencil_write = meta_no_stencil_write; - i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace; - i915->intel.vtbl.meta_depth_replace = meta_depth_replace; - i915->intel.vtbl.meta_color_mask = meta_color_mask; - i915->intel.vtbl.meta_no_texture = meta_no_texture; - i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; - i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; - i915->intel.vtbl.meta_draw_region = meta_draw_region; - i915->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_program.c b/src/mesa/drivers/dri/i915tex/i915_program.c index 0be89d3320..fdfe39abea 100644 --- a/src/mesa/drivers/dri/i915tex/i915_program.c +++ b/src/mesa/drivers/dri/i915tex/i915_program.c @@ -25,491 +25,113 @@ * **************************************************************************/ -#include <strings.h> - #include "glheader.h" #include "macros.h" #include "enums.h" +#include "tnl/tnl.h" #include "tnl/t_context.h" #include "intel_batchbuffer.h" #include "i915_reg.h" #include "i915_context.h" -#include "i915_program.h" - - -#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) -#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT) -#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT) -#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT) -#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT) - -/* These are special, and don't have swizzle/negate bits. - */ -#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT) -#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \ - (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT)) +#include "program_instruction.h" +#include "program.h" +#include "programopt.h" -/* Macros for translating UREG's into the various register fields used - * by the I915 programmable unit. - */ -#define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT) -#define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT) -#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) -#define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT) -#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) -#define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT) -#define UREG_MASK 0xffffff00 -#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \ - (REG_NR_MASK << UREG_NR_SHIFT)) - - -#define I915_CONSTFLAG_PARAM 0x1f - -GLuint -i915_get_temp(struct i915_fragment_program *p) +static void i915BindProgram( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) { - int bit = ffs(~p->temp_flag); - if (!bit) { - fprintf(stderr, "%s: out of temporaries\n", __FILE__); - exit(1); - } + struct intel_context *intel = intel_context(ctx); - p->temp_flag |= 1 << (bit - 1); - return UREG(REG_TYPE_R, (bit - 1)); -} - - -GLuint -i915_get_utemp(struct i915_fragment_program * p) -{ - int bit = ffs(~p->utemp_flag); - if (!bit) { - fprintf(stderr, "%s: out of temporaries\n", __FILE__); - exit(1); + switch (target) { + case GL_VERTEX_PROGRAM_ARB: +/* intel->state.dirty.intel |= INTEL_NEW_VERTEX_PROGRAM; */ + break; + case GL_FRAGMENT_PROGRAM_ARB: + intel->state.dirty.intel |= INTEL_NEW_FRAGMENT_PROGRAM; + break; } - - p->utemp_flag |= 1 << (bit - 1); - return UREG(REG_TYPE_U, (bit - 1)); } -void -i915_release_utemps(struct i915_fragment_program *p) +static struct gl_program *i915NewProgram( GLcontext *ctx, + GLenum target, + GLuint id ) { - p->utemp_flag = ~0x7; -} - - -GLuint -i915_emit_decl(struct i915_fragment_program *p, - GLuint type, GLuint nr, GLuint d0_flags) -{ - GLuint reg = UREG(type, nr); - - if (type == REG_TYPE_T) { - if (p->decl_t & (1 << nr)) - return reg; - - p->decl_t |= (1 << nr); - } - else if (type == REG_TYPE_S) { - if (p->decl_s & (1 << nr)) - return reg; - - p->decl_s |= (1 << nr); - } - else - return reg; - - *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); - *(p->decl++) = D1_MBZ; - *(p->decl++) = D2_MBZ; - - p->nr_decl_insn++; - return reg; -} - -GLuint -i915_emit_arith(struct i915_fragment_program * p, - GLuint op, - GLuint dest, - GLuint mask, - GLuint saturate, GLuint src0, GLuint src1, GLuint src2) -{ - GLuint c[3]; - GLuint nr_const = 0; - - assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); - dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); - assert(dest); - - if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) - c[nr_const++] = 0; - if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) - c[nr_const++] = 1; - if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) - c[nr_const++] = 2; + struct i915_context *i915 = i915_context(ctx); - /* Recursively call this function to MOV additional const values - * into temporary registers. Use utemp registers for this - - * currently shouldn't be possible to run out, but keep an eye on - * this. - */ - if (nr_const > 1) { - GLuint s[3], first, i, old_utemp_flag; + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), + target, id); - s[0] = src0; - s[1] = src1; - s[2] = src2; - old_utemp_flag = p->utemp_flag; + case GL_FRAGMENT_PROGRAM_ARB: { + struct i915_fragment_program *prog = CALLOC_STRUCT(i915_fragment_program); + if (prog) { + prog->id = i915->program_id++; - first = GET_UREG_NR(s[c[0]]); - for (i = 1; i < nr_const; i++) { - if (GET_UREG_NR(s[c[i]]) != first) { - GLuint tmp = i915_get_utemp(p); - - i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, - s[c[i]], 0, 0); - s[c[i]] = tmp; - } + return _mesa_init_fragment_program( ctx, &prog->Base, + target, id ); } - - src0 = s[0]; - src1 = s[1]; - src2 = s[2]; - p->utemp_flag = old_utemp_flag; /* restore */ - } - - *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); - *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); - *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); - - p->nr_alu_insn++; - return dest; -} - -GLuint i915_emit_texld( struct i915_fragment_program *p, - GLuint dest, - GLuint destmask, - GLuint sampler, - GLuint coord, - GLuint op ) -{ - if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) { - /* No real way to work around this in the general case - need to - * allocate and declare a new temporary register (a utemp won't - * do). Will fallback for now. - */ - i915_program_error(p, "Can't (yet) swizzle TEX arguments"); - return 0; - } - - /* Don't worry about saturate as we only support - */ - if (destmask != A0_DEST_CHANNEL_ALL) { - GLuint tmp = i915_get_utemp(p); - i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); - i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); - return dest; + else + return NULL; } - else { - assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); - assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); - - if (GET_UREG_TYPE(coord) != REG_TYPE_T) { - p->nr_tex_indirect++; - } - - *(p->csr++) = (op | - T0_DEST( dest ) | - T0_SAMPLER( sampler )); - *(p->csr++) = T1_ADDRESS_REG( coord ); - *(p->csr++) = T2_MBZ; - - p->nr_tex_insn++; - return dest; + default: + return _mesa_new_program(ctx, target, id); } } - -GLuint -i915_emit_const1f(struct i915_fragment_program * p, GLfloat c0) +static void i915DeleteProgram( GLcontext *ctx, + struct gl_program *prog ) { - GLint reg, idx; - - if (c0 == 0.0) - return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); - if (c0 == 1.0) - return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) - continue; - for (idx = 0; idx < 4; idx++) { - if (!(p->constant_flags[reg] & (1 << idx)) || - p->constant[reg][idx] == c0) { - p->constant[reg][idx] = c0; - p->constant_flags[reg] |= 1 << idx; - if (reg + 1 > p->nr_constants) - p->nr_constants = reg + 1; - return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); - } - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; + + _mesa_delete_program( ctx, prog ); } -GLuint -i915_emit_const2f(struct i915_fragment_program * p, GLfloat c0, GLfloat c1) -{ - GLint reg, idx; - - if (c0 == 0.0) - return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); - if (c0 == 1.0) - return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); - if (c1 == 0.0) - return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); - if (c1 == 1.0) - return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf || - p->constant_flags[reg] == I915_CONSTFLAG_PARAM) - continue; - for (idx = 0; idx < 3; idx++) { - if (!(p->constant_flags[reg] & (3 << idx))) { - p->constant[reg][idx] = c0; - p->constant[reg][idx + 1] = c1; - p->constant_flags[reg] |= 3 << idx; - if (reg + 1 > p->nr_constants) - p->nr_constants = reg + 1; - return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, - ONE); - } - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - - -GLuint -i915_emit_const4f(struct i915_fragment_program * p, - GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3) -{ - GLint reg; - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf && - p->constant[reg][0] == c0 && - p->constant[reg][1] == c1 && - p->constant[reg][2] == c2 && p->constant[reg][3] == c3) { - return UREG(REG_TYPE_CONST, reg); - } - else if (p->constant_flags[reg] == 0) { - p->constant[reg][0] = c0; - p->constant[reg][1] = c1; - p->constant[reg][2] = c2; - p->constant[reg][3] = c3; - p->constant_flags[reg] = 0xf; - if (reg + 1 > p->nr_constants) - p->nr_constants = reg + 1; - return UREG(REG_TYPE_CONST, reg); - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - -GLuint -i915_emit_const4fv(struct i915_fragment_program * p, const GLfloat * c) +static GLboolean i915IsProgramNative( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) { - return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); + return GL_TRUE; } - -GLuint -i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values) +static void i915ProgramStringNotify( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) { - GLint reg, i; - - for (i = 0; i < p->nr_params; i++) { - if (p->param[i].values == values) - return UREG(REG_TYPE_CONST, p->param[i].reg); - } - - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0) { - p->constant_flags[reg] = I915_CONSTFLAG_PARAM; - i = p->nr_params++; - - p->param[i].values = values; - p->param[i].reg = reg; - p->params_uptodate = 0; - - if (reg + 1 > p->nr_constants) - p->nr_constants = reg + 1; - return UREG(REG_TYPE_CONST, reg); - } + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = i915_context(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *)prog; + struct i915_fragment_program *fp = (struct i915_fragment_program *)i915->fragment_program; + if (p == fp) + i915->intel.state.dirty.intel |= INTEL_NEW_FRAGMENT_PROGRAM; + p->id = i915->program_id++; + p->param_state = p->Base.Base.Parameters->StateFlags; + } + else if (target == GL_VERTEX_PROGRAM_ARB) { + + /* Also tell tnl about it: + */ + _tnl_program_string(ctx, target, prog); } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - - -void -i915_program_error(struct i915_fragment_program *p, const char *msg) -{ - _mesa_problem(NULL, "i915_program_error: %s", msg); - p->error = 1; -} - - -void -i915_init_program(struct i915_context *i915, struct i915_fragment_program *p) -{ - GLcontext *ctx = &i915->intel.ctx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - - p->translated = 0; - p->params_uptodate = 0; - p->on_hardware = 0; - p->error = 0; - - p->nr_tex_indirect = 1; /* correct? */ - p->nr_tex_insn = 0; - p->nr_alu_insn = 0; - p->nr_decl_insn = 0; - - p->ctx = ctx; - memset(p->constant_flags, 0, sizeof(p->constant_flags)); - - p->nr_constants = 0; - p->csr = p->program; - p->decl = p->declarations; - p->decl_s = 0; - p->decl_t = 0; - p->temp_flag = 0xffff000; - p->utemp_flag = ~0x7; - p->wpos_tex = -1; - p->depth_written = 0; - p->nr_params = 0; - - p->src_texture = UREG_BAD; - p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE); - p->last_tex_stage = 0; - p->VB = &tnl->vb; - - *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; } - -void -i915_fini_program(struct i915_fragment_program *p) +void i915InitFragProgFuncs( struct dd_function_table *functions ) { - GLuint program_size = p->csr - p->program; - GLuint decl_size = p->decl - p->declarations; - - if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) - i915_program_error(p, "Exceeded max nr indirect texture lookups"); - - if (p->nr_tex_insn > I915_MAX_TEX_INSN) - i915_program_error(p, "Exceeded max TEX instructions"); - - if (p->nr_alu_insn > I915_MAX_ALU_INSN) - i915_program_error(p, "Exceeded max ALU instructions"); - - if (p->nr_decl_insn > I915_MAX_DECL_INSN) - i915_program_error(p, "Exceeded max DECL instructions"); + assert(functions->ProgramStringNotify == _tnl_program_string); - if (p->error) { - p->FragProg.Base.NumNativeInstructions = 0; - p->FragProg.NumNativeAluInstructions = 0; - p->FragProg.NumNativeTexInstructions = 0; - p->FragProg.NumNativeTexIndirections = 0; - } - else { - p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn + - p->nr_tex_insn + - p->nr_decl_insn); - p->FragProg.NumNativeAluInstructions = p->nr_alu_insn; - p->FragProg.NumNativeTexInstructions = p->nr_tex_insn; - p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect; - } - - p->declarations[0] |= program_size + decl_size - 2; + functions->BindProgram = i915BindProgram; + functions->NewProgram = i915NewProgram; + functions->DeleteProgram = i915DeleteProgram; + functions->IsProgramNative = i915IsProgramNative; + functions->ProgramStringNotify = i915ProgramStringNotify; } -void -i915_upload_program(struct i915_context *i915, - struct i915_fragment_program *p) -{ - GLuint program_size = p->csr - p->program; - GLuint decl_size = p->decl - p->declarations; - - FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error); - - /* Could just go straight to the batchbuffer from here: - */ - if (i915->state.ProgramSize != (program_size + decl_size) || - memcmp(i915->state.Program + decl_size, p->program, - program_size * sizeof(int)) != 0) { - I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM); - memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int)); - memcpy(i915->state.Program + decl_size, p->program, - program_size * sizeof(int)); - i915->state.ProgramSize = decl_size + program_size; - } - - /* Always seemed to get a failure if I used memcmp() to - * shortcircuit this state upload. Needs further investigation? - */ - if (p->nr_constants) { - GLuint nr = p->nr_constants; - - I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1); - I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS); - i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4); - i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1); - memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr)); - i915->state.ConstantSize = 2 + (nr) * 4; - if (0) { - GLuint i; - for (i = 0; i < nr; i++) { - fprintf(stderr, "const[%d]: %f %f %f %f\n", i, - p->constant[i][0], - p->constant[i][1], p->constant[i][2], p->constant[i][3]); - } - } - } - else { - I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0); - } - - p->on_hardware = 1; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_program.h b/src/mesa/drivers/dri/i915tex/i915_program.h deleted file mode 100644 index 3c12b34f16..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_program.h +++ /dev/null @@ -1,160 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - - -#ifndef I915_PROGRAM_H -#define I915_PROGRAM_H - -#include "i915_context.h" -#include "i915_reg.h" - - - -/* Having zero and one in here makes the definition of swizzle a lot - * easier. - */ -#define UREG_TYPE_SHIFT 29 -#define UREG_NR_SHIFT 24 -#define UREG_CHANNEL_X_NEGATE_SHIFT 23 -#define UREG_CHANNEL_X_SHIFT 20 -#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 -#define UREG_CHANNEL_Y_SHIFT 16 -#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 -#define UREG_CHANNEL_Z_SHIFT 12 -#define UREG_CHANNEL_W_NEGATE_SHIFT 11 -#define UREG_CHANNEL_W_SHIFT 8 -#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 -#define UREG_CHANNEL_ZERO_SHIFT 4 -#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 -#define UREG_CHANNEL_ONE_SHIFT 0 - -#define UREG_BAD 0xffffffff /* not a valid ureg */ - -#define X SRC_X -#define Y SRC_Y -#define Z SRC_Z -#define W SRC_W -#define ZERO SRC_ZERO -#define ONE SRC_ONE - -/* Construct a ureg: - */ -#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ - ((nr) << UREG_NR_SHIFT) | \ - (X << UREG_CHANNEL_X_SHIFT) | \ - (Y << UREG_CHANNEL_Y_SHIFT) | \ - (Z << UREG_CHANNEL_Z_SHIFT) | \ - (W << UREG_CHANNEL_W_SHIFT) | \ - (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ - (ONE << UREG_CHANNEL_ONE_SHIFT)) - -#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) -#define CHANNEL_SRC( src, channel ) (src>>(channel*4)) - -#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) -#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) - - - -#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 - -/* One neat thing about the UREG representation: - */ -static INLINE int -swizzle(int reg, int x, int y, int z, int w) -{ - return ((reg & ~UREG_XYZW_CHANNEL_MASK) | - CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | - CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | - CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | - CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); -} - -/* Another neat thing about the UREG representation: - */ -static INLINE int -negate(int reg, int x, int y, int z, int w) -{ - return reg ^ (((x & 1) << UREG_CHANNEL_X_NEGATE_SHIFT) | - ((y & 1) << UREG_CHANNEL_Y_NEGATE_SHIFT) | - ((z & 1) << UREG_CHANNEL_Z_NEGATE_SHIFT) | - ((w & 1) << UREG_CHANNEL_W_NEGATE_SHIFT)); -} - - -extern GLuint i915_get_temp(struct i915_fragment_program *p); -extern GLuint i915_get_utemp(struct i915_fragment_program *p); -extern void i915_release_utemps(struct i915_fragment_program *p); - - -extern GLuint i915_emit_texld(struct i915_fragment_program *p, - GLuint dest, - GLuint destmask, - GLuint sampler, GLuint coord, GLuint op); - -extern GLuint i915_emit_arith(struct i915_fragment_program *p, - GLuint op, - GLuint dest, - GLuint mask, - GLuint saturate, - GLuint src0, GLuint src1, GLuint src2); - -extern GLuint i915_emit_decl(struct i915_fragment_program *p, - GLuint type, GLuint nr, GLuint d0_flags); - - -extern GLuint i915_emit_const1f(struct i915_fragment_program *p, GLfloat c0); - -extern GLuint i915_emit_const2f(struct i915_fragment_program *p, - GLfloat c0, GLfloat c1); - -extern GLuint i915_emit_const4fv(struct i915_fragment_program *p, - const GLfloat * c); - -extern GLuint i915_emit_const4f(struct i915_fragment_program *p, - GLfloat c0, GLfloat c1, - GLfloat c2, GLfloat c3); - - -extern GLuint i915_emit_param4fv(struct i915_fragment_program *p, - const GLfloat * values); - -extern void i915_program_error(struct i915_fragment_program *p, - const char *msg); - -extern void i915_init_program(struct i915_context *i915, - struct i915_fragment_program *p); - -extern void i915_upload_program(struct i915_context *i915, - struct i915_fragment_program *p); - -extern void i915_fini_program(struct i915_fragment_program *p); - - - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_reg.h b/src/mesa/drivers/dri/i915tex/i915_reg.h index 04b199905c..02d2972db2 100644 --- a/src/mesa/drivers/dri/i915tex/i915_reg.h +++ b/src/mesa/drivers/dri/i915tex/i915_reg.h @@ -424,6 +424,16 @@ #define S7_DEPTH_OFFSET_CONST_MASK ~0 + + +#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT) +#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT) +#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT) +#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT) + + + + /* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */ /* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */ diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c index 1fafadced0..e21237400f 100644 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -28,993 +28,111 @@ #include "glheader.h" #include "context.h" -#include "macros.h" -#include "enums.h" -#include "dd.h" -#include "tnl/tnl.h" -#include "tnl/t_context.h" - -#include "texmem.h" - -#include "intel_fbo.h" -#include "intel_screen.h" -#include "intel_batchbuffer.h" +#include "intel_state.h" #include "i915_context.h" -#include "i915_reg.h" +#include "i915_state.h" #define FILE_DEBUG_FLAG DEBUG_STATE -static void -i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, - GLuint mask) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - - mask = mask & 0xff; - - DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(func), ref, mask); - - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(mask)); - - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | - (test << - S5_STENCIL_TEST_FUNC_SHIFT)); -} - -static void -i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - DBG("%s : mask 0x%x\n", __FUNCTION__, mask); - - mask = mask & 0xff; - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(mask)); -} - - -static void -i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, - GLenum zpass) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int fop = intel_translate_stencil_op(fail); - int dfop = intel_translate_stencil_op(zfail); - int dpop = intel_translate_stencil_op(zpass); - - - DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(fail), - _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass)); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | - (dfop << - S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (dpop << - S5_STENCIL_PASS_Z_PASS_SHIFT)); -} - -static void -i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - GLubyte refByte; - - UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | - S6_ALPHA_REF_MASK); - i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | - (((GLuint) refByte) << - S6_ALPHA_REF_SHIFT)); -} - -/* This function makes sure that the proper enables are - * set for LogicOp, Independant Alpha Blend, and Blending. - * It needs to be called from numerous places where we - * could change the LogicOp or Independant Alpha Blend without subsequent - * calls to glEnable. - */ -static void -i915EvalLogicOpBlendState(GLcontext * ctx) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (RGBA_LOGICOP_ENABLED(ctx)) { - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; - } - else { - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; - - if (ctx->Color.BlendEnabled) { - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; - } - else { - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; - } - } -} - -static void -i915BlendColor(GLcontext * ctx, const GLfloat color[4]) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLubyte r, g, b, a; - - DBG("%s\n", __FUNCTION__); - - UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = - (a << 24) | (r << 16) | (g << 8) | b; -} - - -#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT) -#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT) -#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT) -#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT) - - - -static GLuint -translate_blend_equation(GLenum mode) -{ - switch (mode) { - case GL_FUNC_ADD: - return BLENDFUNC_ADD; - case GL_MIN: - return BLENDFUNC_MIN; - case GL_MAX: - return BLENDFUNC_MAX; - case GL_FUNC_SUBTRACT: - return BLENDFUNC_SUBTRACT; - case GL_FUNC_REVERSE_SUBTRACT: - return BLENDFUNC_REVERSE_SUBTRACT; - default: - return 0; - } -} - -static void -i915UpdateBlendState(GLcontext * ctx) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] & - ~(IAB_SRC_FACTOR_MASK | - IAB_DST_FACTOR_MASK | - (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); - - GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & - ~(S6_CBUF_SRC_BLEND_FACT_MASK | - S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); - - GLuint eqRGB = ctx->Color.BlendEquationRGB; - GLuint eqA = ctx->Color.BlendEquationA; - GLuint srcRGB = ctx->Color.BlendSrcRGB; - GLuint dstRGB = ctx->Color.BlendDstRGB; - GLuint srcA = ctx->Color.BlendSrcA; - GLuint dstA = ctx->Color.BlendDstA; - - if (eqRGB == GL_MIN || eqRGB == GL_MAX) { - srcRGB = dstRGB = GL_ONE; - } - - if (eqA == GL_MIN || eqA == GL_MAX) { - srcA = dstA = GL_ONE; - } - - lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); - lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); - lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; - - iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); - iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); - iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; + - if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) - iab |= IAB_ENABLE; - - if (iab != i915->state.Ctx[I915_CTXREG_IAB] || - lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_IAB] = iab; - i915->state.Ctx[I915_CTXREG_LIS6] = lis6; - } - - /* This will catch a logicop blend equation */ - i915EvalLogicOpBlendState(ctx); -} - - -static void -i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB, - GLenum dstRGB, GLenum srcA, GLenum dstA) -{ - i915UpdateBlendState(ctx); -} - - -static void -i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA) -{ - i915UpdateBlendState(ctx); -} - - -static void -i915DepthFunc(GLcontext * ctx, GLenum func) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - - DBG("%s\n", __FUNCTION__); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; - i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; -} - -static void -i915DepthMask(GLcontext * ctx, GLboolean flag) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - DBG("%s flag (%d)\n", __FUNCTION__, flag); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (flag && ctx->Depth.Test) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; -} - -/* ============================================================= - * Polygon stipple - * - * The i915 supports a 4x4 stipple natively, GL wants 32x32. - * Fortunately stipple is usually a repeating pattern. +/* This is used to initialize intel->state.atoms[]. We could use this + * list directly except for a single atom, i915_constants, which + * has a .dirty value which changes according to the parameters of the + * current fragment and vertex programs, and so cannot be a static + * value. */ -static void -i915PolygonStipple(GLcontext * ctx, const GLubyte * mask) +const struct intel_tracked_state *atoms[] = { - struct i915_context *i915 = I915_CONTEXT(ctx); - const GLubyte *m = mask; - GLubyte p[4]; - int i, j, k; - int active = (ctx->Polygon.StippleFlag && - i915->intel.reduced_primitive == GL_TRIANGLES); - GLuint newMask; - - if (active) { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; - } - - p[0] = mask[12] & 0xf; - p[0] |= p[0] << 4; - p[1] = mask[8] & 0xf; - p[1] |= p[1] << 4; - p[2] = mask[4] & 0xf; - p[2] |= p[2] << 4; - p[3] = mask[0] & 0xf; - p[3] |= p[3] << 4; + &i915_check_fallback, + &i915_invarient_state, - for (k = 0; k < 8; k++) - for (j = 3; j >= 0; j--) - for (i = 0; i < 4; i++, m++) - if (*m != p[j]) { - i915->intel.hw_stipple = 0; - return; - } - - newMask = (((p[0] & 0xf) << 0) | - ((p[1] & 0xf) << 4) | - ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); - - - if (newMask == 0xffff || newMask == 0x0) { - /* this is needed to make conform pass */ - i915->intel.hw_stipple = 0; - return; - } - i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; - i915->state.Stipple[I915_STPREG_ST1] |= newMask; - i915->intel.hw_stipple = 1; + &intel_update_viewport, + &intel_update_render_index, - if (active) - i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; -} - - -/* ============================================================= - * Hardware clipping - */ -static void -i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int x1, y1, x2, y2; - - if (!ctx->DrawBuffer) - return; - - DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); - - if (ctx->DrawBuffer->Name == 0) { - x1 = x; - y1 = ctx->DrawBuffer->Height - (y + h); - x2 = x + w - 1; - y2 = y1 + h - 1; - DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); - } - else { - /* FBO - not inverted - */ - x1 = x; - y1 = y; - x2 = x + w - 1; - y2 = y + h - 1; - DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); - } - - x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); - y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); - x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); - y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); - - DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); - - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); - i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); -} - -static void -i915LogicOp(GLcontext * ctx, GLenum opcode) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int tmp = intel_translate_logic_op(opcode); - - DBG("%s\n", __FUNCTION__); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); -} - - - -static void -i915CullFaceFrontFace(GLcontext * ctx, GLenum unused) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLuint mode; - - DBG("%s %d\n", __FUNCTION__, - ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); - - if (!ctx->Polygon.CullFlag) { - mode = S4_CULLMODE_NONE; - } - else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { - mode = S4_CULLMODE_CW; - - if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); - if (ctx->Polygon.CullFaceMode == GL_FRONT) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); - if (ctx->Polygon.FrontFace != GL_CCW) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); - } - else { - mode = S4_CULLMODE_BOTH; - } - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; - i915->state.Ctx[I915_CTXREG_LIS4] |= mode; -} - -static void -i915LineWidth(GLcontext * ctx, GLfloat widthf) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; - int width; - - DBG("%s\n", __FUNCTION__); - - width = (int) (widthf * 2); - CLAMP_SELF(width, 1, 0xf); - lis4 |= width << S4_LINE_WIDTH_SHIFT; - - if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] = lis4; - } -} - -static void -i915PointSize(GLcontext * ctx, GLfloat size) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; - GLint point_size = (int) size; - - DBG("%s\n", __FUNCTION__); - - CLAMP_SELF(point_size, 1, 255); - lis4 |= point_size << S4_POINT_WIDTH_SHIFT; - - if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] = lis4; - } -} - - -/* ============================================================= - * Color masks - */ - -static void -i915ColorMask(GLcontext * ctx, - GLboolean r, GLboolean g, GLboolean b, GLboolean a) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; - - DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, - a); - - if (!r) - tmp |= S5_WRITEDISABLE_RED; - if (!g) - tmp |= S5_WRITEDISABLE_GREEN; - if (!b) - tmp |= S5_WRITEDISABLE_BLUE; - if (!a) - tmp |= S5_WRITEDISABLE_ALPHA; - - if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS5] = tmp; - } -} - -static void -update_specular(GLcontext * ctx) -{ - /* A hack to trigger the rebuild of the fragment program. + /* */ - intel_context(ctx)->NewGLState |= _NEW_TEXTURE; -} +/* &i915_fp_choose_prog, */ -static void -i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) -{ - DBG("%s\n", __FUNCTION__); + /* Scan VB: + */ +/* &i915_vb_output_sizes, */ + + /* Get compiled version of the fragment program which is mildly + * optimized according to input sizes. This will be cached, but + * for now recompile on all changes. + * + * Also calculate vertex layout, immediate (S2,S4) state, vertex + * size. + */ + &i915_fp_compile_and_upload, - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { - update_specular(ctx); - } -} - -static void -i915ShadeModel(GLcontext * ctx, GLenum mode) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (mode == GL_SMOOTH) { - i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | - S4_FLATSHADE_COLOR | - S4_FLATSHADE_SPECULAR); - } - else { - i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | - S4_FLATSHADE_COLOR | - S4_FLATSHADE_SPECULAR); - } -} - -/* ============================================================= - * Fog - */ -void -i915_update_fog(GLcontext * ctx) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLenum mode; - GLboolean enabled; - GLboolean try_pixel_fog; - - if (ctx->FragmentProgram._Active) { - /* Pull in static fog state from program */ - - mode = ctx->FragmentProgram._Current->FogOption; - enabled = (mode != GL_NONE); - try_pixel_fog = 0; - } - else { - enabled = ctx->Fog.Enabled; - mode = ctx->Fog.Mode; - - try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && ctx->Hint.Fog == GL_NICEST && 0); /* XXX - DISABLE -- Need ortho fallback */ - } - - if (!enabled) { - i915->vertex_fog = I915_FOG_NONE; - } - else if (try_pixel_fog) { - - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; - i915->vertex_fog = I915_FOG_PIXEL; - - switch (mode) { - case GL_LINEAR: - if (ctx->Fog.End <= ctx->Fog.Start) { - /* XXX - this won't work with fragment programs. Need to - * either fallback or append fog instructions to end of - * program in the case of linear fog. - */ - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; - i915->vertex_fog = I915_FOG_VERTEX; - } - else { - GLfloat c1 = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start); - GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); - - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; - i915->state.Fog[I915_FOGREG_MODE1] |= - ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; - - if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { - i915->state.Fog[I915_FOGREG_MODE2] = - (GLuint) (c2 * FMC2_C2_ONE); - } - else { - union - { - float f; - int i; - } fi; - fi.f = c2; - i915->state.Fog[I915_FOGREG_MODE2] = fi.i; - } - } - break; - case GL_EXP: - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; - break; - case GL_EXP2: - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; - break; - default: - break; - } - } - else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */ - - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; - i915->vertex_fog = I915_FOG_VERTEX; - } - - { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); - if (enabled) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; - } - - /* always enbale pixel fog - * vertex fog use precaculted fog coord will conflict with appended - * fog program + /* Calculate vertex format, program t_vertex.c, etc: */ - _tnl_allow_vertex_fog( ctx, 0 ); - _tnl_allow_pixel_fog( ctx, 1 ); -} + &i915_vertex_format, -static void -i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - switch (pname) { - case GL_FOG_COORDINATE_SOURCE_EXT: - case GL_FOG_MODE: - case GL_FOG_START: - case GL_FOG_END: - break; - - case GL_FOG_DENSITY: - I915_STATECHANGE(i915, I915_UPLOAD_FOG); + /* Immediate state. Don't make any effort to combine packets yet. + */ + &i915_upload_MODES4, + &i915_upload_S2S4, + &i915_upload_S5, + &i915_upload_S6, + &i915_upload_IAB, + &i915_upload_BLENDCOLOR, + + /* Other state. This will eventually be able to emit itself either + * to the batchbuffer directly, or as indirect state. Indirect + * state will be subject to caching so that we get something like + * constant state objects from the i965 driver. + */ + &i915_upload_buffers, + &i915_upload_scissor, - if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { - i915->state.Fog[I915_FOGREG_MODE3] = (GLuint) (ctx->Fog.Density * - FMC3_D_ONE); - } - else { - union - { - float f; - int i; - } fi; - fi.f = ctx->Fog.Density; - i915->state.Fog[I915_FOGREG_MODE3] = fi.i; - } - break; + /* Note this packet has a dependency on the current primitive: + */ + &i915_upload_stipple, - case GL_FOG_COLOR: - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_COLOR] = - (_3DSTATE_FOG_COLOR_CMD | - ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | - ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | - ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); - break; + &i915_upload_maps, /* must do before samplers */ + &i915_upload_samplers, - default: - break; - } -} + NULL, /* i915_fp_constants */ -static void -i915Hint(GLcontext * ctx, GLenum target, GLenum state) -{ - switch (target) { - case GL_FOG_HINT: - break; - default: - break; - } -} + &i915_upload_BFO, + &i915_upload_S0S1 +}; -/* ============================================================= - */ -static void -i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) +void i915_init_state( struct i915_context *i915 ) { - struct i915_context *i915 = I915_CONTEXT(ctx); - - switch (cap) { - case GL_TEXTURE_2D: - break; - - case GL_LIGHTING: - case GL_COLOR_SUM: - update_specular(ctx); - break; - - case GL_ALPHA_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; - break; - - case GL_BLEND: - i915EvalLogicOpBlendState(ctx); - break; - - case GL_COLOR_LOGIC_OP: - i915EvalLogicOpBlendState(ctx); - - /* Logicop doesn't seem to work at 16bpp: - */ - if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */ - FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); - break; - - case GL_FRAGMENT_PROGRAM_ARB: - break; - - case GL_DITHER: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; - break; - - case GL_DEPTH_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; + struct intel_context *intel = &i915->intel; + GLuint i; - i915DepthMask(ctx, ctx->Depth.Mask); - break; + intel->driver_state.atoms = _mesa_malloc(sizeof(atoms)); + intel->driver_state.nr_atoms = sizeof(atoms)/sizeof(*atoms); + _mesa_memcpy(intel->driver_state.atoms, atoms, sizeof(atoms)); - case GL_SCISSOR_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - if (state) - i915->state.Buffer[I915_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); - else - i915->state.Buffer[I915_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - break; - - case GL_LINE_SMOOTH: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; - break; - - case GL_FOG: - break; - - case GL_CULL_FACE: - i915CullFaceFrontFace(ctx, 0); - break; - - case GL_STENCIL_TEST: - { - GLboolean hw_stencil = GL_FALSE; - if (ctx->DrawBuffer) { - struct intel_renderbuffer *irbStencil - = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); - hw_stencil = (irbStencil && irbStencil->region); - } - if (hw_stencil) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - } - else { - FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); - } - } - break; - - case GL_POLYGON_STIPPLE: - /* The stipple command worked on my 855GM box, but not my 845G. - * I'll do more testing later to find out exactly which hardware - * supports it. Disabled for now. - */ - if (i915->intel.hw_stipple && - i915->intel.reduced_primitive == GL_TRIANGLES) { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - if (state) - i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; - else - i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; - } - break; - - case GL_POLYGON_SMOOTH: - break; - - case GL_POINT_SMOOTH: - break; + /* Patch in a pointer to the dynamic state atom: + */ + for (i = 0; i < intel->driver_state.nr_atoms; i++) + if (intel->driver_state.atoms[i] == NULL) + intel->driver_state.atoms[i] = &i915->constants.tracked_state; - default: - ; - } + _mesa_memcpy(&i915->constants.tracked_state, + &i915_fp_constants, + sizeof(i915_fp_constants)); } -static void -i915_init_packets(struct i915_context *i915) +void i915_destroy_state( struct i915_context *i915 ) { - intelScreenPrivate *screen = i915->intel.intelScreen; - - /* Zero all state */ - memset(&i915->state, 0, sizeof(i915->state)); - - - { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - /* Probably don't want to upload all this stuff every time one - * piece changes. - */ - i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | - I1_LOAD_S(2) | - I1_LOAD_S(4) | - I1_LOAD_S(5) | I1_LOAD_S(6) | (3)); - i915->state.Ctx[I915_CTXREG_LIS2] = 0; - i915->state.Ctx[I915_CTXREG_LIS4] = 0; - i915->state.Ctx[I915_CTXREG_LIS5] = 0; - - if (screen->cpp == 2) /* XXX FBO fix */ - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; - - - i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | - (2 << S6_TRISTRIP_PV_SHIFT)); + struct intel_context *intel = &i915->intel; - i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | - LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff) | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(0xff)); - - i915->state.Ctx[I915_CTXREG_IAB] = - (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); - - i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = - _3DSTATE_CONST_BLEND_COLOR_CMD; - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; - - } - - { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; - } - - - { - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD; - i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE | - FMC1_FOGFUNC_VERTEX | - FMC1_FOGINDEX_MODIFY_ENABLE | - FMC1_FOGINDEX_W | - FMC1_C1_C2_MODIFY_ENABLE | - FMC1_DENSITY_MODIFY_ENABLE); - i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD; - } - - - { - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - /* color buffer offset/stride */ - i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ - i915->state.Buffer[I915_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - - i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ - i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - - i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; - - /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ -#if 0 /* seems we don't need this */ - switch (screen->fbFormat) { - case DV_PF_565: - i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - DITHER_FULL_ALWAYS | - screen->fbFormat | - DEPTH_FRMT_16_FIXED); - break; - case DV_PF_8888: - i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - screen->fbFormat | - DEPTH_FRMT_24_FIXED_8_OTHER); - break; - } -#endif - - - /* scissor */ - i915->state.Buffer[I915_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; - i915->state.Buffer[I915_DESTREG_SR1] = 0; - i915->state.Buffer[I915_DESTREG_SR2] = 0; + if (intel->driver_state.atoms) { + _mesa_free(intel->driver_state.atoms); + intel->driver_state.atoms = NULL; } - - -#if 0 - { - I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); - i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; - i915->state.Default[I915_DEFREG_C1] = 0; - i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; - i915->state.Default[I915_DEFREG_S1] = 0; - i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; - i915->state.Default[I915_DEFREG_Z1] = 0; - } -#endif - - - /* These will be emitted every at the head of every buffer, unless - * we get hardware contexts working. - */ - i915->state.active = (I915_UPLOAD_PROGRAM | - I915_UPLOAD_STIPPLE | - I915_UPLOAD_CTX | - I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT); } -void -i915InitStateFunctions(struct dd_function_table *functions) -{ - functions->AlphaFunc = i915AlphaFunc; - functions->BlendColor = i915BlendColor; - functions->BlendEquationSeparate = i915BlendEquationSeparate; - functions->BlendFuncSeparate = i915BlendFuncSeparate; - functions->ColorMask = i915ColorMask; - functions->CullFace = i915CullFaceFrontFace; - functions->DepthFunc = i915DepthFunc; - functions->DepthMask = i915DepthMask; - functions->Enable = i915Enable; - functions->Fogfv = i915Fogfv; - functions->FrontFace = i915CullFaceFrontFace; - functions->Hint = i915Hint; - functions->LightModelfv = i915LightModelfv; - functions->LineWidth = i915LineWidth; - functions->LogicOpcode = i915LogicOp; - functions->PointSize = i915PointSize; - functions->PolygonStipple = i915PolygonStipple; - functions->Scissor = i915Scissor; - functions->ShadeModel = i915ShadeModel; - functions->StencilFuncSeparate = i915StencilFuncSeparate; - functions->StencilMaskSeparate = i915StencilMaskSeparate; - functions->StencilOpSeparate = i915StencilOpSeparate; -} - - -void -i915InitState(struct i915_context *i915) -{ - GLcontext *ctx = &i915->intel.ctx; - - i915_init_packets(i915); - - intelInitState(ctx); - - memcpy(&i915->initial, &i915->state, sizeof(i915->state)); - i915->current = &i915->state; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_state.h b/src/mesa/drivers/dri/i915tex/i915_state.h new file mode 100644 index 0000000000..4ba0d8b775 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state.h @@ -0,0 +1,62 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +#ifndef I915_STATE_H +#define I915_STATE_H + +#include "i915_context.h" + +void i915_init_state( struct i915_context *i915 ); +void i915_destroy_state( struct i915_context *i915 ); + + +const struct intel_tracked_state i915_check_fallback; +const struct intel_tracked_state i915_fp_constants; +const struct intel_tracked_state i915_fp_compile_and_upload; +const struct intel_tracked_state i915_vertex_format; +const struct intel_tracked_state i915_invarient_state; +const struct intel_tracked_state i915_upload_BFO; +const struct intel_tracked_state i915_upload_BLENDCOLOR; +const struct intel_tracked_state i915_upload_IAB; +const struct intel_tracked_state i915_upload_MODES4; +const struct intel_tracked_state i915_upload_S0S1; +const struct intel_tracked_state i915_upload_S2S4; +const struct intel_tracked_state i915_upload_S5; +const struct intel_tracked_state i915_upload_S6; +const struct intel_tracked_state i915_upload_buffers; +const struct intel_tracked_state i915_upload_maps; +const struct intel_tracked_state i915_upload_samplers; +const struct intel_tracked_state i915_upload_scissor; +const struct intel_tracked_state i915_upload_stipple; + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_state_fallback.c b/src/mesa/drivers/dri/i915tex/i915_state_fallback.c new file mode 100644 index 0000000000..c327e19c44 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_fallback.c @@ -0,0 +1,114 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + + +#include "intel_batchbuffer.h" +#include "intel_regions.h" +#include "intel_context.h" +#include "intel_tex.h" +#include "intel_fbo.h" +#include "i915_context.h" + +/* A place to check fallbacks that aren't calculated on the fly or in + * callback functions. + */ +static GLboolean do_check_fallback(struct intel_context *intel) +{ + GLuint i; + + /* INTEL_NEW_METAOPS + */ + if (intel->metaops.active) + return GL_FALSE; + + /* _NEW_BUFFERS + */ + if (intel->state._ColorDrawBufferMask0 != BUFFER_BIT_FRONT_LEFT && + intel->state._ColorDrawBufferMask0 != BUFFER_BIT_BACK_LEFT) + return GL_TRUE; + + /* _NEW_RENDERMODE + * + * XXX: need to save/restore RenderMode in metaops state, or + * somehow move to a new attribs pointer: + */ + if (intel->state.RenderMode != GL_RENDER) + return GL_TRUE; + + /* _NEW_TEXTURE: + */ + for (i = 0; i < I915_TEX_UNITS; i++) { + struct gl_texture_unit *texUnit = &intel->state.Texture->Unit[i]; + if (texUnit->_ReallyEnabled) { + struct intel_texture_object *intelObj = intel_texture_object(texUnit->_Current); + struct gl_texture_image *texImage = intelObj->base.Image[0][intelObj->firstLevel]; + if (texImage->Border) + return GL_TRUE; + } + } + + /* _NEW_STENCIL, _NEW_BUFFERS + */ + if (intel->state.Stencil->Enabled) { + struct intel_renderbuffer *irbStencil = + (intel->state.DrawBuffer + ? intel_get_renderbuffer(intel->state.DrawBuffer, BUFFER_STENCIL) + : NULL); + + intel->hw_stencil = irbStencil && irbStencil->region; + + if (!intel->hw_stencil) + return GL_TRUE; + } + + + return GL_FALSE; +} + +static void check_fallback( struct intel_context *intel ) +{ + GLboolean flag = do_check_fallback( intel ); + + /* May raise INTEL_NEW_FALLBACK + */ + FALLBACK(intel, INTEL_FALLBACK_OTHER, flag ); +} + +const struct intel_tracked_state i915_check_fallback = { + .dirty = { + .mesa = _NEW_BUFFERS | _NEW_RENDERMODE | _NEW_TEXTURE | _NEW_STENCIL, + .intel = INTEL_NEW_METAOPS, + .extra = 0 + }, + .update = check_fallback +}; + diff --git a/src/mesa/drivers/dri/i915tex/i915_state_fp.c b/src/mesa/drivers/dri/i915tex/i915_state_fp.c new file mode 100644 index 0000000000..e8a768c2e3 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_fp.c @@ -0,0 +1,158 @@ +/************************************************************************** + * + * 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 "glheader.h" +#include "macros.h" +#include "enums.h" +#include "program.h" + +#include "intel_batchbuffer.h" +#include "i915_context.h" +#include "i915_fpc.h" + + + + + +/********************************************************************************* + * Program instructions (and decls) + */ + + +static void i915_upload_fp( struct intel_context *intel ) +{ + struct i915_context *i915 = i915_context( &intel->ctx ); + struct i915_fragment_program *fp = i915->fragment_program; + GLuint i; + + if (&fp->Base != intel->state.FragmentProgram->_Current) { + i915->fragment_program = (struct i915_fragment_program *) + intel->state.FragmentProgram->_Current; + + fp = i915->fragment_program; + /* This is stupid + */ + intel->state.dirty.intel |= INTEL_NEW_FRAGMENT_PROGRAM; + } + + /* As the compiled program depends only on the original program + * text (??? for now at least ???), there is no need for a compiled + * program cache, just store the compiled version with the original + * text. + */ + if (!fp->translated) { + i915_compile_fragment_program(i915, fp); + } + + BEGIN_BATCH( fp->program_size, 0 ); + + for (i = 0; i < fp->program_size; i++) + OUT_BATCH( fp->program[i] ); + + ADVANCE_BATCH(); + +#if 0 + emit_indirect(intel, LI0_STATE_PROGRAM, + state->Program, state->ProgramSize * sizeof(GLuint)); +#endif + +} + + +/* See i915_wm.c: + */ +const struct intel_tracked_state i915_fp_compile_and_upload = { + .dirty = { + .mesa = (0), + .intel = (INTEL_NEW_FRAGMENT_PROGRAM), /* ?? Is this all ?? */ + .extra = 0 + }, + .update = i915_upload_fp +}; + + +/********************************************************************************* + * Program constants and state parameters + */ +static void +upload_constants(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context( &intel->ctx ); + struct i915_fragment_program *p = i915->fragment_program; + GLint i; + + /* XXX: Pull from state, not ctx!!! + */ + if (p->nr_params) + _mesa_load_state_parameters(&intel->ctx, p->Base.Base.Parameters); + + for (i = 0; i < p->nr_params; i++) { + GLint reg = p->param[i].reg; + COPY_4V(p->constant[reg], p->param[i].values); + } + + /* Always seemed to get a failure if I used memcmp() to + * shortcircuit this state upload. Needs further investigation? + */ + if (p->nr_constants) { + GLuint nr = p->nr_constants; + + BEGIN_BATCH( nr * 4 + 2, 0 ); + OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) ); + OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) ); + + for (i = 0; i < nr; i++) { + OUT_BATCH_F(p->constant[i][0]); + OUT_BATCH_F(p->constant[i][1]); + OUT_BATCH_F(p->constant[i][2]); + OUT_BATCH_F(p->constant[i][3]); + } + + ADVANCE_BATCH(); + } + +#if 0 + emit_indirect(intel, LI0_STATE_CONSTANTS, + state->Constant, state->ConstantSize * sizeof(GLuint)); +#endif +} + + +/* This tracked state is unique in that the state it monitors varies + * dynamically depending on the parameters tracked by the fragment and + * vertex programs. This is the template used as a starting point, + * each context will maintain a copy of this internally and update as + * required. + */ +const struct intel_tracked_state i915_fp_constants = { + .dirty = { + .mesa = 0, /* plus fp state flags */ + .intel = INTEL_NEW_FRAGMENT_PROGRAM, + .extra = 0 + }, + .update = upload_constants +}; diff --git a/src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c b/src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c new file mode 100644 index 0000000000..8bbdc0f29a --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c @@ -0,0 +1,209 @@ +/************************************************************************** + * + * 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 "glheader.h" +#include "macros.h" +#include "enums.h" +#include "program.h" + +#include "intel_batchbuffer.h" +#include "i915_context.h" +#include "i915_reg.h" +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + + +#if 0 +/* Scan the TNL VB struct and look at the size of each attribute + * coming out. + * + * The fragment program has been determined by this point, so it is ok + * to restrict the list to the inputs referenced by the fragprog. + * + * This is not a + */ +void check_input_sizes( struct intel_context *intel ) +{ + struct i915_context *i915 = i915_context( &intel->ctx ); + GLcontext *ctx = &intel->ctx; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte old_sizes[8]; + GLuint i; + + memcpy(old_sizes, i915->fragprog.input_sizes, sizeof(old_sizes)); + + for (i = 0; i < FRAG_ATTRIB_MAX; i++) { + GLvector4f *attrib = VB->AttribPtr[i]; + i915->fragprog.input_sizes[i] = attrib->size; + } + + /* Raise statechanges if input sizes and varying have changed: + */ + if (memcmp(i915->fragprog.input_sizes, old_sizes, sizeof(old_sizes)) != 0) + intel->state.dirty.intel |= I915_NEW_INPUT_SIZES; +} + +#endif + + +/*********************************************************************** + * + */ + +#define SZ_TO_HW(sz) ((sz-2)&0x3) +#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) +#define EMIT_ATTR( ATTR, STYLE, S4, SZ ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ + intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ + s4 |= S4; \ + intel->vertex_attr_count++; \ + offset += (SZ); \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ + intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ + intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ + intel->vertex_attr_count++; \ + offset += (N); \ +} while (0) + +/*********************************************************************** + * + */ + + +static void i915_calculate_vertex_format( struct intel_context *intel ) +{ + struct i915_context *i915 = i915_context( &intel->ctx ); + struct i915_fragment_program *fp = i915->fragment_program; + const GLuint inputsRead = fp->Base.Base.InputsRead; + GLuint s2 = S2_TEXCOORD_NONE; + GLuint s4 = 0; + GLuint offset = 0; + GLuint i; + + intel->vertex_attr_count = 0; + intel->wpos_offset = 0; + intel->wpos_size = 0; + intel->coloroffset = 0; + intel->specoffset = 0; + + if (inputsRead & FRAG_BITS_TEX_ANY) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16); + } + else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12); + } + + if (inputsRead & FRAG_BIT_COL0) { + intel->coloroffset = offset / 4; + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4); + } + + if (inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) { + if (inputsRead & FRAG_BIT_COL1) { + intel->specoffset = offset / 4; + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3); + } + else + EMIT_PAD(3); + + if (inputsRead & FRAG_BIT_FOGC) + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1); + else + EMIT_PAD(1); + } + + if (inputsRead & FRAG_BIT_FOGC) { + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4); + } + + for (i = 0; i < I915_TEX_UNITS; i++) { + if (inputsRead & (FRAG_BIT_TEX0 << i)) { + + /* _NEW_VB_OUTPUT_SIZES + */ +/* int sz = VB->TexCoordPtr[i]->size; */ + int sz = 2; + + s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); + s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); + + EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4); + } + else if (i == fp->wpos_tex) { + + /* If WPOS is required, duplicate the XYZ position data in an + * unused texture coordinate: + */ + s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); + s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); + + intel->wpos_offset = offset; + intel->wpos_size = 3 * sizeof(GLuint); + + EMIT_PAD(intel->wpos_size); + } + } + + if (s2 != i915->fragprog.LIS2 || + s4 != i915->fragprog.LIS4) { + + GLuint vs = _tnl_install_attrs(&intel->ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->vertex_size = vs >> 2; + + _mesa_printf("inputs %x vertex size %d\n", + inputsRead, + intel->vertex_size); + i915->fragprog.LIS2 = s2; + i915->fragprog.LIS4 = s4; + intel->state.dirty.intel |= I915_NEW_VERTEX_FORMAT; + } +} + + +/* Could use the information calculated here to optimize the fragment + * program. + */ +const struct intel_tracked_state i915_vertex_format = { + .dirty = { + .mesa = 0, + .intel = (INTEL_NEW_FRAGMENT_PROGRAM +/* | INTEL_NEW_VB_OUTPUT_SIZES */ + ), + .extra = 0 + }, + .update = i915_calculate_vertex_format +}; + diff --git a/src/mesa/drivers/dri/i915tex/i915_state_immediate.c b/src/mesa/drivers/dri/i915tex/i915_state_immediate.c new file mode 100644 index 0000000000..e08748ad96 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_immediate.c @@ -0,0 +1,328 @@ +/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +#include "intel_batchbuffer.h" +#include "intel_regions.h" +#include "intel_state_inlines.h" + +#include "macros.h" + +#include "i915_context.h" +#include "i915_state.h" +#include "i915_state_inlines.h" +#include "i915_reg.h" + + +#define STATE_LOGICOP_ENABLED(state) \ + ((state)->Color->ColorLogicOpEnabled || \ + ((state)->Color->BlendEnabled && (state)->Color->BlendEquationRGB == GL_LOGIC_OP)) + + +/*********************************************************************** + * S0,S1: Vertex buffer state. + */ +static void upload_S0S1( struct intel_context *intel ) +{ + + /* INTEL_NEW_VBO */ + if (intel->state.vbo) { + + BEGIN_BATCH(3, 0); + + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(0) | + I1_LOAD_S(1) | + 1); + + /* INTEL_NEW_VBO, INTEL_NEW_RELOC */ + OUT_RELOC(intel->state.vbo, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, + intel->state.vbo_offset); + + /* INTEL_NEW_VERTEX_SIZE */ + OUT_BATCH((intel->vertex_size << 24) | + (intel->vertex_size << 16)); + + ADVANCE_BATCH(); + } +} + +const struct intel_tracked_state i915_upload_S0S1 = { + .dirty = { + .mesa = 0, + .intel = INTEL_NEW_VBO | INTEL_NEW_VERTEX_SIZE | INTEL_NEW_FENCE, + .extra = 0 + }, + .update = upload_S0S1 +}; + + + + + +/*********************************************************************** + * S4: Vertex format, rasterization state + */ +static void upload_S2S4(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context( &intel->ctx ); + GLuint LIS2, LIS4; + + /* I915_NEW_VERTEX_FORMAT */ + LIS2 = i915->fragprog.LIS2; + LIS4 = i915->fragprog.LIS4; + + + /* _NEW_POLYGON, _NEW_BUFFERS */ + { + GLuint mode; + + if (!intel->state.Polygon->CullFlag) { + mode = S4_CULLMODE_NONE; + } + else if (intel->state.Polygon->CullFaceMode != GL_FRONT_AND_BACK) { + mode = S4_CULLMODE_CW; + + if (intel->state.DrawBuffer && intel->state.DrawBuffer->Name != 0) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + if (intel->state.Polygon->CullFaceMode == GL_FRONT) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + if (intel->state.Polygon->FrontFace != GL_CCW) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + } + else { + mode = S4_CULLMODE_BOTH; + } + + LIS4 |= mode; + } + + + /* _NEW_LINE */ + { + GLint width = (GLint) (intel->state.Line->Width * 2); + + CLAMP_SELF(width, 1, 0xf); + LIS4 |= width << S4_LINE_WIDTH_SHIFT; + + if (intel->state.Line->SmoothFlag) + LIS4 |= S4_LINE_ANTIALIAS_ENABLE; + } + + /* _NEW_POINT */ + { + GLint point_size = (int) intel->state.Point->_Size; + + CLAMP_SELF(point_size, 1, 255); + LIS4 |= point_size << S4_POINT_WIDTH_SHIFT; + } + + /* _NEW_LIGHT */ + if (intel->state.Light->ShadeModel == GL_FLAT) { + LIS4 |= (S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } + + + BEGIN_BATCH(3, 0); + + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(2) | + I1_LOAD_S(4) | + 1); + OUT_BATCH(LIS2); + OUT_BATCH(LIS4); + ADVANCE_BATCH(); +} + + +const struct intel_tracked_state i915_upload_S2S4 = { + .dirty = { + .mesa = (_NEW_POLYGON | + _NEW_BUFFERS | + _NEW_LINE | + _NEW_POINT | + _NEW_LIGHT), + + .intel = I915_NEW_VERTEX_FORMAT, + .extra = 0 + }, + .update = upload_S2S4 +}; + + + +/*********************************************************************** + * + */ +static void upload_S5( struct intel_context *intel ) +{ + GLuint LIS5 = 0; + + /* _NEW_STENCIL */ + if (intel->state.Stencil->Enabled) { + GLint test = intel_translate_compare_func(intel->state.Stencil->Function[0]); + GLint fop = intel_translate_stencil_op(intel->state.Stencil->FailFunc[0]); + GLint dfop = intel_translate_stencil_op(intel->state.Stencil->ZFailFunc[0]); + GLint dpop = intel_translate_stencil_op(intel->state.Stencil->ZPassFunc[0]); + GLint ref = intel->state.Stencil->Ref[0] & 0xff; + + LIS5 |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE | + (ref << S5_STENCIL_REF_SHIFT) | + (test << S5_STENCIL_TEST_FUNC_SHIFT) | + (fop << S5_STENCIL_FAIL_SHIFT) | + (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT)); + } + + /* _NEW_COLOR */ + if (STATE_LOGICOP_ENABLED(&intel->state)) { + LIS5 |= S5_LOGICOP_ENABLE; + } + + if (intel->state.Color->DitherFlag) { + LIS5 |= S5_COLOR_DITHER_ENABLE; + } + + { + const GLubyte *mask = intel->state.Color->ColorMask; + + if (!mask[0]) + LIS5 |= S5_WRITEDISABLE_RED; + + if (!mask[1]) + LIS5 |= S5_WRITEDISABLE_GREEN; + + if (!mask[2]) + LIS5 |= S5_WRITEDISABLE_BLUE; + + if (!mask[3]) + LIS5 |= S5_WRITEDISABLE_ALPHA; + } + + BEGIN_BATCH(2, 0); + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(5) | + 0); + OUT_BATCH(LIS5); + ADVANCE_BATCH(); + +} + +const struct intel_tracked_state i915_upload_S5 = { + .dirty = { + .mesa = (_NEW_STENCIL | _NEW_COLOR), + .intel = 0, + .extra = 0 + }, + .update = upload_S5 +}; + + +/*********************************************************************** + */ +static void upload_S6( struct intel_context *intel ) +{ + GLuint LIS6 = (S6_COLOR_WRITE_ENABLE | + (2 << S6_TRISTRIP_PV_SHIFT)); + + /* _NEW_COLOR + */ + if (1) { + int test = intel_translate_compare_func(intel->state.Color->AlphaFunc); + GLubyte refByte; + + CLAMPED_FLOAT_TO_UBYTE(refByte, intel->state.Color->AlphaRef); + + if (intel->state.Color->AlphaEnabled) + LIS6 |= S6_ALPHA_TEST_ENABLE; + + LIS6 |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | + (((GLuint) refByte) << S6_ALPHA_REF_SHIFT)); + } + + /* _NEW_COLOR + */ + if (1) { + + GLuint eqRGB = intel->state.Color->BlendEquationRGB; + GLuint srcRGB = intel->state.Color->BlendSrcRGB; + GLuint dstRGB = intel->state.Color->BlendDstRGB; + + if (eqRGB == GL_MIN || eqRGB == GL_MAX) { + srcRGB = dstRGB = GL_ONE; + } + + if (intel->state.Color->BlendEnabled && + !STATE_LOGICOP_ENABLED(&intel->state)) + LIS6 |= S6_CBUF_BLEND_ENABLE; + + LIS6 |= (SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)) | + DST_BLND_FACT(intel_translate_blend_factor(dstRGB)) | + (i915_translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT)); + } + + /* _NEW_DEPTH + */ + if (1) { + GLint func = intel_translate_compare_func(intel->state.Depth->Func); + + LIS6 |= func << S6_DEPTH_TEST_FUNC_SHIFT; + + if (intel->state.Depth->Test) { + LIS6 |= S6_DEPTH_TEST_ENABLE; + if (intel->state.Depth->Mask) + LIS6 |= S6_DEPTH_WRITE_ENABLE; + } + } + + BEGIN_BATCH(2, 0); + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(6) | + 0); + OUT_BATCH(LIS6); + ADVANCE_BATCH(); + +} + +const struct intel_tracked_state i915_upload_S6 = { + .dirty = { + .mesa = (_NEW_COLOR | _NEW_DEPTH), + .intel = 0, + .extra = 0 + }, + .update = upload_S6 +}; + diff --git a/src/mesa/drivers/dri/i915tex/i915_state_indirect.c b/src/mesa/drivers/dri/i915tex/i915_state_indirect.c new file mode 100644 index 0000000000..0445f8e6f7 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_indirect.c @@ -0,0 +1,129 @@ +/* Emit packets to preserved batch buffers, which can then be + * referenced by the LOAD_INDIRECT command. + * + * Need to figure out what STATIC vs DYNAMIC state is supposed to be. + */ + + + +static GLuint emit_indirect(struct intel_context *intel, + GLuint flag, + const GLuint *state, + GLuint size ) +{ + GLuint delta; + GLuint segment; + + switch (flag) { + case LI0_STATE_DYNAMIC_INDIRECT: + segment = SEGMENT_DYNAMIC_INDIRECT; + + /* Dynamic indirect state is different - tell it the ending + * address, it will execute from either the previous end address + * or the beginning of the 4k page, depending on what it feels + * like. + */ + delta = ((intel->batch->segment_finish_offset[segment] + size - 4) | + DIS0_BUFFER_VALID | + DIS0_BUFFER_RESET); + + + BEGIN_BATCH(2,0); + OUT_BATCH( _3DSTATE_LOAD_INDIRECT | flag | (1<<14) | 0); + OUT_RELOC( intel->batch->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE, + delta ); + ADVANCE_BATCH(); + break; + + default: + segment = SEGMENT_OTHER_INDIRECT; + + /* Other state is more conventional: tell the hardware the start + * point and size. + */ + delta = (intel->batch->segment_finish_offset[segment] | + SIS0_FORCE_LOAD | /* XXX: fix me */ + SIS0_BUFFER_VALID); + + BEGIN_BATCH(3,0); + OUT_BATCH( _3DSTATE_LOAD_INDIRECT | flag | (1<<14) | 1); + OUT_RELOC( intel->batch->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE, + delta ); + OUT_BATCH( (size/4)-1 ); + ADVANCE_BATCH(); + + + break; + } + + { + GLuint offset = intel->batch->segment_finish_offset[segment]; + intel->batch->segment_finish_offset[segment] += size; + + if (state != NULL) + memcpy(intel->batch->map + offset, state, size); + + return offset; + } +} + + +/* "constant state", or constant-ish?? + */ +static void emit_static_indirect_state() +{ +} + +/* "slow state", compared probably to the state in + * LOAD_STATE_IMMEDIATE. + */ +static void emit_dynamic_indirect_state() +{ +} + +/* Need to figure out how to do driBO relocations on addresses in the + * indirect state buffers. When do the relocations become invalid? + */ + +static void emit_sampler_state() +{ +} + +static void emit_map_state() +{ +} + +static void emit_program() +{ +} + +static void emit_constants() +{ +} + +void emit_indirect_state() +{ + /* Just emit the packet straight to batch: + */ + + /* Look at the dirty flags and figure out what needs to be sent. + */ +} + +const struct i915_tracked_state i915_indirect_state = { + .dirty = { + .mesa = 0, + .i915 = I915_NEW_STATE_MODE, + .indirect = (INDIRECT_NEW_STATIC | + INDIRECT_NEW_DYNAMIC | + INDIRECT_NEW_SAMPLER | + INDIRECT_NEW_MAP | + INDIRECT_NEW_PROGRAM | + INDIRECT_NEW_CONSTANTS); + }, + .update = upload_indirect_state +}; diff --git a/src/mesa/drivers/dri/i915tex/i915_state_invarient.c b/src/mesa/drivers/dri/i915tex/i915_state_invarient.c new file mode 100644 index 0000000000..ecca70aad0 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_invarient.c @@ -0,0 +1,143 @@ +/************************************************************************** + * + * 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 "glheader.h" +#include "macros.h" +#include "enums.h" +#include "program.h" + +#include "intel_batchbuffer.h" +#include "i915_context.h" +#include "i915_reg.h" + + + + +/*********************************************************************** + * Misc invarient state packets + */ + +static void upload_invarient_state( struct intel_context *intel ) +{ + static GLuint invarient_state[] = { + + (_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | + AA_LINE_REGION_WIDTH_1_0), + + /* Could use these to reduce the size of vertices when the incoming + * array is constant. + */ + (_3DSTATE_DFLT_DIFFUSE_CMD), + (0), + + (_3DSTATE_DFLT_SPEC_CMD), + (0), + + (_3DSTATE_DFLT_Z_CMD), + (0), + + /* We support texture crossbar via the fragment shader, rather than + * with this mechanism. + */ + (_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | + CSB_TCB(1, 1) | + CSB_TCB(2, 2) | + CSB_TCB(3, 3) | + CSB_TCB(4, 4) | + CSB_TCB(5, 5) | + CSB_TCB(6, 6) | + CSB_TCB(7, 7)), + + /* Setup OpenGL rasterization state: + */ + (_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | + ENABLE_TEXKILL_3D_4D | + TEXKILL_4D), + + /* Need to initialize this to zero. + */ + (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(3) | + (0)), + (0), + + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT), + (_3DSTATE_SCISSOR_RECT_0_CMD), + (0), + (0), + + + /* For private depth buffers but shared color buffers, eg + * front-buffer rendering with a private depthbuffer. We don't do + * this. + */ + (_3DSTATE_DEPTH_SUBRECT_DISABLE), + + (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0) + }; + + /* Disable indirect state for now. + */ + BEGIN_BATCH(2, 0); + OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); + OUT_BATCH(0); + ADVANCE_BATCH(); + + + { + GLuint i; + + BEGIN_BATCH(sizeof(invarient_state)/4, 0); + + for (i = 0; i < sizeof(invarient_state)/4; i++) + OUT_BATCH( invarient_state[i] ); + + ADVANCE_BATCH(); + } +} + +const struct intel_tracked_state i915_invarient_state = { + .dirty = { + .mesa = 0, + .intel = INTEL_NEW_CONTEXT, /* or less frequently? */ + .extra = 0 + }, + .update = upload_invarient_state +}; + + + diff --git a/src/mesa/drivers/dri/i915tex/i915_state_map.c b/src/mesa/drivers/dri/i915tex/i915_state_map.c new file mode 100644 index 0000000000..ea01c54777 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_map.c @@ -0,0 +1,184 @@ +/************************************************************************** + * + * 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 "mtypes.h" +#include "enums.h" +#include "texformat.h" +#include "dri_bufmgr.h" + +#include "intel_mipmap_tree.h" +#include "intel_tex.h" +#include "intel_batchbuffer.h" + +#include "i915_context.h" +#include "i915_reg.h" + + +static GLuint +translate_texture_format(GLuint mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case MESA_FORMAT_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case MESA_FORMAT_A8: + return MAPSURF_8BIT | MT_8BIT_A8; + case MESA_FORMAT_AL88: + return MAPSURF_16BIT | MT_16BIT_AY88; + case MESA_FORMAT_RGB565: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case MESA_FORMAT_ARGB1555: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case MESA_FORMAT_ARGB4444: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case MESA_FORMAT_ARGB8888: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case MESA_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case MESA_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); + case MESA_FORMAT_Z16: + return (MAPSURF_16BIT | MT_16BIT_L16); + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case MESA_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case MESA_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + case MESA_FORMAT_Z24_S8: + return (MAPSURF_32BIT | MT_32BIT_xL824); + default: + assert(0); + return 0; + } +} + + + + + +static void +upload_maps( struct intel_context *intel ) +{ + struct i915_context *i915 = i915_context( &intel->ctx ); + GLuint state[I915_TEX_UNITS][2]; + GLuint i, dirty = 0, nr = 0; + + for (i = 0; i < I915_TEX_UNITS; i++) { + /* Decrement refcounts on old buffers + */ + if (i915->state.tex_buffer[i] != NULL) { + driBOUnReference(i915->state.tex_buffer[i]); + i915->state.tex_buffer[i] = NULL; + } + + if (intel->state.Texture->Unit[i]._ReallyEnabled) { + struct gl_texture_object *tObj = intel->state.Texture->Unit[i]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + struct gl_texture_image *firstImage; + + if (!intel_finalize_mipmap_tree(intel, i)) { + /* XXX: TODO */ +/* return GL_FALSE; */ + assert(0); + } + + /* Reference new buffers + */ + i915->state.tex_buffer[i] = driBOReference(intelObj->mt->region->buffer); + i915->state.tex_offset[i] = intel_miptree_image_offset(intelObj->mt, 0, + intelObj-> firstLevel); + + /* Get first image here, since intelObj->firstLevel will get set in + * the intel_finalize_mipmap_tree() call above. + */ + firstImage = tObj->Image[0][intelObj->firstLevel]; + + state[i][0] = + (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | + ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | + translate_texture_format(firstImage->TexFormat->MesaFormat) | + MS3_USE_FENCE_REGS); + + state[i][1] = + (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - 1) << MS4_PITCH_SHIFT) | + MS4_CUBE_FACE_ENA_MASK | + ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) << MS4_MAX_LOD_SHIFT) | + ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT)); + + dirty |= (1<<i); + nr++; + } + } + + if (nr) { + BEGIN_BATCH(2 + nr * 3, 0); + OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); + OUT_BATCH(dirty); + + for (i = 0; i < I915_TEX_UNITS; i++) { + if (dirty & (1<<i)) { + + if (i915->state.tex_buffer[i]) { + OUT_RELOC(i915->state.tex_buffer[i], + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, + i915->state.tex_offset[i]); + } + else { + assert(i == 0); + assert(intel->metaops.active); /* when does this happen? */ + OUT_BATCH(0); + } + + OUT_BATCH(state[i][0]); + OUT_BATCH(state[i][1]); + } + } + ADVANCE_BATCH(); + } + +/* return GL_TRUE; */ +} + + + + + +const struct intel_tracked_state i915_upload_maps = { + .dirty = { + .mesa = (_NEW_TEXTURE), + .intel = 0, + .extra = 0 + }, + .update = upload_maps +}; diff --git a/src/mesa/drivers/dri/i915tex/i915_state_misc.c b/src/mesa/drivers/dri/i915tex/i915_state_misc.c new file mode 100644 index 0000000000..1c97d4d975 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_misc.c @@ -0,0 +1,448 @@ +/************************************************************************** + * + * 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 "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" + +#include "intel_fbo.h" +#include "intel_batchbuffer.h" +#include "intel_regions.h" +#include "intel_state_inlines.h" + +#include "i915_context.h" +#include "i915_reg.h" +#include "i915_state.h" +#include "i915_state_inlines.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +/*********************************************************************** + * Modes4: stencil masks and logicop + */ +static void upload_MODES4( struct intel_context *intel ) +{ + GLuint modes4 = _3DSTATE_MODES_4_CMD; + + /* _NEW_STENCIL */ + if (1||intel->state.Stencil->Enabled) { + GLint testmask = intel->state.Stencil->ValueMask[0] & 0xff; + GLint writemask = intel->state.Stencil->WriteMask[0] & 0xff; + + modes4 |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(testmask) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(writemask)); + } + + /* _NEW_COLOR */ + if (1 || intel->state.Color->_LogicOpEnabled) + { + modes4 |= (ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(intel_translate_logic_op(intel->state.Color->LogicOp))); + } + else { + /* This seems to be the only way to turn off logicop. The + * ENABLE_LOGIC_OP_FUNC is just a modify-enable bit to say this + * field is present in the instruction. + */ + modes4 |= (ENABLE_LOGIC_OP_FUNC | + LOGICOP_COPY); + } + + /* This needs to be sent in all states (subject eventually to + * caching to avoid duplicate emits, and later to indirect state + * management) + */ + BEGIN_BATCH(1,0); + OUT_BATCH(modes4); + ADVANCE_BATCH(); +} + +const struct intel_tracked_state i915_upload_MODES4 = { + .dirty = { + .mesa = _NEW_STENCIL | _NEW_COLOR, + .intel = 0, + .extra = 0 + }, + .update = upload_MODES4 +}; + + +/*********************************************************************** + * BFO: Backface stencil + */ + +static void upload_BFO( struct intel_context *intel ) +{ + GLuint bfo; + + /* _NEW_STENCIL + */ + if (intel->state.Stencil->Enabled) { + GLint test = intel_translate_compare_func(intel->state.Stencil->Function[1]); + GLint fop = intel_translate_stencil_op(intel->state.Stencil->FailFunc[1]); + GLint dfop = intel_translate_stencil_op(intel->state.Stencil->ZFailFunc[1]); + GLint dpop = intel_translate_stencil_op(intel->state.Stencil->ZPassFunc[1]); + GLint ref = intel->state.Stencil->Ref[1] & 0xff; + + bfo = (_3DSTATE_BACKFACE_STENCIL_OPS | + BFO_ENABLE_STENCIL_FUNCS | + BFO_ENABLE_STENCIL_TWO_SIDE | + BFO_ENABLE_STENCIL_REF | + BFO_STENCIL_TWO_SIDE | + (ref << BFO_STENCIL_REF_SHIFT) | + (test << BFO_STENCIL_TEST_SHIFT) | + (fop << BFO_STENCIL_FAIL_SHIFT) | + (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) | + (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT)); + } + else { + /* This actually disables two-side stencil: The bit set is a + * modify-enable bit to indicate we are changing the two-side + * setting. Then there is a symbolic zero to show that we are + * setting the flag to zero/off. + */ + bfo = (_3DSTATE_BACKFACE_STENCIL_OPS | + BFO_ENABLE_STENCIL_TWO_SIDE | + 0); + } + + BEGIN_BATCH(1,0); + OUT_BATCH(bfo); + ADVANCE_BATCH(); +} + +const struct intel_tracked_state i915_upload_BFO = { + .dirty = { + .mesa = _NEW_STENCIL, + .intel = 0, + .extra = 0 + }, + .update = upload_BFO +}; + + +/*********************************************************************** + * BLENDCOLOR + */ +static void upload_BLENDCOLOR( struct intel_context *intel ) +{ + /* _NEW_COLOR + */ + if (1 || intel->state.Color->BlendEnabled) { + const GLfloat *color = intel->state.Color->BlendColor; + GLubyte r, g, b, a; + + UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); + + /* Only needs to be sent when blend is enabled + */ + BEGIN_BATCH(2, 0); + OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD); + OUT_BATCH( (a << 24) | (r << 16) | (g << 8) | b ); + ADVANCE_BATCH(); + } +} + +const struct intel_tracked_state i915_upload_BLENDCOLOR = { + .dirty = { + .mesa = _NEW_COLOR, + .intel = 0, + .extra = 0 + }, + .update = upload_BLENDCOLOR +}; + + +/*********************************************************************** + * IAB: Independent Alpha Blend + */ +static void upload_IAB( struct intel_context *intel ) +{ + GLuint iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | + IAB_MODIFY_ENABLE | + 0); + + if (1) { + GLuint eqRGB = intel->state.Color->BlendEquationRGB; + GLuint eqA = intel->state.Color->BlendEquationA; + GLuint srcRGB = intel->state.Color->BlendSrcRGB; + GLuint dstRGB = intel->state.Color->BlendDstRGB; + GLuint srcA = intel->state.Color->BlendSrcA; + GLuint dstA = intel->state.Color->BlendDstA; + + iab |= (IAB_MODIFY_FUNC | + IAB_MODIFY_SRC_FACTOR | + IAB_MODIFY_DST_FACTOR | + SRC_ABLND_FACT(intel_translate_blend_factor(srcA)) | + DST_ABLND_FACT(intel_translate_blend_factor(dstA)) | + (i915_translate_blend_equation(eqA) << IAB_FUNC_SHIFT)); + + if (srcA != srcRGB || + dstA != dstRGB || + eqA != eqRGB) { + +#if 0 + /* later */ + if (eqA == GL_MIN || eqA == GL_MAX) { + srcA = dstA = GL_ONE; + } +#endif + + + if (intel->state.Color->BlendEnabled) + iab |= IAB_ENABLE; + } + } + + BEGIN_BATCH(1, 0); + OUT_BATCH( iab ); + ADVANCE_BATCH(); +} + +const struct intel_tracked_state i915_upload_IAB = { + .dirty = { + .mesa = _NEW_COLOR, + .intel = 0, + .extra = 0 + }, + .update = upload_IAB +}; + + +/*********************************************************************** + * Depthbuffer - currently constant, but rotation would change that. + */ + + +static void upload_buffers(struct intel_context *intel) +{ + struct intel_region *color_region = intel->state.draw_region; + struct intel_region *depth_region = intel->state.depth_region; + + if (color_region) { + BEGIN_BATCH(4, 0); + OUT_BATCH( _3DSTATE_BUF_INFO_CMD ); + OUT_BATCH( BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(color_region->pitch * color_region->cpp) | + BUF_3D_USE_FENCE); + OUT_RELOC(intel->state.draw_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + intel->state.draw_region->draw_offset); + ADVANCE_BATCH(); + } + + if (depth_region) { + BEGIN_BATCH(4, 0); + OUT_BATCH( _3DSTATE_BUF_INFO_CMD ); + OUT_BATCH( BUF_3D_ID_DEPTH | + BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) | + BUF_3D_USE_FENCE ); + OUT_RELOC(intel->state.depth_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + intel->state.depth_region->draw_offset); + ADVANCE_BATCH(); + } + + /* + * Compute/set I915_DESTREG_DV1 value + */ + BEGIN_BATCH(2, 0); + OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); + + OUT_BATCH( DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + DITHER_FULL_ALWAYS | + (color_region && color_region->cpp == 4 + ? DV_PF_8888 + : DV_PF_565) | + (depth_region && depth_region->cpp == 4 + ? DEPTH_FRMT_24_FIXED_8_OTHER + : DEPTH_FRMT_16_FIXED) ); + + ADVANCE_BATCH(); +} + +const struct intel_tracked_state i915_upload_buffers = { + .dirty = { + .mesa = 0, + .intel = INTEL_NEW_CBUF | INTEL_NEW_ZBUF | INTEL_NEW_FENCE, + .extra = 0 + }, + .update = upload_buffers +}; + + + +/*********************************************************************** + * Polygon stipple + * + * The i915 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + * + * XXX: does stipple pattern need to be adjusted according to + * the window position? + * + * XXX: possibly need workaround for conform paths test. + */ + +static void upload_stipple( struct intel_context *intel ) +{ + GLuint st0 = _3DSTATE_STIPPLE; + GLuint st1 = 0; + + GLboolean hw_stipple_fallback = 0; + + /* _NEW_POLYGON, INTEL_NEW_REDUCED_PRIMITIVE + */ + if (intel->state.Polygon->StippleFlag && + intel->reduced_primitive == GL_TRIANGLES) { + + /* _NEW_POLYGONSTIPPLE + */ + const GLubyte *mask = (const GLubyte *)intel->state.PolygonStipple; + GLubyte p[4]; + GLint i, j, k; + + p[0] = mask[12] & 0xf; + p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; + p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; + p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; + p[3] |= p[3] << 4; + + st1 |= ST1_ENABLE; + + for (k = 0; k < 8; k++) { + for (j = 3; j >= 0; j--) { + for (i = 0; i < 4; i++, mask++) { + if (*mask != p[j]) { + hw_stipple_fallback = 1; + st1 &= ~ST1_ENABLE; + } + } + } + } + + st1 |= (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12)); + } + + assert(!hw_stipple_fallback); /* TODO */ + + BEGIN_BATCH(2, 0); + OUT_BATCH(st0); + OUT_BATCH(st1); + ADVANCE_BATCH(); +} + + +const struct intel_tracked_state i915_upload_stipple = { + .dirty = { + .mesa = _NEW_POLYGONSTIPPLE, _NEW_POLYGON, + .intel = INTEL_NEW_REDUCED_PRIMITIVE, + .extra = 0 + }, + .update = upload_stipple +}; + + + +/*********************************************************************** + * Scissor. + */ + +static void upload_scissor( struct intel_context *intel ) +{ + /* _NEW_SCISSOR, _NEW_BUFFERS + */ + if (intel->state.Scissor->Enabled && + intel->state.DrawBuffer) { + + GLint x = intel->state.Scissor->X; + GLint y = intel->state.Scissor->Y; + GLint w = intel->state.Scissor->Width; + GLint h = intel->state.Scissor->Height; + + GLint x1, y1, x2, y2; + + if (intel->state.DrawBuffer->Name == 0) { + x1 = x; + y1 = intel->state.DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + } + else { + /* FBO - not inverted + */ + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + } + + x1 = CLAMP(x1, 0, intel->state.DrawBuffer->Width - 1); + y1 = CLAMP(y1, 0, intel->state.DrawBuffer->Height - 1); + x2 = CLAMP(x2, 0, intel->state.DrawBuffer->Width - 1); + y2 = CLAMP(y2, 0, intel->state.DrawBuffer->Height - 1); + + BEGIN_BATCH(4, 0); + OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); + OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); + OUT_BATCH((y1 << 16) | (x1 & 0xffff)); + OUT_BATCH((y2 << 16) | (x2 & 0xffff)); + ADVANCE_BATCH(); + } + else { + BEGIN_BATCH(1, 0); + OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + ADVANCE_BATCH(); + } +} + +const struct intel_tracked_state i915_upload_scissor = { + .dirty = { + .mesa = _NEW_SCISSOR | _NEW_BUFFERS, + .intel = 0, + .extra = 0 + }, + .update = upload_scissor +}; + diff --git a/src/mesa/drivers/dri/i915tex/i915_state_sampler.c b/src/mesa/drivers/dri/i915tex/i915_state_sampler.c new file mode 100644 index 0000000000..5eba939e46 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state_sampler.c @@ -0,0 +1,257 @@ +/************************************************************************** + * + * 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 "mtypes.h" +#include "enums.h" +#include "texformat.h" +#include "macros.h" +#include "dri_bufmgr.h" + +#include "intel_mipmap_tree.h" +#include "intel_tex.h" +#include "intel_batchbuffer.h" +#include "intel_state_inlines.h" + +#include "i915_context.h" +#include "i915_reg.h" + + + + + + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static GLuint +translate_wrap_mode(GLenum wrap) +{ + switch (wrap) { + case GL_REPEAT: + return TEXCOORDMODE_WRAP; + case GL_CLAMP: + return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ + case GL_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP_EDGE; + case GL_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; + case GL_MIRRORED_REPEAT: + return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} + + + +/* Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + */ +static void update_sampler(struct intel_context *intel, + GLuint unit, + GLuint *state ) +{ + struct gl_texture_unit *tUnit = &intel->state.Texture->Unit[unit]; + struct gl_texture_object *tObj = tUnit->_Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + + /* Need to do this after updating the maps, which call the + * intel_finalize_mipmap_tree and hence can update firstLevel: + */ + struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel]; + + state[0] = state[1] = state[2] = 0; + + { + GLuint minFilt, mipFilt, magFilt; + + switch (tObj->MinFilter) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + } + + if (tObj->MaxAnisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (tObj->MagFilter) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + magFilt = FILTER_NEAREST; + break; + } + } + + { + GLint b = (int) ((tObj->LodBias + tUnit->LodBias) * 16.0); + b = CLAMP(b, -256, 255); + + state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); + } + + + /* YUV conversion: + */ + if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || + firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) + state[0] |= SS2_COLORSPACE_CONVERSION; + + /* Shadow: + */ + if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && + tObj->Target != GL_TEXTURE_3D) { + + state[0] |= (SS2_SHADOW_ENABLE | + intel_translate_compare_func(tObj->CompareFunc)); + + minFilt = FILTER_4X4_FLAT; + magFilt = FILTER_4X4_FLAT; + } + + state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | + (mipFilt << SS2_MIP_FILTER_SHIFT) | + (magFilt << SS2_MAG_FILTER_SHIFT)); + } + + { + GLenum ws = tObj->WrapS; + GLenum wt = tObj->WrapT; + GLenum wr = tObj->WrapR; + + + /* 3D textures don't seem to respect the border color. + * Fallback if there's ever a danger that they might refer to + * it. + * + * Effectively this means fallback on 3D clamp or + * clamp_to_border. + */ + if (tObj->Target == GL_TEXTURE_3D && + (tObj->MinFilter != GL_NEAREST || + tObj->MagFilter != GL_NEAREST) && + (ws == GL_CLAMP || + wt == GL_CLAMP || + wr == GL_CLAMP || + ws == GL_CLAMP_TO_BORDER || + wt == GL_CLAMP_TO_BORDER || + wr == GL_CLAMP_TO_BORDER)) { + + if (intel->strict_conformance) { + assert(0); +/* sampler->fallback = true; */ + /* TODO */ + } + } + + state[1] = + ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT) | + (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); + + /* Or some field in tObj? */ + if (intel->state.Texture->Unit[unit]._ReallyEnabled != TEXTURE_RECT_BIT) + state[1] |= SS3_NORMALIZED_COORDS; + } + + state[2] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], + tObj->_BorderChan[1], + tObj->_BorderChan[2], + tObj->_BorderChan[3]); +} + + + +static void upload_samplers( struct intel_context *intel ) +{ + GLint i, dirty = 0, nr = 0; + GLuint state[I915_TEX_UNITS][3]; + + for (i = 0; i < I915_TEX_UNITS; i++) { + if (intel->state.Texture->Unit[i]._ReallyEnabled) { + update_sampler( intel, i, state[i] ); + nr++; + dirty |= (1<<i); + } + } + + if (nr) { + BEGIN_BATCH(2 + nr * 3, 0); + OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr)); + OUT_BATCH(dirty); + for (i = 0; i < I915_TEX_UNITS; i++) { + if (intel->state.Texture->Unit[i]._ReallyEnabled) { + OUT_BATCH(state[i][0]); + OUT_BATCH(state[i][1]); + OUT_BATCH(state[i][2]); + } + } + ADVANCE_BATCH(); + } +} + +const struct intel_tracked_state i915_upload_samplers = { + .dirty = { + .mesa = _NEW_TEXTURE, + .intel = 0, + .extra = 0 + }, + .update = upload_samplers +}; diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c deleted file mode 100644 index 59e148ca04..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_tex.c +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************** - * - * 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 "glheader.h" -#include "mtypes.h" -#include "imports.h" -#include "simple_list.h" -#include "enums.h" -#include "image.h" -#include "texstore.h" -#include "texformat.h" -#include "texmem.h" -#include "swrast/swrast.h" - -#include "mm.h" - -#include "intel_ioctl.h" - -#include "i915_context.h" -#include "i915_reg.h" - - - -static void -i915TexEnv(GLcontext * ctx, GLenum target, - GLenum pname, const GLfloat * param) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - switch (pname) { - case GL_TEXTURE_LOD_BIAS:{ - GLuint unit = ctx->Texture.CurrentUnit; - GLint b = (int) ((*param) * 16.0); - if (b > 255) - b = 255; - if (b < -256) - b = -256; - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->lodbias_ss2[unit] = - ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); - break; - } - - default: - break; - } -} - - -void -i915InitTextureFuncs(struct dd_function_table *functions) -{ - functions->TexEnv = i915TexEnv; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c index 333fefef85..c83bc73b12 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c @@ -36,21 +36,23 @@ #define FILE_DEBUG_FLAG DEBUG_TEXTURE -static GLint initial_offsets[6][2] = { {0, 0}, -{0, 2}, -{1, 0}, -{1, 2}, -{1, 1}, -{1, 3} +static GLint initial_offsets[6][2] = { + {0, 0}, + {0, 2}, + {1, 0}, + {1, 2}, + {1, 1}, + {1, 3} }; -static GLint step_offsets[6][2] = { {0, 2}, -{0, 2}, -{-1, 2}, -{-1, 2}, -{-1, 1}, -{-1, 1} +static GLint step_offsets[6][2] = { + {0, 2}, + {0, 2}, + {-1, 2}, + {-1, 2}, + {-1, 1}, + {-1, 1} }; GLboolean diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_texstate.c deleted file mode 100644 index e0ecdfde24..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_texstate.c +++ /dev/null @@ -1,338 +0,0 @@ -/************************************************************************** - * - * 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 "mtypes.h" -#include "enums.h" -#include "texformat.h" -#include "dri_bufmgr.h" - -#include "intel_mipmap_tree.h" -#include "intel_tex.h" - -#include "i915_context.h" -#include "i915_reg.h" - - -static GLuint -translate_texture_format(GLuint mesa_format) -{ - switch (mesa_format) { - case MESA_FORMAT_L8: - return MAPSURF_8BIT | MT_8BIT_L8; - case MESA_FORMAT_I8: - return MAPSURF_8BIT | MT_8BIT_I8; - case MESA_FORMAT_A8: - return MAPSURF_8BIT | MT_8BIT_A8; - case MESA_FORMAT_AL88: - return MAPSURF_16BIT | MT_16BIT_AY88; - case MESA_FORMAT_RGB565: - return MAPSURF_16BIT | MT_16BIT_RGB565; - case MESA_FORMAT_ARGB1555: - return MAPSURF_16BIT | MT_16BIT_ARGB1555; - case MESA_FORMAT_ARGB4444: - return MAPSURF_16BIT | MT_16BIT_ARGB4444; - case MESA_FORMAT_ARGB8888: - return MAPSURF_32BIT | MT_32BIT_ARGB8888; - case MESA_FORMAT_YCBCR_REV: - return (MAPSURF_422 | MT_422_YCRCB_NORMAL); - case MESA_FORMAT_YCBCR: - return (MAPSURF_422 | MT_422_YCRCB_SWAPY); - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); - case MESA_FORMAT_Z16: - return (MAPSURF_16BIT | MT_16BIT_L16); - case MESA_FORMAT_RGBA_DXT1: - case MESA_FORMAT_RGB_DXT1: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - case MESA_FORMAT_RGBA_DXT3: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - case MESA_FORMAT_RGBA_DXT5: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); - case MESA_FORMAT_Z24_S8: - return (MAPSURF_32BIT | MT_32BIT_xL824); - default: - fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); - abort(); - return 0; - } -} - - - - -/* The i915 (and related graphics cores) do not support GL_CLAMP. The - * Intel drivers for "other operating systems" implement GL_CLAMP as - * GL_CLAMP_TO_EDGE, so the same is done here. - */ -static GLuint -translate_wrap_mode(GLenum wrap) -{ - switch (wrap) { - case GL_REPEAT: - return TEXCOORDMODE_WRAP; - case GL_CLAMP: - return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ - case GL_CLAMP_TO_EDGE: - return TEXCOORDMODE_CLAMP_EDGE; - case GL_CLAMP_TO_BORDER: - return TEXCOORDMODE_CLAMP_BORDER; - case GL_MIRRORED_REPEAT: - return TEXCOORDMODE_MIRROR; - default: - return TEXCOORDMODE_WRAP; - } -} - - - -/* Recalculate all state from scratch. Perhaps not the most - * efficient, but this has gotten complex enough that we need - * something which is understandable and reliable. - */ -static GLboolean -i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) -{ - GLcontext *ctx = &intel->ctx; - struct i915_context *i915 = i915_context(ctx); - struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; - struct intel_texture_object *intelObj = intel_texture_object(tObj); - struct gl_texture_image *firstImage; - GLuint *state = i915->state.Tex[unit]; - - memset(state, 0, sizeof(state)); - - /*We need to refcount these. */ - - if (i915->state.tex_buffer[unit] != NULL) { - driBOUnReference(i915->state.tex_buffer[unit]); - i915->state.tex_buffer[unit] = NULL; - } - - if (!intel_finalize_mipmap_tree(intel, unit)) - return GL_FALSE; - - /* Get first image here, since intelObj->firstLevel will get set in - * the intel_finalize_mipmap_tree() call above. - */ - firstImage = tObj->Image[0][intelObj->firstLevel]; - - i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer); - i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, - intelObj-> - firstLevel); - - state[I915_TEXREG_MS3] = - (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | - ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | - translate_texture_format(firstImage->TexFormat->MesaFormat) | - MS3_USE_FENCE_REGS); - - state[I915_TEXREG_MS4] = - (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK | - ((((intelObj->lastLevel - - intelObj->firstLevel) * - 4)) << MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - - 1) << MS4_VOLUME_DEPTH_SHIFT)); - - - { - GLuint minFilt, mipFilt, magFilt; - - switch (tObj->MinFilter) { - case GL_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NONE; - break; - case GL_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_LINEAR; - break; - default: - return GL_FALSE; - } - - if (tObj->MaxAnisotropy > 1.0) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - } - else { - switch (tObj->MagFilter) { - case GL_NEAREST: - magFilt = FILTER_NEAREST; - break; - case GL_LINEAR: - magFilt = FILTER_LINEAR; - break; - default: - return GL_FALSE; - } - } - - state[I915_TEXREG_SS2] = i915->lodbias_ss2[unit]; - - /* YUV conversion: - */ - if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || - firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) - state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION; - - /* Shadow: - */ - if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && - tObj->Target != GL_TEXTURE_3D) { - - state[I915_TEXREG_SS2] |= - (SS2_SHADOW_ENABLE | - intel_translate_compare_func(tObj->CompareFunc)); - - minFilt = FILTER_4X4_FLAT; - magFilt = FILTER_4X4_FLAT; - } - - state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | - (mipFilt << SS2_MIP_FILTER_SHIFT) | - (magFilt << SS2_MAG_FILTER_SHIFT)); - } - - { - GLenum ws = tObj->WrapS; - GLenum wt = tObj->WrapT; - GLenum wr = tObj->WrapR; - - - /* 3D textures don't seem to respect the border color. - * Fallback if there's ever a danger that they might refer to - * it. - * - * Effectively this means fallback on 3D clamp or - * clamp_to_border. - */ - if (tObj->Target == GL_TEXTURE_3D && - (tObj->MinFilter != GL_NEAREST || - tObj->MagFilter != GL_NEAREST) && - (ws == GL_CLAMP || - wt == GL_CLAMP || - wr == GL_CLAMP || - ws == GL_CLAMP_TO_BORDER || - wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER)) - return GL_FALSE; - - - state[I915_TEXREG_SS3] = ss3; /* SS3_NORMALIZED_COORDS */ - - state[I915_TEXREG_SS3] |= - ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | - (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | - (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); - - state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); - } - - - state[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], - tObj->_BorderChan[1], - tObj->_BorderChan[2], - tObj->_BorderChan[3]); - - - I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); - /* memcmp was already disabled, but definitely won't work as the - * region might now change and that wouldn't be detected: - */ - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - - -#if 0 - DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]); - DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]); - DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]); - DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]); - DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]); - DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]); -#endif - - return GL_TRUE; -} - - - - -void -i915UpdateTextureState(struct intel_context *intel) -{ - GLboolean ok = GL_TRUE; - GLuint i; - - for (i = 0; i < I915_TEX_UNITS && ok; i++) { - switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { - case TEXTURE_1D_BIT: - case TEXTURE_2D_BIT: - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - ok = i915_update_tex_unit(intel, i, SS3_NORMALIZED_COORDS); - break; - case TEXTURE_RECT_BIT: - ok = i915_update_tex_unit(intel, i, 0); - break; - case 0:{ - struct i915_context *i915 = i915_context(&intel->ctx); - if (i915->state.active & I915_UPLOAD_TEX(i)) - I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE); - - if (i915->state.tex_buffer[i] != NULL) { - driBOUnReference(i915->state.tex_buffer[i]); - i915->state.tex_buffer[i] = NULL; - } - - break; - } - default: - ok = GL_FALSE; - break; - } - } - - FALLBACK(intel, I915_FALLBACK_TEXTURE, !ok); -} diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index 49c0142af8..14b9c50ace 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -43,320 +43,12 @@ #include "i915_reg.h" #include "i915_context.h" -static void -i915_render_start(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - i915ValidateFragmentProgram(i915); -} - - -static void -i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; - - st1 &= ~ST1_ENABLE; - - switch (rprim) { - case GL_TRIANGLES: - if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) - st1 |= ST1_ENABLE; - break; - case GL_LINES: - case GL_POINTS: - default: - break; - } - - i915->intel.reduced_primitive = rprim; - - if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { - INTEL_FIREVERTICES(intel); - - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST1] = st1; - } -} - - -/* Pull apart the vertex format registers and figure out how large a - * vertex is supposed to be. - */ -static GLboolean -i915_check_vertex_size(struct intel_context *intel, GLuint expected) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; - int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; - int i, sz = 0; - - switch (lis4 & S4_VFMT_XYZW_MASK) { - case S4_VFMT_XY: - sz = 2; - break; - case S4_VFMT_XYZ: - sz = 3; - break; - case S4_VFMT_XYW: - sz = 3; - break; - case S4_VFMT_XYZW: - sz = 4; - break; - default: - fprintf(stderr, "no xyzw specified\n"); - return 0; - } - - if (lis4 & S4_VFMT_SPEC_FOG) - sz++; - if (lis4 & S4_VFMT_COLOR) - sz++; - if (lis4 & S4_VFMT_DEPTH_OFFSET) - sz++; - if (lis4 & S4_VFMT_POINT_WIDTH) - sz++; - if (lis4 & S4_VFMT_FOG_PARAM) - sz++; - - for (i = 0; i < 8; i++) { - switch (lis2 & S2_TEXCOORD_FMT0_MASK) { - case TEXCOORDFMT_2D: - sz += 2; - break; - case TEXCOORDFMT_3D: - sz += 3; - break; - case TEXCOORDFMT_4D: - sz += 4; - break; - case TEXCOORDFMT_1D: - sz += 1; - break; - case TEXCOORDFMT_2D_16: - sz += 1; - break; - case TEXCOORDFMT_4D_16: - sz += 2; - break; - case TEXCOORDFMT_NOT_PRESENT: - break; - default: - fprintf(stderr, "bad texcoord fmt %d\n", i); - return GL_FALSE; - } - lis2 >>= S2_TEXCOORD_FMT1_SHIFT; - } - - if (sz != expected) - fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); - - return sz == expected; -} - -static GLuint emit_indirect(struct intel_context *intel, - GLuint flag, - const GLuint *state, - GLuint size ) -{ - GLuint delta; - GLuint segment; - - switch (flag) { - case LI0_STATE_DYNAMIC_INDIRECT: - segment = SEGMENT_DYNAMIC_INDIRECT; - - /* Dynamic indirect state is different - tell it the ending - * address, it will execute from either the previous end address - * or the beginning of the 4k page, depending on what it feels - * like. - */ - delta = ((intel->batch->segment_finish_offset[segment] + size - 4) | - DIS0_BUFFER_VALID | - DIS0_BUFFER_RESET); - - - BEGIN_BATCH(2,0); - OUT_BATCH( _3DSTATE_LOAD_INDIRECT | flag | (1<<14) | 0); - OUT_RELOC( intel->batch->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE, - delta ); - ADVANCE_BATCH(); - break; - - default: - segment = SEGMENT_OTHER_INDIRECT; - - /* Other state is more conventional: tell the hardware the start - * point and size. - */ - delta = (intel->batch->segment_finish_offset[segment] | - SIS0_FORCE_LOAD | /* XXX: fix me */ - SIS0_BUFFER_VALID); - - BEGIN_BATCH(3,0); - OUT_BATCH( _3DSTATE_LOAD_INDIRECT | flag | (1<<14) | 1); - OUT_RELOC( intel->batch->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE, - delta ); - OUT_BATCH( (size/4)-1 ); - ADVANCE_BATCH(); - - - break; - } - - { - GLuint offset = intel->batch->segment_finish_offset[segment]; - intel->batch->segment_finish_offset[segment] += size; - - if (state != NULL) - memcpy(intel->batch->map + offset, state, size); - - return offset; - } -} - - -static void -i915_emit_invarient_state(struct intel_context *intel) -{ - static GLuint invarient_state[] = { - - (_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | - AA_LINE_REGION_WIDTH_1_0), - - /* Could use these to reduce the size of vertices when the incoming - * array is constant. - */ - (_3DSTATE_DFLT_DIFFUSE_CMD), - (0), - - (_3DSTATE_DFLT_SPEC_CMD), - (0), - - (_3DSTATE_DFLT_Z_CMD), - (0), - - /* We support texture crossbar via the fragment shader, rather than - * with this mechanism. - */ - (_3DSTATE_COORD_SET_BINDINGS | - CSB_TCB(0, 0) | - CSB_TCB(1, 1) | - CSB_TCB(2, 2) | - CSB_TCB(3, 3) | - CSB_TCB(4, 4) | - CSB_TCB(5, 5) | - CSB_TCB(6, 6) | - CSB_TCB(7, 7)), - - /* Setup OpenGL rasterization state: - */ - (_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | - ENABLE_TEXKILL_3D_4D | - TEXKILL_4D), - - /* Need to initialize this to zero. - */ - (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | - I1_LOAD_S(3) | - (1)), - (0), - - (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT), - (_3DSTATE_SCISSOR_RECT_0_CMD), - (0), - (0), - - /* Turn off stipple for now - */ - _3DSTATE_STIPPLE, - 0, - - /* For private depth buffers but shared color buffers, eg - * front-buffer rendering with a private depthbuffer. We don't do - * this. - */ - (_3DSTATE_DEPTH_SUBRECT_DISABLE), - - (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0) - }; - - emit_indirect( intel, - LI0_STATE_STATIC_INDIRECT, - invarient_state, - sizeof(invarient_state) ); -} -static GLuint -get_dirty(struct i915_hw_state *state) -{ - GLuint dirty; - - /* Workaround the multitex hang - if one texture unit state is - * modified, emit all texture units. - */ - dirty = state->active & ~state->emitted; - if (dirty & I915_UPLOAD_TEX_ALL) - state->emitted &= ~I915_UPLOAD_TEX_ALL; - dirty = state->active & ~state->emitted; - return dirty; -} - - -static GLuint -get_state_size(struct i915_hw_state *state) -{ - GLuint dirty = get_dirty(state); - GLuint i; - GLuint sz = 0; - - if (dirty & I915_UPLOAD_CTX) - sz += sizeof(state->Ctx); - - if (dirty & I915_UPLOAD_BUFFERS) - sz += sizeof(state->Buffer); - - if (dirty & I915_UPLOAD_STIPPLE) - sz += sizeof(state->Stipple); - - if (dirty & I915_UPLOAD_FOG) - sz += sizeof(state->Fog); - - if (dirty & I915_UPLOAD_TEX_ALL) { - int nr = 0; - for (i = 0; i < I915_TEX_UNITS; i++) - if (dirty & I915_UPLOAD_TEX(i)) - nr++; - - sz += (2 + nr * 3) * sizeof(GLuint) * 2; - } - - if (dirty & I915_UPLOAD_CONSTANTS) - sz += state->ConstantSize * sizeof(GLuint); +#if 0 - if (dirty & I915_UPLOAD_PROGRAM) - sz += state->ProgramSize * sizeof(GLuint); - return sz; -} #define OUT(x) do { \ if (0) _mesa_printf("OUT(0x%08x)\n", x); \ @@ -542,9 +234,6 @@ i915_emit_state(struct intel_context *intel) assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize); - emit_indirect(intel, LI0_STATE_PROGRAM, - state->Program, state->ProgramSize * sizeof(GLuint)); - if (INTEL_DEBUG & DEBUG_STATE) i915_disassemble_program(state->Program, state->ProgramSize); } @@ -554,135 +243,33 @@ i915_emit_state(struct intel_context *intel) if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); - emit_indirect(intel, LI0_STATE_CONSTANTS, - state->Constant, state->ConstantSize * sizeof(GLuint)); } state->emitted |= dirty; } -static void -i915_destroy_context(struct intel_context *intel) -{ - _tnl_free_vertices(&intel->ctx); -} - - -/** - * Set the drawing regions for the color and depth/stencil buffers. - * This involves setting the pitch, cpp and buffer ID/location. - * Also set pixel format for color and Z rendering - * Used for setting both regular and meta state. - */ -void -i915_state_draw_region(struct intel_context *intel, - struct i915_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint value; - - ASSERT(state == &i915->state || state == &i915->meta); - - if (state->draw_region != color_region) { - intel_region_release(&state->draw_region); - intel_region_reference(&state->draw_region, color_region); - } - if (state->depth_region != depth_region) { - intel_region_release(&state->depth_region); - intel_region_reference(&state->depth_region, depth_region); - } - - /* - * Set stride/cpp values - */ - if (color_region) { - state->Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - state->Buffer[I915_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(color_region->pitch * color_region->cpp) | - BUF_3D_USE_FENCE); - } - - if (depth_region) { - state->Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - state->Buffer[I915_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) | - BUF_3D_USE_FENCE); - } - - /* - * Compute/set I915_DESTREG_DV1 value - */ - value = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL); - if (color_region && color_region->cpp == 4) { - value |= DV_PF_8888; - } - else { - value |= (DITHER_FULL_ALWAYS | DV_PF_565); - } - if (depth_region && depth_region->cpp == 4) { - value |= DEPTH_FRMT_24_FIXED_8_OTHER; - } - else { - value |= DEPTH_FRMT_16_FIXED; - } - state->Buffer[I915_DESTREG_DV1] = value; - - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); -} +#endif static void -i915_set_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) +i915_destroy_context(struct intel_context *intel) { - struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->state, color_region, depth_region); + _tnl_free_vertices(&intel->ctx); } -static void -i915_lost_hardware(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915->state.emitted = 0; -} - static GLuint i915_flush_cmd(void) { return MI_FLUSH | FLUSH_MAP_CACHE; } -static void -i915_assert_not_dirty( struct intel_context *intel ) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - struct i915_hw_state *state = i915->current; - GLuint dirty = get_dirty(state); - assert(!dirty); -} - void i915InitVtbl(struct i915_context *i915) { - i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; i915->intel.vtbl.destroy = i915_destroy_context; - i915->intel.vtbl.emit_state = i915_emit_state; - i915->intel.vtbl.lost_hardware = i915_lost_hardware; - i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; - i915->intel.vtbl.render_start = i915_render_start; - i915->intel.vtbl.set_draw_region = i915_set_draw_region; - 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; } diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index dd6e416810..d63d9ba086 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -28,6 +28,7 @@ #include "intel_batchbuffer.h" #include "intel_ioctl.h" #include "intel_idx_render.h" +#include "intel_reg.h" /* Relocations in kernel space: * - pass dma buffer seperately @@ -297,7 +298,10 @@ do_flush_locked(struct intel_batchbuffer *batch, sched_yield(); LOCK_HARDWARE(intel); } - intel->vtbl.lost_hardware(intel); + /* This sucks: + */ + intel->state.dirty.intel |= ~0; + intel->state.dirty.mesa |= ~0; } } diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c index 1ded0b5417..a3f52f6752 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c @@ -34,6 +34,7 @@ #include "intel_tris.h" #include "intel_regions.h" #include "intel_batchbuffer.h" +#include "intel_metaops.h" #include "context.h" #include "utils.h" #include "drirenderbuffer.h" @@ -242,12 +243,8 @@ intelWindowMoved(struct intel_context *intel) intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY; } - /* Update hardware scissor */ - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); - - /* Re-calculate viewport related state */ - ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); + /* Raise a state flag */ + intel->state.dirty.intel |= INTEL_NEW_WINDOW_DIMENSIONS; } @@ -271,7 +268,7 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask) GLint cx, cy, cw, ch; GLuint buf; - intel->vtbl.install_meta_state(intel); + intel_install_meta_state(intel); /* Get clear bounds after locking */ cx = ctx->DrawBuffer->_Xmin; @@ -297,29 +294,33 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask) const GLuint clearColor = (backRegion && backRegion->cpp == 4) ? intel->ClearColor8888 : intel->ClearColor565; - intel->vtbl.meta_draw_region(intel, backRegion, depthRegion); + intel_meta_draw_region(intel, backRegion, depthRegion); if (mask & BUFFER_BIT_BACK_LEFT) - intel->vtbl.meta_color_mask(intel, GL_TRUE); + intel_meta_color_mask(intel, GL_TRUE); else - intel->vtbl.meta_color_mask(intel, GL_FALSE); + intel_meta_color_mask(intel, GL_FALSE); if (mask & BUFFER_BIT_STENCIL) - intel->vtbl.meta_stencil_replace(intel, + intel_meta_stencil_replace(intel, intel->ctx.Stencil.WriteMask[0], intel->ctx.Stencil.Clear); else - intel->vtbl.meta_no_stencil_write(intel); + intel_meta_no_stencil_write(intel); if (mask & BUFFER_BIT_DEPTH) - intel->vtbl.meta_depth_replace(intel); + intel_meta_depth_replace(intel); else - intel->vtbl.meta_no_depth_write(intel); + intel_meta_no_depth_write(intel); /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the * drawing origin may not be correctly emitted. */ - intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, intel->ctx.Depth.Clear, clearColor, 0, 0, 0, 0); /* texcoords */ + intel_meta_draw_quad(intel, + clear.x1, clear.x2, + clear.y1, clear.y2, + intel->ctx.Depth.Clear, + clearColor, 0, 0, 0, 0); /* texcoords */ mask &= ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH); @@ -337,10 +338,10 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask) ASSERT(irbColor); - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_color_mask(intel, GL_TRUE); - intel->vtbl.meta_draw_region(intel, irbColor->region, NULL); + intel_meta_no_depth_write(intel); + intel_meta_no_stencil_write(intel); + intel_meta_color_mask(intel, GL_TRUE); + intel_meta_draw_region(intel, irbColor->region, NULL); /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the * drawing origin may not be correctly emitted. @@ -352,7 +353,7 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask) } } - intel->vtbl.leave_meta_state(intel); + intel_leave_meta_state(intel); intel_batchbuffer_flush(intel->batch); } UNLOCK_HARDWARE(intel); @@ -394,11 +395,11 @@ intelRotateWindow(struct intel_context *intel, return; } - intel->vtbl.install_meta_state(intel); + intel_install_meta_state(intel); - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_color_mask(intel, GL_FALSE); + intel_meta_no_depth_write(intel); + intel_meta_no_stencil_write(intel); + intel_meta_color_mask(intel, GL_FALSE); /* save current drawing origin and cliprects (restored at end) */ @@ -419,7 +420,7 @@ intelRotateWindow(struct intel_context *intel, intel->numClipRects = 1; intel->pClipRects = &fullRect; - intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */ + intel_meta_draw_region(intel, screen->rotated_region, NULL); /* ? */ if (srcBuf == BUFFER_BIT_FRONT_LEFT) { src = intel->intelScreen->front_region; @@ -442,12 +443,12 @@ intelRotateWindow(struct intel_context *intel, } /* set the whole screen up as a texture to avoid alignment issues */ - intel->vtbl.meta_tex_rect_source(intel, + intel_meta_tex_rect_source(intel, src->buffer, screen->width, screen->height, src->pitch, format, type); - intel->vtbl.meta_texture_blend_replace(intel); + intel_meta_texture_blend_replace(intel); /* * loop over the source window's cliprects @@ -492,7 +493,7 @@ intelRotateWindow(struct intel_context *intel, } /* cliprect loop */ - intel->vtbl.leave_meta_state(intel); + intel_leave_meta_state(intel); intel_batchbuffer_flush(intel->batch); /* restore original drawing origin and cliprects */ @@ -572,6 +573,20 @@ intelClear(GLcontext *ctx, GLbitfield mask) } } + { + const GLfloat *color = intel->ctx.Color.ClearColor; + GLubyte clear[4]; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + /* compute both 32 and 16-bit clear values */ + intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], + clear[2], clear[3]); + intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); + } intelFlush(ctx); /* XXX intelClearWithBlit also does this */ @@ -724,6 +739,8 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) * Basically, this needs to be called any time the current framebuffer * changes, the renderbuffers change, or we need to draw into different * color buffers. + * + * XXX: Make this into a tracked state atom... */ void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) @@ -762,12 +779,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) /* * How many color buffers are we drawing into? */ - if (fb->_NumColorDrawBuffers[0] != 1 -#if 0 - /* XXX FBO temporary - always use software rendering */ - || 1 -#endif - ) { + if (fb->_NumColorDrawBuffers[0] != 1) { /* writing to 0 or 2 or 4 color buffers */ /*_mesa_debug(ctx, "Software rendering\n");*/ FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); @@ -809,20 +821,6 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) colorRegion = (irb && irb->region) ? irb->region : NULL; } - /* Update culling direction which changes depending on the - * orientation of the buffer: - */ - if (ctx->Driver.FrontFace) - ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); - else - ctx->NewState |= _NEW_POLYGON; - - if (!colorRegion) { - FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); - } - else { - FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); - } /*** *** Get depth buffer region and check if we need a software fallback. @@ -855,8 +853,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) if (irbStencil && irbStencil->region) { ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); - /* need to re-compute stencil hw state */ - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + if (!depthRegion) depthRegion = irbStencil->region; } @@ -867,34 +864,27 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) else { /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); - /* need to re-compute stencil hw state */ - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); } - /** - ** Release old regions, reference new regions - **/ -#if 0 /* XXX FBO: this seems to be redundant with i915_state_draw_region() */ - if (intel->draw_region != colorRegion) { - intel_region_release(&intel->draw_region); - intel_region_reference(&intel->draw_region, colorRegion); - } - if (intel->intelScreen->depth_region != depthRegion) { - intel_region_release(&intel->intelScreen->depth_region); - intel_region_reference(&intel->intelScreen->depth_region, depthRegion); + if (intel->state.draw_region != colorRegion) { + intel_region_release(&intel->state.draw_region); + intel_region_reference(&intel->state.draw_region, colorRegion); + + /* Raise a state flag to ensure viewport, scissor get recalculated. + */ + intel->state.dirty.intel |= INTEL_NEW_CBUF; } -#endif - intel->vtbl.set_draw_region(intel, colorRegion, depthRegion); + if (intel->state.depth_region != depthRegion) { + intel_region_release(&intel->state.depth_region); + intel_region_reference(&intel->state.depth_region, depthRegion); - /* update viewport since it depends on window size */ - ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, - ctx->Viewport.Width, ctx->Viewport.Height); + /* Raise a state flag to ensure viewport, scissor get recalculated. + */ + intel->state.dirty.intel |= INTEL_NEW_ZBUF; + } - /* Update hardware scissor */ - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); } diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index 208e53041f..ad4b9b0053 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -59,6 +59,8 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" #include "intel_fbo.h" +#include "intel_metaops.h" +#include "intel_state.h" #include "vblank.h" #include "utils.h" @@ -244,12 +246,24 @@ static const struct dri_debug_control debug_control[] = { static void intelInvalidateState(GLcontext * ctx, GLuint new_state) { + struct intel_context *intel = intel_context(ctx); + _swrast_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); _tnl_invalidate_vertex_state(ctx, new_state); - intel_context(ctx)->NewGLState |= new_state; + + assert(!intel->metaops.active); + + intel->state.dirty.mesa |= new_state; + intel->state.dirty.intel |= INTEL_NEW_MESA; +} + +void intel_lost_hardware( struct intel_context *intel ) +{ + intel->state.dirty.intel |= ~0; + intel->state.dirty.mesa |= ~0; } @@ -332,11 +346,11 @@ intelInitDriverFunctions(struct dd_function_table *functions) intelInitTextureFuncs(functions); intelInitPixelFuncs(functions); - intelInitStateFuncs(functions); intelInitBufferFuncs(functions); } + GLboolean intelInitContext(struct intel_context *intel, const __GLcontextModes * mesaVis, @@ -418,7 +432,7 @@ intelInitContext(struct intel_context *intel, intel->hw_stipple = 1; - /* XXX FBO: this doesn't seem to be used anywhere */ + /* XXX FBO: recalculate on bind */ switch (mesaVis->depthBits) { case 0: /* what to do in this case? */ case 16: @@ -446,8 +460,6 @@ intelInitContext(struct intel_context *intel, intel->do_irqs = (intel->intelScreen->irq_active && fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS); - intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); - intel->vblank_flags = (intel->intelScreen->irq_active != 0) ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; @@ -469,8 +481,14 @@ intelInitContext(struct intel_context *intel, intel_bufferobj_init(intel); intel_fbo_init(intel); + intel_state_init(intel); + intel_metaops_init(intel); intel_idx_init(intel); + intel->state.dirty.mesa = ~0; + intel->state.dirty.intel = ~0; + + if (intel->ctx.Mesa_DXTn) { _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); _mesa_enable_extension(ctx, "GL_S3_s3tc"); @@ -672,7 +690,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags) intel->prim.flush = 0; /* re-emit all state */ - intel->vtbl.lost_hardware(intel); + intel_lost_hardware(intel); /* force window update */ intel->lastStamp = 0; diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index ab88e83853..5486f63a1d 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -52,6 +52,11 @@ struct intel_region; struct intel_context; struct _DriBufferObject; + +struct intel_texture_object; +struct intel_texture_image; + + typedef void (*intel_tri_func) (struct intel_context *, intelVertex *, intelVertex *, intelVertex *); typedef void (*intel_line_func) (struct intel_context *, intelVertex *, @@ -64,54 +69,93 @@ typedef void (*intel_point_func) (struct intel_context *, intelVertex *); #define INTEL_FALLBACK_STENCIL_BUFFER 0x8 #define INTEL_FALLBACK_USER 0x10 #define INTEL_FALLBACK_RENDERMODE 0x20 +#define INTEL_FALLBACK_OTHER 0x40 extern void intelFallback(struct intel_context *intel, GLuint bit, GLboolean mode); #define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode ) - #define INTEL_WRITE_PART 0x1 #define INTEL_WRITE_FULL 0x2 #define INTEL_READ 0x4 -struct intel_texture_object -{ - struct gl_texture_object base; /* The "parent" object */ - /* The mipmap tree must include at least these levels once - * validated: - */ - GLuint firstLevel; - GLuint lastLevel; - /* Offset for firstLevel image: - */ - GLuint textureOffset; +#define INTEL_NEW_MESA 0x1 /* Mesa state has changed */ +#define INTEL_NEW_FRAGMENT_PROGRAM 0x2 +#define INTEL_NEW_VERTEX_SIZE 0x4 +#define INTEL_NEW_INPUT_SIZES 0x8 +#define INTEL_NEW_CONTEXT 0x10 /* Lost hardware? */ +#define INTEL_NEW_REDUCED_PRIMITIVE 0x20 +#define INTEL_NEW_FALLBACK 0x40 +#define INTEL_NEW_METAOPS 0x80 /* not needed? */ +#define INTEL_NEW_VBO 0x100 +#define INTEL_NEW_FENCE 0x200 /* whatever invalidates RELOC's */ +#define INTEL_NEW_CBUF 0x400 +#define INTEL_NEW_ZBUF 0x800 +#define INTEL_NEW_WINDOW_DIMENSIONS 0x1000 - /* On validation any active images held in main memory or in other - * regions will be copied to this region and the old storage freed. - */ - struct intel_mipmap_tree *mt; +#define INTEL_NEW_DRIVER0 0x10000 + +struct intel_state_flags { + GLuint mesa; + GLuint intel; + GLuint extra; }; +struct intel_context_state { + struct gl_colorbuffer_attrib *Color; + struct gl_depthbuffer_attrib *Depth; + struct gl_fog_attrib *Fog; + struct gl_hint_attrib *Hint; + struct gl_light_attrib *Light; + struct gl_line_attrib *Line; + struct gl_point_attrib *Point; + struct gl_polygon_attrib *Polygon; + GLuint *PolygonStipple; + struct gl_scissor_attrib *Scissor; + struct gl_stencil_attrib *Stencil; + struct gl_texture_attrib *Texture; + struct gl_transform_attrib *Transform; + struct gl_viewport_attrib *Viewport; + struct gl_vertex_program_state *VertexProgram; + struct gl_fragment_program_state *FragmentProgram; -struct intel_texture_image -{ - struct gl_texture_image base; + GLframebuffer *DrawBuffer; + GLframebuffer *ReadBuffer; + GLenum RenderMode; - /* These aren't stored in gl_texture_image - */ - GLuint level; - GLuint face; + GLuint _ColorDrawBufferMask0; /* ??? */ + + struct intel_region *draw_region; /* INTEL_NEW_CBUF */ + struct intel_region *depth_region; /* INTEL_NEW_ZBUF */ - /* If intelImage->mt != NULL, image data is stored here. - * Else if intelImage->base.Data != NULL, image is stored there. - * Else there is no image data. + + struct gl_fragment_program *fp; + + /* Indexed rendering support. GEN3 specific. */ - struct intel_mipmap_tree *mt; + struct _DriBufferObject *vbo; + GLuint vbo_offset; + + + struct intel_state_flags dirty; +}; + +/* A single atom of derived state + */ +struct intel_tracked_state { + struct intel_state_flags dirty; + void (*update)( struct intel_context *intel ); }; +struct intel_driver_state { + struct intel_tracked_state **atoms; + GLuint nr_atoms; +}; + + #define INTEL_MAX_FIXUP 64 @@ -122,54 +166,16 @@ struct intel_context struct { void (*destroy) (struct intel_context * intel); - void (*emit_state) (struct intel_context * intel); void (*lost_hardware) (struct intel_context * intel); - void (*update_texture_state) (struct intel_context * intel); void (*render_start) (struct intel_context * intel); void (*set_draw_region) (struct intel_context * intel, struct intel_region * draw_region, struct intel_region * depth_region); - GLuint(*flush_cmd) (void); - - void (*reduced_primitive_state) (struct intel_context * intel, - GLenum rprim); - - GLboolean(*check_vertex_size) (struct intel_context * intel, - GLuint expected); - - - /* Metaops: - */ - void (*install_meta_state) (struct intel_context * intel); - void (*leave_meta_state) (struct intel_context * intel); - - void (*meta_draw_region) (struct intel_context * intel, - struct intel_region * draw_region, - struct intel_region * depth_region); - - void (*meta_color_mask) (struct intel_context * intel, GLboolean); + GLuint (*flush_cmd) (void); - void (*meta_stencil_replace) (struct intel_context * intel, - GLuint mask, GLuint clear); - - void (*meta_depth_replace) (struct intel_context * intel); - - void (*meta_texture_blend_replace) (struct intel_context * intel); - - void (*meta_no_stencil_write) (struct intel_context * intel); - void (*meta_no_depth_write) (struct intel_context * intel); - void (*meta_no_texture) (struct intel_context * intel); - - void (*meta_import_pixel_state) (struct intel_context * intel); - - GLboolean(*meta_tex_rect_source) (struct intel_context * intel, - struct _DriBufferObject * buffer, - GLuint offset, - GLuint pitch, - GLuint height, - GLenum format, GLenum type); + /* Do with metaops: */ void (*rotate_window) (struct intel_context * intel, __DRIdrawablePrivate * dPriv, GLuint srcBuf); @@ -178,8 +184,21 @@ struct intel_context } vtbl; GLint refcount; + + struct intel_context_state state; + + struct intel_driver_state driver_state; + + struct { + /* Will be allocated on demand if needed. + */ + struct intel_context_state state; + struct gl_buffer_object *vbo; + GLboolean active; + } metaops; + + GLuint Fallback; - GLuint NewGLState; struct _DriFenceObject *last_swap_fence; struct _DriFenceObject *first_swap_fence; @@ -196,18 +215,10 @@ struct intel_context } prim; GLboolean locked; - char *prevLockFile; - int prevLockLine; GLuint ClearColor565; GLuint ClearColor8888; - /* Offsets of fields within the current vertex: - */ - GLuint coloroffset; - GLuint specoffset; - GLuint wpos_offset; - GLuint wpos_size; struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; @@ -215,6 +226,8 @@ struct intel_context GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */ GLboolean hw_stipple; + GLboolean hw_stencil; + GLboolean strict_conformance; /* AGP memory buffer manager: @@ -224,6 +237,10 @@ struct intel_context /* State for intelvb.c and inteltris.c. */ + GLuint coloroffset; + GLuint specoffset; + GLuint wpos_offset; + GLuint wpos_size; GLuint RenderIndex; GLmatrix ViewportMatrix; GLenum render_primitive; @@ -231,13 +248,6 @@ struct intel_context GLuint vertex_size; GLubyte *verts; /* points to tnl->clipspace.vertex_buf */ -#if 0 - struct intel_region *front_region; /* XXX FBO: obsolete */ - struct intel_region *rotated_region; /* XXX FBO: obsolete */ - struct intel_region *back_region; /* XXX FBO: obsolete */ - struct intel_region *draw_region; /* XXX FBO: rename to color_region */ - struct intel_region *depth_region; /**< currently bound depth/Z region */ -#endif /* Fallback rasterization functions */ @@ -252,9 +262,6 @@ struct intel_context drm_clip_rect_t *pClipRects; drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ - int perf_boxes; - - GLuint do_usleeps; int do_irqs; GLuint irqsEmitted; drm_i915_irq_wait_t iw; @@ -279,22 +286,19 @@ struct intel_context */ GLuint vbl_seq; GLuint vblank_flags; - int64_t swap_ust; int64_t swap_missed_ust; - GLuint swap_count; GLuint swap_missed_count; - GLuint swap_scheduled; - /* Rotation. Need to match that of the - * current screen. - */ + /* Rotation. Need to match that of the + * current screen. + */ - int width; - int height; - int current_rotation; + int width; + int height; + int current_rotation; }; /* These are functions now: @@ -411,77 +415,12 @@ extern GLboolean intelInitContext(struct intel_context *intel, extern void intelGetLock(struct intel_context *intel, GLuint flags); -extern void intelInitState(GLcontext * ctx); extern void intelFinish(GLcontext * ctx); extern void intelFlush(GLcontext * ctx); extern void intelInitDriverFunctions(struct dd_function_table *functions); - -/* ================================================================ - * intel_state.c: - */ -extern void intelInitStateFuncs(struct dd_function_table *functions); - -#define COMPAREFUNC_ALWAYS 0 -#define COMPAREFUNC_NEVER 0x1 -#define COMPAREFUNC_LESS 0x2 -#define COMPAREFUNC_EQUAL 0x3 -#define COMPAREFUNC_LEQUAL 0x4 -#define COMPAREFUNC_GREATER 0x5 -#define COMPAREFUNC_NOTEQUAL 0x6 -#define COMPAREFUNC_GEQUAL 0x7 - -#define STENCILOP_KEEP 0 -#define STENCILOP_ZERO 0x1 -#define STENCILOP_REPLACE 0x2 -#define STENCILOP_INCRSAT 0x3 -#define STENCILOP_DECRSAT 0x4 -#define STENCILOP_INCR 0x5 -#define STENCILOP_DECR 0x6 -#define STENCILOP_INVERT 0x7 - -#define LOGICOP_CLEAR 0 -#define LOGICOP_NOR 0x1 -#define LOGICOP_AND_INV 0x2 -#define LOGICOP_COPY_INV 0x3 -#define LOGICOP_AND_RVRSE 0x4 -#define LOGICOP_INV 0x5 -#define LOGICOP_XOR 0x6 -#define LOGICOP_NAND 0x7 -#define LOGICOP_AND 0x8 -#define LOGICOP_EQUIV 0x9 -#define LOGICOP_NOOP 0xa -#define LOGICOP_OR_INV 0xb -#define LOGICOP_COPY 0xc -#define LOGICOP_OR_RVRSE 0xd -#define LOGICOP_OR 0xe -#define LOGICOP_SET 0xf - -#define BLENDFACT_ZERO 0x01 -#define BLENDFACT_ONE 0x02 -#define BLENDFACT_SRC_COLR 0x03 -#define BLENDFACT_INV_SRC_COLR 0x04 -#define BLENDFACT_SRC_ALPHA 0x05 -#define BLENDFACT_INV_SRC_ALPHA 0x06 -#define BLENDFACT_DST_ALPHA 0x07 -#define BLENDFACT_INV_DST_ALPHA 0x08 -#define BLENDFACT_DST_COLR 0x09 -#define BLENDFACT_INV_DST_COLR 0x0a -#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b -#define BLENDFACT_CONST_COLOR 0x0c -#define BLENDFACT_INV_CONST_COLOR 0x0d -#define BLENDFACT_CONST_ALPHA 0x0e -#define BLENDFACT_INV_CONST_ALPHA 0x0f -#define BLENDFACT_MASK 0x0f - -#define MI_BATCH_BUFFER_END (0xA<<23) - - -extern int intel_translate_compare_func(GLenum func); -extern int intel_translate_stencil_op(GLenum op); -extern int intel_translate_blend_factor(GLenum factor); -extern int intel_translate_logic_op(GLenum opcode); +void intel_lost_hardware( struct intel_context *intel ); /*====================================================================== diff --git a/src/mesa/drivers/dri/i915tex/intel_idx_render.h b/src/mesa/drivers/dri/i915tex/intel_debug.h index 6639bf5507..90d654ea1d 100644 --- a/src/mesa/drivers/dri/i915tex/intel_idx_render.h +++ b/src/mesa/drivers/dri/i915tex/intel_debug.h @@ -25,13 +25,34 @@ * **************************************************************************/ -#ifndef INTEL_IDX_H -#define INTEL_IDX_H +#ifndef INTEL_DEBUG_H +#define INTEL_DEBUG_H -#include "intel_context.h" +#include "imports.h" -void intel_idx_init( struct intel_context *intel ); -void intel_idx_destroy( struct intel_context *intel ); -void intel_idx_lost_hardware( struct intel_context *intel ); +#if defined(DEBUG) +#define DO_DEBUG 1 +extern int INTEL_DEBUG; +#else +#define INTEL_DEBUG 0 +#endif + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BLIT 0x8 +#define DEBUG_MIPTREE 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_BATCH 0x80 +#define DEBUG_PIXEL 0x100 +#define DEBUG_BUFMGR 0x200 +#define DEBUG_REGION 0x400 +#define DEBUG_FBO 0x800 +#define DEBUG_LOCK 0x1000 +#define DEBUG_IDX 0x2000 +#define DEBUG_TRI 0x4000 + +#define DBG(...) do { if (INTEL_DEBUG & FILE_DEBUG_FLAG) _mesa_printf(__VA_ARGS__); } while(0) #endif diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c index ab0e569bd9..9cac2ef9f8 100644 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.c +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c @@ -42,6 +42,7 @@ #include "intel_mipmap_tree.h" #include "intel_regions.h" #include "intel_span.h" +#include "intel_tex.h" #define FILE_DEBUG_FLAG DEBUG_FBO @@ -380,12 +381,6 @@ intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, irb->pfMap = map; irb->pfPitch = pitch / cpp; /* in pixels */ -#if 00 - irb->region = intel_region_create_static(intel, - DRM_MM_TT, - offset, map, cpp, width, height); -#endif - return irb; } diff --git a/src/mesa/drivers/dri/i915tex/intel_idx_render.c b/src/mesa/drivers/dri/i915tex/intel_idx_render.c deleted file mode 100644 index b5b57c399f..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_idx_render.c +++ /dev/null @@ -1,439 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/* - * Render vertex buffers by emitting vertices directly to dma buffers. - */ -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "imports.h" -#include "mtypes.h" -#include "enums.h" - -#include "tnl/t_context.h" -#include "tnl/t_vertex.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_tris.h" -#include "intel_batchbuffer.h" -#include "intel_buffer_objects.h" -#include "intel_reg.h" -#include "intel_idx_render.h" - -/* XXX: NAUGHTY: - */ -#include "i915_reg.h" - -#define FILE_DEBUG_FLAG DEBUG_IDX - - - -#define MAX_VBO 32 /* XXX: make dynamic */ -#define VBO_SIZE (128*1024) - - -/* Basically limited to what is addressable by the 16-bit indices, - * and the number of indices we can fit in a batchbuffer after - * making room for state. - */ -#define HW_MAX_INDEXABLE_VERTS ((1<<16)-1) -#define HW_MAX_INDICES ((BATCH_SZ - 1024) / 2) - - - -struct intel_vb { - struct intel_context *intel; - - struct intel_buffer_object *vbo[MAX_VBO]; - GLuint nr_vbo; - - struct intel_buffer_object *current_vbo; - - GLuint current_vbo_size; - GLuint current_vbo_used; - void *current_vbo_ptr; - - GLuint hw_vbo_offset; - GLuint hw_vbo_delta; - GLuint vertex_size; - - GLuint dirty; -}; - - -static GLboolean check_idx_render(GLcontext *ctx, - struct vertex_buffer *VB, - GLuint *max_nr_verts, - GLuint *max_nr_indices ) - -{ - struct intel_context *intel = intel_context(ctx); - GLuint i; - - if (intel->Fallback != 0 || - intel->RenderIndex != 0) - return GL_FALSE; - - /* These are constant, but for some hardware they might vary - * depending on the state, eg. according to vertex size. - */ - *max_nr_verts = HW_MAX_INDEXABLE_VERTS; - *max_nr_indices = HW_MAX_INDICES; - - /* Fix points with different dstorg bias state?? or use different - * viewport transform in this case only (requires flush at level - * above). - */ - for (i = 0; i < VB->PrimitiveCount; i++) { - if (VB->Primitive[i].mode == GL_POINTS) - return GL_FALSE; - } - - return GL_TRUE; -} - - -static void -emit_vb_state( struct intel_vb *vb ) -{ - struct intel_context *intel = vb->intel; - - DBG("%s\n", __FUNCTION__); - - /* Additionally, emit our vertex buffer state. - * - * XXX: need to push into the regular state mechanism, otherwise - * will fail with multiple apps when they mix up the submit order - * of their batchbuffers. - * - * XXX: need i830 version - */ - BEGIN_BATCH(3, 0); - - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | - I1_LOAD_S(0) | - I1_LOAD_S(1) | - 2); - - OUT_RELOC(vb->current_vbo->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, - vb->hw_vbo_offset); - - OUT_BATCH((vb->vertex_size << 24) | - (vb->vertex_size << 16)); - - ADVANCE_BATCH(); - - vb->dirty = 0; -} - - -static void -release_current_vbo( struct intel_vb *vb ) -{ - GLcontext *ctx = &vb->intel->ctx; - - DBG("%s\n", __FUNCTION__); - - if (vb->current_vbo_ptr) - ctx->Driver.UnmapBuffer( ctx, - GL_ARRAY_BUFFER_ARB, - &vb->current_vbo->Base ); - - vb->current_vbo = NULL; - vb->current_vbo_ptr = NULL; - vb->current_vbo_size = 0; - vb->current_vbo_used = 0; - vb->dirty = 0; -} - -static void -reset_vbo( struct intel_vb *vb ) -{ - DBG("%s\n", __FUNCTION__); - - if (vb->current_vbo) - release_current_vbo( vb ); - - vb->nr_vbo = 0; -} - - - - -static void -get_next_vbo( struct intel_vb *vb, GLuint size ) -{ - GLcontext *ctx = &vb->intel->ctx; - - DBG("%s\n", __FUNCTION__); - - /* XXX: just allocate more vbos here: - */ - if (vb->nr_vbo == MAX_VBO) { - DBG("XXX: out of vbo's, flushing\n"); - INTEL_FIREVERTICES(vb->intel); - intel_batchbuffer_flush(vb->intel->batch); - reset_vbo(vb); - } - - /* Unmap current vbo: - */ - if (vb->current_vbo) - release_current_vbo( vb ); - - if (size < VBO_SIZE) - size = VBO_SIZE; - - vb->current_vbo = vb->vbo[vb->nr_vbo++]; - vb->current_vbo_size = size; - vb->current_vbo_used = 0; - vb->hw_vbo_offset = 0; - vb->dirty = 1; - - /* Clear out buffer contents and break any hardware dependency on - * the old memory: - */ - ctx->Driver.BufferData( ctx, - GL_ARRAY_BUFFER_ARB, - vb->current_vbo_size, - NULL, - GL_DYNAMIC_DRAW_ARB, - &vb->current_vbo->Base ); - -} - -static void *get_space( struct intel_vb *vb, GLuint nr, GLuint vertex_size ) -{ - GLcontext *ctx = &vb->intel->ctx; - void *ptr; - GLuint space = nr * vertex_size * 4; - - DBG("%s %d*%d, vbo %d\n", __FUNCTION__, nr, vertex_size, vb->nr_vbo); - - if (vb->current_vbo_used + space > vb->current_vbo_size || !vb->current_vbo_ptr) - get_next_vbo( vb, space ); - - if (vb->vertex_size != vertex_size) { - vb->vertex_size = vertex_size; - vb->hw_vbo_offset = vb->current_vbo_used; - vb->dirty = 1; - } - - if (!vb->current_vbo_ptr) { - DBG("%s map vbo %d\n", __FUNCTION__, vb->nr_vbo); - - /* Map the vbo now, will be unmapped in release_current_vbo, above. - */ - vb->current_vbo_ptr = ctx->Driver.MapBuffer( ctx, - GL_ARRAY_BUFFER_ARB, - GL_WRITE_ONLY, - &vb->current_vbo->Base ); - } - - - /* Hmm, could just re-emit the vertex buffer packet & avoid this: - */ - vb->hw_vbo_delta = (vb->current_vbo_used - vb->hw_vbo_offset) / (vb->vertex_size * 4); - - ptr = vb->current_vbo_ptr + vb->current_vbo_used; - vb->current_vbo_used += space; - - return ptr; -} - - -static void -build_and_emit_vertices(GLcontext * ctx, GLuint nr) -{ - struct intel_context *intel = intel_context(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - void *ptr = get_space(intel->vb, nr, intel->vertex_size ); - - DBG("%s %d\n", __FUNCTION__, nr); - - assert(tnl->clipspace.vertex_size == intel->vertex_size * 4); - - tnl->clipspace.new_inputs |= VERT_BIT_POS; - _tnl_emit_vertices_to_buffer( ctx, 0, nr, ptr ); -} - -/* Emits vertices previously built by a call to BuildVertices. - * - * XXX: have t_vertex.c use our buffer to build into and avoid the - * copy (assuming our buffer is cached...) - */ -static void emit_built_vertices( GLcontext *ctx, GLuint nr ) -{ - struct intel_context *intel = intel_context(ctx); - void *ptr = get_space(intel->vb, nr, intel->vertex_size ); - - DBG("%s %d\n", __FUNCTION__, nr); - - memcpy(ptr, _tnl_get_vertex(ctx, 0), - nr * intel->vertex_size * sizeof(GLuint)); -} - -/* Emit primitives and indices referencing the previously emitted - * vertex buffer. - */ -static void emit_prims( GLcontext *ctx, - const struct _mesa_prim *prim, - GLuint nr_prims, - const GLuint *indices, - GLuint nr_indices ) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_vb *vb = intel->vb; - GLuint i, j; - - assert(indices); - - DBG("%s - start\n", __FUNCTION__); - - - for (i = 0; i < nr_prims; i++) { - GLuint nr, hw_prim; - GLuint start = prim[i].start; - GLuint offset = vb->hw_vbo_delta; - - switch (prim[i].mode) { - case GL_TRIANGLES: - hw_prim = PRIM3D_TRILIST; - nr = prim[i].count - prim[i].count % 3; - break; - case GL_LINES: - hw_prim = PRIM3D_LINELIST; - nr = prim[i].count - prim[i].count % 2; - break; - default: - assert(0); - continue; - } - - if (nr == 0) - continue; - - /* XXX: Can emit upto 64k indices, need to split larger prims - */ - BEGIN_BATCH(2 + (nr+1)/2, INTEL_BATCH_CLIPRECTS); - - /* Most state has already been emitted by the RenderStart callback. - */ - if (vb->dirty) { - emit_vb_state( vb ); - } - - OUT_BATCH(0); - OUT_BATCH( _3DPRIMITIVE | - hw_prim | - PRIM_INDIRECT | - PRIM_INDIRECT_ELTS | - nr ); - - /* Pack indices into 16bits - */ - for (j = 0; j < nr-1; j += 2) { - OUT_BATCH( (offset + indices[start+j]) | ((offset + indices[start+j+1])<<16) ); - } - - if (j < nr) - OUT_BATCH( (offset + indices[start+j]) ); - - ADVANCE_BATCH(); - - /* This won't fail, but only because of the wierd emit above: - */ - assert(!vb->dirty); - } - - - DBG("%s - done\n", __FUNCTION__); -} - - -/* Callback from (eventually) intel_batchbuffer_flush() - */ -void intel_idx_lost_hardware( struct intel_context *intel ) -{ - GLcontext *ctx = &intel->ctx; - struct intel_vb *vb = intel->vb; - - DBG("%s\n", __FUNCTION__); - - if (vb->current_vbo_ptr) { - ctx->Driver.UnmapBuffer( ctx, - GL_ARRAY_BUFFER_ARB, - &vb->current_vbo->Base ); - vb->current_vbo_ptr = NULL; - } -} - -void intel_idx_init( struct intel_context *intel ) -{ - GLcontext *ctx = &intel->ctx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint i; - - tnl->Driver.Render.CheckIdxRender = check_idx_render; - tnl->Driver.Render.BuildAndEmitVertices = build_and_emit_vertices; - tnl->Driver.Render.EmitBuiltVertices = emit_built_vertices; - tnl->Driver.Render.EmitPrims = emit_prims; - - - /* Create the vb context: - */ - intel->vb = CALLOC_STRUCT( intel_vb ); - intel->vb->intel = intel; - - for (i = 0; i < MAX_VBO; i++) { - intel->vb->vbo[i] = (struct intel_buffer_object *) - ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); - } -} - -void intel_idx_destroy( struct intel_context *intel ) -{ - GLcontext *ctx = &intel->ctx; - struct intel_vb *vb = intel->vb; - GLuint i; - - if (vb) { - reset_vbo( vb ); - - /* Destroy the vbo: - */ - for (i = 0; i < MAX_VBO; i++) - if (vb->vbo[i]) - ctx->Driver.DeleteBuffer( ctx, &vb->vbo[i]->Base ); - - FREE( intel->vb ); - } -} diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.c b/src/mesa/drivers/dri/i915tex/intel_ioctl.c index 3250c6b3a9..8d38e2925d 100644 --- a/src/mesa/drivers/dri/i915tex/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.c @@ -134,5 +134,5 @@ intel_batch_ioctl(struct intel_context *intel, /* FIXME: use hardware contexts to avoid 'losing' hardware after * each buffer flush. */ - intel->vtbl.lost_hardware(intel); + intel_lost_hardware(intel); } diff --git a/src/mesa/drivers/dri/i915tex/intel_metaops.c b/src/mesa/drivers/dri/i915tex/intel_metaops.c new file mode 100644 index 0000000000..e78423947f --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_metaops.c @@ -0,0 +1,546 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * frame buffer texture by Gary Wong <gtw@gnu.org> + */ + +/* TODO: push this type of operation into core mesa. + */ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" + +#include "shader/arbprogparse.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_regions.h" +#include "intel_context.h" +#include "intel_metaops.h" +#include "intel_reg.h" + + +#define DUP(i915, STRUCT, ATTRIB) \ +do { \ + intel->metaops.state.ATTRIB = MALLOC_STRUCT(STRUCT); \ + memcpy(intel->metaops.state.ATTRIB, \ + intel->state.ATTRIB, \ + sizeof(struct STRUCT)); \ +} while (0) + + +#define INSTALL(intel, ATTRIB, STATE) \ +do { \ + intel->state.ATTRIB = intel->metaops.state.ATTRIB; \ + intel->state.dirty.mesa |= STATE; \ +} while (0) + +#define RESTORE(intel, ATTRIB, STATE) \ +do { \ + intel->state.ATTRIB = &intel->ctx.ATTRIB; \ + intel->state.dirty.mesa |= STATE; \ +} while (0) + +static void init_state( struct intel_context *intel ) +{ + DUP(intel, gl_colorbuffer_attrib, Color); + DUP(intel, gl_depthbuffer_attrib, Depth); + DUP(intel, gl_fog_attrib, Fog); + DUP(intel, gl_hint_attrib, Hint); + DUP(intel, gl_light_attrib, Light); + DUP(intel, gl_line_attrib, Line); + DUP(intel, gl_point_attrib, Point); + DUP(intel, gl_polygon_attrib, Polygon); + DUP(intel, gl_scissor_attrib, Scissor); + DUP(intel, gl_stencil_attrib, Stencil); + DUP(intel, gl_texture_attrib, Texture); + DUP(intel, gl_transform_attrib, Transform); + DUP(intel, gl_viewport_attrib, Viewport); + DUP(intel, gl_vertex_program_state, VertexProgram); + DUP(intel, gl_fragment_program_state, FragmentProgram); +} + +static void install_state( struct intel_context *intel ) +{ + INSTALL(intel, Color, _NEW_COLOR); + INSTALL(intel, Depth, _NEW_DEPTH); + INSTALL(intel, Fog, _NEW_FOG); + INSTALL(intel, Hint, _NEW_HINT); + INSTALL(intel, Light, _NEW_LIGHT); + INSTALL(intel, Line, _NEW_LINE); + INSTALL(intel, Point, _NEW_POINT); + INSTALL(intel, Polygon, _NEW_POLYGON); + INSTALL(intel, Scissor, _NEW_SCISSOR); + INSTALL(intel, Stencil, _NEW_STENCIL); + INSTALL(intel, Texture, _NEW_TEXTURE); + INSTALL(intel, Transform, _NEW_TRANSFORM); + INSTALL(intel, Viewport, _NEW_VIEWPORT); + INSTALL(intel, VertexProgram, _NEW_PROGRAM); + INSTALL(intel, FragmentProgram, _NEW_PROGRAM); +} + +static void restore_state( struct intel_context *intel ) +{ + RESTORE(intel, Color, _NEW_COLOR); + RESTORE(intel, Depth, _NEW_DEPTH); + RESTORE(intel, Fog, _NEW_FOG); + RESTORE(intel, Hint, _NEW_HINT); + RESTORE(intel, Light, _NEW_LIGHT); + RESTORE(intel, Line, _NEW_LINE); + RESTORE(intel, Point, _NEW_POINT); + RESTORE(intel, Polygon, _NEW_POLYGON); + RESTORE(intel, Scissor, _NEW_SCISSOR); + RESTORE(intel, Stencil, _NEW_STENCIL); + RESTORE(intel, Texture, _NEW_TEXTURE); + RESTORE(intel, Transform, _NEW_TRANSFORM); + RESTORE(intel, Viewport, _NEW_VIEWPORT); + RESTORE(intel, VertexProgram, _NEW_PROGRAM); + RESTORE(intel, FragmentProgram, _NEW_PROGRAM); +} + +/* It would certainly be preferably to skip the vertex program step + * and go straight to post-transform draw. We can probably do that + * with the indexed-render code and after noting that fallbacks are + * never active during metaops. + */ +static const char *vp_prog_tex = + "!!ARBvp1.0\n" + "MOV result.texcoord[0], vertex.texcoord[0];\n" + "MOV result.color, vertex.color;\n" + "MOV result.position, vertex.position;\n" + "END\n"; + + +/* Because the texenv program is calculated from ctx derived state, + * and bypasses our intel->state attribute pointer mechanism, it won't + * be correctly calculated in metaops. So, we have to supply our own + * fragment programs to do the right thing: + */ +static const char *fp_prog = + "!!ARBfp1.0\n" + "MOV result.color, fragment.color;\n" + "END\n"; + +static const char *fp_tex_prog = + "!!ARBfp1.0\n" + "TEX result.color, fragment.texcoord[0], texture[0], 2D;\n" + "END\n"; + + +void intel_meta_flat_shade( struct intel_context *intel ) +{ + intel->metaops.state.Light->ShadeModel = GL_FLAT; + intel->state.dirty.mesa |= _NEW_LIGHT; +} + + +void intel_meta_no_stencil_write( struct intel_context *intel ) +{ + intel->metaops.state.Stencil->Enabled = GL_FALSE; + intel->metaops.state.Stencil->WriteMask[0] = GL_FALSE; + intel->state.dirty.mesa |= _NEW_STENCIL; +} + +void intel_meta_no_depth_write( struct intel_context *intel ) +{ + intel->metaops.state.Depth->Test = GL_FALSE; + intel->metaops.state.Depth->Mask = GL_FALSE; + intel->state.dirty.mesa |= _NEW_DEPTH; +} + + +void intel_meta_depth_replace( struct intel_context *intel ) +{ + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) + * ctx->Driver.DepthMask( ctx, GL_TRUE ) + */ + intel->metaops.state.Depth->Test = GL_TRUE; + intel->metaops.state.Depth->Mask = GL_TRUE; + intel->state.dirty.mesa |= _NEW_DEPTH; + + /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) + */ + intel->metaops.state.Depth->Func = GL_ALWAYS; + + intel->state.dirty.mesa |= _NEW_DEPTH; +} + + +void intel_meta_stencil_replace( struct intel_context *intel, + GLuint s_mask, + GLuint s_clear) +{ + intel->metaops.state.Stencil->Enabled = GL_TRUE; + intel->metaops.state.Stencil->WriteMask[0] = s_mask; + intel->metaops.state.Stencil->ValueMask[0] = 0xff; + intel->metaops.state.Stencil->Ref[0] = s_clear; + intel->metaops.state.Stencil->Function[0] = GL_ALWAYS; + intel->metaops.state.Stencil->FailFunc[0] = GL_REPLACE; + intel->metaops.state.Stencil->ZPassFunc[0] = GL_REPLACE; + intel->metaops.state.Stencil->ZFailFunc[0] = GL_REPLACE; + intel->state.dirty.mesa |= _NEW_STENCIL; +} + + +void intel_meta_color_mask( struct intel_context *intel, GLboolean state ) +{ + if (state) + COPY_4V(intel->metaops.state.Color->ColorMask, + intel->ctx.Color.ColorMask); + else + ASSIGN_4V(intel->metaops.state.Color->ColorMask, 0, 0, 0, 0); + + intel->state.dirty.mesa |= _NEW_COLOR; +} + +void intel_meta_no_texture( struct intel_context *intel ) +{ + intel->metaops.state.Texture->CurrentUnit = 0; + intel->metaops.state.Texture->_EnabledUnits = 0; + intel->metaops.state.Texture->_EnabledCoordUnits = 0; + intel->metaops.state.Texture->Unit[ 0 ].Enabled = 0; + intel->metaops.state.Texture->Unit[ 0 ]._ReallyEnabled = 0; + + intel->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM; +} + +void intel_meta_texture_blend_replace(struct intel_context *intel) +{ + intel->metaops.state.Texture->CurrentUnit = 0; + intel->metaops.state.Texture->_EnabledUnits = 1; + intel->metaops.state.Texture->_EnabledCoordUnits = 1; + intel->metaops.state.Texture->Unit[ 0 ].Enabled = TEXTURE_2D_BIT; + intel->metaops.state.Texture->Unit[ 0 ]._ReallyEnabled = TEXTURE_2D_BIT; +/* intel->metaops.state.Texture->Unit[ 0 ].Current2D = */ +/* intel->frame_buffer_texobj; */ +/* intel->metaops.state.Texture->Unit[ 0 ]._Current = */ +/* intel->frame_buffer_texobj; */ + + intel->state.dirty.mesa |= _NEW_TEXTURE | _NEW_PROGRAM; +} + +void intel_meta_import_pixel_state(struct intel_context *intel) +{ + RESTORE(intel, Color, _NEW_COLOR); + RESTORE(intel, Depth, _NEW_DEPTH); + RESTORE(intel, Fog, _NEW_FOG); + RESTORE(intel, Scissor, _NEW_SCISSOR); + RESTORE(intel, Stencil, _NEW_STENCIL); + RESTORE(intel, Texture, _NEW_TEXTURE); + RESTORE(intel, FragmentProgram, _NEW_PROGRAM); +} + + + +/* Set up an arbitary piece of memory as a rectangular texture + * (including the front or back buffer). + */ +GLboolean intel_meta_tex_rect_source(struct intel_context *intel, + struct _DriBufferObject *buffer, + GLuint offset, + GLuint pitch, GLuint height, + GLenum format, GLenum type) +{ + assert(0); +#if 0 + GLuint unit = 0; + GLint numLevels = 1; + GLuint *state = intel->meta.Tex[0]; + GLuint textureFormat; + GLuint cpp; + + /* A full implementation of this would do the upload through + * glTexImage2d, and get all the conversion operations at that + * point. We are restricted, but still at least have access to the + * fragment program swizzle. + */ + switch (format) { + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_BGR: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5_REV: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + + if ((pitch * cpp) & 3) { + _mesa_printf("%s: texture is not dword pitch\n", __FUNCTION__); + return GL_FALSE; + } + +/* intel_region_release(&intel->meta.tex_region[0]); */ +/* intel_region_reference(&intel->meta.tex_region[0], region); */ + intel->meta.tex_buffer[0] = buffer; + intel->meta.tex_offset[0] = offset; +#endif + + /* Don't do this, fill in the state objects as appropriate instead. + */ +#if 0 + state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | + ((pitch - 1) << MS3_WIDTH_SHIFT) | + textureFormat | MS3_USE_FENCE_REGS); + + state[I915_TEXREG_MS4] = (((((pitch * cpp) / 4) - 1) << MS4_PITCH_SHIFT) | + MS4_CUBE_FACE_ENA_MASK | + ((((numLevels - 1) * 4)) << MS4_MAX_LOD_SHIFT)); + + state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | + (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | + (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); + + state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | + (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); + + state[I915_TEXREG_SS4] = 0; + + i915->meta.emitted &= ~I915_UPLOAD_TEX(0); +#endif + + return GL_TRUE; +} + + + +void intel_meta_draw_region( struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region ) +{ +#if 0 + if (!intel->metaops.saved_draw_region) { + intel->metaops.saved_draw_region = intel->state.draw_region; + intel->metaops.saved_depth_region = intel->state.depth_region; + } + + intel->state.draw_region = draw_region; + intel->state.depth_region = depth_region; + + intel->state.dirty.mesa |= _NEW_BUFFERS; +#endif +} + + +/* Big problem is that tnl doesn't know about our internal + * state-swaping mechanism so wouldn't respect it if we passed this + * here. That *should* get fixed by pushing the state mechanism + * higher into mesa, but I haven't got there yet. In the meantime, + */ +void +intel_meta_draw_poly(struct intel_context *intel, + GLuint n, + GLfloat xy[][2], + GLfloat z, GLuint color, GLfloat tex[][2]) +{ + GLint sz; + GLint i; + + intel_emit_state( intel ); + + sz = intel->vertex_size; + + /* All 3d primitives should be emitted with INTEL_BATCH_CLIPRECTS, + * otherwise the drawing origin (DR4) might not be set correctly. + */ + BEGIN_BATCH(2+n*sz, INTEL_BATCH_CLIPRECTS); + + OUT_BATCH( _3DPRIMITIVE | + PRIM3D_TRIFAN | + (n * intel->vertex_size - 1 )); + + + for (i = 0; i < n; i++) { + OUT_BATCH_F( xy[i][0] ); + OUT_BATCH_F( xy[i][1] ); + OUT_BATCH_F( z ); + OUT_BATCH( color ); + if (intel->vertex_size == 6) { + OUT_BATCH_F( tex[i][0] ); + OUT_BATCH_F( tex[i][1] ); + } + else { + assert(intel->vertex_size == 4); + } + } + ADVANCE_BATCH(); +} + +void +intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1) +{ + GLfloat xy[4][2]; + GLfloat tex[4][2]; + + xy[0][0] = x0; + xy[0][1] = y0; + xy[1][0] = x1; + xy[1][1] = y0; + xy[2][0] = x1; + xy[2][1] = y1; + xy[3][0] = x0; + xy[3][1] = y1; + + tex[0][0] = s0; + tex[0][1] = t0; + tex[1][0] = s1; + tex[1][1] = t0; + tex[2][0] = s1; + tex[2][1] = t1; + tex[3][0] = s0; + tex[3][1] = t1; + + intel_meta_draw_poly(intel, 4, xy, z, color, tex); +} + + +void intel_install_meta_state( struct intel_context *intel ) +{ + assert(0); + + install_state(intel); + + intel_meta_no_texture(intel); + intel_meta_flat_shade(intel); + +/* intel->metaops.restore_draw_mask = ctx->DrawBuffer->_ColorDrawBufferMask[0]; */ +/* intel->metaops.restore_fp = ctx->FragmentProgram.Current; */ + + /* This works without adjusting refcounts. Fix later? + */ +/* intel->metaops.saved_draw_region = intel->state.draw_region; */ +/* intel->metaops.saved_depth_region = intel->state.depth_region; */ + intel->metaops.active = 1; + + intel->state.dirty.intel |= INTEL_NEW_METAOPS; +} + +void intel_leave_meta_state( struct intel_context *intel ) +{ + restore_state(intel); + +/* ctx->DrawBuffer->_ColorDrawBufferMask[0] = intel->metaops.restore_draw_mask; */ +/* ctx->FragmentProgram.Current = intel->metaops.restore_fp; */ + +/* intel->state.draw_region = intel->metaops.saved_draw_region; */ +/* intel->state.depth_region = intel->metaops.saved_depth_region; */ +/* intel->metaops.saved_draw_region = NULL; */ +/* intel->metaops.saved_depth_region = NULL; */ + intel->metaops.active = 0; + + intel->state.dirty.mesa |= _NEW_BUFFERS; + intel->state.dirty.intel |= INTEL_NEW_METAOPS; +} + + + +void intel_metaops_init( struct intel_context *intel ) +{ +/* GLcontext *ctx = &intel->ctx; */ + + init_state(intel); + +#if 0 + intel->metaops.fp = (struct gl_fragment_program *) + ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 ); + + intel->metaops.fp_tex = (struct gl_fragment_program *) + ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1 ); + + _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB, + fp_prog, strlen(fp_prog), + intel->metaops.fp); + + _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB, + fp_tex_prog, strlen(fp_tex_prog), + intel->metaops.fp_tex); +#endif + +/* intel->metaops.state.VertexProgram->Current = intel->metaops.vp; */ +/* intel->metaops.state.VertexProgram->_Enabled = GL_TRUE; */ +} + +void intel_metaops_destroy( struct intel_context *intel ) +{ + GLcontext *ctx = &intel->ctx; + + if (intel->metaops.vbo) + ctx->Driver.DeleteBuffer( ctx, intel->metaops.vbo ); + +/* ctx->Driver.DeleteProgram( ctx, intel->metaops.vp ); */ +} diff --git a/src/mesa/drivers/dri/i915tex/intel_metaops.h b/src/mesa/drivers/dri/i915tex/intel_metaops.h new file mode 100644 index 0000000000..0a4f0969ac --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_metaops.h @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + +#ifndef INTEL_METAOPS_H +#define INTEL_METAOPS_H + +#include "glheader.h" + +struct intel_context; +struct intel_region; +struct _DriBufferObject; + +void intel_meta_draw_poly(struct intel_context *intel, + GLuint n, + GLfloat xy[][2], + GLfloat z, GLuint color, GLfloat tex[][2]); + +void intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1); + +void intel_meta_draw_region( struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region ); + +GLboolean intel_meta_tex_rect_source(struct intel_context *intel, + struct _DriBufferObject *buffer, + GLuint offset, + GLuint pitch, GLuint height, + GLenum format, GLenum type); + +void intel_meta_import_pixel_state(struct intel_context *intel); + +void intel_meta_texture_blend_replace(struct intel_context *intel); + +void intel_meta_no_texture( struct intel_context *intel ); + +void intel_meta_color_mask( struct intel_context *intel, GLboolean state ); + +void intel_meta_stencil_replace( struct intel_context *intel, + GLuint s_mask, + GLuint s_clear); + +void intel_meta_depth_replace( struct intel_context *intel ); + +void intel_meta_no_depth_write( struct intel_context *intel ); + +void intel_meta_no_stencil_write( struct intel_context *intel ); + +void intel_meta_flat_shade( struct intel_context *intel ); + +void intel_install_meta_state( struct intel_context *intel ); +void intel_leave_meta_state( struct intel_context *intel ); + +void intel_metaops_init( struct intel_context *intel ); +void intel_metaops_destroy( struct intel_context *intel ); + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c index 9d478283e4..87bc0fc354 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c @@ -42,6 +42,7 @@ #include "intel_regions.h" #include "intel_tris.h" #include "intel_pixel.h" +#include "intel_metaops.h" #define FILE_DEBUG_FLAG DEBUG_PIXEL @@ -154,19 +155,19 @@ do_texture_copypixels(GLcontext * ctx, intelFlush(&intel->ctx); - intel->vtbl.install_meta_state(intel); + intel_install_meta_state(intel); /* Is this true? Also will need to turn depth testing on according * to state: */ - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_no_depth_write(intel); + intel_meta_no_stencil_write(intel); + intel_meta_no_depth_write(intel); /* Set the 3d engine to draw into the destination region: */ - intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + intel_meta_draw_region(intel, dst, intel->intelScreen->depth_region); - intel->vtbl.meta_import_pixel_state(intel); + intel_meta_import_pixel_state(intel); if (src->cpp == 2) { src_format = GL_RGB; @@ -179,15 +180,15 @@ do_texture_copypixels(GLcontext * ctx, /* Set the frontbuffer up as a large rectangular texture. */ - if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0, + if (!intel_meta_tex_rect_source(intel, src->buffer, 0, src->pitch, src->height, src_format, src_type)) { - intel->vtbl.leave_meta_state(intel); + intel_leave_meta_state(intel); return GL_FALSE; } - intel->vtbl.meta_texture_blend_replace(intel); + intel_meta_texture_blend_replace(intel); LOCK_HARDWARE(intel); @@ -229,7 +230,7 @@ do_texture_copypixels(GLcontext * ctx, srcx, srcx + width, srcy, srcy + height); out: - intel->vtbl.leave_meta_state(intel); + intel_leave_meta_state(intel); intel_batchbuffer_flush(intel->batch); } UNLOCK_HARDWARE(intel); diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c index 10a079896a..297e2222d9 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c @@ -43,6 +43,7 @@ #include "intel_pixel.h" #include "intel_buffer_objects.h" #include "intel_tris.h" +#include "intel_metaops.h" @@ -64,8 +65,7 @@ do_texture_drawpixels(GLcontext * ctx, fprintf(stderr, "%s\n", __FUNCTION__); intelFlush(&intel->ctx); - intel->vtbl.render_start(intel); - intel->vtbl.emit_state(intel); + intel_emit_state(intel); if (!dst) return GL_FALSE; @@ -101,20 +101,20 @@ do_texture_drawpixels(GLcontext * ctx, return GL_FALSE; } - intel->vtbl.install_meta_state(intel); + intel_install_meta_state(intel); /* Is this true? Also will need to turn depth testing on according * to state: */ - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_no_depth_write(intel); + intel_meta_no_stencil_write(intel); + intel_meta_no_depth_write(intel); /* Set the 3d engine to draw into the destination region: */ - intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + intel_meta_draw_region(intel, dst, intel->intelScreen->depth_region); - intel->vtbl.meta_import_pixel_state(intel); + intel_meta_import_pixel_state(intel); src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, format, type, 0, 0, 0); @@ -127,13 +127,13 @@ do_texture_drawpixels(GLcontext * ctx, * The major exception is any 24bit texture, like RGB888, for which * there is no hardware support. */ - if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, src_offset, + if (!intel_meta_tex_rect_source(intel, src->buffer, src_offset, rowLength, height, format, type)) { - intel->vtbl.leave_meta_state(intel); + intel_leave_meta_state(intel); return GL_FALSE; } - intel->vtbl.meta_texture_blend_replace(intel); + intel_meta_texture_blend_replace(intel); LOCK_HARDWARE(intel); @@ -178,7 +178,7 @@ do_texture_drawpixels(GLcontext * ctx, 0x00ff00ff, srcx, srcx + width, srcy + height, srcy); out: - intel->vtbl.leave_meta_state(intel); + intel_leave_meta_state(intel); intel_batchbuffer_flush(intel->batch); } UNLOCK_HARDWARE(intel); diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c index 24e49ae066..13b69dc776 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c @@ -94,9 +94,9 @@ do_texture_readpixels(GLcontext * ctx, return GL_FALSE; } - intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); + intel_meta_texrect_source(intel, intel_readbuf_region(intel)); - if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { + if (!intel_meta_render_dest(intel, dest_region, type, format)) { if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s: couldn't set dest %s/%s\n", __FUNCTION__, @@ -108,9 +108,9 @@ do_texture_readpixels(GLcontext * ctx, 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); + intel_install_meta_state(intel); + intel_meta_no_depth_write(intel); + intel_meta_no_stencil_write(intel); if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { UNLOCK_HARDWARE(intel); @@ -127,28 +127,28 @@ do_texture_readpixels(GLcontext * ctx, /* Set the frontbuffer up as a large rectangular texture. */ - intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); + intel_meta_tex_rect_source(intel, src_region, textureFormat); - intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); + intel_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); /* ?? */ + intel_meta_draw_region(intel, dest_region); + intel_meta_draw_format(intel, destFormat, depthFormat); /* ?? */ /* Draw a single quad, no cliprects: */ - intel->vtbl.meta_disable_cliprects(intel); + intel_meta_disable_cliprects(intel); - intel->vtbl.draw_quad(intel, + intel_draw_quad(intel, 0, width, 0, height, 0x00ff00ff, x, x + width, y, y + height); - intel->vtbl.leave_meta_state(intel); + intel_leave_meta_state(intel); } UNLOCK_HARDWARE(intel); diff --git a/src/mesa/drivers/dri/i915tex/intel_program.c b/src/mesa/drivers/dri/i915tex/intel_program.c new file mode 100644 index 0000000000..e54b600667 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_program.c @@ -0,0 +1,269 @@ +/************************************************************************** + * + * 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 "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "intel_batchbuffer.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_fp.h" + +#include "program_instruction.h" +#include "program.h" +#include "programopt.h" + + +static void brwBindProgram( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) +{ + struct brw_context *brw = brw_context(ctx); + + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; + break; + case GL_FRAGMENT_PROGRAM_ARB: + brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; + break; + } +} + +static struct gl_program *brwNewProgram( GLcontext *ctx, + GLenum target, + GLuint id ) +{ + struct brw_context *brw = brw_context(ctx); + + switch (target) { + case GL_VERTEX_PROGRAM_ARB: { + struct brw_vertex_program *prog = CALLOC_STRUCT(brw_vertex_program); + if (prog) { + prog->id = brw->program_id++; + + return _mesa_init_vertex_program( ctx, &prog->program, + target, id ); + } + else + return NULL; + } + + case GL_FRAGMENT_PROGRAM_ARB: { + struct brw_fragment_program *prog = CALLOC_STRUCT(brw_fragment_program); + if (prog) { + prog->id = brw->program_id++; + + return _mesa_init_fragment_program( ctx, &prog->program, + target, id ); + } + else + return NULL; + } + + default: + return _mesa_new_program(ctx, target, id); + } +} + +static void brwDeleteProgram( GLcontext *ctx, + struct gl_program *prog ) +{ + + _mesa_delete_program( ctx, prog ); +} + + +static GLboolean brwIsProgramNative( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) +{ + return GL_TRUE; +} + +static void brwProgramStringNotify( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct brw_context *brw = brw_context(ctx); + struct brw_fragment_program *p = (struct brw_fragment_program *)prog; + struct brw_fragment_program *fp = (struct brw_fragment_program *)brw->fragment_program; + if (p == fp) + brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; + p->id = brw->program_id++; + p->param_state = brw_parameter_list_state_flags(p->program.Base.Parameters); + } + else if (target == GL_VERTEX_PROGRAM_ARB) { + struct brw_context *brw = brw_context(ctx); + struct brw_vertex_program *p = (struct brw_vertex_program *)prog; + struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program; + if (p == vp) + brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; + p->id = brw->program_id++; + p->param_state = brw_parameter_list_state_flags(p->program.Base.Parameters); + + /* Also tell tnl about it: + */ + _tnl_program_string(ctx, target, prog); + } +} + +void brwInitFragProgFuncs( struct dd_function_table *functions ) +{ + assert(functions->ProgramStringNotify == _tnl_program_string); + + functions->BindProgram = brwBindProgram; + functions->NewProgram = brwNewProgram; + functions->DeleteProgram = brwDeleteProgram; + functions->IsProgramNative = brwIsProgramNative; + functions->ProgramStringNotify = brwProgramStringNotify; +} + + + + +static void +i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = I915_CONTEXT(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (i915->current_program == p) + return; + + i915->current_program = p; + + assert(p->on_hardware == 0); + assert(p->params_uptodate == 0); + + /* Hack: make sure fog is correctly enabled according to this + * fragment program's fog options. + */ + ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, + ctx->FragmentProgram.Enabled); + } +} + +static struct gl_program * +i915NewProgram(GLcontext * ctx, GLenum target, GLuint id) +{ + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), + target, id); + + case GL_FRAGMENT_PROGRAM_ARB:{ + struct i915_fragment_program *prog = + CALLOC_STRUCT(i915_fragment_program); + if (prog) { + i915_init_program(I915_CONTEXT(ctx), prog); + + return _mesa_init_fragment_program(ctx, &prog->FragProg, + target, id); + } + else + return NULL; + } + + default: + /* Just fallback: + */ + return _mesa_new_program(ctx, target, id); + } +} + +static void +i915DeleteProgram(GLcontext * ctx, struct gl_program *prog) +{ + if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = I915_CONTEXT(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (i915->current_program == p) + i915->current_program = 0; + } + + _mesa_delete_program(ctx, prog); +} + + +static GLboolean +i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (!p->translated) + translate_program(p); + + return !p->error; + } + else + return GL_TRUE; +} + +static void +i915ProgramStringNotify(GLcontext * ctx, + GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + p->translated = 0; + + /* Hack: make sure fog is correctly enabled according to this + * fragment program's fog options. + */ + ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, + ctx->FragmentProgram.Enabled); + + if (p->FragProg.FogOption) { + /* add extra instructions to do fog, then turn off FogOption field */ + _mesa_append_fog_code(ctx, &p->FragProg); + p->FragProg.FogOption = GL_NONE; + } + } + + _tnl_program_string(ctx, target, prog); +} + + + +void +i915InitFragProgFuncs(struct dd_function_table *functions) +{ + functions->BindProgram = i915BindProgram; + functions->NewProgram = i915NewProgram; + functions->DeleteProgram = i915DeleteProgram; + functions->IsProgramNative = i915IsProgramNative; + functions->ProgramStringNotify = i915ProgramStringNotify; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_reg.h b/src/mesa/drivers/dri/i915tex/intel_reg.h index 1ec153266c..b5a1a20eaf 100644 --- a/src/mesa/drivers/dri/i915tex/intel_reg.h +++ b/src/mesa/drivers/dri/i915tex/intel_reg.h @@ -81,4 +81,60 @@ #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define COMPAREFUNC_ALWAYS 0 +#define COMPAREFUNC_NEVER 0x1 +#define COMPAREFUNC_LESS 0x2 +#define COMPAREFUNC_EQUAL 0x3 +#define COMPAREFUNC_LEQUAL 0x4 +#define COMPAREFUNC_GREATER 0x5 +#define COMPAREFUNC_NOTEQUAL 0x6 +#define COMPAREFUNC_GEQUAL 0x7 + +#define STENCILOP_KEEP 0 +#define STENCILOP_ZERO 0x1 +#define STENCILOP_REPLACE 0x2 +#define STENCILOP_INCRSAT 0x3 +#define STENCILOP_DECRSAT 0x4 +#define STENCILOP_INCR 0x5 +#define STENCILOP_DECR 0x6 +#define STENCILOP_INVERT 0x7 + +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf + +#define BLENDFACT_ZERO 0x01 +#define BLENDFACT_ONE 0x02 +#define BLENDFACT_SRC_COLR 0x03 +#define BLENDFACT_INV_SRC_COLR 0x04 +#define BLENDFACT_SRC_ALPHA 0x05 +#define BLENDFACT_INV_SRC_ALPHA 0x06 +#define BLENDFACT_DST_ALPHA 0x07 +#define BLENDFACT_INV_DST_ALPHA 0x08 +#define BLENDFACT_DST_COLR 0x09 +#define BLENDFACT_INV_DST_COLR 0x0a +#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b +#define BLENDFACT_CONST_COLOR 0x0c +#define BLENDFACT_INV_CONST_COLOR 0x0d +#define BLENDFACT_CONST_ALPHA 0x0e +#define BLENDFACT_INV_CONST_ALPHA 0x0f +#define BLENDFACT_MASK 0x0f + +#define MI_BATCH_BUFFER_END (0xA<<23) + + #endif diff --git a/src/mesa/drivers/dri/i915tex/intel_render.c b/src/mesa/drivers/dri/i915tex/intel_render.c index f9fa55051e..148a486266 100644 --- a/src/mesa/drivers/dri/i915tex/intel_render.c +++ b/src/mesa/drivers/dri/i915tex/intel_render.c @@ -112,7 +112,7 @@ intelDmaPrimitive(struct intel_context *intel, GLenum prim) if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); INTEL_FIREVERTICES(intel); - intel->vtbl.reduced_primitive_state(intel, reduced_prim[prim]); +/* intel->vtbl.reduced_primitive_state(intel, reduced_prim[prim]); */ intelStartInlinePrimitive(intel, hw_prim[prim], INTEL_BATCH_CLIPRECTS); } diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index efa1b014a6..8a4c1194c0 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -108,21 +108,11 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) return GL_FALSE; } -#if 0 - _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *) & intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } -#endif if (0) - printf("Mappings: front: %p back: %p depth: %p tex: %p\n", + printf("Mappings: front: %p back: %p depth: %p\n", intelScreen->front.map, intelScreen->back.map, - intelScreen->depth.map, intelScreen->tex.map); + intelScreen->depth.map); return GL_TRUE; } @@ -246,12 +236,6 @@ intelUnmapScreenRegions(intelScreenPrivate * intelScreen) intelScreen->depth.map = NULL; #endif } - if (intelScreen->tex.map) { -#if REALLY_UNMAP - drmUnmap(intelScreen->tex.map, intelScreen->tex.size); - intelScreen->tex.map = NULL; -#endif - } } @@ -271,8 +255,6 @@ intelPrintDRIInfo(intelScreenPrivate * intelScreen, fprintf(stderr, "*** Rotated size: 0x%x offset: 0x%x pitch: %d\n", intelScreen->rotated.size, intelScreen->rotated.offset, intelScreen->rotated.pitch); - fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n", - intelScreen->tex.size, intelScreen->tex.offset); fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); } @@ -330,11 +312,6 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, intelScreen->depth.handle = sarea->depth_handle; intelScreen->depth.size = sarea->depth_size; - intelScreen->tex.offset = sarea->tex_offset; - intelScreen->logTextureGranularity = sarea->log_tex_granularity; - intelScreen->tex.handle = sarea->tex_handle; - intelScreen->tex.size = sarea->tex_size; - intelScreen->rotated.offset = sarea->rotated_offset; intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp; intelScreen->rotated.size = sarea->rotated_size; @@ -401,7 +378,7 @@ intelInitDriver(__DRIscreenPrivate * sPriv) intelScreen->fbFormat = DV_PF_8888; break; default: - exit(1); + assert(0); break; } @@ -414,24 +391,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) return GL_FALSE; } -#if 0 - - /* - * FIXME: Remove this code and its references. - */ - - intelScreen->tex.offset = gDRIPriv->textureOffset; - intelScreen->logTextureGranularity = gDRIPriv->logTextureGranularity; - intelScreen->tex.handle = gDRIPriv->textures; - intelScreen->tex.size = gDRIPriv->textureSize; - -#else - intelScreen->tex.offset = 0; - intelScreen->logTextureGranularity = 0; - intelScreen->tex.handle = 0; - intelScreen->tex.size = 0; -#endif - intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; if (0) @@ -455,22 +414,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) } } - /* Determine if batchbuffers are allowed */ - { - int ret; - drmI830GetParam gp; - - gp.param = I830_PARAM_ALLOW_BATCHBUFFER; - gp.value = &intelScreen->allow_batchbuffer; - - ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, - &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret); - return GL_FALSE; - } - } - if (glx_enable_extension != NULL) { (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); @@ -670,7 +613,8 @@ intelCreateContext(const __GLcontextModes * mesaVis, case PCI_CHIP_I830_M: case PCI_CHIP_I855_GM: case PCI_CHIP_I865_G: - return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); +/* return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); */ + return GL_FALSE; case PCI_CHIP_I915_G: case PCI_CHIP_I915_GM: diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h index 17698773f3..99b18ca578 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.h +++ b/src/mesa/drivers/dri/i915tex/intel_screen.h @@ -53,7 +53,6 @@ typedef struct intelRegion back; intelRegion rotated; intelRegion depth; - intelRegion tex; struct intel_region *front_region; struct intel_region *back_region; @@ -66,18 +65,14 @@ typedef struct int mem; /* unused */ int cpp; /* for front and back buffers */ -/* int bitsPerPixel; */ int fbFormat; /* XXX FBO: this is obsolete - remove after i830 updates */ - int logTextureGranularity; - __DRIscreenPrivate *driScrnPriv; unsigned int sarea_priv_offset; int drmMinor; int irq_active; - int allow_batchbuffer; struct matrix23 rotMatrix; diff --git a/src/mesa/drivers/dri/i915tex/intel_state.c b/src/mesa/drivers/dri/i915tex/intel_state.c index f85d8ef835..573c6bdc16 100644 --- a/src/mesa/drivers/dri/i915tex/intel_state.c +++ b/src/mesa/drivers/dri/i915tex/intel_state.c @@ -39,325 +39,119 @@ #include "intel_regions.h" #include "swrast/swrast.h" -int -intel_translate_compare_func(GLenum func) -{ - switch (func) { - case GL_NEVER: - return COMPAREFUNC_NEVER; - case GL_LESS: - return COMPAREFUNC_LESS; - case GL_LEQUAL: - return COMPAREFUNC_LEQUAL; - case GL_GREATER: - return COMPAREFUNC_GREATER; - case GL_GEQUAL: - return COMPAREFUNC_GEQUAL; - case GL_NOTEQUAL: - return COMPAREFUNC_NOTEQUAL; - case GL_EQUAL: - return COMPAREFUNC_EQUAL; - case GL_ALWAYS: - return COMPAREFUNC_ALWAYS; - } - - fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); - return COMPAREFUNC_ALWAYS; -} - -int -intel_translate_stencil_op(GLenum op) -{ - switch (op) { - case GL_KEEP: - return STENCILOP_KEEP; - case GL_ZERO: - return STENCILOP_ZERO; - case GL_REPLACE: - return STENCILOP_REPLACE; - case GL_INCR: - return STENCILOP_INCRSAT; - case GL_DECR: - return STENCILOP_DECRSAT; - case GL_INCR_WRAP: - return STENCILOP_INCR; - case GL_DECR_WRAP: - return STENCILOP_DECR; - case GL_INVERT: - return STENCILOP_INVERT; - default: - return STENCILOP_ZERO; - } -} +/*********************************************************************** + */ -int -intel_translate_blend_factor(GLenum factor) +static GLboolean check_state( const struct intel_state_flags *a, + const struct intel_state_flags *b ) { - switch (factor) { - case GL_ZERO: - return BLENDFACT_ZERO; - case GL_SRC_ALPHA: - return BLENDFACT_SRC_ALPHA; - case GL_ONE: - return BLENDFACT_ONE; - case GL_SRC_COLOR: - return BLENDFACT_SRC_COLR; - case GL_ONE_MINUS_SRC_COLOR: - return BLENDFACT_INV_SRC_COLR; - case GL_DST_COLOR: - return BLENDFACT_DST_COLR; - case GL_ONE_MINUS_DST_COLOR: - return BLENDFACT_INV_DST_COLR; - case GL_ONE_MINUS_SRC_ALPHA: - return BLENDFACT_INV_SRC_ALPHA; - case GL_DST_ALPHA: - return BLENDFACT_DST_ALPHA; - case GL_ONE_MINUS_DST_ALPHA: - return BLENDFACT_INV_DST_ALPHA; - case GL_SRC_ALPHA_SATURATE: - return BLENDFACT_SRC_ALPHA_SATURATE; - case GL_CONSTANT_COLOR: - return BLENDFACT_CONST_COLOR; - case GL_ONE_MINUS_CONSTANT_COLOR: - return BLENDFACT_INV_CONST_COLOR; - case GL_CONSTANT_ALPHA: - return BLENDFACT_CONST_ALPHA; - case GL_ONE_MINUS_CONSTANT_ALPHA: - return BLENDFACT_INV_CONST_ALPHA; - } - - fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor); - return BLENDFACT_ZERO; + return ((a->mesa & b->mesa) || + (a->intel & b->intel) || + (a->extra & b->extra)); } -int -intel_translate_logic_op(GLenum opcode) +static void accumulate_state( struct intel_state_flags *a, + const struct intel_state_flags *b ) { - switch (opcode) { - case GL_CLEAR: - return LOGICOP_CLEAR; - case GL_AND: - return LOGICOP_AND; - case GL_AND_REVERSE: - return LOGICOP_AND_RVRSE; - case GL_COPY: - return LOGICOP_COPY; - case GL_COPY_INVERTED: - return LOGICOP_COPY_INV; - case GL_AND_INVERTED: - return LOGICOP_AND_INV; - case GL_NOOP: - return LOGICOP_NOOP; - case GL_XOR: - return LOGICOP_XOR; - case GL_OR: - return LOGICOP_OR; - case GL_OR_INVERTED: - return LOGICOP_OR_INV; - case GL_NOR: - return LOGICOP_NOR; - case GL_EQUIV: - return LOGICOP_EQUIV; - case GL_INVERT: - return LOGICOP_INV; - case GL_OR_REVERSE: - return LOGICOP_OR_RVRSE; - case GL_NAND: - return LOGICOP_NAND; - case GL_SET: - return LOGICOP_SET; - default: - return LOGICOP_SET; - } + a->mesa |= b->mesa; + a->intel |= b->intel; + a->extra |= b->extra; } -static void -intelClearColor(GLcontext * ctx, const GLfloat color[4]) +static void xor_states( struct intel_state_flags *result, + const struct intel_state_flags *a, + const struct intel_state_flags *b ) { - struct intel_context *intel = intel_context(ctx); - GLubyte clear[4]; - - CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); - CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); - - /* compute both 32 and 16-bit clear values */ - intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], - clear[2], clear[3]); - intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); + result->mesa = a->mesa ^ b->mesa; + result->intel = a->intel ^ b->intel; + result->extra = a->extra ^ b->extra; } -/** - * Update the viewport transformation matrix. Depends on: - * - viewport pos/size - * - depthrange - * - window pos/size or FBO size +/*********************************************************************** + * Emit all state: */ -static void -intelCalcViewport(GLcontext * ctx) +void intel_emit_state( struct intel_context *intel ) { - struct intel_context *intel = intel_context(ctx); - const GLfloat *v = ctx->Viewport._WindowMap.m; - const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; - GLfloat *m = intel->ViewportMatrix.m; - GLfloat yScale, yBias; + struct intel_state_flags *state = &intel->state.dirty; + GLuint i; - if (ctx->DrawBuffer->Name) { - /* User created FBO */ - struct intel_renderbuffer *irb - = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]); - if (irb && !irb->RenderToTexture) { - /* y=0=top */ - yScale = -1.0; - yBias = irb->Base.Height; - } - else { - /* y=0=bottom */ - yScale = 1.0; - yBias = 0.0; + if (state->intel == 0) + return; + + if (!intel->metaops.active) { + intel->state.DrawBuffer = intel->ctx.DrawBuffer; + intel->state.ReadBuffer = intel->ctx.ReadBuffer; + intel->state.RenderMode = intel->ctx.RenderMode; + intel->state._ColorDrawBufferMask0 = intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]; + } + + if (INTEL_DEBUG) { + /* Debug version which enforces various sanity checks on the + * state flags which are generated and checked to help ensure + * state atoms are ordered correctly in the list. + */ + struct intel_state_flags examined, prev; + _mesa_memset(&examined, 0, sizeof(examined)); + prev = *state; + + for (i = 0; i < intel->driver_state.nr_atoms; i++) { + const struct intel_tracked_state *atom = intel->driver_state.atoms[i]; + struct intel_state_flags generated; + + assert(atom->dirty.mesa || + atom->dirty.intel || + atom->dirty.extra); + assert(atom->update); + + if (check_state(state, &atom->dirty)) { + intel->driver_state.atoms[i]->update( intel ); + } + + accumulate_state(&examined, &atom->dirty); + + /* generated = (prev ^ state) + * if (examined & generated) + * fail; + */ + xor_states(&generated, &prev, state); + assert(!check_state(&examined, &generated)); + prev = *state; } } else { - /* window buffer, y=0=top */ - yScale = -1.0; - yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F; - } - - m[MAT_SX] = v[MAT_SX]; - m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; - - m[MAT_SY] = v[MAT_SY] * yScale; - m[MAT_TY] = v[MAT_TY] * yScale + yBias + SUBPIXEL_Y; - - m[MAT_SZ] = v[MAT_SZ] * depthScale; - m[MAT_TZ] = v[MAT_TZ] * depthScale; -} - -static void -intelViewport(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height) -{ - intelCalcViewport(ctx); -} - -static void -intelDepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) -{ - intelCalcViewport(ctx); -} - -/* Fallback to swrast for select and feedback. - */ -static void -intelRenderMode(GLcontext * ctx, GLenum mode) -{ - struct intel_context *intel = intel_context(ctx); - FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER)); -} + const GLuint nr = intel->driver_state.nr_atoms; + for (i = 0; i < nr; i++) { + if (check_state(state, &intel->driver_state.atoms[i]->dirty)) + intel->driver_state.atoms[i]->update( intel ); + } + } -void -intelInitStateFuncs(struct dd_function_table *functions) -{ - functions->RenderMode = intelRenderMode; - functions->Viewport = intelViewport; - functions->DepthRange = intelDepthRange; - functions->ClearColor = intelClearColor; + memset(state, 0, sizeof(*state)); } - -void -intelInitState(GLcontext * ctx) +void intel_state_init( struct intel_context *intel ) { - /* Mesa should do this for us: - */ - ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); - - ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); - - ctx->Driver.BlendEquationSeparate(ctx, - ctx->Color.BlendEquationRGB, - ctx->Color.BlendEquationA); - - ctx->Driver.BlendFuncSeparate(ctx, - ctx->Color.BlendSrcRGB, - ctx->Color.BlendDstRGB, - ctx->Color.BlendSrcA, ctx->Color.BlendDstA); - - ctx->Driver.ColorMask(ctx, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP]); - - ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode); - ctx->Driver.DepthFunc(ctx, ctx->Depth.Func); - ctx->Driver.DepthMask(ctx, ctx->Depth.Mask); - - ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); - ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled); - ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled); - ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled); - ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag); - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); - ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag); - ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled); - ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled); - ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag); - ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag); - ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled); - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); - - ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); - ctx->Driver.Fogfv(ctx, GL_FOG_MODE, 0); - ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); - ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); - ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); - - ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); - - { - GLfloat f = (GLfloat) ctx->Light.Model.ColorControl; - ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f); - } - - ctx->Driver.LineWidth(ctx, ctx->Line.Width); - ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp); - ctx->Driver.PointSize(ctx, ctx->Point.Size); - ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple); - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); - ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel); - ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, - ctx->Stencil.Function[0], - ctx->Stencil.Ref[0], - ctx->Stencil.ValueMask[0]); - ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, - ctx->Stencil.Function[1], - ctx->Stencil.Ref[1], - ctx->Stencil.ValueMask[1]); - ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]); - ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]); - ctx->Driver.StencilOpSeparate(ctx, GL_FRONT, - ctx->Stencil.FailFunc[0], - ctx->Stencil.ZFailFunc[0], - ctx->Stencil.ZPassFunc[0]); - ctx->Driver.StencilOpSeparate(ctx, GL_BACK, - ctx->Stencil.FailFunc[1], - ctx->Stencil.ZFailFunc[1], - ctx->Stencil.ZPassFunc[1]); - - - /* XXX this isn't really needed */ - ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]); + GLcontext *ctx = &intel->ctx; + + intel->state.Color = &ctx->Color; + intel->state.Depth = &ctx->Depth; + intel->state.Fog = &ctx->Fog; + intel->state.Hint = &ctx->Hint; + intel->state.Light = &ctx->Light; + intel->state.Line = &ctx->Line; + intel->state.Point = &ctx->Point; + intel->state.Polygon = &ctx->Polygon; + intel->state.Scissor = &ctx->Scissor; + intel->state.Stencil = &ctx->Stencil; + intel->state.Texture = &ctx->Texture; + intel->state.Transform = &ctx->Transform; + intel->state.Viewport = &ctx->Viewport; + intel->state.VertexProgram = &ctx->VertexProgram; + intel->state.FragmentProgram = &ctx->FragmentProgram; + intel->state.PolygonStipple = &ctx->PolygonStipple[0]; } diff --git a/src/mesa/drivers/dri/i915tex/intel_state.h b/src/mesa/drivers/dri/i915tex/intel_state.h new file mode 100644 index 0000000000..1f71454334 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_state.h @@ -0,0 +1,46 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + +#ifndef INTEL_STATE_H +#define INTEL_STATE_H + +struct intel_context; +struct intel_tracked_state; + +void intel_state_init( struct intel_context *intel ); +void intel_emit_state( struct intel_context *intel ); + + +const struct intel_tracked_state intel_update_viewport; +const struct intel_tracked_state intel_update_render_index; + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_state_callbacks.c b/src/mesa/drivers/dri/i915tex/intel_state_callbacks.c new file mode 100644 index 0000000000..5c1f994c68 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_state_callbacks.c @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 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 "context.h" +#include "colormac.h" +#include "intel_context.h" +#include "intel_fbo.h" + + + + +/** + * Update the viewport transformation matrix. Depends on: + * - viewport pos/size + * - depthrange + * - window pos/size or FBO size + */ +static void update_viewport( struct intel_context *intel ) +{ + GLfloat yScale, yBias; + const GLframebuffer *DrawBuffer = intel->state.DrawBuffer; + + /* _NEW_BUFFERS + */ + if (DrawBuffer->Name) { + /* User created FBO */ + struct intel_renderbuffer *irb + = intel_renderbuffer(DrawBuffer->_ColorDrawBuffers[0][0]); + if (irb && !irb->RenderToTexture) { + /* y=0=top */ + yScale = -1.0; + yBias = irb->Base.Height; + } + else { + /* y=0=bottom */ + yScale = 1.0; + yBias = 0.0; + } + } + else { + /* window buffer, y=0=top */ + yScale = -1.0; + + /* INTEL_NEW_WINDOW_DIMENSIONS + * + * XXX: Note: this is only really valid while the lock is held. + * However, it is only invalidated when the window size changes, + * and when that happens we don't improve matters by noticing + * and adjusting the viewport halfway through a frame - it would + * actually be preferable to finish the frame with the same + * viewport origin as it started with. As it stands this does + * no real harm. + */ + yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F; + } + + { + /* _NEW_VIEWPORT + */ + const GLfloat *v = intel->state.Viewport->_WindowMap.m; + const GLfloat depthScale = 1.0F / DrawBuffer->_DepthMaxF; + GLfloat *m = intel->ViewportMatrix.m; + + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + + m[MAT_SY] = v[MAT_SY] * yScale; + m[MAT_TY] = v[MAT_TY] * yScale + yBias + SUBPIXEL_Y; + + m[MAT_SZ] = v[MAT_SZ] * depthScale; + m[MAT_TZ] = v[MAT_TZ] * depthScale; + + /* Raise a flag like INTEL_NEW_VIEWPORT? + */ + } +} + + +const struct intel_tracked_state intel_update_viewport = { + .dirty = { + .mesa = _NEW_BUFFERS | _NEW_VIEWPORT, + .intel = INTEL_NEW_WINDOW_DIMENSIONS, + .extra = 0 + }, + .update = update_viewport +}; diff --git a/src/mesa/drivers/dri/i915tex/intel_state_inlines.h b/src/mesa/drivers/dri/i915tex/intel_state_inlines.h new file mode 100644 index 0000000000..c19d9645b8 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_state_inlines.h @@ -0,0 +1,165 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef INTEL_STATE_INLINES_H +#define INTEL_STATE_INLINES_H + +#include "glheader.h" +#include "intel_reg.h" + + +static INLINE int +intel_translate_compare_func(GLenum func) +{ + switch (func) { + case GL_NEVER: + return COMPAREFUNC_NEVER; + case GL_LESS: + return COMPAREFUNC_LESS; + case GL_LEQUAL: + return COMPAREFUNC_LEQUAL; + case GL_GREATER: + return COMPAREFUNC_GREATER; + case GL_GEQUAL: + return COMPAREFUNC_GEQUAL; + case GL_NOTEQUAL: + return COMPAREFUNC_NOTEQUAL; + case GL_EQUAL: + return COMPAREFUNC_EQUAL; + case GL_ALWAYS: + return COMPAREFUNC_ALWAYS; + default: + return COMPAREFUNC_ALWAYS; + } +} + +static INLINE int +intel_translate_stencil_op(GLenum op) +{ + switch (op) { + case GL_KEEP: + return STENCILOP_KEEP; + case GL_ZERO: + return STENCILOP_ZERO; + case GL_REPLACE: + return STENCILOP_REPLACE; + case GL_INCR: + return STENCILOP_INCRSAT; + case GL_DECR: + return STENCILOP_DECRSAT; + case GL_INCR_WRAP: + return STENCILOP_INCR; + case GL_DECR_WRAP: + return STENCILOP_DECR; + case GL_INVERT: + return STENCILOP_INVERT; + default: + return STENCILOP_ZERO; + } +} + +static INLINE int +intel_translate_blend_factor(GLenum factor) +{ + switch (factor) { + case GL_ZERO: + return BLENDFACT_ZERO; + case GL_SRC_ALPHA: + return BLENDFACT_SRC_ALPHA; + case GL_ONE: + return BLENDFACT_ONE; + case GL_SRC_COLOR: + return BLENDFACT_SRC_COLR; + case GL_ONE_MINUS_SRC_COLOR: + return BLENDFACT_INV_SRC_COLR; + case GL_DST_COLOR: + return BLENDFACT_DST_COLR; + case GL_ONE_MINUS_DST_COLOR: + return BLENDFACT_INV_DST_COLR; + case GL_ONE_MINUS_SRC_ALPHA: + return BLENDFACT_INV_SRC_ALPHA; + case GL_DST_ALPHA: + return BLENDFACT_DST_ALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return BLENDFACT_INV_DST_ALPHA; + case GL_SRC_ALPHA_SATURATE: + return BLENDFACT_SRC_ALPHA_SATURATE; + case GL_CONSTANT_COLOR: + return BLENDFACT_CONST_COLOR; + case GL_ONE_MINUS_CONSTANT_COLOR: + return BLENDFACT_INV_CONST_COLOR; + case GL_CONSTANT_ALPHA: + return BLENDFACT_CONST_ALPHA; + case GL_ONE_MINUS_CONSTANT_ALPHA: + return BLENDFACT_INV_CONST_ALPHA; + default: + return BLENDFACT_ZERO; + } +} + +static INLINE int +intel_translate_logic_op(GLenum opcode) +{ + switch (opcode) { + case GL_CLEAR: + return LOGICOP_CLEAR; + case GL_AND: + return LOGICOP_AND; + case GL_AND_REVERSE: + return LOGICOP_AND_RVRSE; + case GL_COPY: + return LOGICOP_COPY; + case GL_COPY_INVERTED: + return LOGICOP_COPY_INV; + case GL_AND_INVERTED: + return LOGICOP_AND_INV; + case GL_NOOP: + return LOGICOP_NOOP; + case GL_XOR: + return LOGICOP_XOR; + case GL_OR: + return LOGICOP_OR; + case GL_OR_INVERTED: + return LOGICOP_OR_INV; + case GL_NOR: + return LOGICOP_NOR; + case GL_EQUIV: + return LOGICOP_EQUIV; + case GL_INVERT: + return LOGICOP_INV; + case GL_OR_REVERSE: + return LOGICOP_OR_RVRSE; + case GL_NAND: + return LOGICOP_NAND; + case GL_SET: + return LOGICOP_SET; + default: + return LOGICOP_SET; + } +} + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.h b/src/mesa/drivers/dri/i915tex/intel_tex.h index 6e9938fe53..4942ed003c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex.h +++ b/src/mesa/drivers/dri/i915tex/intel_tex.h @@ -33,6 +33,46 @@ #include "texmem.h" +struct intel_texture_object +{ + struct gl_texture_object base; /* The "parent" object */ + + /* The mipmap tree must include at least these levels once + * validated: + */ + GLuint firstLevel; + GLuint lastLevel; + + /* Offset for firstLevel image: + */ + GLuint textureOffset; + + /* On validation any active images held in main memory or in other + * regions will be copied to this region and the old storage freed. + */ + struct intel_mipmap_tree *mt; +}; + + + +struct intel_texture_image +{ + struct gl_texture_image base; + + /* These aren't stored in gl_texture_image + */ + GLuint level; + GLuint face; + + /* If intelImage->mt != NULL, image data is stored here. + * Else if intelImage->base.Data != NULL, image is stored there. + * Else there is no image data. + */ + struct intel_mipmap_tree *mt; +}; + + + void intelInitTextureFuncs(struct dd_function_table *functions); const struct gl_texture_format *intelChooseTextureFormat(GLcontext * ctx, diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.c b/src/mesa/drivers/dri/i915tex/intel_tris.c index aaf4d71b51..1341cb197c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tris.c +++ b/src/mesa/drivers/dri/i915tex/intel_tris.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "intel_span.h" #include "intel_tex.h" +#include "intel_state.h" static void intelRenderPrimitive(GLcontext * ctx, GLenum prim); static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim, @@ -88,7 +89,7 @@ intelStartInlinePrimitive(struct intel_context *intel, { BATCH_LOCALS; - intel->vtbl.emit_state(intel); + intel_emit_state(intel); /* Need to make sure at the very least that we don't wrap * batchbuffers in BEGIN_BATCH below, otherwise the primitive will @@ -98,7 +99,7 @@ intelStartInlinePrimitive(struct intel_context *intel, if (intel_batchbuffer_space(intel->batch, 0) < 100) { assert(0); /* XXX: later! */ intel_batchbuffer_flush(intel->batch); - intel->vtbl.emit_state(intel); + intel_emit_state(intel); } /* _mesa_printf("%s *", __progname); */ @@ -146,7 +147,7 @@ intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords) /* _mesa_printf("."); */ - intel->vtbl.assert_not_dirty(intel); + assert(intel->state.dirty.intel == 0); ptr = (GLuint *) (intel->batch->map + intel->batch->segment_finish_offset[0]); intel->batch->segment_finish_offset[0] += sz; @@ -160,7 +161,7 @@ intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords) * Emit primitives as inline vertices * ***********************************************************************/ -#ifdef __i386__ +#if !defined(DEBUG) && defined(__i386__) #define COPY_DWORDS( j, vb, vertsize, v ) \ do { \ int __tmp; \ @@ -175,6 +176,7 @@ do { \ do { \ for ( j = 0 ; j < vertsize ; j++ ) { \ vb[j] = ((GLuint *)v)[j]; \ + _mesa_printf("%d: %08x (%f)\n", j, vb[j], ((GLfloat *)v)[j]); \ } \ vb += vertsize; \ } while (0) @@ -753,76 +755,79 @@ intelFastRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) -#define ANY_FALLBACK_FLAGS (DD_LINE_STIPPLE | DD_TRI_STIPPLE | DD_POINT_ATTEN | DD_POINT_SMOOTH | DD_TRI_SMOOTH) -#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_TRI_UNFILLED) - -void -intelChooseRenderState(GLcontext * ctx) +static void update_render_index( struct intel_context *intel ) { + GLcontext *ctx = &intel->ctx; TNLcontext *tnl = TNL_CONTEXT(ctx); - struct intel_context *intel = intel_context(ctx); - GLuint flags = ctx->_TriangleCaps; + + /* INTEL_NEW_FRAGMENT_PROGRAM, XXX! + */ const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS)); GLuint index = 0; - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "\n%s\n", __FUNCTION__); + intel->draw_point = intel_draw_point; + intel->draw_line = intel_draw_line; + intel->draw_tri = intel_draw_triangle; - if ((flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) || have_wpos) { + /* _NEW_LIGHT + */ + if (intel->state.Light->Enabled && intel->state.Light->Model.TwoSide) + index |= INTEL_TWOSIDE_BIT; - if (flags & ANY_RASTER_FLAGS) { - if (flags & DD_TRI_LIGHT_TWOSIDE) - index |= INTEL_TWOSIDE_BIT; - if (flags & DD_TRI_OFFSET) - index |= INTEL_OFFSET_BIT; - if (flags & DD_TRI_UNFILLED) - index |= INTEL_UNFILLED_BIT; - } + /* _NEW_POLYGON + */ + if (intel->state.Polygon->OffsetPoint || + intel->state.Polygon->OffsetLine || + intel->state.Polygon->OffsetFill) + index |= INTEL_OFFSET_BIT; + + if (intel->state.Polygon->FrontMode != GL_FILL || + intel->state.Polygon->BackMode != GL_FILL) + index |= INTEL_UNFILLED_BIT; + + if (have_wpos) { + intel->draw_point = intel_wpos_point; + intel->draw_line = intel_wpos_line; + intel->draw_tri = intel_wpos_triangle; + + /* Make sure these get called: + */ + index |= INTEL_FALLBACK_BIT; + } - if (have_wpos) { - intel->draw_point = intel_wpos_point; - intel->draw_line = intel_wpos_line; - intel->draw_tri = intel_wpos_triangle; + /* _NEW_LINE + */ + if (intel->state.Line->StippleFlag) { + intel->draw_line = intel_fallback_line; + index |= INTEL_FALLBACK_BIT; + } + + /* INTEL_NEW_FALLBACK ?? _NEW_POLYGON_STIPPLE at least... + */ + if (intel->state.Polygon->StippleFlag && !intel->hw_stipple) { + intel->draw_tri = intel_fallback_tri; + index |= INTEL_FALLBACK_BIT; + } - /* Make sure these get called: - */ - index |= INTEL_FALLBACK_BIT; - } - else { - intel->draw_point = intel_draw_point; - intel->draw_line = intel_draw_line; - intel->draw_tri = intel_draw_triangle; - } + if (intel->state.Line->SmoothFlag && intel->strict_conformance) { + intel->draw_tri = intel_fallback_tri; + index |= INTEL_FALLBACK_BIT; + } - /* Hook in fallbacks for specific primitives. - */ - if (flags & ANY_FALLBACK_FLAGS) { - if (flags & DD_LINE_STIPPLE) - intel->draw_line = intel_fallback_line; - - if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple) - intel->draw_tri = intel_fallback_tri; - - if (flags & DD_TRI_SMOOTH) { - if (intel->strict_conformance) - intel->draw_tri = intel_fallback_tri; - } - - if (flags & DD_POINT_ATTEN) { - if (0) - intel->draw_point = intel_atten_point; - else - intel->draw_point = intel_fallback_point; - } - - if (flags & DD_POINT_SMOOTH) { - if (intel->strict_conformance) - intel->draw_point = intel_fallback_point; - } - - index |= INTEL_FALLBACK_BIT; - } + /* _NEW_POINT + */ + if (intel->state.Point->_Attenuated) { + if (0) + intel->draw_point = intel_atten_point; + else + intel->draw_point = intel_fallback_point; + index |= INTEL_FALLBACK_BIT; + } + + if (intel->state.Point->SmoothFlag && intel->strict_conformance) { + intel->draw_point = intel_fallback_point; + index |= INTEL_FALLBACK_BIT; } if (intel->RenderIndex != index) { @@ -848,6 +853,21 @@ intelChooseRenderState(GLcontext * ctx) } } + +const struct intel_tracked_state intel_update_render_index = { + .dirty = { + .mesa = (_NEW_LINE | + _NEW_POLYGON | + _NEW_LIGHT | + _NEW_POLYGONSTIPPLE), + + .intel = INTEL_NEW_FRAGMENT_PROGRAM, + .extra = 0 + }, + .update = update_render_index +}; + + static const GLenum reduced_prim[GL_POLYGON + 1] = { GL_POINTS, GL_LINES, @@ -879,18 +899,7 @@ intelRunPipeline(GLcontext * ctx) if (ctx->NewState) _mesa_update_state_locked(ctx); - if (intel->NewGLState) { - if (intel->NewGLState & _NEW_TEXTURE) { - intel->vtbl.update_texture_state(intel); - } - - if (!intel->Fallback) { - if (intel->NewGLState & _INTEL_NEW_RENDERSTATE) - intelChooseRenderState(ctx); - } - - intel->NewGLState = 0; - } + intel_emit_state( intel ); _tnl_run_pipeline(ctx); @@ -901,9 +910,11 @@ static void intelRenderStart(GLcontext * ctx) { struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; - intel->vtbl.render_start(intel_context(ctx)); - intel->vtbl.emit_state(intel); + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + intel_emit_state(intel); } static void @@ -915,6 +926,12 @@ intelRenderFinish(GLcontext * ctx) _swrast_flush(ctx); INTEL_FIREVERTICES(intel); + + if (intel->state.vbo) { + intel->state.vbo = 0; + intel->state.vbo_offset = 0; + } + } @@ -932,7 +949,12 @@ intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim) fprintf(stderr, "%s %s %x\n", __FUNCTION__, _mesa_lookup_enum_by_nr(rprim), hwprim); - intel->vtbl.reduced_primitive_state(intel, rprim); + if (intel->reduced_primitive != rprim) { + INTEL_FIREVERTICES(intel); + + intel->reduced_primitive = rprim; + intel->state.dirty.intel |= INTEL_NEW_REDUCED_PRIMITIVE; + } /* Start a new primitive. Arrange to have it flushed later on. */ @@ -1026,6 +1048,7 @@ intelFallback(struct intel_context *intel, GLuint bit, GLboolean mode) bit, getFallbackString(bit)); _swsetup_Wakeup(ctx); intel->RenderIndex = ~0; + intel->state.dirty.intel |= INTEL_NEW_FALLBACK; } } else { @@ -1048,7 +1071,7 @@ intelFallback(struct intel_context *intel, GLuint bit, GLboolean mode) intel->vertex_attr_count, intel->ViewportMatrix.m, 0); - intel->NewGLState |= _INTEL_NEW_RENDERSTATE; + intel->state.dirty.intel |= INTEL_NEW_FALLBACK; } } } @@ -1063,65 +1086,6 @@ union fi /**********************************************************************/ /* Used only with the metaops callbacks. */ /**********************************************************************/ -void -intel_meta_draw_poly(struct intel_context *intel, - GLuint n, - GLfloat xy[][2], - GLfloat z, GLuint color, GLfloat tex[][2]) -{ - union fi *vb; - GLint i; - - /* All 3d primitives should be emitted with INTEL_BATCH_CLIPRECTS, - * otherwise the drawing origin (DR4) might not be set correctly. - */ - intelStartInlinePrimitive(intel, PRIM3D_TRIFAN, INTEL_BATCH_CLIPRECTS); - vb = (union fi *) intelExtendInlinePrimitive(intel, n * 6); - - for (i = 0; i < n; i++) { - vb[0].f = xy[i][0]; - vb[1].f = xy[i][1]; - vb[2].f = z; - vb[3].i = color; - vb[4].f = tex[i][0]; - vb[5].f = tex[i][1]; - vb += 6; - } - - INTEL_FIREVERTICES(intel); -} - -void -intel_meta_draw_quad(struct intel_context *intel, - GLfloat x0, GLfloat x1, - GLfloat y0, GLfloat y1, - GLfloat z, - GLuint color, - GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1) -{ - GLfloat xy[4][2]; - GLfloat tex[4][2]; - - xy[0][0] = x0; - xy[0][1] = y0; - xy[1][0] = x1; - xy[1][1] = y0; - xy[2][0] = x1; - xy[2][1] = y1; - xy[3][0] = x0; - xy[3][1] = y1; - - tex[0][0] = s0; - tex[0][1] = t0; - tex[1][0] = s1; - tex[1][1] = t0; - tex[2][0] = s1; - tex[2][1] = t1; - tex[3][0] = s0; - tex[3][1] = t1; - - intel_meta_draw_poly(intel, 4, xy, z, color, tex); -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.h b/src/mesa/drivers/dri/i915tex/intel_tris.h index b7bae8cd3b..9ea5520c77 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tris.h +++ b/src/mesa/drivers/dri/i915tex/intel_tris.h @@ -32,14 +32,6 @@ -#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ - _DD_NEW_TRI_UNFILLED | \ - _DD_NEW_TRI_LIGHT_TWOSIDE | \ - _DD_NEW_TRI_OFFSET | \ - _DD_NEW_TRI_STIPPLE | \ - _NEW_PROGRAM | \ - _NEW_POLYGONSTIPPLE) - extern void intelInitTriFuncs(GLcontext * ctx); extern void intelChooseRenderState(GLcontext * ctx); @@ -51,19 +43,4 @@ extern void intelWrapInlinePrimitive(struct intel_context *intel); GLuint *intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords); - -void intel_meta_draw_quad(struct intel_context *intel, - GLfloat x0, GLfloat x1, - GLfloat y0, GLfloat y1, - GLfloat z, - GLuint color, - GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1); - -void intel_meta_draw_poly(struct intel_context *intel, - GLuint n, - GLfloat xy[][2], - GLfloat z, GLuint color, GLfloat tex[][2]); - - - #endif |