summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_screen.c')
-rw-r--r--src/gallium/drivers/r300/r300_screen.c160
1 files changed, 75 insertions, 85 deletions
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 15740f6125..390b63007e 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,14 +80,13 @@ 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;
+ /* XXX enable now to get GL2.1 API,
+ * figure out later how to emulate this */
+ return 1;
case PIPE_CAP_TWO_SIDED_STENCIL:
if (r300screen->caps->is_r500) {
return 1;
@@ -88,53 +94,40 @@ 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 */
- return 13;
- } else {
- /* 12 == 2048x2048 */
- return 12;
- }
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- /* So, technically, the limit is the same as above, but some math
- * shows why this is silly. Assuming RGBA, 4cpp, we can see that
- * 4096*4096*4096 = 64.0 GiB exactly, so it's not exactly
- * practical. However, if at some point a game really wants this,
- * then we can remove or raise this limit. */
- if (r300screen->caps->is_r500) {
- /* 9 == 256x256x256 */
- return 9;
- } else {
- /* 8 == 128*128*128 */
- return 8;
- }
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
if (r300screen->caps->is_r500) {
- /* 13 == 4096x4096 */
+ /* 13 == 4096 */
return 13;
} else {
- /* 12 == 2048x2048 */
+ /* 12 == 2048 */
return 12;
}
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
@@ -142,10 +135,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;
@@ -183,19 +174,22 @@ 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)
+static boolean check_tex_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 +199,37 @@ 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;
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_A8L8_UNORM:
+ 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 +239,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,10 +262,15 @@ 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 */
static boolean r300_is_format_supported(struct pipe_screen* pscreen,
enum pipe_format format,
enum pipe_texture_target target,
@@ -274,15 +278,13 @@ static boolean r300_is_format_supported(struct pipe_screen* pscreen,
unsigned geom_flags)
{
switch (target) {
+ case PIPE_TEXTURE_1D: /* handle 1D textures as 2D ones */
case PIPE_TEXTURE_2D:
- return check_tex_2d_format(format, tex_usage,
- r300_screen(pscreen)->caps->is_r500);
- case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_3D:
case PIPE_TEXTURE_CUBE:
- debug_printf("r300: Implementation error: Unsupported format "
- "target: %d\n", target);
- break;
+ return check_tex_format(format, tex_usage,
+ r300_screen(pscreen)->caps->is_r500);
+
default:
debug_printf("r300: Fatal: This is not a format target: %d\n",
target);
@@ -302,35 +304,29 @@ 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;
- /* XXX Add support for these things */
- if (texture->target == PIPE_TEXTURE_CUBE) {
- debug_printf("PIPE_TEXTURE_CUBE is not yet supported.\n");
- /* offset = tex->image_offset[level][face]; */
- }
- else if (texture->target == PIPE_TEXTURE_3D) {
- debug_printf("PIPE_TEXTURE_3D is not yet supported.\n");
- /* offset = tex->image_offset[level][zslice]; */
- }
- else {
- offset = tex->offset[level];
- assert(face == 0);
- assert(zslice == 0);
- }
+ offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */
trans = CALLOC_STRUCT(r300_transfer);
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;
+
+ /* XXX not sure whether it's required to set these two,
+ the driver doesn't use them */
+ trans->transfer.zslice = zslice;
+ trans->transfer.face = face;
+
trans->offset = offset;
}
return &trans->transfer;
@@ -348,16 +344,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 +382,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);