diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_screen.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_screen.c | 95 |
1 files changed, 55 insertions, 40 deletions
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 15740f6125..1d9f91d0f7 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -20,7 +20,14 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "pipe/p_inlines.h" +#include "util/u_memory.h" +#include "util/u_simple_screen.h" + +#include "r300_context.h" #include "r300_screen.h" +#include "r300_texture.h" +#include "r300_winsys.h" /* Return the identifier behind whom the brave coders responsible for this * amalgamation of code, sweat, and duct tape, routinely obscure their names. @@ -73,13 +80,10 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) struct r300_screen* r300screen = r300_screen(pscreen); switch (param) { - /* XXX cases marked "IN THEORY" are possible on the hardware, - * but haven't been implemented yet. */ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: /* XXX I'm told this goes up to 16 */ return 8; case PIPE_CAP_NPOT_TEXTURES: - /* IN THEORY */ return 0; case PIPE_CAP_TWO_SIDED_STENCIL: if (r300screen->caps->is_r500) { @@ -88,26 +92,32 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) return 0; } case PIPE_CAP_GLSL: - if (r300screen->caps->is_r500) { - return 1; - } else { - return 0; - } - case PIPE_CAP_S3TC: + /* I'll be frank. This is a lie. + * + * We don't truly support GLSL on any of this driver's chipsets. + * To be fair, no chipset supports the full GLSL specification + * to the best of our knowledge, but some of the less esoteric + * features are still missing here. + * + * Rather than cripple ourselves intentionally, I'm going to set + * this flag, and as Gallium's interface continues to change, I + * hope that this single monolithic GLSL enable can slowly get + * split down into many different pieces and the state tracker + * will handle fallbacks transparently, like it should. + * + * ~ C. + */ return 1; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: - /* IN THEORY */ - return 0; + return 1; case PIPE_CAP_MAX_RENDER_TARGETS: return 4; case PIPE_CAP_OCCLUSION_QUERY: - /* IN THEORY */ - return 0; + return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: - /* IN THEORY */ - return 0; + return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: if (r300screen->caps->is_r500) { /* 13 == 4096x4096 */ @@ -142,10 +152,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) case PIPE_CAP_TEXTURE_MIRROR_REPEAT: return 1; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - /* XXX guessing (what a terrible guess) */ - return 2; + return 0; case PIPE_CAP_TGSI_CONT_SUPPORTED: - /* XXX */ return 0; case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; @@ -186,16 +194,19 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param) static boolean check_tex_2d_format(enum pipe_format format, uint32_t usage, boolean is_r500) { + uint32_t retval = 0; + switch (format) { /* Supported formats. */ /* Colorbuffer */ case PIPE_FORMAT_A4R4G4B4_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: - return usage & + retval = usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DISPLAY_TARGET | PIPE_TEXTURE_USAGE_PRIMARY); + break; /* Texture */ case PIPE_FORMAT_A8R8G8B8_SRGB: @@ -205,31 +216,35 @@ static boolean check_tex_2d_format(enum pipe_format format, uint32_t usage, case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: case PIPE_FORMAT_YCBCR: - return usage & PIPE_TEXTURE_USAGE_SAMPLER; + retval = usage & PIPE_TEXTURE_USAGE_SAMPLER; + break; /* Colorbuffer or texture */ case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8X8_UNORM: case PIPE_FORMAT_I8_UNORM: - return usage & + retval = usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DISPLAY_TARGET | PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_SAMPLER); + break; - /* Z buffer */ + /* Z buffer or texture */ case PIPE_FORMAT_Z16_UNORM: - return usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL; - + case PIPE_FORMAT_Z24X8_UNORM: /* Z buffer with stencil or texture */ case PIPE_FORMAT_Z24S8_UNORM: - return usage & + retval = usage & (PIPE_TEXTURE_USAGE_DEPTH_STENCIL | PIPE_TEXTURE_USAGE_SAMPLER); + break; /* Definitely unsupported formats. */ /* Non-usable Z buffer/stencil formats. */ - case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z32_UNORM: case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: debug_printf("r300: Note: Got unsupported format: %s in %s\n", @@ -239,7 +254,6 @@ static boolean check_tex_2d_format(enum pipe_format format, uint32_t usage, /* XXX These don't even exist case PIPE_FORMAT_A32R32G32B32: case PIPE_FORMAT_A16R16G16B16: */ - /* XXX Insert YUV422 packed VYUY and YVYU here */ /* XXX What the deuce is UV88? (r3xx accel page 14) debug_printf("r300: Warning: Got unimplemented format: %s in %s\n", pf_name(format), __FUNCTION__); @@ -263,7 +277,13 @@ static boolean check_tex_2d_format(enum pipe_format format, uint32_t usage, break; } - return FALSE; + /* If usage was a mask that contained multiple bits, and not all of them + * are supported, this will catch that and return FALSE. + * e.g. usage = 2 | 4; retval = 4; (retval >= usage) == FALSE + * + * This also returns FALSE for any unknown formats. + */ + return (retval >= usage); } /* XXX moar targets */ @@ -302,7 +322,7 @@ r300_get_tex_transfer(struct pipe_screen *screen, { struct r300_texture *tex = (struct r300_texture *)texture; struct r300_transfer *trans; - unsigned offset; /* in bytes */ + unsigned offset = 0; /* in bytes */ /* XXX Add support for these things */ if (texture->target == PIPE_TEXTURE_CUBE) { @@ -323,13 +343,14 @@ r300_get_tex_transfer(struct pipe_screen *screen, if (trans) { pipe_texture_reference(&trans->transfer.texture, texture); trans->transfer.format = texture->format; + trans->transfer.x = x; + trans->transfer.y = y; trans->transfer.width = w; trans->transfer.height = h; trans->transfer.block = texture->block; trans->transfer.nblocksx = texture->nblocksx[level]; trans->transfer.nblocksy = texture->nblocksy[level]; - trans->transfer.stride = align(pf_get_stride(&trans->transfer.block, - texture->width[level]), 32); + trans->transfer.stride = r300_texture_get_stride(tex, level); trans->transfer.usage = usage; trans->offset = offset; } @@ -348,16 +369,9 @@ static void* r300_transfer_map(struct pipe_screen* screen, { struct r300_texture* tex = (struct r300_texture*)transfer->texture; char* map; - unsigned flags = 0; - if (transfer->usage != PIPE_TRANSFER_WRITE) { - flags |= PIPE_BUFFER_USAGE_CPU_READ; - } - if (transfer->usage != PIPE_TRANSFER_READ) { - flags |= PIPE_BUFFER_USAGE_CPU_WRITE; - } - - map = pipe_buffer_map(screen, tex->buffer, flags); + map = pipe_buffer_map(screen, tex->buffer, + pipe_transfer_buffer_flags(transfer)); if (!map) { return NULL; @@ -393,6 +407,7 @@ struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys) caps->pci_id = r300_winsys->pci_id; caps->num_frag_pipes = r300_winsys->gb_pipes; + caps->num_z_pipes = r300_winsys->z_pipes; r300_parse_chipset(caps); |