diff options
Diffstat (limited to 'src/gallium/drivers')
71 files changed, 3552 insertions, 783 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 512d85d3525..bd48ce70050 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 648aaa0da52..49d80cb41c5 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 00000000000..e32b9102e59 --- /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 00000000000..7f079dd0a8b --- /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 00000000000..a500ec60454 --- /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 00000000000..75b73fc7df6 --- /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 00000000000..555220f8531 --- /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 00000000000..cf2ad2ce07f --- /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 00000000000..e893e599408 --- /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 00000000000..ce58faa3c7c --- /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 00000000000..cac14cfd604 --- /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 00000000000..259f1be36e7 --- /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 00000000000..2c4f1290894 --- /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 4bbedfb4d69..ff2febb668e 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 5afd028ddd2..f315cf54f05 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 b03c291f9d9..4469b22d91a 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 024356ca74c..e6924ad71eb 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 31bc1f31734..c8b40784b05 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 cb1a260eaad..44b6a74715a 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 b8b2af482a9..5d2a4216c5a 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 273142f9e0f..c2f739157ad 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 ce45055fe82..6d92ac3db9c 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 6b605ba416c..22465e02274 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 fd39fa738b7..ce8f906b15f 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 0caf4b4e914..d313e9de4fe 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 8db3b6d344d..3da9d6e7285 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 e44f9b9dfc5..faceec9842f 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 182ed2d459a..493d7b28bc3 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 27bc7fd1a93..d891fd6265f 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 678cd2b8121..c83e8526cf7 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 c86410ec0a9..6b58c1e2501 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 93cf6909a33..7ba56cdc1d2 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 946f625bd89..fda26f39481 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 89a5f2b20cf..0dff1c6f4fb 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 a1b224b39ce..9a83d89daab 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 00000000000..4b304306d0f --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs.c @@ -0,0 +1,109 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * 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 00000000000..18deb7a05e4 --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs.h @@ -0,0 +1,36 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * 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 00000000000..be4be9465e6 --- /dev/null +++ b/src/gallium/drivers/r300/r300_fs_inlines.h @@ -0,0 +1,158 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * 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 4f447ea45b8..6a7646087a7 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 3bb9bc47b50..6825d998700 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 */ - - /* 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 - - /* 0x16 - some 16 bit green format.. ?? */ +# 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 + +# 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) + # 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 a6f1efe3563..da1d5ffe2fd 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 3f52dbc3bea..2a0e41fbc3b 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 00000000000..a04f45b03e2 --- /dev/null +++ b/src/gallium/drivers/r300/r300_shader_inlines.h @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * 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 01e2b511534..68da0aa4cbb 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 e438114010c..9f534b8ce3c 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 c9e2dff14ed..fdabe4d9cfe 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 9a4c39f58bd..d01f0b143f5 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 5ea9f56247b..11c7858d422 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 98fb5c9a08f..3b56f0307c0 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 8cf8250425e..f87435f9f07 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 2c8b586c2f5..165d7178122 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 00000000000..6e05d769773 --- /dev/null +++ b/src/gallium/drivers/r300/r3xx_fs.c @@ -0,0 +1,96 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * 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 00000000000..3da39ec2526 --- /dev/null +++ b/src/gallium/drivers/r300/r3xx_fs.h @@ -0,0 +1,76 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Joakim Sindholt <[email protected]> + * + * 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 cc7f6a7c4b0..99d826278ce 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 <[email protected]> + * Joakim Sindholt <[email protected]> * * 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 b6087404cef..629e587be4d 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 <[email protected]> + * Joakim Sindholt <[email protected]> * * 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 62e8d99cfd0..86df320ea8a 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 b89a7292e5b..7888c2f644b 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 f117096bf73..d4045816d03 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 035f4b963eb..4a14d49686e 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 06725fd09b4..42021789ea8 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)); - - 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-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) ); + } } 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 692deeb8fd3..6178c4ac7e3 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 c6844a26498..de3ae3c3696 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 6b6a4c3ff34..75551000c9b 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 adbd0cb7f0c..a1d3bade27a 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 4aeb8e3d7ed..dd6831c70ab 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 00000000000..98ac75e3fa3 --- /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 00000000000..845c66a32aa --- /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 3a1409e95a7..643587ab427 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 31ac70802f0..32592bab12f 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 23a2473b574..bcf6751af4f 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 920f418ebf0..5b1e26a52d7 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"); |