diff options
Diffstat (limited to 'src/gallium/drivers')
71 files changed, 3549 insertions, 780 deletions
| diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 512d85d352..bd48ce7005 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -86,6 +86,8 @@ cell_get_param(struct pipe_screen *screen, int param)        return 1; /* XXX not really true */     case PIPE_CAP_TEXTURE_MIRROR_CLAMP:        return 0; /* XXX to do */ +   case PIPE_CAP_TGSI_CONT_SUPPORTED: +      return 1;     default:        return 0;     } diff --git a/src/gallium/drivers/i965simple/brw_draw.c b/src/gallium/drivers/i965simple/brw_draw.c index 648aaa0da5..49d80cb41c 100644 --- a/src/gallium/drivers/i965simple/brw_draw.c +++ b/src/gallium/drivers/i965simple/brw_draw.c @@ -35,6 +35,7 @@  #include "pipe/p_context.h"  #include "pipe/internal/p_winsys_screen.h" +#include "util/u_prim.h"  static unsigned hw_prim[PIPE_PRIM_POLYGON+1] = {     _3DPRIM_POINTLIST, @@ -50,20 +51,6 @@ static unsigned hw_prim[PIPE_PRIM_POLYGON+1] = {  }; -static const int reduced_prim[PIPE_PRIM_POLYGON+1] = { -   PIPE_PRIM_POINTS, -   PIPE_PRIM_LINES, -   PIPE_PRIM_LINES, -   PIPE_PRIM_LINES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES -}; - -  /* When the primitive changes, set a state bit and re-validate.  Not   * the nicest and would rather deal with this by having all the   * programs be immune to the active primitive (ie. cope with all @@ -85,8 +72,8 @@ static void brw_set_prim(struct brw_context *brw, int prim)        brw->primitive = prim;        brw->state.dirty.brw |= BRW_NEW_PRIMITIVE; -      if (reduced_prim[prim] != brw->reduced_primitive) { -	 brw->reduced_primitive = reduced_prim[prim]; +      if (u_reduced_prim(prim) != brw->reduced_primitive) { +	 brw->reduced_primitive = u_reduced_prim(prim);  	 brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE;        } diff --git a/src/gallium/drivers/identity/Makefile b/src/gallium/drivers/identity/Makefile new file mode 100644 index 0000000000..e32b9102e5 --- /dev/null +++ b/src/gallium/drivers/identity/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = identity + +C_SOURCES = \ +	id_objects.c \ +	id_context.c \ +	id_screen.c \ +	id_drm.c + +include ../../Makefile.template diff --git a/src/gallium/drivers/identity/SConscript b/src/gallium/drivers/identity/SConscript new file mode 100644 index 0000000000..7f079dd0a8 --- /dev/null +++ b/src/gallium/drivers/identity/SConscript @@ -0,0 +1,13 @@ +Import('*') + +env = env.Clone() + +identity = env.ConvenienceLibrary( +	target = 'identity', +	source = [ +		'id_screen.c', +		'id_context.c', +		'id_objects.c', +	]) + +Export('identity') diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c new file mode 100644 index 0000000000..a500ec6045 --- /dev/null +++ b/src/gallium/drivers/identity/id_context.c @@ -0,0 +1,719 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 "pipe/p_context.h" +#include "util/u_memory.h" + +#include "id_public.h" +#include "id_context.h" +#include "id_objects.h" + + +static void +identity_destroy(struct pipe_context *_pipe) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->destroy(pipe); + +   free(id_pipe); +} + +static void +identity_set_edgeflags(struct pipe_context *_pipe, +                       const unsigned *bitfield) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->set_edgeflags(pipe, +                       bitfield); +} + +static boolean +identity_draw_arrays(struct pipe_context *_pipe, +                     unsigned prim, +                     unsigned start, +                     unsigned count) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->draw_arrays(pipe, +                            prim, +                            start, +                            count); +} + +static boolean +identity_draw_elements(struct pipe_context *_pipe, +                       struct pipe_buffer *_indexBuffer, +                       unsigned indexSize, +                       unsigned prim, +                       unsigned start, +                       unsigned count) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct identity_buffer *id_buffer = identity_buffer(_indexBuffer); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_buffer *indexBuffer = id_buffer->buffer; + +   return pipe->draw_elements(pipe, +                              indexBuffer, +                              indexSize, +                              prim, +                              start, +                              count); +} + +static boolean +identity_draw_range_elements(struct pipe_context *_pipe, +                             struct pipe_buffer *_indexBuffer, +                             unsigned indexSize, +                             unsigned minIndex, +                             unsigned maxIndex, +                             unsigned mode, +                             unsigned start, +                             unsigned count) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct identity_buffer *id_buffer = identity_buffer(_indexBuffer); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_buffer *indexBuffer = id_buffer->buffer; + +   return pipe->draw_range_elements(pipe, +                                    indexBuffer, +                                    indexSize, +                                    minIndex, +                                    maxIndex, +                                    mode, +                                    start, +                                    count); +} + +static struct pipe_query * +identity_create_query(struct pipe_context *_pipe, +                      unsigned query_type) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->create_query(pipe, +                             query_type); +} + +static void +identity_destroy_query(struct pipe_context *_pipe, +                       struct pipe_query *query) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->destroy_query(pipe, +                       query); +} + +static void +identity_begin_query(struct pipe_context *_pipe, +                     struct pipe_query *query) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->begin_query(pipe, +                     query); +} + +static void +identity_end_query(struct pipe_context *_pipe, +                   struct pipe_query *query) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->end_query(pipe, +                   query); +} + +static boolean +identity_get_query_result(struct pipe_context *_pipe, +                          struct pipe_query *query, +                          boolean wait, +                          uint64_t *result) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->get_query_result(pipe, +                                 query, +                                 wait, +                                 result); +} + +static void * +identity_create_blend_state(struct pipe_context *_pipe, +                            const struct pipe_blend_state *blend) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->create_blend_state(pipe, +                                   blend); +} + +static void +identity_bind_blend_state(struct pipe_context *_pipe, +                          void *blend) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->bind_blend_state(pipe, +                              blend); +} + +static void +identity_delete_blend_state(struct pipe_context *_pipe, +                            void *blend) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->delete_blend_state(pipe, +                            blend); +} + +static void * +identity_create_sampler_state(struct pipe_context *_pipe, +                              const struct pipe_sampler_state *sampler) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->create_sampler_state(pipe, +                                     sampler); +} + +static void +identity_bind_sampler_states(struct pipe_context *_pipe, +                             unsigned num, +                             void **samplers) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->bind_sampler_states(pipe, +                             num, +                             samplers); +} + +static void +identity_delete_sampler_state(struct pipe_context *_pipe, +                              void *sampler) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->delete_sampler_state(pipe, +                              sampler); +} + +static void * +identity_create_rasterizer_state(struct pipe_context *_pipe, +                                 const struct pipe_rasterizer_state *rasterizer) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->create_rasterizer_state(pipe, +                                        rasterizer); +} + +static void +identity_bind_rasterizer_state(struct pipe_context *_pipe, +                               void *rasterizer) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->bind_rasterizer_state(pipe, +                               rasterizer); +} + +static void +identity_delete_rasterizer_state(struct pipe_context *_pipe, +                                 void *rasterizer) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->delete_rasterizer_state(pipe, +                                 rasterizer); +} + +static void * +identity_create_depth_stencil_alpha_state(struct pipe_context *_pipe, +                                          const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->create_depth_stencil_alpha_state(pipe, +                                                 depth_stencil_alpha); +} + +static void +identity_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, +                                        void *depth_stencil_alpha) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->bind_depth_stencil_alpha_state(pipe, +                                        depth_stencil_alpha); +} + +static void +identity_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, +                                          void *depth_stencil_alpha) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->delete_depth_stencil_alpha_state(pipe, +                                          depth_stencil_alpha); +} + +static void * +identity_create_fs_state(struct pipe_context *_pipe, +                         const struct pipe_shader_state *fs) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->create_fs_state(pipe, +                                fs); +} + +static void +identity_bind_fs_state(struct pipe_context *_pipe, +                       void *fs) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->bind_fs_state(pipe, +                       fs); +} + +static void +identity_delete_fs_state(struct pipe_context *_pipe, +                         void *fs) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->delete_fs_state(pipe, +                         fs); +} + +static void * +identity_create_vs_state(struct pipe_context *_pipe, +                         const struct pipe_shader_state *vs) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   return pipe->create_vs_state(pipe, +                                vs); +} + +static void +identity_bind_vs_state(struct pipe_context *_pipe, +                       void *vs) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->bind_vs_state(pipe, +                       vs); +} + +static void +identity_delete_vs_state(struct pipe_context *_pipe, +                         void *vs) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->delete_vs_state(pipe, +                         vs); +} + +static void +identity_set_blend_color(struct pipe_context *_pipe, +                         const struct pipe_blend_color *blend_color) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->set_blend_color(pipe, +                         blend_color); +} + +static void +identity_set_clip_state(struct pipe_context *_pipe, +                        const struct pipe_clip_state *clip) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->set_clip_state(pipe, +                        clip); +} + +static void +identity_set_constant_buffer(struct pipe_context *_pipe, +                             uint shader, +                             uint index, +                             const struct pipe_constant_buffer *_buffer) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_constant_buffer unwrapped_buffer; +   struct pipe_constant_buffer *buffer = NULL; + +   /* unwrap the input state */ +   if (_buffer) { +      unwrapped_buffer.buffer = identity_buffer_unwrap(_buffer->buffer); +      buffer = &unwrapped_buffer; +   } + +   pipe->set_constant_buffer(pipe, +                             shader, +                             index, +                             buffer); +} + +static void +identity_set_framebuffer_state(struct pipe_context *_pipe, +                               const struct pipe_framebuffer_state *_state) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_framebuffer_state unwrapped_state; +   struct pipe_framebuffer_state *state = NULL; +   unsigned i; + +   /* unwrap the input state */ +   if (_state) { +      memcpy(&unwrapped_state, _state, sizeof(unwrapped_state)); +      for(i = 0; i < _state->nr_cbufs; i++) +         unwrapped_state.cbufs[i] = identity_surface_unwrap(_state->cbufs[i]); +      for (; i < PIPE_MAX_COLOR_BUFS; i++) +         unwrapped_state.cbufs[i] = NULL; +      unwrapped_state.zsbuf = identity_surface_unwrap(_state->zsbuf); +      state = &unwrapped_state; +   } + +   pipe->set_framebuffer_state(pipe, +                               state); +} + +static void +identity_set_polygon_stipple(struct pipe_context *_pipe, +                             const struct pipe_poly_stipple *poly_stipple) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->set_polygon_stipple(pipe, +                             poly_stipple); +} + +static void +identity_set_scissor_state(struct pipe_context *_pipe, +                           const struct pipe_scissor_state *scissor) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->set_scissor_state(pipe, +                           scissor); +} + +static void +identity_set_viewport_state(struct pipe_context *_pipe, +                            const struct pipe_viewport_state *viewport) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->set_viewport_state(pipe, +                            viewport); +} + +static void +identity_set_sampler_textures(struct pipe_context *_pipe, +                              unsigned num_textures, +                              struct pipe_texture **_textures) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; +   struct pipe_texture **textures = NULL; +   unsigned i; + +   if (_textures) { +      for (i = 0; i < num_textures; i++) +         unwrapped_textures[i] = identity_texture_unwrap(_textures[i]); +      for (; i < PIPE_MAX_SAMPLERS; i++) +         unwrapped_textures[i] = NULL; + +      textures = unwrapped_textures; +   } + +   pipe->set_sampler_textures(pipe, +                              num_textures, +                              _textures); +} + +static void +identity_set_vertex_buffers(struct pipe_context *_pipe, +                            unsigned num_buffers, +                            const struct pipe_vertex_buffer *_buffers) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS]; +   struct pipe_vertex_buffer *buffers = NULL; +   unsigned i; + +   if (num_buffers) { +      memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); +      for (i = 0; i < num_buffers; i++) +         unwrapped_buffers[i].buffer = identity_buffer_unwrap(_buffers[i].buffer); +      buffers = unwrapped_buffers; +   } + +   pipe->set_vertex_buffers(pipe, +                            num_buffers, +                            buffers); +} + +static void +identity_set_vertex_elements(struct pipe_context *_pipe, +                             unsigned num_elements, +                             const struct pipe_vertex_element *vertex_elements) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->set_vertex_elements(pipe, +                             num_elements, +                             vertex_elements); +} + +static void +identity_surface_copy(struct pipe_context *_pipe, +                      struct pipe_surface *_dst, +                      unsigned dstx, +                      unsigned dsty, +                      struct pipe_surface *_src, +                      unsigned srcx, +                      unsigned srcy, +                      unsigned width, +                      unsigned height) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct identity_surface *id_surface_dst = identity_surface(_dst); +   struct identity_surface *id_surface_src = identity_surface(_src); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_surface *dst = id_surface_dst->surface; +   struct pipe_surface *src = id_surface_src->surface; + +   pipe->surface_copy(pipe, +                      dst, +                      dstx, +                      dsty, +                      src, +                      srcx, +                      srcy, +                      width, +                      height); +} + +static void +identity_surface_fill(struct pipe_context *_pipe, +                      struct pipe_surface *_dst, +                      unsigned dstx, +                      unsigned dsty, +                      unsigned width, +                      unsigned height, +                      unsigned value) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct identity_surface *id_surface_dst = identity_surface(_dst); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_surface *dst = id_surface_dst->surface; + +   pipe->surface_fill(pipe, +                      dst, +                      dstx, +                      dsty, +                      width, +                      height, +                      value); +} + +static void +identity_clear(struct pipe_context *_pipe, +               unsigned buffers, +               const float *rgba, +               double depth, +               unsigned stencil) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->clear(pipe, +               buffers, +               rgba, +               depth, +               stencil); +} + +static void +identity_flush(struct pipe_context *_pipe, +               unsigned flags, +               struct pipe_fence_handle **fence) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct pipe_context *pipe = id_pipe->pipe; + +   pipe->flush(pipe, +               flags, +               fence); +} + +static unsigned int +identity_is_texture_referenced(struct pipe_context *_pipe, +                               struct pipe_texture *_texture, +                               unsigned face, +                               unsigned level) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct identity_texture *id_texture = identity_texture(_texture); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_texture *texture = id_texture->texture; + +   return pipe->is_texture_referenced(pipe, +                                      texture, +                                      face, +                                      level); +} + +static unsigned int +identity_is_buffer_referenced(struct pipe_context *_pipe, +                              struct pipe_buffer *_buffer) +{ +   struct identity_context *id_pipe = identity_context(_pipe); +   struct identity_buffer *id_buffer = identity_buffer(_buffer); +   struct pipe_context *pipe = id_pipe->pipe; +   struct pipe_buffer *buffer = id_buffer->buffer; + +   return pipe->is_buffer_referenced(pipe, +                                     buffer); +} + +struct pipe_context * +identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) +{ +   struct identity_context *id_pipe; +   (void)identity_screen(_screen); + +   id_pipe = CALLOC_STRUCT(identity_context); +   if (!id_pipe) { +      return NULL; +   } + +   id_pipe->base.winsys = NULL; +   id_pipe->base.screen = _screen; +   id_pipe->base.priv = pipe->priv; +   id_pipe->base.draw = NULL; + +   id_pipe->base.destroy = identity_destroy; +   id_pipe->base.set_edgeflags = identity_set_edgeflags; +   id_pipe->base.draw_arrays = identity_draw_arrays; +   id_pipe->base.draw_elements = identity_draw_elements; +   id_pipe->base.draw_range_elements = identity_draw_range_elements; +   id_pipe->base.create_query = identity_create_query; +   id_pipe->base.destroy_query = identity_destroy_query; +   id_pipe->base.begin_query = identity_begin_query; +   id_pipe->base.end_query = identity_end_query; +   id_pipe->base.get_query_result = identity_get_query_result; +   id_pipe->base.create_blend_state = identity_create_blend_state; +   id_pipe->base.bind_blend_state = identity_bind_blend_state; +   id_pipe->base.delete_blend_state = identity_delete_blend_state; +   id_pipe->base.create_sampler_state = identity_create_sampler_state; +   id_pipe->base.bind_sampler_states = identity_bind_sampler_states; +   id_pipe->base.delete_sampler_state = identity_delete_sampler_state; +   id_pipe->base.create_rasterizer_state = identity_create_rasterizer_state; +   id_pipe->base.bind_rasterizer_state = identity_bind_rasterizer_state; +   id_pipe->base.delete_rasterizer_state = identity_delete_rasterizer_state; +   id_pipe->base.create_depth_stencil_alpha_state = identity_create_depth_stencil_alpha_state; +   id_pipe->base.bind_depth_stencil_alpha_state = identity_bind_depth_stencil_alpha_state; +   id_pipe->base.delete_depth_stencil_alpha_state = identity_delete_depth_stencil_alpha_state; +   id_pipe->base.create_fs_state = identity_create_fs_state; +   id_pipe->base.bind_fs_state = identity_bind_fs_state; +   id_pipe->base.delete_fs_state = identity_delete_fs_state; +   id_pipe->base.create_vs_state = identity_create_vs_state; +   id_pipe->base.bind_vs_state = identity_bind_vs_state; +   id_pipe->base.delete_vs_state = identity_delete_vs_state; +   id_pipe->base.set_blend_color = identity_set_blend_color; +   id_pipe->base.set_clip_state = identity_set_clip_state; +   id_pipe->base.set_constant_buffer = identity_set_constant_buffer; +   id_pipe->base.set_framebuffer_state = identity_set_framebuffer_state; +   id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple; +   id_pipe->base.set_scissor_state = identity_set_scissor_state; +   id_pipe->base.set_viewport_state = identity_set_viewport_state; +   id_pipe->base.set_sampler_textures = identity_set_sampler_textures; +   id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; +   id_pipe->base.set_vertex_elements = identity_set_vertex_elements; +   id_pipe->base.surface_copy = identity_surface_copy; +   id_pipe->base.surface_fill = identity_surface_fill; +   id_pipe->base.clear = identity_clear; +   id_pipe->base.flush = identity_flush; +   id_pipe->base.is_texture_referenced = identity_is_texture_referenced; +   id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced; + +   id_pipe->pipe = pipe; + +   return &id_pipe->base; +} diff --git a/src/gallium/drivers/identity/id_context.h b/src/gallium/drivers/identity/id_context.h new file mode 100644 index 0000000000..75b73fc7df --- /dev/null +++ b/src/gallium/drivers/identity/id_context.h @@ -0,0 +1,48 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 ID_CONTEXT_H +#define ID_CONTEXT_H + +#include "pipe/p_state.h" +#include "pipe/p_context.h" + + +struct identity_context { +   struct pipe_context base;  /**< base class */ + +   struct pipe_context *pipe; +}; + + +static INLINE struct identity_context * +identity_context(struct pipe_context *pipe) +{ +   return (struct identity_context *)pipe; +} + +#endif /* ID_CONTEXT_H */ diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c new file mode 100644 index 0000000000..555220f853 --- /dev/null +++ b/src/gallium/drivers/identity/id_drm.c @@ -0,0 +1,187 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 "state_tracker/drm_api.h" + +#include "util/u_memory.h" +#include "identity/id_drm.h" +#include "identity/id_public.h" +#include "identity/id_screen.h" +#include "identity/id_objects.h" + +struct identity_drm_api +{ +   struct drm_api base; + +   struct drm_api *api; +}; + +static INLINE struct identity_drm_api * +identity_drm_api(struct drm_api *_api) +{ +   return (struct identity_drm_api *)_api; +} + +static struct pipe_screen * +identity_drm_create_screen(struct drm_api *_api, int fd, +                           struct drm_create_screen_arg *arg) +{ +   struct identity_drm_api *id_api = identity_drm_api(_api); +   struct drm_api *api = id_api->api; +   struct pipe_screen *screen; + +   if (arg && arg->mode != DRM_CREATE_NORMAL) +      return NULL; + +   screen = api->create_screen(api, fd, arg); + +   return identity_screen_create(screen); +}; + +static struct pipe_context * +identity_drm_create_context(struct drm_api *_api, +                            struct pipe_screen *_screen) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_drm_api *id_api = identity_drm_api(_api); +   struct pipe_screen *screen = id_screen->screen; +   struct drm_api *api = id_api->api; +   struct pipe_context *pipe; + +   pipe = api->create_context(api, screen); + +   pipe = identity_context_create(_screen, pipe); + +   return pipe; +}; + +static boolean +identity_drm_buffer_from_texture(struct drm_api *_api, +                                 struct pipe_texture *_texture, +                                 struct pipe_buffer **_buffer, +                                 unsigned *stride) +{ +   struct identity_texture *id_texture = identity_texture(_texture); +   struct identity_drm_api *id_api = identity_drm_api(_api); +   struct pipe_texture *texture = id_texture->texture; +   struct drm_api *api = id_api->api; +   struct pipe_buffer *buffer = NULL; +   boolean result; + +   result = api->buffer_from_texture(api, texture, &buffer, stride); + +   if (result && _buffer) +      buffer = identity_buffer_create(identity_screen(texture->screen), buffer); + +   if (_buffer) +      *_buffer = buffer; +   else +      pipe_buffer_reference(&buffer, NULL); + +   return result; +} + +static struct pipe_buffer * +identity_drm_buffer_from_handle(struct drm_api *_api, +                                struct pipe_screen *_screen, +                                const char *name, +                                unsigned handle) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_drm_api *id_api = identity_drm_api(_api); +   struct pipe_screen *screen = id_screen->screen; +   struct drm_api *api = id_api->api; +   struct pipe_buffer *result; + +   result = api->buffer_from_handle(api, screen, name, handle); + +   result = identity_buffer_create(identity_screen(_screen), result); + +   return result; +} + +static boolean +identity_drm_handle_from_buffer(struct drm_api *_api, +                                struct pipe_screen *_screen, +                                struct pipe_buffer *_buffer, +                                unsigned *handle) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_buffer *id_buffer = identity_buffer(_buffer); +   struct identity_drm_api *id_api = identity_drm_api(_api); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *buffer = id_buffer->buffer; +   struct drm_api *api = id_api->api; + +   return api->handle_from_buffer(api, screen, buffer, handle); +} + +static boolean +identity_drm_global_handle_from_buffer(struct drm_api *_api, +                                       struct pipe_screen *_screen, +                                       struct pipe_buffer *_buffer, +                                       unsigned *handle) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_buffer *id_buffer = identity_buffer(_buffer); +   struct identity_drm_api *id_api = identity_drm_api(_api); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *buffer = id_buffer->buffer; +   struct drm_api *api = id_api->api; + +   return api->global_handle_from_buffer(api, screen, buffer, handle); +} + +static void +identity_drm_destroy(struct drm_api *_api) +{ +   struct identity_drm_api *id_api = identity_drm_api(_api); +   struct drm_api *api = id_api->api; +   api->destroy(api); + +   free(id_api); +} + +struct drm_api * +identity_drm_create(struct drm_api *api) +{ +   struct identity_drm_api *id_api = CALLOC_STRUCT(identity_drm_api); + +   if (!id_api) +      return NULL; + +   id_api->base.create_screen = identity_drm_create_screen; +   id_api->base.create_context = identity_drm_create_context; +   id_api->base.buffer_from_texture = identity_drm_buffer_from_texture; +   id_api->base.buffer_from_handle = identity_drm_buffer_from_handle; +   id_api->base.handle_from_buffer = identity_drm_handle_from_buffer; +   id_api->base.global_handle_from_buffer = identity_drm_global_handle_from_buffer; +   id_api->base.destroy = identity_drm_destroy; +   id_api->api = api; + +   return &id_api->base; +} diff --git a/src/gallium/drivers/identity/id_drm.h b/src/gallium/drivers/identity/id_drm.h new file mode 100644 index 0000000000..cf2ad2ce07 --- /dev/null +++ b/src/gallium/drivers/identity/id_drm.h @@ -0,0 +1,35 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 ID_DRM_H +#define ID_DRM_H + +struct drm_api; + +struct drm_api* identity_drm_create(struct drm_api *api); + +#endif /* ID_DRM_H */ diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c new file mode 100644 index 0000000000..e893e59940 --- /dev/null +++ b/src/gallium/drivers/identity/id_objects.c @@ -0,0 +1,182 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 "util/u_memory.h" + +#include "id_public.h" +#include "id_screen.h" +#include "id_objects.h" + +struct pipe_buffer * +identity_buffer_create(struct identity_screen *id_screen, +                       struct pipe_buffer *buffer) +{ +   struct identity_buffer *id_buffer; + +   if(!buffer) +      goto error; + +   assert(buffer->screen == id_screen->screen); + +   id_buffer = CALLOC_STRUCT(identity_buffer); +   if(!id_buffer) +      goto error; + +   memcpy(&id_buffer->base, buffer, sizeof(struct pipe_buffer)); + +   pipe_reference_init(&id_buffer->base.reference, 1); +   id_buffer->base.screen = &id_screen->base; +   id_buffer->buffer = buffer; + +   return &id_buffer->base; + +error: +   pipe_buffer_reference(&buffer, NULL); +   return NULL; +} + +void +identity_buffer_destroy(struct identity_buffer *id_buffer) +{ +   pipe_buffer_reference(&id_buffer->buffer, NULL); +   FREE(id_buffer); +} + + +struct pipe_texture * +identity_texture_create(struct identity_screen *id_screen, +                        struct pipe_texture *texture) +{ +   struct identity_texture *id_texture; + +   if(!texture) +      goto error; + +   assert(texture->screen == id_screen->screen); + +   id_texture = CALLOC_STRUCT(identity_texture); +   if(!id_texture) +      goto error; + +   memcpy(&id_texture->base, texture, sizeof(struct pipe_texture)); + +   pipe_reference_init(&id_texture->base.reference, 1); +   id_texture->base.screen = &id_screen->base; +   id_texture->texture = texture; + +   return &id_texture->base; + +error: +   pipe_texture_reference(&texture, NULL); +   return NULL; +} + +void +identity_texture_destroy(struct identity_texture *id_texture) +{ +   pipe_texture_reference(&id_texture->texture, NULL); +   FREE(id_texture); +} + + +struct pipe_surface * +identity_surface_create(struct identity_texture *id_texture, +                        struct pipe_surface *surface) +{ +   struct identity_surface *id_surface; + +   if(!surface) +      goto error; + +   assert(surface->texture == id_texture->texture); + +   id_surface = CALLOC_STRUCT(identity_surface); +   if(!id_surface) +      goto error; + +   memcpy(&id_surface->base, surface, sizeof(struct pipe_surface)); + +   pipe_reference_init(&id_surface->base.reference, 1); +   id_surface->base.texture = NULL; +   pipe_texture_reference(&id_surface->base.texture, &id_texture->base); +   id_surface->surface = surface; + +   return &id_surface->base; + +error: +   pipe_surface_reference(&surface, NULL); +   return NULL; +} + +void +identity_surface_destroy(struct identity_surface *id_surface) +{ +   pipe_texture_reference(&id_surface->base.texture, NULL); +   pipe_surface_reference(&id_surface->surface, NULL); +   FREE(id_surface); +} + + +struct pipe_transfer * +identity_transfer_create(struct identity_texture *id_texture, +                         struct pipe_transfer *transfer) +{ +   struct identity_transfer *id_transfer; + +   if(!transfer) +      goto error; + +   assert(transfer->texture == id_texture->texture); + +   id_transfer = CALLOC_STRUCT(identity_transfer); +   if(!id_transfer) +      goto error; + +   memcpy(&id_transfer->base, transfer, sizeof(struct pipe_transfer)); + +   id_transfer->base.texture = NULL; +   pipe_texture_reference(&id_transfer->base.texture, &id_texture->base); +   id_transfer->transfer = transfer; +   assert(id_transfer->base.texture == &id_texture->base); + +   return &id_transfer->base; + +error: +   transfer->texture->screen->tex_transfer_destroy(transfer); +   return NULL; +} + +void +identity_transfer_destroy(struct identity_transfer *id_transfer) +{ +   struct identity_screen *id_screen = identity_screen(id_transfer->base.texture->screen); +   struct pipe_screen *screen = id_screen->screen; + +   pipe_texture_reference(&id_transfer->base.texture, NULL); +   screen->tex_transfer_destroy(id_transfer->transfer); +   FREE(id_transfer); +} diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h new file mode 100644 index 0000000000..ce58faa3c7 --- /dev/null +++ b/src/gallium/drivers/identity/id_objects.h @@ -0,0 +1,169 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 ID_OBJECTS_H +#define ID_OBJECTS_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "id_screen.h" + + +struct identity_buffer +{ +   struct pipe_buffer base; + +   struct pipe_buffer *buffer; +}; + + +struct identity_texture +{ +   struct pipe_texture base; + +   struct pipe_texture *texture; +}; + + +struct identity_surface +{ +   struct pipe_surface base; + +   struct pipe_surface *surface; +}; + + +struct identity_transfer +{ +   struct pipe_transfer base; + +   struct pipe_transfer *transfer; +}; + + +static INLINE struct identity_buffer * +identity_buffer(struct pipe_buffer *_buffer) +{ +   if(!_buffer) +      return NULL; +   (void)identity_screen(_buffer->screen); +   return (struct identity_buffer *)_buffer; +} + +static INLINE struct identity_texture * +identity_texture(struct pipe_texture *_texture) +{ +   if(!_texture) +      return NULL; +   (void)identity_screen(_texture->screen); +   return (struct identity_texture *)_texture; +} + +static INLINE struct identity_surface * +identity_surface(struct pipe_surface *_surface) +{ +   if(!_surface) +      return NULL; +   (void)identity_texture(_surface->texture); +   return (struct identity_surface *)_surface; +} + +static INLINE struct identity_transfer * +identity_transfer(struct pipe_transfer *_transfer) +{ +   if(!_transfer) +      return NULL; +   (void)identity_texture(_transfer->texture); +   return (struct identity_transfer *)_transfer; +} + + +static INLINE struct pipe_buffer * +identity_buffer_unwrap(struct pipe_buffer *_buffer) +{ +   if(!_buffer) +      return NULL; +   return identity_buffer(_buffer)->buffer; +} + +static INLINE struct pipe_texture * +identity_texture_unwrap(struct pipe_texture *_texture) +{ +   if(!_texture) +      return NULL; +   return identity_texture(_texture)->texture; +} + +static INLINE struct pipe_surface * +identity_surface_unwrap(struct pipe_surface *_surface) +{ +   if(!_surface) +      return NULL; +   return identity_surface(_surface)->surface; +} + +static INLINE struct pipe_transfer * +identity_transfer_unwrap(struct pipe_transfer *_transfer) +{ +   if(!_transfer) +      return NULL; +   return identity_transfer(_transfer)->transfer; +} + + +struct pipe_buffer * +identity_buffer_create(struct identity_screen *id_screen, +                       struct pipe_buffer *buffer); + +void +identity_buffer_destroy(struct identity_buffer *id_buffer); + +struct pipe_texture * +identity_texture_create(struct identity_screen *id_screen, +                        struct pipe_texture *texture); + +void +identity_texture_destroy(struct identity_texture *id_texture); + +struct pipe_surface * +identity_surface_create(struct identity_texture *id_texture, +                        struct pipe_surface *surface); + +void +identity_surface_destroy(struct identity_surface *id_surface); + +struct pipe_transfer * +identity_transfer_create(struct identity_texture *id_texture, +                         struct pipe_transfer *transfer); + +void +identity_transfer_destroy(struct identity_transfer *id_transfer); + + +#endif /* ID_OBJECTS_H */ diff --git a/src/gallium/drivers/identity/id_public.h b/src/gallium/drivers/identity/id_public.h new file mode 100644 index 0000000000..cac14cfd60 --- /dev/null +++ b/src/gallium/drivers/identity/id_public.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 ID_PUBLIC_H +#define ID_PUBLIC_H + +struct pipe_screen; +struct pipe_context; + +struct pipe_screen * +identity_screen_create(struct pipe_screen *screen); + +struct pipe_context * +identity_context_create(struct pipe_screen *screen, struct pipe_context *pipe); + +#endif /* PT_PUBLIC_H */ diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c new file mode 100644 index 0000000000..259f1be36e --- /dev/null +++ b/src/gallium/drivers/identity/id_screen.c @@ -0,0 +1,481 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 "pipe/p_screen.h" +#include "pipe/p_state.h" +#include "util/u_memory.h" + +#include "id_public.h" +#include "id_screen.h" +#include "id_objects.h" + + +static void +identity_screen_destroy(struct pipe_screen *_screen) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   screen->destroy(screen); + +   FREE(id_screen); +} + +static const char * +identity_screen_get_name(struct pipe_screen *_screen) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   return screen->get_name(screen); +} + +static const char * +identity_screen_get_vendor(struct pipe_screen *_screen) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   return screen->get_vendor(screen); +} + +static int +identity_screen_get_param(struct pipe_screen *_screen, +                          int param) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   return screen->get_param(screen, +                            param); +} + +static float +identity_screen_get_paramf(struct pipe_screen *_screen, +                           int param) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   return screen->get_paramf(screen, +                             param); +} + +static boolean +identity_screen_is_format_supported(struct pipe_screen *_screen, +                                    enum pipe_format format, +                                    enum pipe_texture_target target, +                                    unsigned tex_usage, +                                    unsigned geom_flags) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   return screen->is_format_supported(screen, +                                      format, +                                      target, +                                      tex_usage, +                                      geom_flags); +} + +static struct pipe_texture * +identity_screen_texture_create(struct pipe_screen *_screen, +                               const struct pipe_texture *templat) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_texture *result; + +   result = screen->texture_create(screen, +                                   templat); + +   if (result) +      return identity_texture_create(id_screen, result); +   return NULL; +} + +static struct pipe_texture * +identity_screen_texture_blanket(struct pipe_screen *_screen, +                                const struct pipe_texture *templat, +                                const unsigned *stride, +                                struct pipe_buffer *_buffer) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_buffer *id_buffer = identity_buffer(_buffer); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *buffer = id_buffer->buffer; +   struct pipe_texture *result; + +   result = screen->texture_blanket(screen, +                                    templat, +                                    stride, +                                    buffer); + +   if (result) +      return identity_texture_create(id_screen, result); +   return NULL; +} + +static void +identity_screen_texture_destroy(struct pipe_texture *_texture) +{ +   identity_texture_destroy(identity_texture(_texture)); +} + +static struct pipe_surface * +identity_screen_get_tex_surface(struct pipe_screen *_screen, +                                struct pipe_texture *_texture, +                                unsigned face, +                                unsigned level, +                                unsigned zslice, +                                unsigned usage) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_texture *id_texture = identity_texture(_texture); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_texture *texture = id_texture->texture; +   struct pipe_surface *result; + +   result = screen->get_tex_surface(screen, +                                    texture, +                                    face, +                                    level, +                                    zslice, +                                    usage); + +   if (result) +      return identity_surface_create(id_texture, result); +   return NULL; +} + +static void +identity_screen_tex_surface_destroy(struct pipe_surface *_surface) +{ +   identity_surface_destroy(identity_surface(_surface)); +} + +static struct pipe_transfer * +identity_screen_get_tex_transfer(struct pipe_screen *_screen, +                                 struct pipe_texture *_texture, +                                 unsigned face, +                                 unsigned level, +                                 unsigned zslice, +                                 enum pipe_transfer_usage usage, +                                 unsigned x, +                                 unsigned y, +                                 unsigned w, +                                 unsigned h) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_texture *id_texture = identity_texture(_texture); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_texture *texture = id_texture->texture; +   struct pipe_transfer *result; + +   result = screen->get_tex_transfer(screen, +                                     texture, +                                     face, +                                     level, +                                     zslice, +                                     usage, +                                     x, +                                     y, +                                     w, +                                     h); + +   if (result) +      return identity_transfer_create(id_texture, result); +   return NULL; +} + +static void +identity_screen_tex_transfer_destroy(struct pipe_transfer *_transfer) +{ +   identity_transfer_destroy(identity_transfer(_transfer)); +} + +static void * +identity_screen_transfer_map(struct pipe_screen *_screen, +                             struct pipe_transfer *_transfer) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_transfer *id_transfer = identity_transfer(_transfer); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_transfer *transfer = id_transfer->transfer; + +   return screen->transfer_map(screen, +                               transfer); +} + +static void +identity_screen_transfer_unmap(struct pipe_screen *_screen, +                               struct pipe_transfer *_transfer) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_transfer *id_transfer = identity_transfer(_transfer); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_transfer *transfer = id_transfer->transfer; + +   screen->transfer_unmap(screen, +                          transfer); +} + +static struct pipe_buffer * +identity_screen_buffer_create(struct pipe_screen *_screen, +                              unsigned alignment, +                              unsigned usage, +                              unsigned size) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *result; + +   result = screen->buffer_create(screen, +                                  alignment, +                                  usage, +                                  size); + +   if (result) +      return identity_buffer_create(id_screen, result); +   return NULL; +} + +static struct pipe_buffer * +identity_screen_user_buffer_create(struct pipe_screen *_screen, +                                   void *ptr, +                                   unsigned bytes) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *result; + +   result = screen->user_buffer_create(screen, +                                       ptr, +                                       bytes); + +   if (result) +      return identity_buffer_create(id_screen, result); +   return NULL; +} + +static struct pipe_buffer * +identity_screen_surface_buffer_create(struct pipe_screen *_screen, +                                      unsigned width, +                                      unsigned height, +                                      enum pipe_format format, +                                      unsigned usage, +                                      unsigned *stride) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *result; + +   result = screen->surface_buffer_create(screen, +                                          width, +                                          height, +                                          format, +                                          usage, +                                          stride); + +   if (result) +      return identity_buffer_create(id_screen, result); +   return NULL; +} + +static void * +identity_screen_buffer_map(struct pipe_screen *_screen, +                           struct pipe_buffer *_buffer, +                           unsigned usage) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_buffer *id_buffer = identity_buffer(_buffer); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *buffer = id_buffer->buffer; + +   return screen->buffer_map(screen, +                             buffer, +                             usage); +} + +static void * +identity_screen_buffer_map_range(struct pipe_screen *_screen, +                                 struct pipe_buffer *_buffer, +                                 unsigned offset, +                                 unsigned length, +                                 unsigned usage) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_buffer *id_buffer = identity_buffer(_buffer); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *buffer = id_buffer->buffer; + +   return screen->buffer_map_range(screen, +                                   buffer, +                                   offset, +                                   length, +                                   usage); +} + +static void +identity_screen_buffer_flush_mapped_range(struct pipe_screen *_screen, +                                          struct pipe_buffer *_buffer, +                                          unsigned offset, +                                          unsigned length) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_buffer *id_buffer = identity_buffer(_buffer); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *buffer = id_buffer->buffer; + +   screen->buffer_flush_mapped_range(screen, +                                     buffer, +                                     offset, +                                     length); +} + +static void +identity_screen_buffer_unmap(struct pipe_screen *_screen, +                             struct pipe_buffer *_buffer) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_buffer *id_buffer = identity_buffer(_buffer); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_buffer *buffer = id_buffer->buffer; + +   screen->buffer_unmap(screen, +                        buffer); +} + +static void +identity_screen_buffer_destroy(struct pipe_buffer *_buffer) +{ +   identity_buffer_destroy(identity_buffer(_buffer)); +} + +static void +identity_screen_flush_frontbuffer(struct pipe_screen *_screen, +                                  struct pipe_surface *_surface, +                                  void *context_private) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct identity_surface *id_surface = identity_surface(_surface); +   struct pipe_screen *screen = id_screen->screen; +   struct pipe_surface *surface = id_surface->surface; + +   screen->flush_frontbuffer(screen, +                             surface, +                             context_private); +} + +static void +identity_screen_fence_reference(struct pipe_screen *_screen, +                                struct pipe_fence_handle **ptr, +                                struct pipe_fence_handle *fence) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   screen->fence_reference(screen, +                           ptr, +                           fence); +} + +static int +identity_screen_fence_signalled(struct pipe_screen *_screen, +                                struct pipe_fence_handle *fence, +                                unsigned flags) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   return screen->fence_signalled(screen, +                                  fence, +                                  flags); +} + +static int +identity_screen_fence_finish(struct pipe_screen *_screen, +                             struct pipe_fence_handle *fence, +                             unsigned flags) +{ +   struct identity_screen *id_screen = identity_screen(_screen); +   struct pipe_screen *screen = id_screen->screen; + +   return screen->fence_finish(screen, +                               fence, +                               flags); +} + +struct pipe_screen * +identity_screen_create(struct pipe_screen *screen) +{ +   struct identity_screen *id_screen; + +   id_screen = CALLOC_STRUCT(identity_screen); +   if (!id_screen) { +      return NULL; +   } + +   id_screen->base.winsys = NULL; + +   id_screen->base.destroy = identity_screen_destroy; +   id_screen->base.get_name = identity_screen_get_name; +   id_screen->base.get_vendor = identity_screen_get_vendor; +   id_screen->base.get_param = identity_screen_get_param; +   id_screen->base.get_paramf = identity_screen_get_paramf; +   id_screen->base.is_format_supported = identity_screen_is_format_supported; +   id_screen->base.texture_create = identity_screen_texture_create; +   id_screen->base.texture_blanket = identity_screen_texture_blanket; +   id_screen->base.texture_destroy = identity_screen_texture_destroy; +   id_screen->base.get_tex_surface = identity_screen_get_tex_surface; +   id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy; +   id_screen->base.get_tex_transfer = identity_screen_get_tex_transfer; +   id_screen->base.tex_transfer_destroy = identity_screen_tex_transfer_destroy; +   id_screen->base.transfer_map = identity_screen_transfer_map; +   id_screen->base.transfer_unmap = identity_screen_transfer_unmap; +   id_screen->base.buffer_create = identity_screen_buffer_create; +   id_screen->base.user_buffer_create = identity_screen_user_buffer_create; +   id_screen->base.surface_buffer_create = identity_screen_surface_buffer_create; +   if (screen->buffer_map) +      id_screen->base.buffer_map = identity_screen_buffer_map; +   if (screen->buffer_map_range) +      id_screen->base.buffer_map_range = identity_screen_buffer_map_range; +   if (screen->buffer_flush_mapped_range) +      id_screen->base.buffer_flush_mapped_range = identity_screen_buffer_flush_mapped_range; +   if (screen->buffer_unmap) +      id_screen->base.buffer_unmap = identity_screen_buffer_unmap; +   id_screen->base.buffer_destroy = identity_screen_buffer_destroy; +   id_screen->base.flush_frontbuffer = identity_screen_flush_frontbuffer; +   id_screen->base.fence_reference = identity_screen_fence_reference; +   id_screen->base.fence_signalled = identity_screen_fence_signalled; +   id_screen->base.fence_finish = identity_screen_fence_finish; + +   id_screen->screen = screen; + +   return &id_screen->base; +} diff --git a/src/gallium/drivers/identity/id_screen.h b/src/gallium/drivers/identity/id_screen.h new file mode 100644 index 0000000000..2c4f129089 --- /dev/null +++ b/src/gallium/drivers/identity/id_screen.h @@ -0,0 +1,48 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 ID_SCREEN_H +#define ID_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + + +struct identity_screen { +   struct pipe_screen base; + +   struct pipe_screen *screen; +}; + + +static INLINE struct identity_screen * +identity_screen(struct pipe_screen *screen) +{ +   return (struct identity_screen *)screen; +} + +#endif /* ID_SCREEN_H */ diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c index 4bbedfb4d6..ff2febb668 100644 --- a/src/gallium/drivers/nv04/nv04_screen.c +++ b/src/gallium/drivers/nv04/nv04_screen.c @@ -40,6 +40,10 @@ nv04_screen_get_param(struct pipe_screen *screen, int param)  		return 0;  	case PIPE_CAP_TEXTURE_MIRROR_REPEAT:  		return 1; +	case PIPE_CAP_TGSI_CONT_SUPPORTED: +		return 0; +	case PIPE_CAP_BLEND_EQUATION_SEPARATE: +		return 0;  	case NOUVEAU_CAP_HW_VTXBUF:  	case NOUVEAU_CAP_HW_IDXBUF:  		return 0; @@ -79,6 +83,13 @@ nv04_screen_is_format_supported(struct pipe_screen *screen,  		switch (format) {  		case PIPE_FORMAT_A8R8G8B8_UNORM:  		case PIPE_FORMAT_R5G6B5_UNORM:  +			return TRUE; +		default: +			break; +		} +	} else +	if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { +		switch (format) {  		case PIPE_FORMAT_Z16_UNORM:  			return TRUE;  		default: diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c index 5afd028ddd..f315cf54f0 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.c +++ b/src/gallium/drivers/nv04/nv04_surface_2d.c @@ -267,8 +267,7 @@ nv04_surface_copy(struct nv04_surface_2d *ctx, struct pipe_surface *dst,  	 * to NV_MEMORY_TO_MEMORY_FORMAT in this case.  	 */  	if ((src->offset & 63) || (dst->offset & 63) || -	    (src_pitch & 63) || (dst_pitch & 63) || -	    debug_get_bool_option("NOUVEAU_NO_COPYBLIT", FALSE)) { +	    (src_pitch & 63) || (dst_pitch & 63)) {  		nv04_surface_copy_m2mf(ctx, dst, dx, dy, src, sx, sy, w, h);  		return;  	} diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index b03c291f9d..4469b22d91 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -35,6 +35,10 @@ nv10_screen_get_param(struct pipe_screen *screen, int param)  		return 12;  	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:  		return 0; +	case PIPE_CAP_TGSI_CONT_SUPPORTED: +		return 0; +	case PIPE_CAP_BLEND_EQUATION_SEPARATE: +		return 0;  	case NOUVEAU_CAP_HW_VTXBUF:  	case NOUVEAU_CAP_HW_IDXBUF:  		return 0; @@ -74,7 +78,15 @@ nv10_screen_is_format_supported(struct pipe_screen *screen,  		switch (format) {  		case PIPE_FORMAT_A8R8G8B8_UNORM:  		case PIPE_FORMAT_R5G6B5_UNORM:  +			 return TRUE; +		default: +			 break; +		} +	} else +	if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { +		switch (format) {  		case PIPE_FORMAT_Z24S8_UNORM: +		case PIPE_FORMAT_Z24X8_UNORM:  		case PIPE_FORMAT_Z16_UNORM:  			return TRUE;  		default: diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c index 024356ca74..e6924ad71e 100644 --- a/src/gallium/drivers/nv20/nv20_screen.c +++ b/src/gallium/drivers/nv20/nv20_screen.c @@ -35,6 +35,10 @@ nv20_screen_get_param(struct pipe_screen *screen, int param)  		return 12;  	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:  		return 0; +	case PIPE_CAP_TGSI_CONT_SUPPORTED: +		return 0; +	case PIPE_CAP_BLEND_EQUATION_SEPARATE: +		return 0;  	case NOUVEAU_CAP_HW_VTXBUF:  	case NOUVEAU_CAP_HW_IDXBUF:  		return 0; @@ -74,7 +78,15 @@ nv20_screen_is_format_supported(struct pipe_screen *screen,  		switch (format) {  		case PIPE_FORMAT_A8R8G8B8_UNORM:  		case PIPE_FORMAT_R5G6B5_UNORM:  +			return TRUE; +		default: +			 break; +		} +	} else +	if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { +		switch (format) {  		case PIPE_FORMAT_Z24S8_UNORM: +		case PIPE_FORMAT_Z24X8_UNORM:  		case PIPE_FORMAT_Z16_UNORM:  			return TRUE;  		default: diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 31bc1f3173..c8b40784b0 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -46,6 +46,10 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param)  		return 1;  	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:  		return 0; +	case PIPE_CAP_TGSI_CONT_SUPPORTED: +		return 0; +	case PIPE_CAP_BLEND_EQUATION_SEPARATE: +		return 0;  	case NOUVEAU_CAP_HW_VTXBUF:  	case NOUVEAU_CAP_HW_IDXBUF:  		return 1; @@ -85,7 +89,15 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen,  		switch (format) {  		case PIPE_FORMAT_A8R8G8B8_UNORM:  		case PIPE_FORMAT_R5G6B5_UNORM: +			return TRUE; +		default: +			break; +		} +	} else +	if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { +		switch (tex_usage) {  		case PIPE_FORMAT_Z24S8_UNORM: +		case PIPE_FORMAT_Z24X8_UNORM:  		case PIPE_FORMAT_Z16_UNORM:  			return TRUE;  		default: diff --git a/src/gallium/drivers/nv30/nv30_state_fb.c b/src/gallium/drivers/nv30/nv30_state_fb.c index cb1a260eaa..44b6a74715 100644 --- a/src/gallium/drivers/nv30/nv30_state_fb.c +++ b/src/gallium/drivers/nv30/nv30_state_fb.c @@ -65,6 +65,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)  		rt_format |= NV34TCL_RT_FORMAT_ZETA_Z16;  		break;  	case PIPE_FORMAT_Z24S8_UNORM: +	case PIPE_FORMAT_Z24X8_UNORM:  	case 0:  		rt_format |= NV34TCL_RT_FORMAT_ZETA_Z24S8;  		break; diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index b8b2af482a..5d2a4216c5 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -44,6 +44,10 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param)  		return 1;  	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:  		return 0; /* We have 4 - but unsupported currently */ +	case PIPE_CAP_TGSI_CONT_SUPPORTED: +		return 0; +	case PIPE_CAP_BLEND_EQUATION_SEPARATE: +		return 1;  	case NOUVEAU_CAP_HW_VTXBUF:  		return 1;  	case NOUVEAU_CAP_HW_IDXBUF: @@ -86,7 +90,15 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen,  		switch (format) {  		case PIPE_FORMAT_A8R8G8B8_UNORM:  		case PIPE_FORMAT_R5G6B5_UNORM:  +			return TRUE; +		default: +			break; +		} +	} else +	if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { +		switch (format) {  		case PIPE_FORMAT_Z24S8_UNORM: +		case PIPE_FORMAT_Z24X8_UNORM:  		case PIPE_FORMAT_Z16_UNORM:  			return TRUE;  		default: diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 273142f9e0..c2f739157a 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -73,6 +73,7 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40)  		rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16;  		break;  	case PIPE_FORMAT_Z24S8_UNORM: +	case PIPE_FORMAT_Z24X8_UNORM:  	case 0:  		rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8;  		break; diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c index ce45055fe8..6d92ac3db9 100644 --- a/src/gallium/drivers/nv40/nv40_transfer.c +++ b/src/gallium/drivers/nv40/nv40_transfer.c @@ -136,7 +136,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,  }  static void -nv40_transfer_del(struct pipe_screen *pscreen, struct pipe_transfer *ptx) +nv40_transfer_del(struct pipe_transfer *ptx)  {  	struct nv40_transfer *tx = (struct nv40_transfer *)ptx; diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 6b605ba416..22465e0227 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -42,6 +42,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)  	mt->base.screen = pscreen;  	switch (pt->format) { +	case PIPE_FORMAT_Z24X8_UNORM:  	case PIPE_FORMAT_Z24S8_UNORM:  	case PIPE_FORMAT_Z16_UNORM:  		tile_flags = 0x2800; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index fd39fa738b..ce8f906b15 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -37,7 +37,15 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,  		switch (format) {  		case PIPE_FORMAT_A8R8G8B8_UNORM:  		case PIPE_FORMAT_R5G6B5_UNORM: +			return TRUE; +		default: +			break; +		} +	} else +	if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { +		switch (format) {  		case PIPE_FORMAT_Z24S8_UNORM: +		case PIPE_FORMAT_Z24X8_UNORM:  		case PIPE_FORMAT_Z16_UNORM:  			return TRUE;  		default: @@ -101,6 +109,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)  		return 1;  	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:  		return 0; +	case PIPE_CAP_TGSI_CONT_SUPPORTED: +		return 0; +	case PIPE_CAP_BLEND_EQUATION_SEPARATE: +		return 1;  	case NOUVEAU_CAP_HW_VTXBUF:  		return 1;  	case NOUVEAU_CAP_HW_IDXBUF: diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 0caf4b4e91..d313e9de4f 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -93,6 +93,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)  			      NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);  		switch (fb->zsbuf->format) {  		case PIPE_FORMAT_Z24S8_UNORM: +		case PIPE_FORMAT_Z24X8_UNORM:  			so_data(so, 0x16);  			break;  		case PIPE_FORMAT_Z16_UNORM: diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 8db3b6d344..3da9d6e728 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -35,7 +35,6 @@ nv50_format(enum pipe_format format)  {  	switch (format) {  	case PIPE_FORMAT_A8R8G8B8_UNORM: -	case PIPE_FORMAT_Z24S8_UNORM:  		return NV50_2D_DST_FORMAT_32BPP;  	case PIPE_FORMAT_X8R8G8B8_UNORM:  		return NV50_2D_DST_FORMAT_24BPP; diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index e44f9b9dfc..faceec9842 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -4,20 +4,22 @@ include $(TOP)/configs/current  LIBNAME = r300  C_SOURCES = \ +	r3xx_fs.c \ +	r5xx_fs.c \  	r300_chipset.c \  	r300_clear.c \  	r300_context.c \  	r300_debug.c \  	r300_emit.c \  	r300_flush.c \ +	r300_fs.c \  	r300_query.c \  	r300_render.c \  	r300_screen.c \  	r300_state.c \  	r300_state_derived.c \  	r300_state_invariant.c \ -	r300_state_shader.c \ -	r300_state_tcl.c \ +	r300_vs.c \  	r300_surface.c \  	r300_texture.c diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 182ed2d459..493d7b28bc 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -5,20 +5,22 @@ env = env.Clone()  r300 = env.ConvenienceLibrary(      target = 'r300',      source = [ +        'r3xx_fs.c', +        'r5xx_fs.c',          'r300_chipset.c',          'r300_clear.c',          'r300_context.c',          'r300_debug.c',          'r300_emit.c',          'r300_flush.c', +        'r300_fs.c',          'r300_query.c',          'r300_render.c',          'r300_screen.c',          'r300_state.c',          'r300_state_derived.c',          'r300_state_invariant.c', -        'r300_state_shader.c', -        'r300_state_tcl.c', +        'r300_vs.c',          'r300_surface.c',          'r300_texture.c',      ]) diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 27bc7fd1a9..d891fd6265 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -149,7 +149,7 @@ struct r300_constant_buffer {      unsigned count;  }; -struct r3xx_fragment_shader { +struct r300_fragment_shader {      /* Parent class */      struct pipe_shader_state state;      struct tgsi_shader_info info; @@ -165,9 +165,9 @@ struct r3xx_fragment_shader {      boolean uses_imms;  }; -struct r300_fragment_shader { +struct r3xx_fragment_shader {      /* Parent class */ -    struct r3xx_fragment_shader shader; +    struct r300_fragment_shader shader;      /* Number of ALU instructions */      int alu_instruction_count; @@ -190,9 +190,9 @@ struct r300_fragment_shader {      } instructions[64]; /* XXX magic num */  }; -struct r500_fragment_shader { +struct r5xx_fragment_shader {      /* Parent class */ -    struct r3xx_fragment_shader shader; +    struct r300_fragment_shader shader;      /* Number of used instructions */      int instruction_count; @@ -217,7 +217,7 @@ struct r300_texture {      /* Stride (pitch?) of this texture in bytes */      unsigned stride; -     +      /* Total size of this texture, in bytes. */      unsigned size; @@ -300,7 +300,7 @@ struct r300_context {      /* Depth, stencil, and alpha state. */      struct r300_dsa_state* dsa_state;      /* Fragment shader. */ -    struct r3xx_fragment_shader* fs; +    struct r300_fragment_shader* fs;      /* Framebuffer state. We currently don't need our own version of this. */      struct pipe_framebuffer_state framebuffer_state;      /* Rasterizer state. */ @@ -331,7 +331,8 @@ struct r300_context {  };  /* Convenience cast wrapper. */ -static struct r300_context* r300_context(struct pipe_context* context) { +static INLINE struct r300_context* r300_context(struct pipe_context* context) +{      return (struct r300_context*)context;  } diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 678cd2b812..c83e8526cf 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -22,7 +22,7 @@  #include "r300_debug.h" -static void r300_dump_fs(struct r300_fragment_shader* fs) +void r3xx_dump_fs(struct r3xx_fragment_shader* fs)  {      int i; @@ -30,7 +30,7 @@ static void r300_dump_fs(struct r300_fragment_shader* fs)      }  } -void r500_fs_dump(struct r500_fragment_shader* fs) +void r5xx_fs_dump(struct r5xx_fragment_shader* fs)  {      int i;      uint32_t inst; @@ -58,8 +58,8 @@ void r500_fs_dump(struct r500_fragment_shader* fs)                  inst & R500_INST_NOP ? "NOP" : "",                  inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : "");          debug_printf("wmask: %s omask: %s\n", -                r500_fs_mask[(inst >> 11) & 0xf], -                r500_fs_mask[(inst >> 15) & 0xf]); +                r5xx_fs_mask[(inst >> 11) & 0xf], +                r5xx_fs_mask[(inst >> 15) & 0xf]);          switch (inst & 0x3) {              case R500_INST_TYPE_ALU:              case R500_INST_TYPE_OUT: @@ -85,36 +85,36 @@ void r500_fs_dump(struct r500_fragment_shader* fs)                  debug_printf("    3: RGB_INST   0x%08x:", inst);                  debug_printf("rgb_A_src:%d %s/%s/%s %d "                          "rgb_B_src:%d %s/%s/%s %d\n", -                        inst & 0x3, r500_fs_swiz[(inst >> 2) & 0x7], -                        r500_fs_swiz[(inst >> 5) & 0x7], -                        r500_fs_swiz[(inst >> 8) & 0x7], +                        inst & 0x3, r5xx_fs_swiz[(inst >> 2) & 0x7], +                        r5xx_fs_swiz[(inst >> 5) & 0x7], +                        r5xx_fs_swiz[(inst >> 8) & 0x7],                          (inst >> 11) & 0x3, (inst >> 13) & 0x3, -                        r500_fs_swiz[(inst >> 15) & 0x7], -                        r500_fs_swiz[(inst >> 18) & 0x7], -                        r500_fs_swiz[(inst >> 21) & 0x7], +                        r5xx_fs_swiz[(inst >> 15) & 0x7], +                        r5xx_fs_swiz[(inst >> 18) & 0x7], +                        r5xx_fs_swiz[(inst >> 21) & 0x7],                          (inst >> 24) & 0x3);                  inst = fs->instructions[i].inst4;                  debug_printf("    4: ALPHA_INST 0x%08x:", inst);                  debug_printf("%s dest:%d%s alp_A_src:%d %s %d "                          "alp_B_src:%d %s %d w:%d\n", -                        r500_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f, +                        r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,                          inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3, -                        r500_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3, -                        (inst >> 19) & 0x3, r500_fs_swiz[(inst >> 21) & 0x7], +                        r5xx_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3, +                        (inst >> 19) & 0x3, r5xx_fs_swiz[(inst >> 21) & 0x7],                          (inst >> 24) & 0x3, (inst >> 31) & 0x1);                  inst = fs->instructions[i].inst5;                  debug_printf("    5: RGBA_INST  0x%08x:", inst);                  debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d "                          "alp_C_src:%d %s %d\n", -                        r500_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f, +                        r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,                          inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3, -                        r500_fs_swiz[(inst >> 14) & 0x7], -                        r500_fs_swiz[(inst >> 17) & 0x7], -                        r500_fs_swiz[(inst >> 20) & 0x7], +                        r5xx_fs_swiz[(inst >> 14) & 0x7], +                        r5xx_fs_swiz[(inst >> 17) & 0x7], +                        r5xx_fs_swiz[(inst >> 20) & 0x7],                          (inst >> 23) & 0x3, (inst >> 25) & 0x3, -                        r500_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3); +                        r5xx_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3);                  break;              case R500_INST_TYPE_FC:                  /* XXX don't even bother yet */ @@ -124,7 +124,7 @@ void r500_fs_dump(struct r500_fragment_shader* fs)                  debug_printf("    1: TEX_INST   0x%08x: id: %d "                          "op:%s, %s, %s %s\n",                          inst, (inst >> 16) & 0xf, -                        r500_fs_tex[(inst >> 22) & 0x7], +                        r5xx_fs_tex[(inst >> 22) & 0x7],                          (inst & (1 << 25)) ? "ACQ" : "",                          (inst & (1 << 26)) ? "IGNUNC" : "",                          (inst & (1 << 27)) ? "UNSCALED" : "SCALED"); @@ -133,15 +133,15 @@ void r500_fs_dump(struct r500_fragment_shader* fs)                  debug_printf("    2: TEX_ADDR   0x%08x: "                          "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n",                          inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "", -                        r500_fs_swiz[(inst >> 8) & 0x3], -                        r500_fs_swiz[(inst >> 10) & 0x3], -                        r500_fs_swiz[(inst >> 12) & 0x3], -                        r500_fs_swiz[(inst >> 14) & 0x3], +                        r5xx_fs_swiz[(inst >> 8) & 0x3], +                        r5xx_fs_swiz[(inst >> 10) & 0x3], +                        r5xx_fs_swiz[(inst >> 12) & 0x3], +                        r5xx_fs_swiz[(inst >> 14) & 0x3],                          (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "", -                        r500_fs_swiz[(inst >> 24) & 0x3], -                        r500_fs_swiz[(inst >> 26) & 0x3], -                        r500_fs_swiz[(inst >> 28) & 0x3], -                        r500_fs_swiz[(inst >> 30) & 0x3]); +                        r5xx_fs_swiz[(inst >> 24) & 0x3], +                        r5xx_fs_swiz[(inst >> 26) & 0x3], +                        r5xx_fs_swiz[(inst >> 28) & 0x3], +                        r5xx_fs_swiz[(inst >> 30) & 0x3]);                  inst = fs->instructions[i].inst3;                  debug_printf("    3: TEX_DXDY   0x%08x\n", inst); diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h index c86410ec0a..6b58c1e250 100644 --- a/src/gallium/drivers/r300/r300_debug.h +++ b/src/gallium/drivers/r300/r300_debug.h @@ -24,10 +24,10 @@  #define R300_DEBUG_H  #include "r300_reg.h" -#include "r300_state_shader.h" -#include "r300_state_tcl.h" +#include "r300_fs.h" +#include "r300_vs.h" -static char* r500_fs_swiz[] = { +static char* r5xx_fs_swiz[] = {      " R",      " G",      " B", @@ -38,7 +38,7 @@ static char* r500_fs_swiz[] = {      " U",  }; -static char* r500_fs_op_rgb[] = { +static char* r5xx_fs_op_rgb[] = {      "MAD",      "DP3",      "DP4", @@ -54,7 +54,7 @@ static char* r500_fs_op_rgb[] = {      "MDV",  }; -static char* r500_fs_op_alpha[] = { +static char* r5xx_fs_op_alpha[] = {      "MAD",      " DP",      "MIN", @@ -73,7 +73,7 @@ static char* r500_fs_op_alpha[] = {      "MDV",  }; -static char* r500_fs_mask[] = { +static char* r5xx_fs_mask[] = {      "NONE",      "R   ",      " G  ", @@ -92,7 +92,7 @@ static char* r500_fs_mask[] = {      "RGBA",  }; -static char* r500_fs_tex[] = { +static char* r5xx_fs_tex[] = {      "    NOP",      "     LD",      "TEXKILL", @@ -203,7 +203,8 @@ static char* r300_vs_swiz_debug[] = {      "U",  }; -void r500_fs_dump(struct r500_fragment_shader* fs); +void r5xx_fs_dump(struct r5xx_fragment_shader* fs); +void r3xx_dump_fs(struct r3xx_fragment_shader* fs);  void r300_vs_dump(struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 93cf6909a3..7ba56cdc1d 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -110,7 +110,7 @@ void r300_emit_dsa_state(struct r300_context* r300,  }  void r300_emit_fragment_shader(struct r300_context* r300, -                               struct r300_fragment_shader* fs) +                               struct r3xx_fragment_shader* fs)  {      int i;      CS_LOCALS(r300); @@ -142,7 +142,7 @@ void r300_emit_fragment_shader(struct r300_context* r300,  }  void r500_emit_fragment_shader(struct r300_context* r300, -                               struct r500_fragment_shader* fs) +                               struct r5xx_fragment_shader* fs)  {      int i;      struct r300_constant_buffer* constants = @@ -289,18 +289,6 @@ void r300_emit_rs_block_state(struct r300_context* r300,      END_CS;  } -void r300_emit_sampler(struct r300_context* r300, -                       struct r300_sampler_state* sampler, unsigned offset) -{ -    CS_LOCALS(r300); - -    BEGIN_CS(6); -    OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), sampler->filter0); -    OUT_CS_REG(R300_TX_FILTER1_0 + (offset * 4), sampler->filter1); -    OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (offset * 4), sampler->border_color); -    END_CS; -} -  void r300_emit_scissor_state(struct r300_context* r300,                               struct r300_scissor_state* scissor)  { @@ -314,11 +302,17 @@ void r300_emit_scissor_state(struct r300_context* r300,  }  void r300_emit_texture(struct r300_context* r300, -                       struct r300_texture* tex, unsigned offset) +                       struct r300_sampler_state* sampler, +                       struct r300_texture* tex, +                       unsigned offset)  {      CS_LOCALS(r300); -    BEGIN_CS(10); +    BEGIN_CS(16); +    OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), sampler->filter0); +    OUT_CS_REG(R300_TX_FILTER1_0 + (offset * 4), sampler->filter1); +    OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (offset * 4), sampler->border_color); +      OUT_CS_REG(R300_TX_FORMAT0_0 + (offset * 4), tex->state.format0);      OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1);      OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2); @@ -570,10 +564,10 @@ validate:      if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {          if (r300screen->caps->is_r500) {              r500_emit_fragment_shader(r300, -                (struct r500_fragment_shader*)r300->fs); +                (struct r5xx_fragment_shader*)r300->fs);          } else {              r300_emit_fragment_shader(r300, -                (struct r300_fragment_shader*)r300->fs); +                (struct r3xx_fragment_shader*)r300->fs);          }          r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;      } @@ -593,29 +587,27 @@ validate:          r300->dirty_state &= ~R300_NEW_RS_BLOCK;      } -    if (r300->dirty_state & R300_ANY_NEW_SAMPLERS) { -        for (i = 0; i < r300->sampler_count; i++) { -            if (r300->dirty_state & (R300_NEW_SAMPLER << i)) { -                r300_emit_sampler(r300, r300->sampler_states[i], i); -                r300->dirty_state &= ~(R300_NEW_SAMPLER << i); -                dirty_tex++; -            } -        } -    } -      if (r300->dirty_state & R300_NEW_SCISSOR) {          r300_emit_scissor_state(r300, r300->scissor_state);          r300->dirty_state &= ~R300_NEW_SCISSOR;      } -    if (r300->dirty_state & R300_ANY_NEW_TEXTURES) { -        for (i = 0; i < r300->texture_count; i++) { -            if (r300->dirty_state & (R300_NEW_TEXTURE << i)) { -                r300_emit_texture(r300, r300->textures[i], i); -                r300->dirty_state &= ~(R300_NEW_TEXTURE << i); +    /* Samplers and textures are tracked separately but emitted together. */ +    if (r300->dirty_state & +            (R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) { +        for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) { +            if (r300->dirty_state & +                    ((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i))) { +                r300_emit_texture(r300, +                        r300->sampler_states[i], +                        r300->textures[i], +                        i); +                r300->dirty_state &= +                    ~((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i));                  dirty_tex++;              }          } +        r300->dirty_state &= ~(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES);      }      if (r300->dirty_state & R300_NEW_VIEWPORT) { @@ -637,6 +629,10 @@ validate:          r300->dirty_state &= ~R300_NEW_VERTEX_SHADER;      } +    /* XXX +    assert(r300->dirty_state == 0); +    */ +      /* Finally, emit the VBO. */      r300_emit_vertex_buffer(r300); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 946f625bd8..fda26f3948 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -43,10 +43,10 @@ void r300_emit_dsa_state(struct r300_context* r300,                           struct r300_dsa_state* dsa);  void r300_emit_fragment_shader(struct r300_context* r300, -                               struct r300_fragment_shader* fs); +                               struct r3xx_fragment_shader* fs);  void r500_emit_fragment_shader(struct r300_context* r300, -                               struct r500_fragment_shader* fs); +                               struct r5xx_fragment_shader* fs);  void r300_emit_fb_state(struct r300_context* r300,                          struct pipe_framebuffer_state* fb); @@ -56,14 +56,13 @@ void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs);  void r300_emit_rs_block_state(struct r300_context* r300,                                struct r300_rs_block* rs); -void r300_emit_sampler(struct r300_context* r300, -                       struct r300_sampler_state* sampler, unsigned offset); -  void r300_emit_scissor_state(struct r300_context* r300,                               struct r300_scissor_state* scissor);  void r300_emit_texture(struct r300_context* r300, -                       struct r300_texture* tex, unsigned offset); +                       struct r300_sampler_state* sampler, +                       struct r300_texture* tex, +                       unsigned offset);  void r300_emit_vertex_buffer(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index 89a5f2b20c..0dff1c6f4f 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -29,7 +29,11 @@ static void r300_flush(struct pipe_context* pipe,      struct r300_context* r300 = r300_context(pipe);      CS_LOCALS(r300); -    draw_flush(r300->draw); +    /* We probably need to flush Draw, but we may have been called from +     * within Draw. This feels kludgy, but it might be the best thing. */ +    if (!r300->draw->flushing) { +        draw_flush(r300->draw); +    }      if (r300->dirty_hw) {          FLUSH_CS; diff --git a/src/gallium/drivers/r300/r300_flush.h b/src/gallium/drivers/r300/r300_flush.h index a1b224b39c..9a83d89daa 100644 --- a/src/gallium/drivers/r300/r300_flush.h +++ b/src/gallium/drivers/r300/r300_flush.h @@ -23,6 +23,8 @@  #ifndef R300_FLUSH_H  #define R300_FLUSH_H +#include "draw/draw_private.h" +  #include "pipe/p_context.h"  #include "r300_context.h" diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c new file mode 100644 index 0000000000..4b304306d0 --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs.c @@ -0,0 +1,109 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR 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 "r300_fs.h" + +void r300_translate_fragment_shader(struct r300_context* r300, +                                    struct r300_fragment_shader* fs) +{ +    struct tgsi_parse_context parser; +    int i; +    boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; +    struct r300_constant_buffer* consts = +        &r300->shader_constants[PIPE_SHADER_FRAGMENT]; + +    struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm); +    if (assembler == NULL) { +        return; +    } +    /* Setup starting offset for immediates. */ +    assembler->imm_offset = consts->user_count; +    /* Enable depth writes, if needed. */ +    assembler->writes_depth = fs->info.writes_z; + +    /* Make sure we start at the beginning of the shader. */ +    if (is_r500) { +        ((struct r5xx_fragment_shader*)fs)->instruction_count = 0; +    } + +    tgsi_parse_init(&parser, fs->state.tokens); + +    while (!tgsi_parse_end_of_tokens(&parser)) { +        tgsi_parse_token(&parser); + +        /* This is seriously the lamest way to create fragment programs ever. +         * I blame TGSI. */ +        switch (parser.FullToken.Token.Type) { +            case TGSI_TOKEN_TYPE_DECLARATION: +                /* Allocated registers sitting at the beginning +                 * of the program. */ +                r300_fs_declare(assembler, &parser.FullToken.FullDeclaration); +                break; +            case TGSI_TOKEN_TYPE_IMMEDIATE: +                debug_printf("r300: Emitting immediate to constant buffer, " +                        "position %d\n", +                        assembler->imm_offset + assembler->imm_count); +                /* I am not amused by the length of these. */ +                for (i = 0; i < 4; i++) { +                    consts->constants[assembler->imm_offset + +                        assembler->imm_count][i] = +                        parser.FullToken.FullImmediate.u.ImmediateFloat32[i] +                        .Float; +                } +                assembler->imm_count++; +                break; +            case TGSI_TOKEN_TYPE_INSTRUCTION: +                if (is_r500) { +                    r5xx_fs_instruction((struct r5xx_fragment_shader*)fs, +                            assembler, &parser.FullToken.FullInstruction); +                } else { +                    r3xx_fs_instruction((struct r3xx_fragment_shader*)fs, +                            assembler, &parser.FullToken.FullInstruction); +                } +                break; +        } +    } + +    debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n", +            assembler->tex_count, assembler->color_count, +            assembler->tex_count + assembler->color_count); + +    consts->count = consts->user_count + assembler->imm_count; +    fs->uses_imms = assembler->imm_count; +    debug_printf("r300: fs: %d total constants, " +            "%d from user and %d from immediates\n", consts->count, +            consts->user_count, assembler->imm_count); +    r3xx_fs_finalize(fs, assembler); +    if (is_r500) { +        r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler); +    } + +    tgsi_dump(fs->state.tokens, 0); +    /* XXX finish r300 dumper too */ +    if (is_r500) { +        r5xx_fs_dump((struct r5xx_fragment_shader*)fs); +    } + +    tgsi_parse_free(&parser); +    FREE(assembler); +} diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h new file mode 100644 index 0000000000..18deb7a05e --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs.h @@ -0,0 +1,36 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR 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 R300_FS_H +#define R300_FS_H + +#include "tgsi/tgsi_dump.h" + +#include "r300_context.h" +#include "r3xx_fs.h" +#include "r5xx_fs.h" + +void r300_translate_fragment_shader(struct r300_context* r300, +                                    struct r300_fragment_shader* fs); + +    #endif /* R300_FS_H */ diff --git a/src/gallium/drivers/r300/r300_fs_inlines.h b/src/gallium/drivers/r300/r300_fs_inlines.h new file mode 100644 index 0000000000..be4be9465e --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs_inlines.h @@ -0,0 +1,158 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR 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 R300_FS_INLINES_H +#define R300_FS_INLINES_H + +#include "tgsi/tgsi_parse.h" + +#include "r300_context.h" +#include "r300_debug.h" +#include "r300_reg.h" +#include "r300_screen.h" +#include "r300_shader_inlines.h" + +/* Temporary struct used to hold assembly state while putting together + * fragment programs. */ +struct r300_fs_asm { +    /* Pipe context. */ +    struct r300_context* r300; +    /* Number of colors. */ +    unsigned color_count; +    /* Number of texcoords. */ +    unsigned tex_count; +    /* Offset for temporary registers. Inputs and temporaries have no +     * distinguishing markings, so inputs start at 0 and the first usable +     * temporary register is after all inputs. */ +    unsigned temp_offset; +    /* Number of requested temporary registers. */ +    unsigned temp_count; +    /* Offset for immediate constants. Neither R300 nor R500 can do four +     * inline constants per source, so instead we copy immediates into the +     * constant buffer. */ +    unsigned imm_offset; +    /* Number of immediate constants. */ +    unsigned imm_count; +    /* Are depth writes enabled? */ +    boolean writes_depth; +    /* Depth write offset. This is the TGSI output that corresponds to +     * depth writes. */ +    unsigned depth_output; +}; + +static INLINE void r300_fs_declare(struct r300_fs_asm* assembler, +                            struct tgsi_full_declaration* decl) +{ +    switch (decl->Declaration.File) { +        case TGSI_FILE_INPUT: +            switch (decl->Semantic.SemanticName) { +                case TGSI_SEMANTIC_COLOR: +                    assembler->color_count++; +                    break; +                case TGSI_SEMANTIC_FOG: +                case TGSI_SEMANTIC_GENERIC: +                    assembler->tex_count++; +                    break; +                default: +                    debug_printf("r300: fs: Bad semantic declaration %d\n", +                        decl->Semantic.SemanticName); +                    break; +            } +            break; +        case TGSI_FILE_OUTPUT: +            /* Depth write. Mark the position of the output so we can +             * identify it later. */ +            if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { +                assembler->depth_output = decl->DeclarationRange.First; +            } +            break; +        case TGSI_FILE_CONSTANT: +            break; +        case TGSI_FILE_TEMPORARY: +            assembler->temp_count++; +            break; +        default: +            debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File); +            break; +    } + +    assembler->temp_offset = assembler->color_count + assembler->tex_count; +} + +static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler, +                                   struct tgsi_src_register* src) +{ +    switch (src->File) { +        case TGSI_FILE_NULL: +            return 0; +        case TGSI_FILE_INPUT: +            /* XXX may be wrong */ +            return src->Index; +            break; +        case TGSI_FILE_TEMPORARY: +            return src->Index + assembler->temp_offset; +            break; +        case TGSI_FILE_IMMEDIATE: +            return (src->Index + assembler->imm_offset) | (1 << 8); +            break; +        case TGSI_FILE_CONSTANT: +            /* XXX magic */ +            return src->Index | (1 << 8); +            break; +        default: +            debug_printf("r300: fs: Unimplemented src %d\n", src->File); +            break; +    } +    return 0; +} + +static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler, +                                   struct tgsi_dst_register* dst) +{ +    switch (dst->File) { +        case TGSI_FILE_NULL: +            /* This happens during KIL instructions. */ +            return 0; +            break; +        case TGSI_FILE_OUTPUT: +            return 0; +            break; +        case TGSI_FILE_TEMPORARY: +            return dst->Index + assembler->temp_offset; +            break; +        default: +            debug_printf("r300: fs: Unimplemented dst %d\n", dst->File); +            break; +    } +    return 0; +} + +static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler, +                                      struct tgsi_dst_register* dst) +{ +    return (assembler->writes_depth && +            (dst->File == TGSI_FILE_OUTPUT) && +            (dst->Index == assembler->depth_output)); +} + +#endif /* R300_FS_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_query.h b/src/gallium/drivers/r300/r300_query.h index 4f447ea45b..6a7646087a 100644 --- a/src/gallium/drivers/r300/r300_query.h +++ b/src/gallium/drivers/r300/r300_query.h @@ -27,6 +27,8 @@  #include "r300_cs.h"  #include "r300_reg.h" +struct r300_context; +  struct r300_query {      /* The kind of query. Currently only OQ is supported. */      unsigned type; diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 3bb9bc47b5..6825d99870 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -1064,8 +1064,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.          R300_GA_COLOR_CONTROL_RGB2_SHADING_FLAT | \          R300_GA_COLOR_CONTROL_ALPHA2_SHADING_FLAT | \          R300_GA_COLOR_CONTROL_RGB3_SHADING_FLAT | \ -        R300_GA_COLOR_CONTROL_ALPHA3_SHADING_FLAT | \ -        R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST ) +        R300_GA_COLOR_CONTROL_ALPHA3_SHADING_FLAT )  #       define R300_SHADE_MODEL_SMOOTH ( \          R300_GA_COLOR_CONTROL_RGB0_SHADING_GOURAUD | \ @@ -1075,8 +1074,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.          R300_GA_COLOR_CONTROL_RGB2_SHADING_GOURAUD | \          R300_GA_COLOR_CONTROL_ALPHA2_SHADING_GOURAUD | \          R300_GA_COLOR_CONTROL_RGB3_SHADING_GOURAUD | \ -        R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD | \ -        R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST ) +        R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD )  /* Specifies red & green components of fill color -- S312 format -- Backwards comp. */  #define R300_GA_SOLID_RG                         0x427c @@ -1480,6 +1478,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #       define R300_TX_PITCH_EN                  (1 << 31)  #       define R300_TX_WIDTH(x)                  ((x) << 0)  #       define R300_TX_HEIGHT(x)                 ((x) << 11) +#       define R300_TX_NUM_LEVELS(x)             ((x) << 26)  #define R300_TX_FORMAT1_0                   0x44C0  	/* The interpretation of the format word by Wladimir van der Laan */ @@ -1487,9 +1486,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  	   They are given meanings as R, G, B and Alpha by the swizzle  	   specification */  #	define R300_TX_FORMAT_X8		    0x0 -#	define R500_TX_FORMAT_X1		    0x0 // bit set in format 2  #	define R300_TX_FORMAT_X16		    0x1 -#	define R500_TX_FORMAT_X1_REV		    0x0 // bit set in format 2  #	define R300_TX_FORMAT_Y4X4		    0x2  #	define R300_TX_FORMAT_Y8X8		    0x3  #	define R300_TX_FORMAT_Y16X16		    0x4 @@ -1506,31 +1503,29 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #	define R300_TX_FORMAT_DXT1	    	    0xF  #	define R300_TX_FORMAT_DXT3	    	    0x10  #	define R300_TX_FORMAT_DXT5	    	    0x11 -#	define R300_TX_FORMAT_D3DMFT_CxV8U8	    0x12     /* no swizzle */ -#	define R300_TX_FORMAT_A8R8G8B8	    	    0x13     /* no swizzle */ -#	define R300_TX_FORMAT_B8G8_B8G8	    	    0x14     /* no swizzle */ -#	define R300_TX_FORMAT_G8R8_G8B8	    	    0x15     /* no swizzle */ +#	define R300_TX_FORMAT_Y8           	    0x12 +#	define R300_TX_FORMAT_AVYU444 	    	    0x13 +#	define R300_TX_FORMAT_VYUY422  	    	    0x14 +#	define R300_TX_FORMAT_YVYU422  	    	    0x15 +#	define R300_TX_FORMAT_16_MPEG  	    	    0x16 +#	define R300_TX_FORMAT_16_16_MPEG    	    0x17 +#	define R300_TX_FORMAT_16F     	    	    0x18 +#	define R300_TX_FORMAT_16F_16F 	    	    0x19 +#	define R300_TX_FORMAT_16F_16F_16F_16F  	    0x1A +#	define R300_TX_FORMAT_32F     	    	    0x1B +#	define R300_TX_FORMAT_32F_32F 	    	    0x1C +#	define R300_TX_FORMAT_32F_32F_32F_32F  	    0x1D +#       define R300_TX_FORMAT_W24_FP                0x1E -	/* These two values are wrong, but they're the only values that -	 * produce any even vaguely correct results.  Can r300 only do 16-bit -	 * depth textures? -	 */ -#	define R300_TX_FORMAT_X24_Y8	    	    0x1e -#	define R300_TX_FORMAT_X32	    	    0x1e +#       define R300_TX_FORMAT_SIGNED_W             (1 << 5) +#       define R300_TX_FORMAT_SIGNED_Z             (1 << 6) +#       define R300_TX_FORMAT_SIGNED_Y             (1 << 7) +#       define R300_TX_FORMAT_SIGNED_X             (1 << 8) +#       define R300_TX_FORMAT_SIGNED               (0xf << 5) -	/* 0x16 - some 16 bit green format.. ?? */  #	define R300_TX_FORMAT_3D		   (1 << 25)  #	define R300_TX_FORMAT_CUBIC_MAP		   (2 << 25) -	/* gap */ -	/* Floating point formats */ -	/* Note - hardware supports both 16 and 32 bit floating point */ -#	define R300_TX_FORMAT_FL_I16	    	    0x18 -#	define R300_TX_FORMAT_FL_I16A16	    	    0x19 -#	define R300_TX_FORMAT_FL_R16G16B16A16	    0x1A -#	define R300_TX_FORMAT_FL_I32	    	    0x1B -#	define R300_TX_FORMAT_FL_I32A32	    	    0x1C -#	define R300_TX_FORMAT_FL_R32G32B32A32	    0x1D  	/* alpha modes, convenience mostly */  	/* if you have alpha, pick constant appropriate to the  	   number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ @@ -1571,7 +1566,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  #	define R300_TX_FORMAT_CONST_Z		(4<<5)  #	define R300_TX_FORMAT_CONST_W		(8<<5) -#	define R300_TX_FORMAT_YUV_MODE		0x00800000 +#       define R300_TX_FORMAT_GAMMA               (1 << 21) +#       define R300_TX_FORMAT_YUV_TO_RGB          (1 << 22)  #define R300_TX_FORMAT2_0		    0x4500 /* obvious missing in gap */  #       define R300_TX_PITCHMASK_SHIFT           0 diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index a6f1efe356..da1d5ffe2f 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -94,8 +94,7 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)                  return 0;              }          case PIPE_CAP_S3TC: -            /* IN THEORY */ -            return 0; +            return 1;          case PIPE_CAP_ANISOTROPIC_FILTER:              return 1;          case PIPE_CAP_POINT_SPRITE: @@ -145,6 +144,9 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)          case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:              /* XXX guessing (what a terrible guess) */              return 2; +        case PIPE_CAP_TGSI_CONT_SUPPORTED: +            /* XXX */ +            return 0;          default:              debug_printf("r300: Implementation error: Bad param %d\n",                  param); @@ -179,21 +181,58 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param)      }  } -static boolean check_tex_2d_format(enum pipe_format format, boolean is_r500) +static boolean check_tex_2d_format(enum pipe_format format, uint32_t usage, +                                   boolean is_r500)  {      switch (format) { +        /* Supported formats. */          /* Colorbuffer */          case PIPE_FORMAT_A4R4G4B4_UNORM:          case PIPE_FORMAT_R5G6B5_UNORM:          case PIPE_FORMAT_A1R5G5B5_UNORM: -        case PIPE_FORMAT_A8R8G8B8_UNORM: +            return usage & +                (PIPE_TEXTURE_USAGE_RENDER_TARGET | +                 PIPE_TEXTURE_USAGE_DISPLAY_TARGET | +                 PIPE_TEXTURE_USAGE_PRIMARY); + +        /* Texture */ +        case PIPE_FORMAT_A8R8G8B8_SRGB: +        case PIPE_FORMAT_R8G8B8A8_SRGB: +        case PIPE_FORMAT_DXT1_RGB: +        case PIPE_FORMAT_DXT1_RGBA: +        case PIPE_FORMAT_DXT3_RGBA: +        case PIPE_FORMAT_DXT5_RGBA: +        case PIPE_FORMAT_YCBCR: +            return usage & PIPE_TEXTURE_USAGE_SAMPLER; +          /* Colorbuffer or texture */ +        case PIPE_FORMAT_A8R8G8B8_UNORM: +        case PIPE_FORMAT_R8G8B8A8_UNORM:          case PIPE_FORMAT_I8_UNORM: +            return usage & +                (PIPE_TEXTURE_USAGE_RENDER_TARGET | +                 PIPE_TEXTURE_USAGE_DISPLAY_TARGET | +                 PIPE_TEXTURE_USAGE_PRIMARY | +                 PIPE_TEXTURE_USAGE_SAMPLER); +          /* Z buffer */          case PIPE_FORMAT_Z16_UNORM: -        /* Z buffer with stencil */ +            return usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + +        /* Z buffer with stencil or texture */          case PIPE_FORMAT_Z24S8_UNORM: -            return TRUE; +            return usage & +                (PIPE_TEXTURE_USAGE_DEPTH_STENCIL | +                 PIPE_TEXTURE_USAGE_SAMPLER); + +        /* Definitely unsupported formats. */ +        /* Non-usable Z buffer/stencil formats. */ +        case PIPE_FORMAT_Z24X8_UNORM: +        case PIPE_FORMAT_S8Z24_UNORM: +        case PIPE_FORMAT_X8Z24_UNORM: +            debug_printf("r300: Note: Got unsupported format: %s in %s\n", +                pf_name(format), __FUNCTION__); +            return FALSE;          /* XXX These don't even exist          case PIPE_FORMAT_A32R32G32B32: @@ -216,7 +255,8 @@ static boolean check_tex_2d_format(enum pipe_format format, boolean is_r500)              return FALSE; */          default: -            debug_printf("r300: Warning: Got unsupported format: %s in %s\n", +            /* Unknown format... */ +            debug_printf("r300: Warning: Got unknown format: %s in %s\n",                  pf_name(format), __FUNCTION__);              break;      } @@ -233,7 +273,7 @@ static boolean r300_is_format_supported(struct pipe_screen* pscreen,  {      switch (target) {          case PIPE_TEXTURE_2D: -            return check_tex_2d_format(format, +            return check_tex_2d_format(format, tex_usage,                  r300_screen(pscreen)->caps->is_r500);          case PIPE_TEXTURE_1D:          case PIPE_TEXTURE_3D: diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 3f52dbc3be..2a0e41fbc3 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -49,7 +49,7 @@ struct r300_transfer {  };  /* Convenience cast wrapper. */ -static struct r300_screen* r300_screen(struct pipe_screen* screen) { +static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {      return (struct r300_screen*)screen;  } diff --git a/src/gallium/drivers/r300/r300_shader_inlines.h b/src/gallium/drivers/r300/r300_shader_inlines.h new file mode 100644 index 0000000000..a04f45b03e --- /dev/null +++ b/src/gallium/drivers/r300/r300_shader_inlines.h @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR 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 R300_SHADER_INLINES_H +#define R300_SHADER_INLINES_H + +/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're + * not using enough of it. */ +static const struct tgsi_full_src_register r300_constant_zero = { +    .SrcRegister.Extended = TRUE, +    .SrcRegister.File = TGSI_FILE_NULL, +    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, +    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, +    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, +    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, +}; + +static const struct tgsi_full_src_register r300_constant_one = { +    .SrcRegister.Extended = TRUE, +    .SrcRegister.File = TGSI_FILE_NULL, +    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE, +    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE, +    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE, +    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE, +}; + +#endif /* R300_SHADER_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 01e2b51153..68da0aa4cb 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -24,12 +24,14 @@  #include "util/u_pack_color.h"  #include "util/u_debug.h" + +#include "pipe/p_config.h"  #include "pipe/internal/p_winsys_screen.h"  #include "r300_context.h"  #include "r300_reg.h"  #include "r300_state_inlines.h" -#include "r300_state_shader.h" +#include "r300_fs.h"  /* r300_state: Functions used to intialize state context by translating   * Gallium state objects into semi-native r300 state objects. */ @@ -283,14 +285,12 @@ static void* r300_create_fs_state(struct pipe_context* pipe,                                    const struct pipe_shader_state* shader)  {      struct r300_context* r300 = r300_context(pipe); -    struct r3xx_fragment_shader* fs = NULL; +    struct r300_fragment_shader* fs = NULL;      if (r300_screen(r300->context.screen)->caps->is_r500) { -        fs = -            (struct r3xx_fragment_shader*)CALLOC_STRUCT(r500_fragment_shader); +        fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader);      } else { -        fs = -            (struct r3xx_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader); +        fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader);      }      /* Copy state directly into shader. */ @@ -306,7 +306,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,  static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)  {      struct r300_context* r300 = r300_context(pipe); -    struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader; +    struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;      if (fs == NULL) {          r300->fs = NULL; @@ -324,7 +324,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)  /* Delete fragment shader state. */  static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)  { -    struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader; +    struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;      FREE(fs->state.tokens);      FREE(shader);  } @@ -352,14 +352,19 @@ static void* r300_create_rs_state(struct pipe_context* pipe,      rs->enable_vte = !state->bypass_vs_clip_and_viewport; +#ifdef PIPE_ARCH_LITTLE_ENDIAN +    rs->vap_control_status = R300_VC_NO_SWAP; +#else +    rs->vap_control_status = R300_VC_32BIT_SWAP; +#endif +      /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.       * Else, enable HW TCL and force Draw's TCL off. */      if (state->bypass_vs_clip_and_viewport ||              !r300_screen(pipe->screen)->caps->has_tcl) { -        rs->vap_control_status = R300_VAP_TCL_BYPASS; +        rs->vap_control_status |= R300_VAP_TCL_BYPASS;      } else {          rs->rs.bypass_vs_clip_and_viewport = TRUE; -        rs->vap_control_status = 0;      }      rs->point_size = pack_float_16_6x(state->point_size) | @@ -423,6 +428,10 @@ static void* r300_create_rs_state(struct pipe_context* pipe,          rs->color_control = R300_SHADE_MODEL_SMOOTH;      } +    if (!state->flatshade_first) { +        rs->color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST; +    } +      return (void*)rs;  } diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index e438114010..9f534b8ce3 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -34,14 +34,17 @@ void r300_emit_invariant_state(struct r300_context* r300)      struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;      CS_LOCALS(r300); -    BEGIN_CS(26 + (caps->has_tcl ? 2: 0)); +    BEGIN_CS(22 + (caps->has_tcl ? 2: 0));      /*** Graphics Backend (GB) ***/      /* Various GB enables */      OUT_CS_REG(R300_GB_ENABLE, 0x0); -    /* Subpixel multisampling for AA */ -    OUT_CS_REG(R300_GB_MSPOS0, 0x66666666); -    OUT_CS_REG(R300_GB_MSPOS1, 0x6666666); +    /* Subpixel multisampling for AA +     * These are commented out because glisse's CS checker doesn't like them. +     * I presume these will be re-enabled later. +     * OUT_CS_REG(R300_GB_MSPOS0, 0x66666666); +     * OUT_CS_REG(R300_GB_MSPOS1, 0x6666666); +     */      /* Source of fog depth */      OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W);      /* AA enable */ @@ -69,7 +72,7 @@ void r300_emit_invariant_state(struct r300_context* r300)      END_CS;      /* XXX unsorted stuff from surface_fill */ -    BEGIN_CS(77 + (caps->has_tcl ? 5 : 0)); +    BEGIN_CS(75 + (caps->has_tcl ? 5 : 0));      /* Flush PVS. */      OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); @@ -77,17 +80,12 @@ void r300_emit_invariant_state(struct r300_context* r300)          R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |          R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |          R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT); -    /* XXX endian */      if (caps->has_tcl) { -        OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP);          OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);          OUT_CS_32F(1.0);          OUT_CS_32F(1.0);          OUT_CS_32F(1.0);          OUT_CS_32F(1.0); -    } else { -        OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP | -                R300_VAP_TCL_BYPASS);      }      /* XXX point tex stuffing */      OUT_CS_REG_SEQ(R300_GA_POINT_S0, 1); diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index c9e2dff14e..fdabe4d9cf 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -151,11 +151,11 @@ validate:      /* Fragment shader setup */      if (caps->is_r500) { -        r500_emit_fragment_shader(r300, &r500_passthrough_fragment_shader); -        r300_emit_rs_block_state(r300, &r500_rs_block_clear_state); +        r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader); +        r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);      } else { -        r300_emit_fragment_shader(r300, &r300_passthrough_fragment_shader); -        r300_emit_rs_block_state(r300, &r300_rs_block_clear_state); +        r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader); +        r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);      }      BEGIN_CS(26); @@ -228,13 +228,14 @@ static void r300_surface_copy(struct pipe_context* pipe,      struct r300_texture* desttex = (struct r300_texture*)dest->texture;      unsigned pixpitch = srctex->stride / srctex->tex.block.size;      boolean invalid = FALSE; +    float fsrcx = srcx, fsrcy = srcy, fdestx = destx, fdesty = desty;      CS_LOCALS(r300);      debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d),"          " dimensions %dx%d (pixel pitch %d)\n",          src, srcx, srcy, dest, destx, desty, w, h, pixpitch); -    if ((srctex == desttex) && +    if ((srctex->buffer == desttex->buffer) &&              ((destx < srcx + w) || (srcx < destx + w)) &&              ((desty < srcy + h) || (srcy < desty + h))) {  fallback: @@ -267,14 +268,10 @@ validate:      r300_surface_setup(r300, desttex, destx, desty, w, h);      /* Setup the texture. */ -    r300_emit_sampler(r300, &r300_sampler_copy_state, 0); -    r300_emit_texture(r300, srctex, 0); +    r300_emit_texture(r300, &r300_sampler_copy_state, srctex, 0);      /* Flush and enable. */ -    BEGIN_CS(4); -    OUT_CS_REG(R300_TX_INVALTAGS, 0); -    OUT_CS_REG(R300_TX_ENABLE, 0x1); -    END_CS; +    r300_flush_textures(r300);      /* Vertex shader setup */      if (caps->has_tcl) { @@ -291,11 +288,11 @@ validate:      /* Fragment shader setup */      if (caps->is_r500) { -        r500_emit_fragment_shader(r300, &r500_texture_fragment_shader); -        r300_emit_rs_block_state(r300, &r500_rs_block_copy_state); +        r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader); +        r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);      } else { -        r300_emit_fragment_shader(r300, &r300_texture_fragment_shader); -        r300_emit_rs_block_state(r300, &r300_rs_block_copy_state); +        r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader); +        r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);      }      BEGIN_CS(30); @@ -329,25 +326,25 @@ validate:      OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING |              (4 << R300_PRIM_NUM_VERTICES_SHIFT));      /* (x    , y    ) */ -    OUT_CS_32F((float)(destx / dest->width)); -    OUT_CS_32F((float)(desty / dest->height)); -    OUT_CS_32F((float)(srcx  / dest->width)); -    OUT_CS_32F((float)(srcy  / dest->height)); +    OUT_CS_32F(fdestx / dest->width); +    OUT_CS_32F(fdesty / dest->height); +    OUT_CS_32F(fsrcx  / src->width); +    OUT_CS_32F(fsrcy  / src->height);      /* (x    , y + h) */ -    OUT_CS_32F((float)(destx / dest->width)); -    OUT_CS_32F((float)((desty + h) / dest->height)); -    OUT_CS_32F((float)(srcx  / dest->width)); -    OUT_CS_32F((float)((srcy  + h) / dest->height)); +    OUT_CS_32F(fdestx / dest->width); +    OUT_CS_32F((fdesty + h) / dest->height); +    OUT_CS_32F(fsrcx  / src->width); +    OUT_CS_32F((fsrcy  + h) / src->height);      /* (x + w, y + h) */ -    OUT_CS_32F((float)((destx + w) / dest->width)); -    OUT_CS_32F((float)((desty + h) / dest->height)); -    OUT_CS_32F((float)((srcx  + w) / dest->width)); -    OUT_CS_32F((float)((srcy  + h) / dest->height)); +    OUT_CS_32F((fdestx + w) / dest->width); +    OUT_CS_32F((fdesty + h) / dest->height); +    OUT_CS_32F((fsrcx  + w) / src->width); +    OUT_CS_32F((fsrcy  + h) / src->height);      /* (x + w, y    ) */ -    OUT_CS_32F((float)((destx + w) / dest->width)); -    OUT_CS_32F((float)(desty / dest->height)); -    OUT_CS_32F((float)((srcx  + w) / dest->width)); -    OUT_CS_32F((float)(srcy  / dest->height)); +    OUT_CS_32F((fdestx + w) / dest->width); +    OUT_CS_32F(fdesty / dest->height); +    OUT_CS_32F((fsrcx  + w) / src->width); +    OUT_CS_32F(fsrcy  / src->height);      OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h index 9a4c39f58b..d01f0b143f 100644 --- a/src/gallium/drivers/r300/r300_surface.h +++ b/src/gallium/drivers/r300/r300_surface.h @@ -31,8 +31,8 @@  #include "r300_context.h"  #include "r300_cs.h"  #include "r300_emit.h" -#include "r300_state_shader.h" -#include "r300_state_tcl.h" +#include "r300_fs.h" +#include "r300_vs.h"  #include "r300_state_inlines.h"  static struct r300_blend_state blend_clear_state = { @@ -72,7 +72,7 @@ static struct r300_rs_state rs_clear_state = {      .color_control = R300_SHADE_MODEL_FLAT,  }; -static struct r300_rs_block r300_rs_block_clear_state = { +static struct r300_rs_block r3xx_rs_block_clear_state = {      .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |          R500_RS_SEL_T(R300_RS_SEL_K0) |          R500_RS_SEL_R(R300_RS_SEL_K0) | @@ -82,7 +82,7 @@ static struct r300_rs_block r300_rs_block_clear_state = {      .inst_count = 0,  }; -static struct r300_rs_block r500_rs_block_clear_state = { +static struct r300_rs_block r5xx_rs_block_clear_state = {      .ip[0] = R500_RS_SEL_S(R500_RS_IP_PTR_K0) |          R500_RS_SEL_T(R500_RS_IP_PTR_K0) |          R500_RS_SEL_R(R500_RS_IP_PTR_K0) | @@ -94,7 +94,7 @@ static struct r300_rs_block r500_rs_block_clear_state = {  /* The following state is used for surface_copy only. */ -static struct r300_rs_block r300_rs_block_copy_state = { +static struct r300_rs_block r3xx_rs_block_copy_state = {      .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |          R500_RS_SEL_T(R300_RS_SEL_K0) |          R500_RS_SEL_R(R300_RS_SEL_K0) | @@ -104,7 +104,7 @@ static struct r300_rs_block r300_rs_block_copy_state = {      .inst_count = R300_RS_TX_OFFSET(0),  }; -static struct r300_rs_block r500_rs_block_copy_state = { +static struct r300_rs_block r5xx_rs_block_copy_state = {      .ip[0] = R500_RS_SEL_S(0) |          R500_RS_SEL_T(1) |          R500_RS_SEL_R(R500_RS_IP_PTR_K0) | diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 5ea9f56247..11c7858d42 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -22,6 +22,8 @@  #include "r300_texture.h" +/* XXX maths need to go to util */ +  static int minify(int i)  {      return MAX2(1, i >> 1); @@ -30,25 +32,29 @@ static int minify(int i)  static void r300_setup_texture_state(struct r300_texture* tex,                                       unsigned width,                                       unsigned height, -                                     unsigned pitch) +                                     unsigned pitch, +                                     unsigned levels)  {      struct r300_texture_state* state = &tex->state;      state->format0 = R300_TX_WIDTH((width - 1) & 0x7ff) | -        R300_TX_HEIGHT((height - 1) & 0x7ff) | R300_TX_PITCH_EN; +        R300_TX_HEIGHT((height - 1) & 0x7ff) | +        R300_TX_NUM_LEVELS(levels) | +        R300_TX_PITCH_EN;      /* XXX */ -    state->format1 = R300_TX_FORMAT_A8R8G8B8; +    state->format1 = r300_translate_texformat(tex->tex.format);      state->format2 = pitch - 1; -    /* XXX +    /* Assume (somewhat foolishly) that oversized textures will +     * not be permitted by the state tracker. */      if (width > 2048) { -        state->pitch |= R300_TXWIDTH_11; +        state->format2 |= R500_TXWIDTH_BIT11;      }      if (height > 2048) { -        state->pitch |= R300_TXHEIGHT_11; -    } */ +        state->format2 |= R500_TXHEIGHT_BIT11; +    }  }  static void r300_setup_miptree(struct r300_texture* tex) @@ -67,14 +73,18 @@ static void r300_setup_miptree(struct r300_texture* tex)          base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]);          base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]); -        /* Radeons enjoy things in multiples of 32. */ -        /* XXX this can be 32 when POT */ -        stride = (base->nblocksx[i] * base->block.size + 63) & ~63; +        /* Radeons enjoy things in multiples of 64. +         * +         * XXX +         * POT, uncompressed, unmippmapped textures can be aligned to 32, +         * instead of 64. */ +        stride = align(base->nblocksx[i] * base->block.size, 64);          size = stride * base->nblocksy[i] * base->depth[i]; -        tex->offset[i] = (tex->size + 63) & ~63; +        tex->offset[i] = align(tex->size, 64);          tex->size = tex->offset[i] + size; +        /* Save stride of first level to the texture. */          if (i == 0) {              tex->stride = stride;          } @@ -98,9 +108,8 @@ static struct pipe_texture*      r300_setup_miptree(tex); -    /* XXX */ -    r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], -            tex->tex.width[0]); +    r300_setup_texture_state(tex, template->width[0], template->height[0], +            template->width[0], template->last_level);      tex->buffer = screen->buffer_create(screen, 64,                                          PIPE_BUFFER_USAGE_PIXEL, @@ -164,6 +173,7 @@ static struct pipe_texture*  {      struct r300_texture* tex; +    /* XXX we should start doing mips now... */      if (base->target != PIPE_TEXTURE_2D ||          base->last_level != 0 ||          base->depth[0] != 1) { @@ -181,8 +191,9 @@ static struct pipe_texture*      tex->stride = *stride; +    /* XXX */      r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], -            tex->stride); +            tex->stride, 0);      pipe_buffer_reference(&tex->buffer, buffer); diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 98fb5c9a08..3b56f0307c 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -32,6 +32,52 @@  void r300_init_screen_texture_functions(struct pipe_screen* screen); +/* Note the signature of R300_EASY_TX_FORMAT(A, R, G, B, FORMAT)... */ +static INLINE uint32_t r300_translate_texformat(enum pipe_format format) +{ +    switch (format) { +        /* X8 */ +        case PIPE_FORMAT_I8_UNORM: +            return R300_EASY_TX_FORMAT(X, X, X, X, X8); +        /* W8Z8Y8X8 */ +        case PIPE_FORMAT_A8R8G8B8_UNORM: +            return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); +        case PIPE_FORMAT_R8G8B8A8_UNORM: +            return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8); +        case PIPE_FORMAT_A8R8G8B8_SRGB: +            return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8) | +                R300_TX_FORMAT_GAMMA; +        case PIPE_FORMAT_R8G8B8A8_SRGB: +            return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) | +                R300_TX_FORMAT_GAMMA; +        /* DXT1 */ +        case PIPE_FORMAT_DXT1_RGB: +            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1); +        case PIPE_FORMAT_DXT1_RGBA: +            return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1); +        /* DXT3 */ +        case PIPE_FORMAT_DXT3_RGBA: +            return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3); +        /* DXT5 */ +        case PIPE_FORMAT_DXT5_RGBA: +            return R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5); +        /* YVYU422 */ +        case PIPE_FORMAT_YCBCR: +            return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | +                R300_TX_FORMAT_YUV_TO_RGB; +        /* W24_FP */ +        case PIPE_FORMAT_Z24S8_UNORM: +            return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP); +        default: +            debug_printf("r300: Implementation error: " +                "Got unsupported texture format %s in %s\n", +                pf_name(format), __FUNCTION__); +            assert(0); +            break; +    } +    return 0; +} +  #ifndef R300_WINSYS_H  boolean r300_get_texture_buffer(struct pipe_texture* texture, diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_vs.c index 8cf8250425..f87435f9f0 100644 --- a/src/gallium/drivers/r300/r300_state_tcl.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -20,7 +20,7 @@   * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE   * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "r300_state_tcl.h" +#include "r300_vs.h"  static void r300_vs_declare(struct r300_vs_asm* assembler,                              struct tgsi_full_declaration* decl) @@ -403,7 +403,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,      debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0],              assembler->tab[1], assembler->tab[2], assembler->tab[3]); -    tgsi_dump(vs->state.tokens); +    tgsi_dump(vs->state.tokens, 0);      /* XXX finish r300 vertex shader dumper */      r300_vs_dump(vs); diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_vs.h index 2c8b586c2f..165d717812 100644 --- a/src/gallium/drivers/r300/r300_state_tcl.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -20,15 +20,17 @@   * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE   * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef R300_STATE_TCL_H -#define R300_STATE_TCL_H +#ifndef R300_VS_H +#define R300_VS_H  #include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_dump.h"  #include "r300_context.h"  #include "r300_debug.h"  #include "r300_reg.h"  #include "r300_screen.h" +#include "r300_shader_inlines.h"  /* XXX get these to r300_reg */  #define R300_PVS_DST_OPCODE(x)   ((x) << 0) @@ -84,15 +86,6 @@      (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \       R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W) -static const struct tgsi_full_src_register r300_constant_zero = { -    .SrcRegister.Extended = TRUE, -    .SrcRegister.File = TGSI_FILE_NULL, -    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, -}; -  /* Temporary struct used to hold assembly state while putting together   * fragment programs. */  struct r300_vs_asm { @@ -161,4 +154,4 @@ static struct r300_vertex_shader r300_texture_vertex_shader = {  void r300_translate_vertex_shader(struct r300_context* r300,                                    struct r300_vertex_shader* vs); -#endif /* R300_STATE_TCL_H */ +#endif /* R300_VS_H */ diff --git a/src/gallium/drivers/r300/r3xx_fs.c b/src/gallium/drivers/r300/r3xx_fs.c new file mode 100644 index 0000000000..6e05d76977 --- /dev/null +++ b/src/gallium/drivers/r300/r3xx_fs.c @@ -0,0 +1,96 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR 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 "r3xx_fs.h" + +static INLINE uint32_t r3xx_rgb_op(unsigned op) +{ +    switch (op) { +        case TGSI_OPCODE_MOV: +            return R300_ALU_OUTC_CMP; +        default: +            return 0; +    } +} + +static INLINE uint32_t r3xx_alpha_op(unsigned op) +{ +    switch (op) { +        case TGSI_OPCODE_MOV: +            return R300_ALU_OUTA_CMP; +        default: +            return 0; +    } +} + +static INLINE void r3xx_emit_maths(struct r3xx_fragment_shader* fs, +                                   struct r300_fs_asm* assembler, +                                   struct tgsi_full_src_register* src, +                                   struct tgsi_full_dst_register* dst, +                                   unsigned op, +                                   unsigned count) +{ +    int i = fs->alu_instruction_count; + +    fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | +        r3xx_rgb_op(op); +    fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | +        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; +    fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | +        r3xx_alpha_op(op); +    fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | +        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; + +    fs->alu_instruction_count++; +} + +void r3xx_fs_finalize(struct r300_fragment_shader* fs, +                      struct r300_fs_asm* assembler) +{ +    fs->stack_size = assembler->temp_count + assembler->temp_offset + 1; +} + +void r3xx_fs_instruction(struct r3xx_fragment_shader* fs, +                         struct r300_fs_asm* assembler, +                         struct tgsi_full_instruction* inst) +{ +    switch (inst->Instruction.Opcode) { +        case TGSI_OPCODE_MOV: +            /* src0 -> src1 and src2 forced to zero */ +            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; +            inst->FullSrcRegisters[2] = r300_constant_zero; +            r3xx_emit_maths(fs, assembler, inst->FullSrcRegisters, +                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); +            break; +        case TGSI_OPCODE_END: +            break; +        default: +            debug_printf("r300: fs: Bad opcode %d\n", +                    inst->Instruction.Opcode); +            break; +    } +} diff --git a/src/gallium/drivers/r300/r3xx_fs.h b/src/gallium/drivers/r300/r3xx_fs.h new file mode 100644 index 0000000000..3da39ec252 --- /dev/null +++ b/src/gallium/drivers/r300/r3xx_fs.h @@ -0,0 +1,76 @@ +/* + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR 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 R3XX_FS_H +#define R3XX_FS_H + +#include "r300_fs_inlines.h" + +static struct r3xx_fragment_shader r3xx_passthrough_fragment_shader = { +    .alu_instruction_count = 1, +    .tex_instruction_count = 0, +    .indirections = 0, +    .shader.stack_size = 1, + +    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | +        R300_ALU_OUTC_CMP, +    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | +        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, +    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | +        R300_ALU_OUTA_CMP, +    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | +        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; + +static struct r3xx_fragment_shader r3xx_texture_fragment_shader = { +    .alu_instruction_count = 1, +    .tex_instruction_count = 0, +    .indirections = 0, +    .shader.stack_size = 1, + +    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | +        R300_ALU_OUTC_CMP, +    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | +        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, +    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | +        R300_ALU_OUTA_CMP, +    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | +        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; + +void r3xx_fs_finalize(struct r300_fragment_shader* fs, +                      struct r300_fs_asm* assembler); + +void r3xx_fs_instruction(struct r3xx_fragment_shader* fs, +                         struct r300_fs_asm* assembler, +                         struct tgsi_full_instruction* inst); + +#endif /* R3XX_FS_H */ diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r5xx_fs.c index cc7f6a7c4b..99d826278c 100644 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ b/src/gallium/drivers/r300/r5xx_fs.c @@ -1,5 +1,6 @@  /*   * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com>   *   * Permission is hereby granted, free of charge, to any person obtaining a   * copy of this software and associated documentation files (the "Software"), @@ -20,104 +21,9 @@   * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE   * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "r300_state_shader.h" +#include "r5xx_fs.h" -static void r300_fs_declare(struct r300_fs_asm* assembler, -                            struct tgsi_full_declaration* decl) -{ -    switch (decl->Declaration.File) { -        case TGSI_FILE_INPUT: -            switch (decl->Semantic.SemanticName) { -                case TGSI_SEMANTIC_COLOR: -                    assembler->color_count++; -                    break; -                case TGSI_SEMANTIC_FOG: -                case TGSI_SEMANTIC_GENERIC: -                    assembler->tex_count++; -                    break; -                default: -                    debug_printf("r300: fs: Bad semantic declaration %d\n", -                        decl->Semantic.SemanticName); -                    break; -            } -            break; -        case TGSI_FILE_OUTPUT: -            /* Depth write. Mark the position of the output so we can -             * identify it later. */ -            if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { -                assembler->depth_output = decl->DeclarationRange.First; -            } -            break; -        case TGSI_FILE_CONSTANT: -            break; -        case TGSI_FILE_TEMPORARY: -            assembler->temp_count++; -            break; -        default: -            debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File); -            break; -    } - -    assembler->temp_offset = assembler->color_count + assembler->tex_count; -} - -static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler, -                                   struct tgsi_src_register* src) -{ -    switch (src->File) { -        case TGSI_FILE_NULL: -            return 0; -        case TGSI_FILE_INPUT: -            /* XXX may be wrong */ -            return src->Index; -            break; -        case TGSI_FILE_TEMPORARY: -            return src->Index + assembler->temp_offset; -            break; -        case TGSI_FILE_IMMEDIATE: -            return (src->Index + assembler->imm_offset) | (1 << 8); -            break; -        case TGSI_FILE_CONSTANT: -            /* XXX magic */ -            return src->Index | (1 << 8); -            break; -        default: -            debug_printf("r300: fs: Unimplemented src %d\n", src->File); -            break; -    } -    return 0; -} - -static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler, -                                   struct tgsi_dst_register* dst) -{ -    switch (dst->File) { -        case TGSI_FILE_NULL: -            /* This happens during KIL instructions. */ -            return 0; -            break; -        case TGSI_FILE_OUTPUT: -            return 0; -            break; -        case TGSI_FILE_TEMPORARY: -            return dst->Index + assembler->temp_offset; -            break; -        default: -            debug_printf("r300: fs: Unimplemented dst %d\n", dst->File); -            break; -    } -    return 0; -} - -static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler, -                                      struct tgsi_dst_register* dst) -{ -    return (assembler->writes_depth && -            (dst->File == TGSI_FILE_OUTPUT) && -            (dst->Index == assembler->depth_output)); -} - -static INLINE unsigned r500_fix_swiz(unsigned s) +static INLINE unsigned r5xx_fix_swiz(unsigned s)  {      /* For historical reasons, the swizzle values x, y, z, w, and 0 are       * equivalent to the actual machine code, but 1 is not. Thus, we just @@ -129,13 +35,13 @@ static INLINE unsigned r500_fix_swiz(unsigned s)      }  } -static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg) +static uint32_t r5xx_rgba_swiz(struct tgsi_full_src_register* reg)  {      if (reg->SrcRegister.Extended) { -        return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) | -            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) | -            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) | -            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9); +        return r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) | +            (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) | +            (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) | +            (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);      } else {          return reg->SrcRegister.SwizzleX |              (reg->SrcRegister.SwizzleY << 3) | @@ -144,7 +50,7 @@ static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg)      }  } -static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg) +static uint32_t r5xx_strq_swiz(struct tgsi_full_src_register* reg)  {      return reg->SrcRegister.SwizzleX |          (reg->SrcRegister.SwizzleY << 2) | @@ -152,43 +58,23 @@ static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg)          (reg->SrcRegister.SwizzleW << 6);  } -static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg) +static INLINE uint32_t r5xx_rgb_swiz(struct tgsi_full_src_register* reg)  {      /* Only the first 9 bits... */ -    return (r500_rgba_swiz(reg) & 0x1ff) | +    return (r5xx_rgba_swiz(reg) & 0x1ff) |          (reg->SrcRegister.Negate ? (1 << 9) : 0) |          (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);  } -static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg) +static INLINE uint32_t r5xx_alpha_swiz(struct tgsi_full_src_register* reg)  {      /* Only the last 3 bits... */ -    return (r500_rgba_swiz(reg) >> 9) | +    return (r5xx_rgba_swiz(reg) >> 9) |          (reg->SrcRegister.Negate ? (1 << 9) : 0) |          (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);  } -static INLINE uint32_t r300_rgb_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_MOV: -            return R300_ALU_OUTC_CMP; -        default: -            return 0; -    } -} - -static INLINE uint32_t r300_alpha_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_MOV: -            return R300_ALU_OUTA_CMP; -        default: -            return 0; -    } -} - -static INLINE uint32_t r500_rgba_op(unsigned op) +static INLINE uint32_t r5xx_rgba_op(unsigned op)  {      switch (op) {          case TGSI_OPCODE_COS: @@ -224,7 +110,7 @@ static INLINE uint32_t r500_rgba_op(unsigned op)      }  } -static INLINE uint32_t r500_alpha_op(unsigned op) +static INLINE uint32_t r5xx_alpha_op(unsigned op)  {      switch (op) {          case TGSI_OPCODE_COS: @@ -264,7 +150,7 @@ static INLINE uint32_t r500_alpha_op(unsigned op)      }  } -static INLINE uint32_t r500_tex_op(unsigned op) +static INLINE uint32_t r5xx_tex_op(unsigned op)  {      switch (op) {          case TGSI_OPCODE_KIL: @@ -280,33 +166,8 @@ static INLINE uint32_t r500_tex_op(unsigned op)      }  } -static INLINE void r300_emit_maths(struct r300_fragment_shader* fs, -                                   struct r300_fs_asm* assembler, -                                   struct tgsi_full_src_register* src, -                                   struct tgsi_full_dst_register* dst, -                                   unsigned op, -                                   unsigned count) -{ -    int i = fs->alu_instruction_count; - -    fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        r300_rgb_op(op); -    fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; -    fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        r300_alpha_op(op); -    fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; - -    fs->alu_instruction_count++; -} -  /* Setup an ALU operation. */ -static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, +static INLINE void r5xx_emit_maths(struct r5xx_fragment_shader* fs,                                     struct r300_fs_asm* assembler,                                     struct tgsi_full_src_register* src,                                     struct tgsi_full_dst_register* dst, @@ -343,9 +204,9 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,                  R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));              fs->instructions[i].inst5 |=                  R500_ALU_RGBA_SEL_C_SRC2 | -                R500_SWIZ_RGBA_C(r500_rgb_swiz(&src[2])) | +                R500_SWIZ_RGBA_C(r5xx_rgb_swiz(&src[2])) |                  R500_ALU_RGBA_ALPHA_SEL_C_SRC2 | -                R500_SWIZ_ALPHA_C(r500_alpha_swiz(&src[2])); +                R500_SWIZ_ALPHA_C(r5xx_alpha_swiz(&src[2]));          case 2:              fs->instructions[i].inst1 |=                  R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister)); @@ -353,10 +214,10 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,                  R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));              fs->instructions[i].inst3 =                  R500_ALU_RGB_SEL_B_SRC1 | -                R500_SWIZ_RGB_B(r500_rgb_swiz(&src[1])); +                R500_SWIZ_RGB_B(r5xx_rgb_swiz(&src[1]));              fs->instructions[i].inst4 |=                  R500_ALPHA_SEL_B_SRC1 | -                R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1])); +                R500_SWIZ_ALPHA_B(r5xx_alpha_swiz(&src[1]));          case 1:          case 0:          default: @@ -366,20 +227,20 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,                  R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));              fs->instructions[i].inst3 |=                  R500_ALU_RGB_SEL_A_SRC0 | -                R500_SWIZ_RGB_A(r500_rgb_swiz(&src[0])); +                R500_SWIZ_RGB_A(r5xx_rgb_swiz(&src[0]));              fs->instructions[i].inst4 |=                  R500_ALPHA_SEL_A_SRC0 | -                R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0])); +                R500_SWIZ_ALPHA_A(r5xx_alpha_swiz(&src[0]));              break;      } -    fs->instructions[i].inst4 |= r500_alpha_op(op); -    fs->instructions[i].inst5 |= r500_rgba_op(op); +    fs->instructions[i].inst4 |= r5xx_alpha_op(op); +    fs->instructions[i].inst5 |= r5xx_rgba_op(op);      fs->instruction_count++;  } -static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, +static INLINE void r5xx_emit_tex(struct r5xx_fragment_shader* fs,                                   struct r300_fs_asm* assembler,                                   struct tgsi_full_src_register* src,                                   struct tgsi_full_dst_register* dst, @@ -392,10 +253,10 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,          R500_INST_TEX_SEM_WAIT;      fs->instructions[i].inst1 = R500_TEX_ID(0) |          R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED | -        r500_tex_op(op); +        r5xx_tex_op(op);      fs->instructions[i].inst2 =          R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) | -        R500_SWIZ_TEX_STRQ(r500_strq_swiz(src)) | +        R500_SWIZ_TEX_STRQ(r5xx_strq_swiz(src)) |          R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) |          R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |          R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; @@ -412,37 +273,24 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,          src[0].SrcRegister.File = TGSI_FILE_TEMPORARY;          src[1] = src[0]; -        src[2] = r500_constant_zero; -        r500_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3); +        src[2] = r300_constant_zero; +        r5xx_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3);      } else {          fs->instruction_count++;      }  } -static void r300_fs_instruction(struct r300_fragment_shader* fs, -                                struct r300_fs_asm* assembler, -                                struct tgsi_full_instruction* inst) +void r5xx_fs_finalize(struct r5xx_fragment_shader* fs, +                      struct r300_fs_asm* assembler)  { -    switch (inst->Instruction.Opcode) { -        case TGSI_OPCODE_MOV: -            /* src0 -> src1 and src2 forced to zero */ -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[2] = r500_constant_zero; -            r300_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; -        case TGSI_OPCODE_END: -            break; -        default: -            debug_printf("r300: fs: Bad opcode %d\n", -                    inst->Instruction.Opcode); -            break; -    } +    /* XXX should this just go with OPCODE_END? */ +    fs->instructions[fs->instruction_count - 1].inst0 |= +        R500_INST_LAST;  } -static void r500_fs_instruction(struct r500_fragment_shader* fs, -                                struct r300_fs_asm* assembler, -                                struct tgsi_full_instruction* inst) +void r5xx_fs_instruction(struct r5xx_fragment_shader* fs, +                         struct r300_fs_asm* assembler, +                         struct tgsi_full_instruction* inst)  {      /* Switch between opcodes. When possible, prefer using the official       * AMD/ATI names for opcodes, please, as it facilitates using the @@ -465,7 +313,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,          case TGSI_OPCODE_DDX:          case TGSI_OPCODE_DDY:          case TGSI_OPCODE_FRC: -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1);              break; @@ -486,7 +334,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              /* Fall through */          case TGSI_OPCODE_DP3:          case TGSI_OPCODE_DP4: -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2);              break; @@ -496,7 +344,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2];              inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0];              inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3]; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);              break; @@ -510,18 +358,18 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              /* Force src0 to one, move all registers over */              inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1];              inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[0] = r500_constant_one; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            inst->FullSrcRegisters[0] = r300_constant_one; +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);              break;          case TGSI_OPCODE_MUL:              /* Force our src2 to zero */ -            inst->FullSrcRegisters[2] = r500_constant_zero; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            inst->FullSrcRegisters[2] = r300_constant_zero; +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);              break;          case TGSI_OPCODE_MAD: -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);              break; @@ -534,8 +382,8 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,          case TGSI_OPCODE_SWZ:              /* src0 -> src1 and src2 forced to zero */              inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[2] = r500_constant_zero; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            inst->FullSrcRegisters[2] = r300_constant_zero; +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);              break; @@ -550,7 +398,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              inst->FullDstRegisters[0].DstRegister.Index =                  assembler->temp_count;              inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);              inst->FullSrcRegisters[2].SrcRegister.Index =                  assembler->temp_count; @@ -563,7 +411,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              inst->FullSrcRegisters[0].SrcRegister.Negate =                  !(inst->FullSrcRegisters[0].SrcRegister.Negate);              inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);              break;          case TGSI_OPCODE_POW: @@ -576,7 +424,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              inst->FullDstRegisters[0].DstRegister.Index =                  assembler->temp_count;              inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1);              inst->FullSrcRegisters[0].SrcRegister.Index =                  assembler->temp_count; @@ -585,11 +433,11 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;              inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;              inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; -            inst->FullSrcRegisters[2] = r500_constant_zero; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            inst->FullSrcRegisters[2] = r300_constant_zero; +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3);              inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; -            r500_emit_maths(fs, assembler, inst->FullSrcRegisters, +            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,                      &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1);              break; @@ -598,7 +446,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,          case TGSI_OPCODE_TEX:          case TGSI_OPCODE_TXB:          case TGSI_OPCODE_TXP: -            r500_emit_tex(fs, assembler, &inst->FullSrcRegisters[0], +            r5xx_emit_tex(fs, assembler, &inst->FullSrcRegisters[0],                      &inst->FullDstRegisters[0], inst->Instruction.Opcode);              break; @@ -617,102 +465,3 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,              R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP;      }  } - -static void r300_fs_finalize(struct r3xx_fragment_shader* fs, -                             struct r300_fs_asm* assembler) -{ -    fs->stack_size = assembler->temp_count + assembler->temp_offset + 1; -} - -static void r500_fs_finalize(struct r500_fragment_shader* fs, -                             struct r300_fs_asm* assembler) -{ -    /* XXX should this just go with OPCODE_END? */ -    fs->instructions[fs->instruction_count - 1].inst0 |= -        R500_INST_LAST; -} - -void r300_translate_fragment_shader(struct r300_context* r300, -                                    struct r3xx_fragment_shader* fs) -{ -    struct tgsi_parse_context parser; -    int i; -    boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500; -    struct r300_constant_buffer* consts = -        &r300->shader_constants[PIPE_SHADER_FRAGMENT]; - -    struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm); -    if (assembler == NULL) { -        return; -    } -    /* Setup starting offset for immediates. */ -    assembler->imm_offset = consts->user_count; -    /* Enable depth writes, if needed. */ -    assembler->writes_depth = fs->info.writes_z; - -    /* Make sure we start at the beginning of the shader. */ -    if (is_r500) { -        ((struct r500_fragment_shader*)fs)->instruction_count = 0; -    } - -    tgsi_parse_init(&parser, fs->state.tokens); - -    while (!tgsi_parse_end_of_tokens(&parser)) { -        tgsi_parse_token(&parser); - -        /* This is seriously the lamest way to create fragment programs ever. -         * I blame TGSI. */ -        switch (parser.FullToken.Token.Type) { -            case TGSI_TOKEN_TYPE_DECLARATION: -                /* Allocated registers sitting at the beginning -                 * of the program. */ -                r300_fs_declare(assembler, &parser.FullToken.FullDeclaration); -                break; -            case TGSI_TOKEN_TYPE_IMMEDIATE: -                debug_printf("r300: Emitting immediate to constant buffer, " -                        "position %d\n", -                        assembler->imm_offset + assembler->imm_count); -                /* I am not amused by the length of these. */ -                for (i = 0; i < 4; i++) { -                    consts->constants[assembler->imm_offset + -                        assembler->imm_count][i] = -                        parser.FullToken.FullImmediate.u.ImmediateFloat32[i] -                        .Float; -                } -                assembler->imm_count++; -                break; -            case TGSI_TOKEN_TYPE_INSTRUCTION: -                if (is_r500) { -                    r500_fs_instruction((struct r500_fragment_shader*)fs, -                            assembler, &parser.FullToken.FullInstruction); -                } else { -                    r300_fs_instruction((struct r300_fragment_shader*)fs, -                            assembler, &parser.FullToken.FullInstruction); -                } -                break; -        } -    } - -    debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n", -            assembler->tex_count, assembler->color_count, -            assembler->tex_count + assembler->color_count); - -    consts->count = consts->user_count + assembler->imm_count; -    fs->uses_imms = assembler->imm_count; -    debug_printf("r300: fs: %d total constants, " -            "%d from user and %d from immediates\n", consts->count, -            consts->user_count, assembler->imm_count); -    r300_fs_finalize(fs, assembler); -    if (is_r500) { -        r500_fs_finalize((struct r500_fragment_shader*)fs, assembler); -    } - -    tgsi_dump(fs->state.tokens); -    /* XXX finish r300 dumper too */ -    if (is_r500) { -        r500_fs_dump((struct r500_fragment_shader*)fs); -    } - -    tgsi_parse_free(&parser); -    FREE(assembler); -} diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r5xx_fs.h index b6087404ce..629e587be4 100644 --- a/src/gallium/drivers/r300/r300_state_shader.h +++ b/src/gallium/drivers/r300/r5xx_fs.h @@ -1,5 +1,6 @@  /*   * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + *                Joakim Sindholt <opensource@zhasha.com>   *   * Permission is hereby granted, free of charge, to any person obtaining a   * copy of this software and associated documentation files (the "Software"), @@ -20,15 +21,10 @@   * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE   * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef R300_STATE_SHADER_H -#define R300_STATE_SHADER_H +#ifndef R5XX_FS_H +#define R5XX_FS_H -#include "tgsi/tgsi_parse.h" - -#include "r300_context.h" -#include "r300_debug.h" -#include "r300_reg.h" -#include "r300_screen.h" +#include "r300_fs_inlines.h"  /* XXX this all should find its way back to r300_reg */  /* Swizzle tools */ @@ -59,78 +55,7 @@  #define R500_ALU_OMASK(x) ((x) << 15)  #define R500_W_OMASK (1 << 31) -/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're - * not using enough of it. */ -static const struct tgsi_full_src_register r500_constant_zero = { -    .SrcRegister.Extended = TRUE, -    .SrcRegister.File = TGSI_FILE_NULL, -    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO, -    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO, -}; - -static const struct tgsi_full_src_register r500_constant_one = { -    .SrcRegister.Extended = TRUE, -    .SrcRegister.File = TGSI_FILE_NULL, -    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE, -    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE, -    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE, -    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE, -}; - -/* Temporary struct used to hold assembly state while putting together - * fragment programs. */ -struct r300_fs_asm { -    /* Pipe context. */ -    struct r300_context* r300; -    /* Number of colors. */ -    unsigned color_count; -    /* Number of texcoords. */ -    unsigned tex_count; -    /* Offset for temporary registers. Inputs and temporaries have no -     * distinguishing markings, so inputs start at 0 and the first usable -     * temporary register is after all inputs. */ -    unsigned temp_offset; -    /* Number of requested temporary registers. */ -    unsigned temp_count; -    /* Offset for immediate constants. Neither R300 nor R500 can do four -     * inline constants per source, so instead we copy immediates into the -     * constant buffer. */ -    unsigned imm_offset; -    /* Number of immediate constants. */ -    unsigned imm_count; -    /* Are depth writes enabled? */ -    boolean writes_depth; -    /* Depth write offset. This is the TGSI output that corresponds to -     * depth writes. */ -    unsigned depth_output; -}; - -void r300_translate_fragment_shader(struct r300_context* r300, -                           struct r3xx_fragment_shader* fs); - -static struct r300_fragment_shader r300_passthrough_fragment_shader = { -    .alu_instruction_count = 1, -    .tex_instruction_count = 0, -    .indirections = 0, -    .shader.stack_size = 1, - -    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        R300_ALU_OUTC_CMP, -    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, -    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        R300_ALU_OUTA_CMP, -    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -static struct r500_fragment_shader r500_passthrough_fragment_shader = { +static struct r5xx_fragment_shader r5xx_passthrough_fragment_shader = {      .shader.stack_size = 0,      .instruction_count = 1,      .instructions[0].inst0 = R500_INST_TYPE_OUT | @@ -156,27 +81,7 @@ static struct r500_fragment_shader r500_passthrough_fragment_shader = {          R500_ALU_RGBA_A_SWIZ_0,  }; -static struct r300_fragment_shader r300_texture_fragment_shader = { -    .alu_instruction_count = 1, -    .tex_instruction_count = 0, -    .indirections = 0, -    .shader.stack_size = 1, - -    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        R300_ALU_OUTC_CMP, -    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, -    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        R300_ALU_OUTA_CMP, -    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -static struct r500_fragment_shader r500_texture_fragment_shader = { +static struct r5xx_fragment_shader r5xx_texture_fragment_shader = {      .shader.stack_size = 1,      .instruction_count = 2,      .instructions[0].inst0 = R500_INST_TYPE_TEX | @@ -217,4 +122,11 @@ static struct r500_fragment_shader r500_texture_fragment_shader = {          R500_ALU_RGBA_A_SWIZ_0,  }; -#endif /* R300_STATE_SHADER_H */ +void r5xx_fs_finalize(struct r5xx_fragment_shader* fs, +                      struct r300_fs_asm* assembler); + +void r5xx_fs_instruction(struct r5xx_fragment_shader* fs, +                         struct r300_fs_asm* assembler, +                         struct tgsi_full_instruction* inst); + +#endif /* R5XX_FS_H */ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 62e8d99cfd..86df320ea8 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -126,6 +126,22 @@ softpipe_is_texture_referenced( struct pipe_context *pipe,  				struct pipe_texture *texture,  				unsigned face, unsigned level)  { +   struct softpipe_context *softpipe = softpipe_context( pipe ); +   unsigned i; + +   if(softpipe->dirty_render_cache) { +      for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { +         if(softpipe->framebuffer.cbufs[i] &&  +            softpipe->framebuffer.cbufs[i]->texture == texture) +            return PIPE_REFERENCED_FOR_WRITE; +      } +      if(softpipe->framebuffer.zsbuf &&  +         softpipe->framebuffer.zsbuf->texture == texture) +         return PIPE_REFERENCED_FOR_WRITE; +   } +    +   /* FIXME: we also need to do the same for the texture cache */ +        return PIPE_UNREFERENCED;  } diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index b89a7292e5..7888c2f644 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -145,6 +145,8 @@ struct softpipe_context {     struct draw_stage *vbuf;     struct softpipe_vbuf_render *vbuf_render; +   boolean dirty_render_cache; +        struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];     struct softpipe_tile_cache *zsbuf_cache; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index f117096bf7..d4045816d0 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -35,6 +35,7 @@  #include "pipe/p_context.h"  #include "pipe/internal/p_winsys_screen.h"  #include "pipe/p_inlines.h" +#include "util/u_prim.h"  #include "sp_context.h"  #include "sp_state.h" @@ -65,6 +66,7 @@ softpipe_map_constant_buffers(struct softpipe_context *sp)                                     size);  } +  static void  softpipe_unmap_constant_buffers(struct softpipe_context *sp)  { @@ -86,20 +88,6 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp)  } -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { -   PIPE_PRIM_POINTS, -   PIPE_PRIM_LINES, -   PIPE_PRIM_LINES, -   PIPE_PRIM_LINES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES, -   PIPE_PRIM_TRIANGLES -}; - -  boolean  softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,                       unsigned start, unsigned count) @@ -108,15 +96,11 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,  } -  /**   * Draw vertex arrays, with optional indexing.   * Basically, map the vertex buffers (and drawing surfaces), then hand off   * the drawing to the 'draw' module. - * - * XXX should the element buffer be specified/bound with a separate function?   */ -  boolean  softpipe_draw_range_elements(struct pipe_context *pipe,                               struct pipe_buffer *indexBuffer, @@ -129,7 +113,7 @@ softpipe_draw_range_elements(struct pipe_context *pipe,     struct draw_context *draw = sp->draw;     unsigned i; -   sp->reduced_api_prim = reduced_prim[mode]; +   sp->reduced_api_prim = u_reduced_prim(mode);     if (sp->dirty)        softpipe_update_derived( sp ); @@ -147,6 +131,7 @@ softpipe_draw_range_elements(struct pipe_context *pipe,                                      PIPE_BUFFER_USAGE_CPU_READ);        draw_set_mapped_vertex_buffer(draw, i, buf);     } +     /* Map index buffer, if present */     if (indexBuffer) {        void *mapped_indexes @@ -159,10 +144,10 @@ softpipe_draw_range_elements(struct pipe_context *pipe,     }     else {        /* no index/element buffer */ -      draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL); +      draw_set_mapped_element_buffer_range(draw, 0, start, +                                           start + count - 1, NULL);     } -     /* draw! */     draw_arrays(draw, mode, start, count); @@ -182,9 +167,12 @@ softpipe_draw_range_elements(struct pipe_context *pipe,     /* Note: leave drawing surfaces mapped */     softpipe_unmap_constant_buffers(sp); +   sp->dirty_render_cache = TRUE; +        return TRUE;  } +  boolean  softpipe_draw_elements(struct pipe_context *pipe,                         struct pipe_buffer *indexBuffer, @@ -198,11 +186,9 @@ softpipe_draw_elements(struct pipe_context *pipe,  } -  void  softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)  {     struct softpipe_context *sp = softpipe_context(pipe);     draw_set_edgeflags(sp->draw, edgeflags);  } - diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 035f4b963e..4a14d49686 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -71,6 +71,8 @@ softpipe_flush( struct pipe_context *pipe,         * to unmap surfaces when flushing.         */        softpipe_unmap_transfers(softpipe); +       +      softpipe->dirty_render_cache = FALSE;     }     /* Enable to dump BMPs of the color/depth buffers each frame */ diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 06725fd09b..42021789ea 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -238,65 +238,117 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)     case PIPE_PRIM_TRIANGLES:        for (i = 2; i < nr; i += 3) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, indices[i-2], stride), -                    get_vert(vertex_buffer, indices[i-1], stride), -                    get_vert(vertex_buffer, indices[i-0], stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-1], stride), +                       get_vert(vertex_buffer, indices[i-0], stride), +                       get_vert(vertex_buffer, indices[i-2], stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-2], stride), +                       get_vert(vertex_buffer, indices[i-1], stride), +                       get_vert(vertex_buffer, indices[i-0], stride) ); +         }        }        break;     case PIPE_PRIM_TRIANGLE_STRIP:        for (i = 2; i < nr; i += 1) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, indices[i+(i&1)-2], stride), -                    get_vert(vertex_buffer, indices[i-(i&1)-1], stride), -                    get_vert(vertex_buffer, indices[i-0], stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i+(i&1)-1], stride), +                       get_vert(vertex_buffer, indices[i-(i&1)], stride), +                       get_vert(vertex_buffer, indices[i-2], stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i+(i&1)-2], stride), +                       get_vert(vertex_buffer, indices[i-(i&1)-1], stride), +                       get_vert(vertex_buffer, indices[i-0], stride) ); +         }        }        break;     case PIPE_PRIM_TRIANGLE_FAN:        for (i = 2; i < nr; i += 1) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, indices[0], stride), -                    get_vert(vertex_buffer, indices[i-1], stride), -                    get_vert(vertex_buffer, indices[i-0], stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-0], stride), +                       get_vert(vertex_buffer, indices[0], stride), +                       get_vert(vertex_buffer, indices[i-1], stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[0], stride), +                       get_vert(vertex_buffer, indices[i-1], stride), +                       get_vert(vertex_buffer, indices[i-0], stride) ); +         }        }        break;     case PIPE_PRIM_QUADS:        for (i = 3; i < nr; i += 4) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, indices[i-3], stride), -                    get_vert(vertex_buffer, indices[i-2], stride), -                    get_vert(vertex_buffer, indices[i-0], stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-2], stride), +                       get_vert(vertex_buffer, indices[i-1], stride), +                       get_vert(vertex_buffer, indices[i-3], stride) ); +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-1], stride), +                       get_vert(vertex_buffer, indices[i-0], stride), +                       get_vert(vertex_buffer, indices[i-3], stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-3], stride), +                       get_vert(vertex_buffer, indices[i-2], stride), +                       get_vert(vertex_buffer, indices[i-0], stride) ); -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, indices[i-2], stride), -                    get_vert(vertex_buffer, indices[i-1], stride), -                    get_vert(vertex_buffer, indices[i-0], stride)); +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-2], stride), +                       get_vert(vertex_buffer, indices[i-1], stride), +                       get_vert(vertex_buffer, indices[i-0], stride) ); +         }        }        break;     case PIPE_PRIM_QUAD_STRIP:        for (i = 3; i < nr; i += 2) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, indices[i-3], stride), -                    get_vert(vertex_buffer, indices[i-2], stride), -                    get_vert(vertex_buffer, indices[i-0], stride)); - -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, indices[i-1], stride), -                    get_vert(vertex_buffer, indices[i-3], stride), -                    get_vert(vertex_buffer, indices[i-0], stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-0], stride), +                       get_vert(vertex_buffer, indices[i-1], stride), +                       get_vert(vertex_buffer, indices[i-3], stride)); +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-2], stride), +                       get_vert(vertex_buffer, indices[i-0], stride), +                       get_vert(vertex_buffer, indices[i-3], stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-3], stride), +                       get_vert(vertex_buffer, indices[i-2], stride), +                       get_vert(vertex_buffer, indices[i-0], stride) ); +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, indices[i-1], stride), +                       get_vert(vertex_buffer, indices[i-3], stride), +                       get_vert(vertex_buffer, indices[i-0], stride) ); +         }        }        break;     case PIPE_PRIM_POLYGON: +      /* Almost same as tri fan but the _first_ vertex specifies the flat +       * shading color.  Note that the first polygon vertex is passed as +       * the last triangle vertex here. +       * flatshade_first state makes no difference. +       */        for (i = 2; i < nr; i += 1) {           setup_tri( setup_ctx, -                    get_vert(vertex_buffer, indices[0-1], stride),                      get_vert(vertex_buffer, indices[i-0], stride), -                    get_vert(vertex_buffer, indices[0], stride)); +                    get_vert(vertex_buffer, indices[i-1], stride), +                    get_vert(vertex_buffer, indices[0], stride) );        }        break; @@ -368,58 +420,104 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)        }        break; -     case PIPE_PRIM_TRIANGLES:        for (i = 2; i < nr; i += 3) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, i-2, stride), -                    get_vert(vertex_buffer, i-1, stride), -                    get_vert(vertex_buffer, i-0, stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-1, stride), +                       get_vert(vertex_buffer, i-0, stride), +                       get_vert(vertex_buffer, i-2, stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-2, stride), +                       get_vert(vertex_buffer, i-1, stride), +                       get_vert(vertex_buffer, i-0, stride) ); +         }        }        break;     case PIPE_PRIM_TRIANGLE_STRIP: -      for (i = 2; i < nr; i += 1) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, i+(i&1)-2, stride), -                    get_vert(vertex_buffer, i-(i&1)-1, stride), -                    get_vert(vertex_buffer, i-0, stride)); +      for (i = 2; i < nr; i++) { +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i+(i&1)-1, stride), +                       get_vert(vertex_buffer, i-(i&1), stride), +                       get_vert(vertex_buffer, i-2, stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i+(i&1)-2, stride), +                       get_vert(vertex_buffer, i-(i&1)-1, stride), +                       get_vert(vertex_buffer, i-0, stride) ); +         }        }        break;     case PIPE_PRIM_TRIANGLE_FAN:        for (i = 2; i < nr; i += 1) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, 0, stride), -                    get_vert(vertex_buffer, i-1, stride), -                    get_vert(vertex_buffer, i-0, stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-0, stride), +                       get_vert(vertex_buffer, 0, stride), +                       get_vert(vertex_buffer, i-1, stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, 0, stride), +                       get_vert(vertex_buffer, i-1, stride), +                       get_vert(vertex_buffer, i-0, stride) ); +         }        }        break;     case PIPE_PRIM_QUADS:        for (i = 3; i < nr; i += 4) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, i-3, stride), -                    get_vert(vertex_buffer, i-2, stride), -                    get_vert(vertex_buffer, i-0, stride)); - -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, i-2, stride), -                    get_vert(vertex_buffer, i-1, stride), -                    get_vert(vertex_buffer, i-0, stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-2, stride), +                       get_vert(vertex_buffer, i-1, stride), +                       get_vert(vertex_buffer, i-3, stride) ); +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-1, stride), +                       get_vert(vertex_buffer, i-0, stride), +                       get_vert(vertex_buffer, i-3, stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-3, stride), +                       get_vert(vertex_buffer, i-2, stride), +                       get_vert(vertex_buffer, i-0, stride) ); +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-2, stride), +                       get_vert(vertex_buffer, i-1, stride), +                       get_vert(vertex_buffer, i-0, stride) ); +         }        }        break; +     case PIPE_PRIM_QUAD_STRIP:        for (i = 3; i < nr; i += 2) { -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, i-3, stride), -                    get_vert(vertex_buffer, i-2, stride), -                    get_vert(vertex_buffer, i-0, stride)); - -         setup_tri( setup_ctx, -                    get_vert(vertex_buffer, i-1, stride), -                    get_vert(vertex_buffer, i-3, stride), -                    get_vert(vertex_buffer, i-0, stride)); +         if (softpipe->rasterizer->flatshade_first) { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-0, stride), +                       get_vert(vertex_buffer, i-1, stride), +                       get_vert(vertex_buffer, i-3, stride) ); +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-2, stride), +                       get_vert(vertex_buffer, i-0, stride), +                       get_vert(vertex_buffer, i-3, stride) ); +         } +         else { +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-3, stride), +                       get_vert(vertex_buffer, i-2, stride), +                       get_vert(vertex_buffer, i-0, stride) ); +            setup_tri( setup_ctx, +                       get_vert(vertex_buffer, i-1, stride), +                       get_vert(vertex_buffer, i-3, stride), +                       get_vert(vertex_buffer, i-0, stride) ); +         }        }        break; @@ -427,12 +525,13 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)        /* Almost same as tri fan but the _first_ vertex specifies the flat         * shading color.  Note that the first polygon vertex is passed as         * the last triangle vertex here. +       * flatshade_first state makes no difference.         */        for (i = 2; i < nr; i += 1) {           setup_tri( setup_ctx,                      get_vert(vertex_buffer, i-1, stride),                      get_vert(vertex_buffer, i-0, stride), -                    get_vert(vertex_buffer, 0, stride)); +                    get_vert(vertex_buffer, 0, stride) );        }        break; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 692deeb8fd..6178c4ac7e 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -87,6 +87,10 @@ softpipe_get_param(struct pipe_screen *screen, int param)        return 8;  /* max 128x128x128 */     case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:        return 13; /* max 4Kx4K */ +   case PIPE_CAP_TGSI_CONT_SUPPORTED: +      return 1; +   case PIPE_CAP_BLEND_EQUATION_SEPARATE: +      return 1;     default:        return 0;     } diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index c6844a2649..de3ae3c369 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -444,7 +444,8 @@ static void flush_spans( struct setup_context *setup )              mask |= MASK_TOP_RIGHT;           if (x+1 >= xleft1 && x+1 < xright1)              mask |= MASK_BOTTOM_RIGHT; -         EMIT_QUAD( setup, x, setup->span.y, mask ); +         if (mask) +            EMIT_QUAD( setup, x, setup->span.y, mask );        }        break; @@ -458,7 +459,8 @@ static void flush_spans( struct setup_context *setup )              mask |= MASK_TOP_LEFT;           if (x+1 >= xleft0 && x+1 < xright0)              mask |= MASK_TOP_RIGHT; -         EMIT_QUAD( setup, x, setup->span.y, mask ); +         if (mask) +            EMIT_QUAD( setup, x, setup->span.y, mask );        }        break; @@ -472,7 +474,8 @@ static void flush_spans( struct setup_context *setup )              mask |= MASK_BOTTOM_LEFT;           if (x+1 >= xleft1 && x+1 < xright1)              mask |= MASK_BOTTOM_RIGHT; -         EMIT_QUAD( setup, x, setup->span.y, mask ); +         if (mask) +            EMIT_QUAD( setup, x, setup->span.y, mask );        }        break; @@ -784,11 +787,10 @@ static void setup_tri_coefficients( struct setup_context *setup )           assert(0);        } -      if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { -         /* FOG.y = front/back facing  XXX fix this */ -         setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.input.facing; -         setup->coef[fragSlot].dadx[1] = 0.0; -         setup->coef[fragSlot].dady[1] = 0.0; +      if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { +         setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; +         setup->coef[fragSlot].dadx[0] = 0.0; +         setup->coef[fragSlot].dady[0] = 0.0;        }     }  } @@ -1051,7 +1053,10 @@ setup_line_coefficients(struct setup_context *setup,     float area;     /* use setup->vmin, vmax to point to vertices */ -   setup->vprovoke = v1; +   if (softpipe->rasterizer->flatshade_first) +      setup->vprovoke = v0; +   else +      setup->vprovoke = v1;     setup->vmin = v0;     setup->vmax = v1; @@ -1095,11 +1100,10 @@ setup_line_coefficients(struct setup_context *setup,           assert(0);        } -      if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { -         /* FOG.y = front/back facing  XXX fix this */ -         setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.input.facing; -         setup->coef[fragSlot].dadx[1] = 0.0; -         setup->coef[fragSlot].dady[1] = 0.0; +      if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { +         setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; +         setup->coef[fragSlot].dadx[0] = 0.0; +         setup->coef[fragSlot].dady[0] = 0.0;        }     }     return TRUE; @@ -1341,11 +1345,10 @@ setup_point( struct setup_context *setup,           assert(0);        } -      if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { -         /* FOG.y = front/back facing  XXX fix this */ -         setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.input.facing; -         setup->coef[fragSlot].dadx[1] = 0.0; -         setup->coef[fragSlot].dady[1] = 0.0; +      if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { +         setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; +         setup->coef[fragSlot].dadx[0] = 0.0; +         setup->coef[fragSlot].dady[0] = 0.0;        }     } diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 6b6a4c3ff3..75551000c9 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -110,6 +110,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)              break;           case TGSI_SEMANTIC_GENERIC: +         case TGSI_SEMANTIC_FACE:              /* this includes texcoords and varying vars */              src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_GENERIC,                                        spfs->info.input_semantic_index[i]); diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index adbd0cb7f0..a1d3bade27 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -705,15 +705,18 @@ get_texel(const struct tgsi_sampler *tgsi_sampler,   * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'   * When we sampled the depth texture, the depth value was put into all   * RGBA channels.  We look at the red channel here. + * \param rgba  quad of (depth) texel values + * \param p  texture 'P' components for four pixels in quad + * \param j  which pixel in the quad to test [0..3]   */  static INLINE void -shadow_compare(uint compare_func, +shadow_compare(const struct pipe_sampler_state *sampler,                 float rgba[NUM_CHANNELS][QUAD_SIZE],                 const float p[QUAD_SIZE],                 uint j)  {     int k; -   switch (compare_func) { +   switch (sampler->compare_func) {     case PIPE_FUNC_LESS:        k = p[j] < rgba[0][j];        break; @@ -744,7 +747,81 @@ shadow_compare(uint compare_func,        break;     } +   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */     rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; +   rgba[3][j] = 1.0F; +} + + +/** + * As above, but do four z/texture comparisons. + */ +static INLINE void +shadow_compare4(const struct pipe_sampler_state *sampler, +                float rgba[NUM_CHANNELS][QUAD_SIZE], +                const float p[QUAD_SIZE]) +{ +   int j, k0, k1, k2, k3; +   float val; + +   /* compare four texcoords vs. four texture samples */ +   switch (sampler->compare_func) { +   case PIPE_FUNC_LESS: +      k0 = p[0] < rgba[0][0]; +      k1 = p[1] < rgba[0][1]; +      k2 = p[2] < rgba[0][2]; +      k3 = p[3] < rgba[0][3]; +      break; +   case PIPE_FUNC_LEQUAL: +      k0 = p[0] <= rgba[0][0]; +      k1 = p[1] <= rgba[0][1]; +      k2 = p[2] <= rgba[0][2]; +      k3 = p[3] <= rgba[0][3]; +      break; +   case PIPE_FUNC_GREATER: +      k0 = p[0] > rgba[0][0]; +      k1 = p[1] > rgba[0][1]; +      k2 = p[2] > rgba[0][2]; +      k3 = p[3] > rgba[0][3]; +      break; +   case PIPE_FUNC_GEQUAL: +      k0 = p[0] >= rgba[0][0]; +      k1 = p[1] >= rgba[0][1]; +      k2 = p[2] >= rgba[0][2]; +      k3 = p[3] >= rgba[0][3]; +      break; +   case PIPE_FUNC_EQUAL: +      k0 = p[0] == rgba[0][0]; +      k1 = p[1] == rgba[0][1]; +      k2 = p[2] == rgba[0][2]; +      k3 = p[3] == rgba[0][3]; +      break; +   case PIPE_FUNC_NOTEQUAL: +      k0 = p[0] != rgba[0][0]; +      k1 = p[1] != rgba[0][1]; +      k2 = p[2] != rgba[0][2]; +      k3 = p[3] != rgba[0][3]; +      break; +   case PIPE_FUNC_ALWAYS: +      k0 = k1 = k2 = k3 = 1; +      break; +   case PIPE_FUNC_NEVER: +      k0 = k1 = k2 = k3 = 0; +      break; +   default: +      k0 = k1 = k2 = k3 = 0; +      assert(0); +      break; +   } + +   /* convert four pass/fail values to an intensity in [0,1] */ +   val = 0.25F * (k0 + k1 + k2 + k3); + +   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ +   for (j = 0; j < 4; j++) { +      rgba[0][j] = rgba[1][j] = rgba[2][j] = val; +      rgba[3][j] = 1.0F; +   }  } @@ -767,7 +844,6 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,     const uint unit = samp->unit;     const struct pipe_texture *texture = sp->texture[unit];     const struct pipe_sampler_state *sampler = sp->sampler[unit]; -   const uint compare_func = sampler->compare_func;     unsigned level0, level1, j, imgFilter;     int width, height;     float levelBlend; @@ -792,7 +868,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,           for (j = 0; j < QUAD_SIZE; j++) {              get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);              if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { -               shadow_compare(compare_func, rgba, p, j); +               shadow_compare(sampler, rgba, p, j);              }              if (level0 != level1) { @@ -804,7 +880,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,                 get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,                           rgba2, j);                 if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ -                  shadow_compare(compare_func, rgba2, p, j); +                  shadow_compare(sampler, rgba2, p, j);                 }                 for (c = 0; c < NUM_CHANNELS; c++) { @@ -831,10 +907,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,              get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);              get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);              if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { -               shadow_compare(compare_func, tx, p, 0); -               shadow_compare(compare_func, tx, p, 1); -               shadow_compare(compare_func, tx, p, 2); -               shadow_compare(compare_func, tx, p, 3); +               shadow_compare4(sampler, tx, p);              }              /* interpolate R, G, B, A */ @@ -856,10 +929,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,                 get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);                 get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);                 if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ -                  shadow_compare(compare_func, tx, p, 0); -                  shadow_compare(compare_func, tx, p, 1); -                  shadow_compare(compare_func, tx, p, 2); -                  shadow_compare(compare_func, tx, p, 3); +                  shadow_compare4(sampler, tx, p);                 }                 /* interpolate R, G, B, A */ @@ -1074,7 +1144,6 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,     const struct pipe_texture *texture = sp->texture[unit];     const struct pipe_sampler_state *sampler = sp->sampler[unit];     const uint face = 0; -   const uint compare_func = sampler->compare_func;     unsigned level0, level1, j, imgFilter;     int width, height;     float levelBlend; @@ -1099,7 +1168,7 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,           for (j = 0; j < QUAD_SIZE; j++) {              get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j);              if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { -               shadow_compare(compare_func, rgba, p, j); +               shadow_compare(sampler, rgba, p, j);              }           }        } @@ -1119,10 +1188,7 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,              get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2);              get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3);              if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { -               shadow_compare(compare_func, tx, p, 0); -               shadow_compare(compare_func, tx, p, 1); -               shadow_compare(compare_func, tx, p, 2); -               shadow_compare(compare_func, tx, p, 3); +               shadow_compare4(sampler, tx, p);              }              for (c = 0; c < 4; c++) {                 rgba[c][j] = lerp_2d(xw[j], yw[j], diff --git a/src/gallium/drivers/trace/Makefile b/src/gallium/drivers/trace/Makefile index 4aeb8e3d7e..dd6831c70a 100644 --- a/src/gallium/drivers/trace/Makefile +++ b/src/gallium/drivers/trace/Makefile @@ -11,6 +11,7 @@ C_SOURCES = \  	tr_screen.c \  	tr_state.c \  	tr_rbug.c \ +	tr_drm.c \  	tr_texture.c  include ../../Makefile.template diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c new file mode 100644 index 0000000000..98ac75e3fa --- /dev/null +++ b/src/gallium/drivers/trace/tr_drm.c @@ -0,0 +1,211 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 "state_tracker/drm_api.h" + +#include "util/u_memory.h" +#include "trace/tr_drm.h" +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#include "trace/tr_buffer.h" +#include "trace/tr_texture.h" + +struct trace_drm_api +{ +   struct drm_api base; + +   struct drm_api *api; +}; + +static INLINE struct trace_drm_api * +trace_drm_api(struct drm_api *_api) +{ +   return (struct trace_drm_api *)_api; +} + +static struct pipe_screen * +trace_drm_create_screen(struct drm_api *_api, int fd, +                           struct drm_create_screen_arg *arg) +{ +   struct trace_drm_api *tr_api = trace_drm_api(_api); +   struct drm_api *api = tr_api->api; +   struct pipe_screen *screen; + +   /* TODO trace call */ + +   if (arg && arg->mode != DRM_CREATE_NORMAL) +      return NULL; + +   screen = api->create_screen(api, fd, arg); + +   return trace_screen_create(screen); +}; + +static struct pipe_context * +trace_drm_create_context(struct drm_api *_api, +                            struct pipe_screen *_screen) +{ +   struct trace_screen *tr_screen = trace_screen(_screen); +   struct trace_drm_api *tr_api = trace_drm_api(_api); +   struct pipe_screen *screen = tr_screen->screen; +   struct drm_api *api = tr_api->api; +   struct pipe_context *pipe; + +   /* TODO trace call */ + +   pipe = api->create_context(api, screen); + +   pipe = trace_context_create(_screen, pipe); + +   return pipe; +}; + +static boolean +trace_drm_buffer_from_texture(struct drm_api *_api, +                                 struct pipe_texture *_texture, +                                 struct pipe_buffer **_buffer, +                                 unsigned *stride) +{ +   struct trace_texture *tr_texture = trace_texture(_texture); +   struct trace_drm_api *tr_api = trace_drm_api(_api); +   struct pipe_texture *texture = tr_texture->texture; +   struct drm_api *api = tr_api->api; +   struct pipe_buffer *buffer = NULL; +   boolean result; + +   /* TODO trace call */ + +   result = api->buffer_from_texture(api, texture, &buffer, stride); + +   if (result && _buffer) +      buffer = trace_buffer_create(trace_screen(texture->screen), buffer); + +   if (_buffer) +      *_buffer = buffer; +   else +      pipe_buffer_reference(&buffer, NULL); + +   return result; +} + +static struct pipe_buffer * +trace_drm_buffer_from_handle(struct drm_api *_api, +                                struct pipe_screen *_screen, +                                const char *name, +                                unsigned handle) +{ +   struct trace_screen *tr_screen = trace_screen(_screen); +   struct trace_drm_api *tr_api = trace_drm_api(_api); +   struct pipe_screen *screen = tr_screen->screen; +   struct drm_api *api = tr_api->api; +   struct pipe_buffer *result; + +   /* TODO trace call */ + +   result = api->buffer_from_handle(api, screen, name, handle); + +   result = trace_buffer_create(trace_screen(_screen), result); + +   return result; +} + +static boolean +trace_drm_handle_from_buffer(struct drm_api *_api, +                                struct pipe_screen *_screen, +                                struct pipe_buffer *_buffer, +                                unsigned *handle) +{ +   struct trace_screen *tr_screen = trace_screen(_screen); +   struct trace_buffer *tr_buffer = trace_buffer(_buffer); +   struct trace_drm_api *tr_api = trace_drm_api(_api); +   struct pipe_screen *screen = tr_screen->screen; +   struct pipe_buffer *buffer = tr_buffer->buffer; +   struct drm_api *api = tr_api->api; + +   /* TODO trace call */ + +   return api->handle_from_buffer(api, screen, buffer, handle); +} + +static boolean +trace_drm_global_handle_from_buffer(struct drm_api *_api, +                                       struct pipe_screen *_screen, +                                       struct pipe_buffer *_buffer, +                                       unsigned *handle) +{ +   struct trace_screen *tr_screen = trace_screen(_screen); +   struct trace_buffer *tr_buffer = trace_buffer(_buffer); +   struct trace_drm_api *tr_api = trace_drm_api(_api); +   struct pipe_screen *screen = tr_screen->screen; +   struct pipe_buffer *buffer = tr_buffer->buffer; +   struct drm_api *api = tr_api->api; + +   /* TODO trace call */ + +   return api->global_handle_from_buffer(api, screen, buffer, handle); +} + +static void +trace_drm_destroy(struct drm_api *_api) +{ +   struct trace_drm_api *tr_api = trace_drm_api(_api); +   struct drm_api *api = tr_api->api; +   api->destroy(api); + +   free(tr_api); +} + +struct drm_api * +trace_drm_create(struct drm_api *api) +{ +   struct trace_drm_api *tr_api; + +   if (!api) +      goto error; + +   if (!trace_enabled()) +      goto error; + +   tr_api = CALLOC_STRUCT(trace_drm_api); + +   if (!tr_api) +      goto error; + +   tr_api->base.create_screen = trace_drm_create_screen; +   tr_api->base.create_context = trace_drm_create_context; +   tr_api->base.buffer_from_texture = trace_drm_buffer_from_texture; +   tr_api->base.buffer_from_handle = trace_drm_buffer_from_handle; +   tr_api->base.handle_from_buffer = trace_drm_handle_from_buffer; +   tr_api->base.global_handle_from_buffer = trace_drm_global_handle_from_buffer; +   tr_api->base.destroy = trace_drm_destroy; +   tr_api->api = api; + +   return &tr_api->base; + +error: +   return api; +} diff --git a/src/gallium/drivers/trace/tr_drm.h b/src/gallium/drivers/trace/tr_drm.h new file mode 100644 index 0000000000..845c66a32a --- /dev/null +++ b/src/gallium/drivers/trace/tr_drm.h @@ -0,0 +1,35 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE 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 TR_DRM_H +#define TR_DRM_H + +struct drm_api; + +struct drm_api* trace_drm_create(struct drm_api *api); + +#endif /* ID_DRM_H */ diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 3a1409e95a..643587ab42 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -451,11 +451,11 @@ void trace_dump_float(double value)  }  void trace_dump_bytes(const void *data, -                      long unsigned size) +                      size_t size)  {     static const char hex_table[16] = "0123456789ABCDEF";     const uint8_t *p = data; -   long unsigned i; +   size_t i;     if (!dumping)        return; diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 31ac70802f..32592bab12 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -91,7 +91,7 @@ void trace_dump_bool(int value);  void trace_dump_int(long long int value);  void trace_dump_uint(long long unsigned value);  void trace_dump_float(double value); -void trace_dump_bytes(const void *data, long unsigned size); +void trace_dump_bytes(const void *data, size_t size);  void trace_dump_string(const char *str);  void trace_dump_enum(const char *value);  void trace_dump_array_begin(void); @@ -130,7 +130,7 @@ void trace_dump_transfer_ptr(struct pipe_transfer *_transfer);  #define trace_dump_array(_type, _obj, _size) \     do { \ -      unsigned long idx; \ +      size_t idx; \        trace_dump_array_begin(); \        for(idx = 0; idx < (_size); ++idx) { \           trace_dump_elem_begin(); \ @@ -142,7 +142,7 @@ void trace_dump_transfer_ptr(struct pipe_transfer *_transfer);  #define trace_dump_struct_array(_type, _obj, _size) \     do { \ -      unsigned long idx; \ +      size_t idx; \        trace_dump_array_begin(); \        for(idx = 0; idx < (_size); ++idx) { \           trace_dump_elem_begin(); \ diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 23a2473b57..bcf6751af4 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -36,12 +36,18 @@  void trace_dump_format(enum pipe_format format)  { +   if (!trace_dumping_enabled_locked()) +      return; +     trace_dump_enum(pf_name(format) );  }  void trace_dump_block(const struct pipe_format_block *block)  { +   if (!trace_dumping_enabled_locked()) +      return; +     trace_dump_struct_begin("pipe_format_block");     trace_dump_member(uint, block, size);     trace_dump_member(uint, block, width); @@ -52,6 +58,9 @@ void trace_dump_block(const struct pipe_format_block *block)  static void trace_dump_reference(const struct pipe_reference *reference)  { +   if (!trace_dumping_enabled_locked()) +      return; +     trace_dump_struct_begin("pipe_reference");     trace_dump_member(int, &reference->count, count);     trace_dump_struct_end(); @@ -60,6 +69,9 @@ static void trace_dump_reference(const struct pipe_reference *reference)  void trace_dump_template(const struct pipe_texture *templat)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!templat) {        trace_dump_null();        return; @@ -95,6 +107,9 @@ void trace_dump_template(const struct pipe_texture *templat)  void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -141,6 +156,9 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state)  void trace_dump_poly_stipple(const struct pipe_poly_stipple *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -160,6 +178,9 @@ void trace_dump_poly_stipple(const struct pipe_poly_stipple *state)  void trace_dump_viewport_state(const struct pipe_viewport_state *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -176,6 +197,9 @@ void trace_dump_viewport_state(const struct pipe_viewport_state *state)  void trace_dump_scissor_state(const struct pipe_scissor_state *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -196,6 +220,9 @@ void trace_dump_clip_state(const struct pipe_clip_state *state)  {     unsigned i; +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -221,6 +248,9 @@ void trace_dump_clip_state(const struct pipe_clip_state *state)  void trace_dump_constant_buffer(const struct pipe_constant_buffer *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -238,6 +268,9 @@ void trace_dump_shader_state(const struct pipe_shader_state *state)  {     static char str[8192]; +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -259,6 +292,9 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_  {     unsigned i; +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -307,6 +343,9 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_  void trace_dump_blend_state(const struct pipe_blend_state *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -336,6 +375,9 @@ void trace_dump_blend_state(const struct pipe_blend_state *state)  void trace_dump_blend_color(const struct pipe_blend_color *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -351,6 +393,9 @@ void trace_dump_blend_color(const struct pipe_blend_color *state)  void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     trace_dump_struct_begin("pipe_framebuffer_state");     trace_dump_member(uint, state, width); @@ -365,6 +410,9 @@ void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state)  void trace_dump_sampler_state(const struct pipe_sampler_state *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -382,7 +430,6 @@ void trace_dump_sampler_state(const struct pipe_sampler_state *state)     trace_dump_member(uint, state, compare_func);     trace_dump_member(bool, state, normalized_coords);     trace_dump_member(uint, state, prefilter); -   trace_dump_member(float, state, shadow_ambient);     trace_dump_member(float, state, lod_bias);     trace_dump_member(float, state, min_lod);     trace_dump_member(float, state, max_lod); @@ -395,6 +442,9 @@ void trace_dump_sampler_state(const struct pipe_sampler_state *state)  void trace_dump_surface(const struct pipe_surface *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -423,6 +473,9 @@ void trace_dump_surface(const struct pipe_surface *state)  void trace_dump_transfer(const struct pipe_transfer *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -454,6 +507,9 @@ void trace_dump_transfer(const struct pipe_transfer *state)  void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; @@ -472,6 +528,9 @@ void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state)  void trace_dump_vertex_element(const struct pipe_vertex_element *state)  { +   if (!trace_dumping_enabled_locked()) +      return; +     if(!state) {        trace_dump_null();        return; diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 920f418ebf..5b1e26a52d 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -38,6 +38,7 @@  static boolean trace = FALSE; +static boolean rbug = FALSE;  static const char *  trace_screen_get_name(struct pipe_screen *_screen) @@ -837,18 +838,11 @@ trace_screen_destroy(struct pipe_screen *_screen)  boolean  trace_enabled(void)  { -   return trace; -} +   static boolean firstrun = TRUE; -struct pipe_screen * -trace_screen_create(struct pipe_screen *screen) -{ -   struct trace_screen *tr_scr; -   struct pipe_winsys *winsys; -   boolean rbug = FALSE; - -   if(!screen) -      goto error1; +   if (!firstrun) +      return trace; +   firstrun = FALSE;     trace_dump_init(); @@ -862,7 +856,19 @@ trace_screen_create(struct pipe_screen *screen)        rbug = TRUE;     } -   if (!trace) +   return trace; +} + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen) +{ +   struct trace_screen *tr_scr; +   struct pipe_winsys *winsys; + +   if(!screen) +      goto error1; + +   if (!trace_enabled())        goto error1;     trace_dump_call_begin("", "pipe_screen_create"); | 
